Skip to main content

优化agent工具列表太多的情况

面对Agent工具列表爆炸的问题(比如几百上千个API),如果一股脑全塞进System Prompt,不仅会撑爆上下文窗口、增加推理延迟,还会因为“Lost in the Middle”现象导致模型选错工具。

我会从架构设计检索策略工具设计执行流程四个维度进行系统性优化,具体方案如下:

1. 架构层:分层路由(Hierarchical Routing)

不要把所有工具平铺给大模型,而是引入**“调度员-专家”**模式:

  • 顶级路由(粗筛):维护一个极小的“元工具”列表(如[搜索类, 代码类, 办公类, 数据库类])。Agent先通过意图识别,只选择1个类别。
  • 二级路由(细筛):确定类别后,只将该类别下的具体工具描述动态加载给LLM进行二次选择。
  • 效果:将 O(n) 的检索复杂度降为 O(1) + O(k),且顶级路由的上下文开销几乎为0。

2. 检索层:语义 + 状态感知的RAG(动态挂载)

不在System Prompt里写死工具列表,而是采用**“即用即查”**策略:

  • 向量检索(语义匹配):将每个工具的函数名+描述+入参示例转化为向量存入向量库。收到用户指令后,通过Embedding召回Top-5最相关的工具。
  • 状态过滤(硬规则):结合当前会话的上下文状态(如是否已登录、当前页面URL、上一轮报错信息),用代码规则硬过滤掉不可用的工具(例如未认证时直接屏蔽所有“写操作”工具)。
  • 热缓存:在一个多轮对话会话中,将本次用过的工具ID存入Session Cache,下一轮优先匹配缓存工具,命中则跳过检索。

3. 工具设计层:API语义压缩与合并(Merging)

很多工具数量多是因为设计得太“细碎”,需要对工具本身做**“外科手术”**:

  • 结构化输入替代多工具:将 get_user, get_user_posts, get_user_followers 三个工具合并为 get_user_info,通过入参的 fields 数组(如 fields: ["profile", "posts", "followers"])来控制返回内容。
  • 支持“万能执行器”:对于内部CRUD类操作,直接提供一个 run_sql_queryexecute_graphql 工具,交给模型生成查询语句,而不是为每个表建一个工具。
  • 精炼描述(关键):删除工具描述中的废话,采用 [用途] + [适用场景] + [禁忌] 的模板。例如,将冗长的描述改为:搜索商品(仅限电商场景,禁止搜索用户),强行降低模型的选择歧义。

4. 执行层:状态机与并行批处理

工具多不仅影响选型,还影响执行效率:

  • 构建DAG依赖图:利用LLM抽取用户的**“依赖链”**,将必须串行的工具(如先创建订单,再支付)强行绑定为一个原子操作(Tool Group)。将互不依赖的工具(如查天气 + 查汇率)标记为parallelizable,一次LLM调用触发多个工具并行执行,减少往返次数。
  • 引入“默认降级”:如果Top-1工具匹配的置信度低于阈值(如<0.7),不使用LLM硬选,而是启动一个**“交互式澄清”**(反问用户:您是想查A还是B?),避免因工具过多导致的幻觉调用。

5. 模型侧微调(进阶方案)

如果工具数量是固定的且超多(>1000),不要依赖通用模型的函数调用能力。

  • 对基座模型进行LoRA微调,将工具的分类标签(Tool Taxonomy)注入模型的内部知识权重中。让模型在推理时,输出的是工具的逻辑ID而非描述文本,这样外部只需维护一个轻量级的 ID->API-Endpoint 映射表。

总结我的核心观点不要试图让LLM在一堆泥沙中找到金子,而是先筛掉泥沙。

如果让我选性价比最高的立即生效方案,我会优先实施 “语义检索(RAG召回)” + “工具合并(fields参数化)”,这两步通常能减少80%的上下文占用,并将工具选择准确率提升至95%以上。

你的工具列表大概是什么规模的(几十个还是上千个)?主要涉及哪些业务领域?如果你愿意分享,我可以给你更具象的代码层实现建议。