这道题其实问的是,当多个工具都能干同一件事的时候,怎么选才是最优的。本质上是个多目标决策问题,要在功能正确、成本、时效性之间取一个平衡。我不会只用一个单一策略,而是倾向于分层架构:先做语义路由,快速过滤出候选集,再对候选集做多维度打分,最后动态决策。
具体来说,第一步是语义路由。我会给每个工具写一段标准化的自然语言描述,比如一个工具是'查询订单状态',另一个是'查询物流轨迹',用 [[Embedding]] 把任务和工具描述都转成向量,算相似度,选出最相关的 Top-K。这一步的目的是快速缩小范围,别让后面的打分模型处理太多无关选项。
第二步是多维度打分。这里我会看几个维度:功能匹配度是基础,历史成功率也很关键,比如某个工具对类似任务的成功率是 95%,另一个只有 70%,那肯定优先选前者。还有成本,包括 Token 消耗、API 费用、响应时间,以及当前负载,比如某个工具正在限流,就得降权。这些维度怎么组合呢?
初期冷启动时,我会用规则加启发式,比如固定优先级排序,成功率优先,成本次之,延迟最后。等积累了一些执行日志,就可以上学习式打分模型了,比如用 GBDT 或者小型神经网络,输入任务和工具的交互特征、历史指标、当前上下文,输出一个综合得分,取 Top-1。另外,为了应对不确定性,我还会保留一小部分流量做在线 Bandit 探索,用 ε-greedy 策略,避免长期固化到次优工具。
举个例子,在客服退款场景里,用户说'我买的东西降价了,能不能退差价'。这个任务可能同时匹配两个工具:一个叫'申请价格保护',另一个叫'发起售后工单'。语义路由会把两者都拉进候选集,然后打分模型一看:价格保护工具的历史成功率是 92%,平均耗时 2 秒,成本低;售后工单成功率 85%,但需要人工审核,耗时 10 分钟。系统就会优先选价格保护。如果价格保护调用失败,再降级到售后工单,并记录失败原因,回流数据更新模型。
这里有个坑:工具描述的质量直接决定语义路由的上限。如果描述写得模糊或者有歧义,比如把'查询订单'和'查询物流'写成一个意思,那第一步就歪了。所以我上线前会花精力维护标准化的工具 Schema,参照 OpenAPI 规范,配上自然语言说明,并且定期用测试用例验证召回率。另一个风险是数据稀疏,新工具上线时没有历史数据,打分模型会失效。我的做法是给新工具一个初始权重,比如假定成功率为 50%,然后靠 Bandit 快速收集数据。
说到这,还有一个延伸点值得注意:当工具数量特别多,比如几百个时,语义路由的召回效率会下降,这时候可能需要引入分层索引或者用 [[ReAct]] 让 LLM 自己做工具选择,而不仅仅是打分。这个边界怎么划,我其实还在思考。
所以,我更倾向于把工具选择看作一个持续优化的过程,不是一次定死的规则。核心是保证功能正确的前提下,用数据驱动的方式不断调优,同时做好降级兜底。