ByteNoteByteNote

字节笔记本

2026年6月21日

hermes教程-工具搜索

API中转
¥120

工具搜索

当会话中附加了大量 MCP 服务器或非核心插件工具时,它们的 JSON 模式会在每次交互中消耗相当大比例的上下文窗口——即使其中只有少数与用户实际请求相关。

工具搜索 是 Hermes 针对该问题提供的可选渐进式披露层。激活后,MCP 和插件工具会在模型可见的工具数组中被三个桥接工具替代,模型按需加载每个特定工具的模式。

信息 — Hermes 内置工具始终直接加载

构成 Hermes 核心能力集的工具(terminalread_filewrite_filepatchsearch_filestodomemorybrowser_*web_searchweb_extractclarifyexecute_codedelegate_tasksession_searchsend_message 以及其余 _HERMES_CORE_TOOLS始终直接加载。只有 MCP 工具和非核心插件工具才可被延迟加载。

工作原理

当工具搜索在某次交互中激活时,模型会看到三个新工具替代了被延迟的工具:

text
tool_search(query, limit?)     — 搜索延迟工具目录
tool_describe(name)            — 加载某个工具的完整模式
tool_call(name, arguments)     — 调用一个延迟工具

典型的交互流程如下:

text
模型: tool_search("create a github issue")
  → { matches: [{ name: "mcp_github_create_issue", ... }, ...] }
模型: tool_describe("mcp_github_create_issue")
  → { parameters: { type: "object", properties: { ... } } }
模型: tool_call("mcp_github_create_issue", { title: "...", body: "..." })
  → { ok: true, issue_number: 42 }

当模型调用 tool_call 时,Hermes 解包桥接并调度底层工具,就像模型直接调用它一样。工具调用前的钩子、护栏、审批提示以及工具调用后的钩子都针对真实工具名称运行——而不是针对 tool_call。CLI 和网关中的活动提要也会解包,以便你看到底层工具,而不是桥接工具。

何时激活?

默认情况下,工具搜索以 auto 模式运行:仅当可延迟工具模式会消耗活动模型上下文窗口至少 10% 时才会激活。低于该阈值时,工具数组的组装是纯直通的,不会产生额外开销。

每次构建工具数组时都会重新评估此决策,因此:

  • 只有少量 MCP 工具且使用长上下文模型的会话永远不会激活工具搜索。
  • 附加了大量 MCP 服务器(通常 15 个以上工具)的会话会开始激活它。
  • 在会话中途移除 MCP 服务器会正确地在下次组装时恢复为直接暴露。

配置

yaml
tools:
  tool_search:
    enabled: auto       # auto(默认)、on 或 off
    threshold_pct: 10   # 上下文百分比——仅在 auto 模式下使用
    search_default_limit: 5
    max_search_limit: 20
默认值含义
enabledautoauto 在超过阈值时激活;on 在至少有一个可延迟工具时始终激活;off 完全禁用。
threshold_pct10auto 模式启动的上下文长度百分比。范围 0–100。
search_default_limit5模型调用 tool_search 时未指定 limit 时返回的命中数。
max_search_limit20模型通过 limit 可请求的硬上限。范围 1–50。

你也可以使用旧的布尔形式:

yaml
tools:
  tool_search: true   # 等同于 {enabled: auto}

何时不使用

工具搜索用固定的每次交互令牌成本(三个桥接工具模式,约 300 个令牌)和至少一次额外的往返(搜索 → 描述 → 调用)来换取延迟模式的节省。当你拥有大量工具但每次交互只使用少数几个时,这是明显的优势;当工具总数很少时,它反而成为开销。

auto 默认值会为你处理这一点。如果你无条件设置 enabled: on,在小型工具集上预计会有轻微的每次交互成本。

无法避免的权衡

这些源于提示缓存完整性不变性——它们是任何渐进式披露设计固有的,并非此实现特有:

  • 冷工具的一次额外往返。 模型首次需要某个延迟工具时,会花费一两次额外的模型调用来查找并加载模式。静态方面的令牌节省是真实的,但部分会在运行时被抵消。
  • 延迟模式无缓存收益。 加载的 tool_describe 结果会进入对话历史(因此在后续交互中确实会被缓存),但它永远无法从系统提示缓存前缀中受益。
  • 模型质量依赖。 工具搜索假设模型能够为其所需的工具编写合理的搜索查询。较小的模型在这方面表现较差;已发布的 Anthropic 数据(Opus 4 上使用工具搜索与不使用相比,从 49% 提升到 74%)显示了优势,但也表明仍有约 26 个百分点的准确率是检索失败。
  • 工具集编辑会使缓存失效。 在会话中途添加或移除工具会改变桥接工具的描述(其中包含延迟工具的数量)和目录,因此提示缓存会失效。这与任何工具集编辑的权衡相同。

实现细节

  • 检索: 对分词后的工具名称 + 描述 + 参数名称进行 BM25 检索。当 BM25 返回无正得分命中时,回退到工具名称的字面子串匹配,这可以防止零 IDF 退化情况(例如,在目录中每个工具名称都包含 "github" 时搜索 "github")。
  • 目录在交互之间无状态。 每次组装时都会从当前工具定义列表重新构建——没有会话键控的 Map。这避免了存储的目录与实时工具注册表不同步的 bug 类别。
  • 目录范围限定于会话的工具集。 tool_searchtool_describetool_call 只能看到和调用会话实际被授予的工具。子代理、看板工作器或网关会话如果被限制在工具子集内,则无法使用桥接来发现或调用该子集之外的工具——延迟目录是会话自身启用/禁用工具集中可延迟的部分,而不是整个进程注册表。
  • 无 JS 沙箱。 Hermes 使用更简单的“结构化工具”模式(将 search / describe / call 作为普通函数)。其他一些实现提供的 JS 沙箱“代码模式”攻击面较大;我们跳过它。

另请参阅

  • tools/tool_search.py — 实现
  • tests/tools/test_tool_search.py — 回归测试套件
  • 原始实现 PR 中的 openclaw-tool-search-report PDF,其中包含塑造该设计的研究

分享: