Skip to content

[bug] SkillToolSet.get_tools() 在 is_include_all_tools=False 时仍忽略 tool_filter #352

Description

@kinolo

问题描述

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。

相关代码:

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

  1. changed the title [-]bug: SkillToolSet.get_tools() 在 is_include_all_tools=False 时仍忽略 tool_filter[/-] [+][bug] SkillToolSet.get_tools() 在 is_include_all_tools=False 时仍忽略 tool_filter[/+] on Sep 30, 2026
  2. added a commit that references this issue on Sep 30, 2026
    e24e06c
  3. raychen911 commented on Oct 9, 2026

    @raychen911
    Contributor

    提交pr:#357

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions