延迟展示与工具搜索入口、BM25 匹配元数据而非业务正文、搜索成功≠业务成功,以及和 Code Mode 目录发现的区分。
规则、权限、长命令讲完后,工具会越来越多:查代码、读文档、看任务记录,参数各不相同。每次把全部工具说明塞进请求会越来越长;只给一个名字又容易猜错用法。第八章讲 Codex 如何先登记工具,任务需要时再把相关定义交给模型——按需发现。
两层状态
- 工具已接入:程序里有执行入口;
- 模型当前能看到多少说明:由另外一层决定——注册表里可以有工具,却不把完整参数提前放进这次请求。
一部分工具直接可用,另一部分放在延迟发现范围,等任务提出具体需求再选出相关定义。按需发现会多出搜索与结果回传;工具很少时直接给定义可能更简单,来源很多时选择性展开更有价值。这是使用取舍,不是「工具越多一定越快」的保证。
何时放入「工具搜索」入口
计划综合:模型是否支持工具搜索、提供方是否支持命名空间、工具自身曝光设置等,区分直接展示、延迟展示、仅在 Code Mode 中调用、隐藏等情况。有些工具可同时支持代码调用与直接调用。搜索条件满足且注册表确有可检索的延迟工具时,才放入工具搜索入口——不要把「当前看见了搜索工具」推广成所有客户端默认一样。延迟工具是在等合适时机展示;搜不到时先查它有没有进入本次可搜索范围。
BM25:匹配的是元数据,不是业务正文
把工具名称、描述、参数信息整理成检索文本(下划线可拆成空格;参数名、说明与嵌套字段也可加入),用 BM25 做文本相关性检索——按词挑出较相关的工具候选。这是元数据匹配,不是模型已理解并搜索了所有业务数据。想找项目缺陷记录时,搜的是「哪个工具能查记录」;记录正文写了什么,要等到实际调用工具才拿到。因此工具描述很重要:名字太泛、说明只有一句「万能查询」,模型与检索都缺少区分依据;写清对象、动作与关键参数,比宣传性形容词更有价值。
搜索调用本身
提交查询词,还可给数量限制。处理器去掉两端空白;空查询返回参数错误;数量限制为 0 也会被拒绝。参数有效后在已有索引里搜索:无可搜索条目可返回空列表;有条目但无合适匹配时,也不应编造「最接近」的工具名。命中结果整理成可加载的工具定义,同一命名空间内容会被组合——包含后续调用需要的名字、说明与输入结构。搜索成功只说明拿到了候选定义,没有替你查缺陷,也没填好所有后续参数;下次模型请求要结合定义再决定调哪个、带哪些参数。
时间线:搜索与执行分开看
模型发起工具搜索 → 客户端处理查询 → 定义放进专门的工具搜索结果条目(带回 call id)→ 进入后续模型输入 → 模型读到新定义后组织真正的业务工具调用 → 业务工具再返回记录或错误。调试要分别看两次输入输出:搜索是否返回合适定义;实际调用是否符合定义、有没有拿到证据。不要只看「搜索工具显示已完成」就把后续业务动作当成成功。
搜索处理器缓存
每次准备请求都重建同一份索引有开销。缓存会比较当前可搜索来源与已缓存来源,条件一致则复用。固定工具可按执行对象身份判断是否同一份;动态说明则比较搜索信息来源或展示设置是否变化。缓存不能只按工具名称保存——同名工具的定义、描述与来源可能已变。模型看到的来源概述可能放在搜索说明或单独上下文状态里;范围仍来自当前登记的能力,不是扫描互联网上所有工具。
与 Code Mode 的发现方式区分
打开 Code Mode 后,JS 里还可访问 tools 一类目录,列出当前启用的嵌套工具名称与描述;实际调用入口在 tools 对象上。有些延迟工具的完整说明未提前写进 exec 描述,仍可出现在这份目录里。这与客户端 BM25 搜索不是同一逻辑:一个是专门的工具搜索请求,一个是代码运行环境中的元数据数组。无论哪条路径,目录只代表当前可枚举范围;枚举到名字 ≠ 无需审批 ≠ 业务结果已返回。
排错路径
- 查询词不合法 → 改查询参数;
- 候选为空 → 确认工具是否启用、有无可检索说明、关键词是否合适;
- 有候选却不会调用 → 看定义里的输入参数与描述,别靠名字猜(不同来源都可能叫 search);
- 已发出调用但遇授权/审批/沙箱 → 进执行策略排查,重复搜索解决不了已明确的权限问题;
- 业务工具失败 → 按返回内容处理。
把搜索原文、命中定义、实际调用参数放在一起核对,分清是没暴露、描述不清,还是模型选择与执行出了问题。
自己写工具描述时
直接写对象与动作,例如「按项目标识搜索缺陷记录」;写清返回摘要还是全文;哪个字段接项目编号、哪个接查询词、哪些限制必须满足。有副作用的工具要把读取/更新/删除写明白。说明清楚 ≠ 执行时免权限检查——检索依据主要来自你提供的元数据,后续调用又依赖同一份定义。
下一期把几次调用写进一小段代码:Code Mode 如何用 JS 编排工具调用与等待。