Repository navigation
[bug] SkillToolSet.get_tools() 在 is_include_all_tools=False 时仍忽略 tool_filter #352
Description
问题描述
SkillToolSet 接收 tool_filter 和 is_include_all_tools 参数,但在显式设置 is_include_all_tools=False 后,get_tools() 仍返回全部工具,没有应用过滤器。
该问题同时存在于首次构建工具列表和后续缓存返回路径。工具名称列表过滤和谓词过滤均不生效。
复现环境
- Python:3.12.14
- SDK:1.2.0,源码安装
- Commit:
02509b20ef83f287c65d0a6e5aee803477e9d9a4
最小复现
无需模型 API Key,也无需实际执行 Skill:
import asyncio
import tempfile
from trpc_agent_sdk.skills import SkillToolSet
async def main():
with tempfile.TemporaryDirectory() as path:
toolset = SkillToolSet(
paths=[path],
tool_filter=["skill_load"],
is_include_all_tools=False,
)
# 分别验证首次构建和缓存返回路径
for label in ("first", "cached"):
names = [tool.name for tool in await toolset.get_tools()]
print(label, names)
asyncio.run(main())预期行为
两次调用均只返回:
['skill_load']
实际行为
两次调用均返回全部 10 个工具:
['skill_load', 'skill_run', 'skill_exec',
'workspace_save_artifact', 'workspace_exec',
'workspace_write_stdin', 'workspace_kill_session',
'skill_list', 'skill_list_docs', 'skill_select_docs']
另外,传入始终返回 False 的谓词,并设置 is_include_all_tools=False 时,仍返回全部工具,谓词调用次数为 0。
原因分析
构造函数已将过滤参数传入 ToolSetABC,但 SkillToolSet.get_tools() 没有调用基类的 _is_tool_selected():
- 缓存路径直接返回
self._default_tools.copy()。 - 首次构建路径直接返回
tools。
相关代码:
trpc-agent-python/trpc_agent_sdk/skills/_toolset.py
Lines 148 to 187 in 02509b2
| async def get_tools(self, invocation_context: Optional[InvocationContext] = None) -> List[ToolABC]: | |
| """Get all tools from registered skills. | |
| Args: | |
| invocation_context: Optional invocation context (not used currently) | |
| Returns: | |
| List of tools from all registered skills | |
| """ | |
| if self._repo_resolver is not None: | |
| repository = self._repo_resolver(invocation_context) | |
| else: | |
| repository = self._repository | |
| if not invocation_context: | |
| invocation_context = get_invocation_ctx() | |
| if invocation_context: | |
| agent_context = invocation_context.agent_context | |
| agent_context.with_metadata(SKILL_REGISTRY_KEY, SKILL_REGISTRY) | |
| agent_context.with_metadata(SKILL_REPOSITORY_KEY, repository) | |
| if not is_exist_skill_config(agent_context): | |
| set_skill_config(agent_context, self._skill_config) | |
| if self._default_tools: | |
| return self._default_tools.copy() | |
| tools: List[ToolABC] = [] | |
| tools.append(self._load_tool) | |
| tools.append(self._run_tool) | |
| tools.append(self._exec_tool) | |
| tools.extend(self._runtime_tools) | |
| skill_functions: List[SkillToolFunction] = SKILL_REGISTRY.get_all() | |
| skill_functions.extend(self._function_tools) | |
| for skill_function in skill_functions: | |
| try: | |
| tools.append(FunctionTool(func=skill_function)) | |
| except Exception as ex: # pylint: disable=broad-except | |
| # Log error but continue loading other tools | |
| logger.warning("Failed to get tools from skill '%s': %s", skill_function.__name__, ex) | |
| continue | |
| self._default_tools.extend(tools) | |
| return tools |
影响
调用方无法通过该配置限制暴露给 Agent 的工具集合。本地进一步通过 ToolsProcessor.process_llm_request() 验证,全部 10 个工具也会进入模型请求的工具声明,而不是在后续流程中被过滤。
建议修复
保留完整的工具缓存,并在每次返回前调用 _is_tool_selected(tool, invocation_context),同时覆盖首次构建和缓存路径,以支持基于当前上下文的谓词过滤。
补充说明:默认 is_include_all_tools=True 时忽略过滤器符合基类现有逻辑,本 issue 针对的是显式设置为 False 后仍不生效的情况。
Activity
[-]bug: SkillToolSet.get_tools() 在 is_include_all_tools=False 时仍忽略 tool_filter[/-][+][bug] SkillToolSet.get_tools() 在 is_include_all_tools=False 时仍忽略 tool_filter[/+]skills: apply tool_filter in SkillToolSet.get_tools
raychen911 commentedon Oct 9, 2026
提交pr:#357