问题描述
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())
预期行为
两次调用均只返回:
实际行为
两次调用均返回全部 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。
相关代码:
|
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 后仍不生效的情况。
问题描述
SkillToolSet接收tool_filter和is_include_all_tools参数,但在显式设置is_include_all_tools=False后,get_tools()仍返回全部工具,没有应用过滤器。该问题同时存在于首次构建工具列表和后续缓存返回路径。工具名称列表过滤和谓词过滤均不生效。
复现环境
02509b20ef83f287c65d0a6e5aee803477e9d9a4最小复现
无需模型 API Key,也无需实际执行 Skill:
预期行为
两次调用均只返回:
实际行为
两次调用均返回全部 10 个工具:
另外,传入始终返回
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
影响
调用方无法通过该配置限制暴露给 Agent 的工具集合。本地进一步通过
ToolsProcessor.process_llm_request()验证,全部 10 个工具也会进入模型请求的工具声明,而不是在后续流程中被过滤。建议修复
保留完整的工具缓存,并在每次返回前调用
_is_tool_selected(tool, invocation_context),同时覆盖首次构建和缓存路径,以支持基于当前上下文的谓词过滤。补充说明:默认
is_include_all_tools=True时忽略过滤器符合基类现有逻辑,本 issue 针对的是显式设置为False后仍不生效的情况。