4.8 主动工具发现
前面讨论了单个工具的设计原则与工具生态。但当可用工具从十几个增长到成百上千,新问题随之而来------如何从庞大的工具库中高效找到当前需要的那一个?本节先精简回顾现有的工具发现方法(检索预筛选、主动声明、层次化匹配),再介绍近来更流行、也更轻量的 Skills 渐进式披露思路。
4.8.1 现有工具发现方法
传统方案:将全部工具schema一次性写入系统提示词。工具数量达到上千时,会占用大量上下文,模型选择精度下降。检索式预筛选通过语义相似度预先筛选候选工具,缓解该问题,但存在局限:仅基于用户初始查询一次性匹配,而复杂任务(例如调试文件)需要多步、跨领域工具链,任务初期无法预判全部所需工具。
从被动选择到主动发现
让Agent在执行过程中识别自身能力缺口,用自然语言声明所需能力,系统动态匹配并注入工具。MCP-Zero是代表性工作:系统提示词不预置任何工具schema,Agent生成结构化能力请求,系统采用服务器级→工具级两层语义路由 ,在上千工具中匹配,相比全量注入节省约98% token。
工程常见实现:系统提示词仅保留少量基础工具(网页搜索、代码解释器)外加工具搜索元工具,Agent使用自然语言描述需求,检索并加载对应工具,Anthropic Claude API的Tool Search Tool属于该方案。
层次化匹配与降级
MCP协议中将工具按服务器分组(类似App,一个服务器承载一组相关工具),分两层匹配:
- 服务器层:按能力描述匹配相关MCP服务器
- 工具层:在目标服务器内部匹配具体工具
将搜索空间从数千个工具缩小,降低算力消耗与跨领域语义混淆。底层依赖可增量更新的离线嵌入索引;两层匹配相似度均低于阈值时,返回"未找到",交由Agent改写需求重试、使用基础工具实现,或新建工具(工具创建见第八章)。
动态加载与KV Cache
朴素方案:全部工具schema放入系统提示词,新增工具会直接导致KV缓存整体失效,缓存命中率极低,首token延迟高。
优化方案:系统提示词保持固定(角色、规则、基础工具,保持KV缓存稳定),变动的工具schema追加到对话轨迹末尾;仅在Agent状态栏维护简短工具名称列表。
主流框架API都采用该架构:OpenAI Responses API的tool_search+defer_loading: true;Claude Code对MCP工具延迟加载;Codex CLI默认开启BM25工具检索。
限制:模型需要专门训练才能理解散落在上下文各处的工具定义;能力弱的模型容易生成非法JSON调用。
上下文结构要点:
- 静态前缀(system prompt、基础工具、discover_tools元工具)固定不变,保证KV缓存命中
- 每次检索得到的工具schema固定追加在轨迹某一位置,后续轮次不再重复注入,作为历史信息复用
- 修改、删除、重排已加载工具会造成缓存从变动位置失效;TTL过期属于独立缓存失效,非工具动态加载特有问题
实验4-6 ★★★:主动工具发现
验证主动工具发现对小参数量模型的提升,使用Qwen3-4B访问包含120+工具的MCP服务器。
任务示例:查询苹果股价+搜索相关新闻;arXiv检索并下载Transformer论文;统计GitHub仓库贡献者并生成可视化报告。
- 对照组:一次性注入全部120+工具schema(>50K tokens)。长上下文造成4B模型指令跟随退化,选错工具、遗忘工具,任务失败。
- 实验组:MCP-Zero主动发现+工具搜索元工具。
- system prompt仅保留web_search、code_interpreter、discover_tools;
- Agent描述自然语言能力需求,向量相似度匹配返回3~5个候选工具及schema;
- 新工具定义追加至对话历史,状态栏更新工具名称;
- 模型遇到能力缺口时主动调用discover_tools。
预期结果:任务完成率、准确率显著提升。主动工具发现不仅服务大模型,也让小模型在上百工具场景下可用。
4.8.2 Skills:把工具发现变成"按需查阅"
Skills渐进式披露是更轻量的新范式,不需要向量索引、语义匹配这类基础设施 。
区别于MCP一次性暴露schema的模式:Agent启动仅加载技能目录(skill名称+简短描述,token量很小)。只有上下文确实需要某项能力时,模型才读取对应子技能,顺着引用逐层读取脚本、子文档。发现动作由任务执行过程驱动,而非任务开始时一次性预匹配。
类比查阅工具书:不需要加载全书,顺着目录,用到哪一条查阅哪一条。Agent依靠基础文件读取能力翻阅技能目录,无需单独实现工具检索模块。
Skills场景下的KV Cache:
加载子技能等价于向上下文插入内容,同样可以追加至末尾复用前缀缓存。但Skills会跨会话反复加载,反复prefill开销高。解决方案是可编辑可组合KV Cache:将每个skill的KV表示预编译缓存,借助RoPE重定位,以更低代价将技能片段拼入上下文;技能小幅更新可以增量勘误,不需要整体重算,解决反复加载带来的性能损耗。