Appearance
通常来讲,真正能落地的Agent基本不应该凭感觉选工具,而是应该把工具做成一个受约束的排序决策问题,最稳的做法不是让大模型拍脑袋决定,而是考虑分成三层
- 先做硬约束过滤,把根本不该用的工具剔除掉
- 再做候选打分/排序,在可用工具里选取最合适的
- 最后根据任务性质决定是单选执行还是并行调用后再融合结果
比如“搜集harness学习资料”的任务,可能用到了web_search、search_library、fetch_url,但是他们承担的角色不同,分别对应发现外部来源、查找本地知识、精读具体链接,如果没有选择模块,常见的问题是「调用错工具」、「重复调用」、「结果不稳定」、「调用成本失控」等,因此成熟的Agent一般都会引入某种显式或者隐式的评分/排序模块,区别在于他是简单规则、还是加权打分还是llm选择器还是别的
工具选择的标准流程
- 任务标准化
- 用户的原始输入通常是自然语言,系统要先转成结构化的参数,这一步的价值是让后面工具的路由不再面对模糊文本,而是面对可判断的任务槽位
- 工具能力建模
- 给每个工具维护一份画像,它擅长什么、不擅长什么、输入要求、平均延迟、平均成功率、是否有副作用、是否需要授权、最近健康度等
- 候选集生成
- 根据任务类型框出可能的工具,再用硬规则过滤,比如用户没有授权写操作的时候,所有修改类的工具必须直接剔除,任务只需要本地知识的时候,联网搜索可以降权甚至禁用
- 打分与排序模块
- 通常会考虑7类因素,任务相关度、历史成功率、工具可靠性、新鲜度价值、延迟、成本、风险,最基础的做法是加权打分
排序
真实系统一般还要区分 工具排序和结果排序
工具排序主要解决的是该调用谁,结果排序解决的是调用回来后信任谁
比如你选择了 web_search,它返回 10 条链接,但并不是每条都适合用户学习,这时还需要第二层排序:官方文档通常比普通博客优先,系统设计文章通常比营销页优先,概览型教程可能比细碎论坛帖优先,更新日期过旧的内容可能降权
是否要引入 LLM 参与选择,答案是可以,但不该让它独裁。LLM 很适合做语义理解,比如判断“这个任务更像资料搜集、精读分析,还是数据读取”,也适合在多个候选工具能力相近时提供软判断;但它不适合单独承担最终决策,因为它对成本、权限、副作用、系统健康度这些工程变量不敏感,也容易出现“工具幻觉”——明明没有这个能力,却自信地选择某个工具。所以更稳的架构是:LLM 负责把自然语言任务转成结构化需求,规则与评分器负责最后裁决。如果你想进一步提高系统自适应能力,可以在评分器之上加一层历史反馈学习机制,把每次调用后的结果记录下来,例如记录:任务类型、所选工具、执行耗时、是否成功、用户是否接受结果、是否发生重试。随着数据积累,各个参数就不再是人工写死,而是动态更新的统计值。再往上走,可以做成 contextual bandit 或 learning-to-rank,让系统在不同任务上下文中逐渐学会“这类任务应该更偏向某类工具”。但这是第二阶段工作,第一版系统完全没必要直接上 RL;对大多数团队来说,静态规则 + 加权打分 + 历史反馈修正已经能解决 80% 的问题。
什么时候该单选,什么时候该并行,也是选择策略里非常重要的一部分。原则很简单:搜索类、读取类、互补类任务适合并行;执行类、写入类、有副作用类任务尽量串行。比如“搜集 harness 学习资料”时,本地知识库检索和外部网络搜索天然互补,那就应该并行,最后再融合;但如果是“修改配置文件”或“删除数据”,绝不能因为两个工具都能做就并行尝试。这种策略有点像数据库里的优化器:不是任何时候都追求一次命中,而是根据任务的错误代价决定你是“探索多个候选”还是“保守地选一个”。工程上常见做法是:给任务打标签,task.mode in ["search", "read"] 时允许 top-2 并行;task.mode in ["write", "execute"] 时只允许 top-1 执行,并且优先低风险链路