一次搜索、三个问题:tool_search 多查询与词干提取升级

你的 agent 需要一个工具——也许它要在同一个任务里创建 GitHub issue、发 Slack 消息、还要搜网页。旧系统下,这是三次独立的 tool_search 调用;如果它拼错一个查询(“issuse” 而不是 “issues”)、或者搜的词和工具名对不上,就会空手而归,只能重来。每一次落空都烧 token、拖延迟。Hermes v0.20.6 用一次对 tool_search 的认真升级(提交 e455e4afd0)修掉了这个问题:多查询搜索、批量 describe、Snowball 词干提取。
改动外形小、行为变化大:tool_search 现在接受 queries: string[],在同一目录里并行搜索;结果按查询分组返回,共享一份工具元数据表,记录每个命中工具的来源、描述和必填参数名。tool_describe 接受 names: string[],返回按名称索引的 map——一个名字写错不再拖垮整次调用。Snowball 词干提取让 “issues” 能命中名为 create_issue 的工具,“browsing” 能找到 browser_exec。来看改了什么、为什么重要。
旧方式 vs 新方式
以前: 一次调用一个查询、近似匹配、查询落空时每次响应都带 fallback:
tool_search("browser") → 一个匹配列表
tool_search("web search") → 又一次调用、又一个列表
tool_search("read pdf") → 第三次调用
现在: 一次调用、多个查询、分组结果:
{ "queries": ["browser snapshot", "web search cache", "read pdf"] }
每个查询都在同一目录里独立搜索,limit 按查询生效(默认 5,钳制到配置上限 25),响应按查询分组返回工具名,一份共享的 tools map 承载每个工具的来源、描述(400 字上限)和必填参数名——只加载一次,不按查询重复。部分查询落空时,单个顶层 available_sources + hint 块取代旧的逐响应 fallback。
工具定义里的真实 schema:
queries:字符串数组,“每个查询用几个关键词描述一种能力(例如['create github issue', 'send slack message'])。并行搜索;结果按查询分组返回。单个字符串也接受,视为一个查询。”limit:“每个查询的最大匹配数。默认 5,钳制到配置上限(默认 25)。”
词干提取:匹配你想表达的意思,而不是你敲的字
这个改动里安静的主角是 Snowball 词干提取(英语)。词干器在索引路径(构建目录时)和查询路径上以完全相同的方式生效,所以 “issues” 能命中名为 create_issue 的工具,“browsing” 命中 browser_exec,“searches” 命中 web_search。你不用再猜准确的动词形态或复数形式——引擎把两边都归一化了。
值得一提的实现细节:Snowball 词干器实例持有可变的解析状态,跨线程不安全——而 bridge 分发可能跑在并行的工具调用线程上。Hermes 的做法是每线程惰性创建一个词干器——一个藏在功能里的小而真实的正确性修复。
tool_describe:批量名称、软失败
tool_describe 得到同样的待遇:现在接受 names: string[],返回按名称索引的 map。未知名称收进 not_found(带刷新提示),不可延迟的名称在 errors 里保留各自的拼写检查错误——一个坏名字不再让整次调用失败。重复项静默去重。所以多查询 tool_search 之后,agent 可以一次 describe 好几个候选,拼错的名字只换来一条备注,而不是一次重试。
实际意义
三个实打实的收益:
- 更少的往返。 需要三种能力的任务一次
tool_search搞定,然后一次批量tool_describe。调用变少 = 延迟更低、模型掉线的机会更少。 - 更便宜的发现。 共享工具表意味着每个命中工具的元数据只发一次,不按查询重复——而且同一窗口内的 schema 精简工作还顺带把
browser_exec从 803 减到 663 token/次调用。工具发现是长任务里最烧 token 的环节之一,这里被削了一刀。 - 更好的召回。 词干提取干掉“接近但不精确”这一整类落空:“issues” →
create_issue、“browsing” →browser_exec、“searches” →web_search。即使查询措辞略有偏差,agent 也能找到对的工具。
对你的工作流意味着什么
工具发现是不可见的管道——不失败你永远看不到它,而一旦失败,agent 要么瞎折腾、要么选一个“接近但错误”的工具。多查询 + 词干提取 + 批量 describe 移除了大部分失败面。正是这类升级让长时间自主运行(批量任务、cron 作业、委派子任务)明显不再脆弱:agent 一个任务需要浏览器工具、搜索工具和 PDF 阅读器时,一次就能全找到。
想了解工具本身,看我们的命令全景了解 tool_search 能搜到的完整表面,浏览器快照预算了解浏览器会话如何保持廉价,web 搜索缓存了解同窗口的姊妹缓存升级。v0.20.6 完整解读见发版记录。
一次调用、三个查询、词干归一、分组去重——agent 更快更便宜地找到对的工具,“我找不到这个工具”的抱怨一天天变少。