AI Agent入门实战第8篇,Spring AI Alibaba多工具协同实战--从“一把锤子”到“全套工具箱”
让Java开发者像写Spring Boot一样开发AI应用——第二阶段第二篇
写在前面
第七天,我们学会了如何给Agent装上第一个工具——让它从“只会说”变成了“会做一件事”。
但现实世界的问题,从来不是靠一个工具就能解决的。
一个旅行规划Agent,需要查天气、搜酒店、找景点;一个智能客服Agent,需要查订单、退换货、转人工;一个数据分析Agent,需要查数据库、算指标、出图表。
如果只给Agent一个工具,它就像一个只有一把锤子的工匠——看什么都像钉子。
今天的主题,就是给Agent配齐“全套工具箱”——多个工具如何注册、如何协同、如何让Agent在它们之间自动做出正确选择。
一、多工具注册:让Agent拥有“全套工具箱”
为什么需要多工具?
第七天的Agent只有一个工具,就像一个只有一把锤子的工匠——什么都是钉子。今天的Agent有多个工具,就像拥有全套工具箱的工匠——锯子、扳手、螺丝刀各司其职。
在真实的业务场景中,一个Agent往往需要多种能力:
| 场景
|
需要的工具
旅行规划
|
天气查询、酒店搜索、景点推荐、交通查询
| |
智能客服
|
订单查询、退换货处理、人工转接、知识库检索
| |
数据分析
|
数据库查询、指标计算、图表生成、报告撰写
|
两种注册方式
方式一:批量注册(推荐)
<span leaf=""><span>// 使用 methodTools() 一次注册多个工具对象</span></span>
方式二:混合注册
<span leaf=""><span>// 同时使用 @Tool 注解和 FunctionToolCallback</span></span>
💡 两种注册方式可以混合使用——不需要把所有工具统一成一种风格,可以根据实际情况灵活选择。
二、Agent如何自动选择工具?
当Agent拥有多个工具时,模型需要决定“调用哪个工具”。这个决策过程由模型自动完成,核心依据是工具的描述(description)。
决策流程
<span leaf="">用户输入:”帮我规划一下杭州三日游”</span>
影响模型选择的关键因素
| 因素
|
权重
|
说明
| 工具描述 |
★★★★★
|
模型通过描述判断工具是否匹配当前任务
| | 参数名称与描述 |
★★★★
|
模型通过参数判断能否从用户问题中提取正确参数
| | 工具名称 |
★★★
|
语义清晰的名称帮助模型快速识别
|
⚠️ 工具描述是影响模型选择准确性的最关键因素。描述写得好,模型选得准;描述写得差,模型可能选错甚至不选。
三、工具依赖链:流水线上的接力赛
什么是工具依赖链?
在实际业务中,工具之间往往存在依赖关系——一个工具的输出,是另一个工具的输入。
典型场景:旅行规划
<span leaf="">用户:”帮我规划杭州三日游”</span>
💡 工具依赖链就像工厂的流水线——上一道工序的产品,是下一道工序的原材料。
Spring AI Alibaba中的三种实现方式
方式一:通过State传递(ReAct Agent自动处理)
ReAct Agent的State机制天然支持工具间的数据传递。当模型连续调用多个工具时,前一个工具的输出会自动存入State,后一个工具可以从State中读取。开发者不需要手动编写粘合代码。
方式二:使用占位符传递(多Agent场景)
<span leaf=""><span>// 第一个Agent:获取位置</span></span>
方式三:在工具内部组合调用
如果依赖关系比较复杂,也可以在工具方法内部直接调用其他工具。
依赖链设计原则
| 原则
|
说明
| 单一职责 |
每个工具只做一件事
| | 接口清晰 |
输入输出类型明确
| | 依赖方向 |
单向依赖,避免循环
| | 可测试性 |
每个工具可以独立测试
| | 容错设计 |
任何一环失败都要有处理
|
四、异常处理与降级:生产环境的必修课
在生产环境中,工具调用失败是常态而不是异常。设计时就要把“失败”当作一种正常情况来考虑。
常见的工具调用异常
| 异常类型
|
原因
| 网络超时 |
外部API响应慢或不可达
| | 参数错误 |
模型提取的参数格式不正确
| | 服务不可用 |
依赖的第三方服务宕机
| | 数据异常 |
返回的数据格式不符合预期
|
策略一:工具内部捕获异常
<span leaf=""><span>@Tool</span>(description = ”查询城市天气”)</span>
策略二:使用ModelRetryInterceptor自动重试
Spring AI Alibaba提供了ModelRetryInterceptor,可以自动重试失败的模型调用:
<span leaf=""><span>ModelRetryInterceptor</span> <span>retryInterceptor</span> <span>=</span> ModelRetryInterceptor.builder()</span>
重试策略:第1次重试等待1000ms,第2次等待2000ms,第3次等待4000ms。
策略三:降级方案
| 降级方案
|
说明
| 返回默认值 |
返回缓存数据或合理的默认结果
| | 跳过该工具 |
让模型用自己的知识回答
| | 使用备用数据源 |
切换到备用的第三方API
|
五、工具描述优化:让模型“看得懂”
为什么工具描述如此重要?
模型的工具选择完全依赖于工具描述。描述是模型与工具之间的唯一“桥梁”。
💡 工具描述就像招聘广告——写得好,合适的人(模型)会主动投简历(调用工具);写得差,要么没人来,要么来一堆不合适的人。
优秀描述的四个规范
规范一:明确“何时调用”
<span leaf=""><span>// ❌ 差:太模糊</span></span>
规范二:详细说明参数
<span leaf=""><span>// ❌ 差</span></span>
规范三:说明返回值格式
<span leaf=""><span>@Tool(</span><span><span>description = ”””</span></span></span>
规范四:区分相似工具
<span leaf=""><span>// 工具A:查询实时天气</span></span>
工具数量控制的建议
当一个Agent注册的工具太多时:
-
工具越多,提示词越臃肿,Token成本线性增长
-
工具越多,模型选择越不稳定
-
工具越多,团队协作越脆弱
建议:单个Agent的工具数量控制在5个以内。
如果确实需要很多工具,可以考虑:
-
使用RoutingAgent按领域分组分发
-
使用Skill机制按需发现和加载工具
-
使用Tool Search动态匹配工具
六、实战:旅行规划工具集
系统设计
构建一个“旅行规划工具集”,包含三个协同工作的工具:
| 工具
|
职责
|
依赖
getLocation |
根据城市名获取经纬度
|
无
|
| getWeather |
根据经纬度查询天气
|
依赖getLocation的输出
|
| recommendAttractions |
根据城市和天气推荐景点
|
依赖前两个工具的输出
|
核心代码
<span leaf=""><span>@Component</span></span>
构建Agent
<span leaf=""><span>@Configuration</span></span>
运行效果
<span leaf=""><span>[用户]</span> 帮我规划杭州三日游</span>
七、本日核心收获
-
多工具让Agent从“专才”变“通才” ——一个Agent可以拥有多种能力
-
模型自动选择工具——核心依据是工具的描述(description),描述写得越好,模型选得越准
-
工具依赖链——一个工具的输出可以作为另一个工具的输入,State机制自动处理数据传递
-
异常处理是生产环境的必修课——工具内部捕获异常、ModelRetryInterceptor自动重试、降级方案三管齐下
-
工具数量控制在5个以内——太多会导致模型选择不稳定、Token成本增加
📌 本文是第二阶段“核心能力实战篇”的第二篇。第七天我们学会了给Agent装第一个工具,今天学会了装“全套工具箱”——多个工具如何注册、如何协同、如何让Agent自动选择。下一篇,我们将进入RAG(检索增强生成),让Agent能够访问私有知识库,回答专属问题。
有任何问题,欢迎在评论区留言交流!
作者:Java老兵搞AI,专注Java生态下的AI应用开发
如果觉得有用,点个「在看」支持一下吧,下期见!
- 原文作者:知识铺
- 原文链接:https://index.zshipu.com/ai002/post/20260823/AI-Agent%E5%85%A5%E9%97%A8%E5%AE%9E%E6%88%98%E7%AC%AC8%E7%AF%87Spring-AI-Alibaba%E5%A4%9A%E5%B7%A5%E5%85%B7%E5%8D%8F%E5%90%8C%E5%AE%9E%E6%88%98--%E4%BB%8E%E4%B8%80%E6%8A%8A%E9%94%A4%E5%AD%90%E5%88%B0%E5%85%A8%E5%A5%97%E5%B7%A5%E5%85%B7%E7%AE%B1/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。
- 免责声明:本页面内容均来源于站内编辑发布,部分信息来源互联网,并不意味着本站赞同其观点或者证实其内容的真实性,如涉及版权等问题,请立即联系客服进行更改或删除,保证您的合法权益。转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。也可以邮件至 sblig@126.com