2.3 构建带工具的智能体


2.3 构建带工具的智能体

本节摘要:工具是智能体从"会说"变"会做"的关键——挂上搜索工具能查最新资讯,挂上金融工具能拿实时行情。本节讲清工具机制、两种挂载方式(内置工具与自定义函数),并用搜索与金融两个真实工具跑通完整示例。

本节地图

阅读完本节,你应当能够:

  1. 解释工具在智能体中的角色与调用机制
  2. 挂载 DuckDuckGoTools 等内置工具
  3. 用装饰器把自定义函数变成工具
  4. 理解模型-工具-结果回传的循环
  5. 选择合适的工具并规避常见坑

一、问题与直觉

模型的知识截止在训练时点,问"今天股市怎么样"它答不上来;模型不会算复杂公式,让它解个方程组也是错。工具就是补这两块短板:搜索工具给最新信息,计算工具给精确结果。Agno 里挂工具几乎零成本——一行参数,智能体就多了一项本领。

二、核心原理

2.1 工具调用的完整循环

模型本身不会执行工具,它只决定要不要用:模型在回复中声明"我需要调用 XX 工具",框架代为执行,把结果塞回上下文,模型再基于结果生成最终答案。这个"模型决策 → 框架执行 → 结果回传"的循环,是智能体工具机制的底层逻辑。

2.2 内置工具与自定义工具

2.2 内置工具与自定义工具

三、工程实践要点

3.1 挂载内置搜索工具

from agno.agent import Agent from agno.tools.duckduckgo import DuckDuckGoTools agent = Agent( name="news_bot", description="擅长检索最新资讯的智能体", tools=[DuckDuckGoTools()], show_tool_calls=True, # 开发期显示工具调用过程 ) agent.print_response("搜索一下今天人工智能领域最重要的新闻")

💡 关键直觉:开发期务必开 show_tool_calls=True——你能看到模型"决定用工具 → 框架执行 → 回传结果"的全过程,排查"为什么没搜到"时一目了然。

3.2 挂载金融数据工具

from agno.agent import Agent from agno.tools.yfinance import YFinanceTools agent = Agent( name="stock_bot", tools=[YFinanceTools(stock_price=True, analyst_recommendations=True)], show_tool_calls=True, ) agent.print_response("某科技龙头的当前股价和机构评级如何?")

3.3 自定义工具:装饰器方式

from agno.agent import Agent def calculate_discount(price: float, ratio: float) -> float: """计算折扣后价格。price 原价, ratio 折扣比例 0-1""" return round(price * ratio, 2) agent = Agent( name="shop_bot", tools=[calculate_discount], instructions=["算价格时调用折扣工具"], ) agent.print_response("原价 1299 的商品打 85 折,多少钱?")

普通函数 + 装饰器标记(在 Agno 中自定义工具直接传函数即可),模型会自动理解函数签名与 docstring,按需调用。

⚠️ 常见坑:自定义工具的 docstring 就是模型的理解依据。docstring 写清楚参数含义与返回格式,模型才能正确调用;写得太含糊,模型会传错参数。

3.4 工具选择速查

工具 场景 安装
DuckDuckGoTools 联网搜索 duckduckgo-search
YFinanceTools 金融行情 yfinance
自定义函数 业务逻辑

3.5 工具使用规范

  • 按需给工具:给太多工具,模型选择负担大、误调用概率高。只挂任务需要的
  • 工具命名清晰:名字与 docstring 说明"什么时候用、怎么用"
  • 失败兜底:工具可能抛异常,指令里说明"工具失败时怎么办"
  • 权限最小化:能只读就只读,别把写库工具直接挂给智能体

四、两个官方工具的实战问答

原始资料对 DuckDuckGoTools 与 YFinanceTools 给了一组现成的问答实验,把这些问题亲手跑一遍,对"工具扩展知识边界"的体会比读十页文档深。

搜索工具的实验设计成对照组:先问"纽约的突发新闻"(本地化,结果具体),再问泛化的"突发新闻"(范围大,结果发散)。跑完能直观看到工具型智能体的一个特性——回答质量受查询词影响,而你可以通过指令教它把用户问题改写成更好的搜索词。

金融工具的实验覆盖三类典型查询:问特斯拉股价(单点数据)、问苹果的分析师评级(聚合观点)、问微软的公司信息(基本面画像)。三问对应三种数据形态,智能体都能把工具返回的结构化数据转成自然语言,还能按指令用表格呈现——"用表格展示数据"这条指令在原始示例里反复出现,说明它对可读性的提升立竿见影。

from agno.tools.yfinance import YFinanceTools finance_agent = Agent( tools=[YFinanceTools(stock_price=True, analyst_recommendations=True, company_info=True)], instructions=["始终用表格展示数据", "数据必须来自工具结果,不得编造"], ) finance_agent.print_response("特斯拉当前股价多少?分析师怎么看?")

注意工具构造参数的写法:能力按开关粒度传入,要什么开什么。这既是权限控制(不让智能体碰不需要的接口),也是降噪(能力越多,模型选择越容易发散)。

五、多工具与工具团队

一个智能体可以挂多个工具,模型按需选用。但工具数量上去后有两个副作用:选择准确率下降、提示词变长。经验阈值是单智能体五六把工具以内,再多就该考虑拆分——这正是团队登场的理由之一:搜索型智能体、金融型智能体各带各的工具,队长按任务性质派活。

工具组合 适合的问题 注意点
仅搜索 时效性问题、开放信息 教模型改写查询词
仅金融 股价、评级、公司画像 明确数值必须来自工具
搜索 + 金融 "前景 + 财务"复合问题 复杂问题建议直接组团队
多工具堆叠 助手 控制数量,开调试提示

💡 关键直觉:工具是智能体的"手",指令是"脑子的用法"。手再多,脑不清楚也没用——先写好"什么时候用什么工具、结果怎么呈现"的规则,再谈扩工具箱。

好工具的四个设计原则

看过官方工具的长相,自己设计工具时照着四个原则打磨。第一,单一职责:一把工具干一件事,"搜索新闻"与"查股价"分开,模型选择才准。第二,描述写给模型看:工具描述不是给程序员的注释,是一份"什么时候该调用我"的说明书,要写清适用场景、输入含义、返回形态,几句话的描述质量直接决定调用准确率。第三,返回宁短勿长:工具结果是塞进上下文的,返回一大篇网页原文既贵又干扰推理,做好运维级摘要再返回。第四,失败要可读:出错时返回结构化的错误说明(什么错了、还能不能重试),模型读到后能自行决策,比抛一堆堆栈友好得多。

工具安全是绕不开的另一半。权限最小化前面提过,这里补执行层的三道保险:超时控制(外部接口卡死不能拖垮整个请求)、重试上限(避免模型对失败工具无限重试)、结果校验(返回格式先验证再进上下文)。三道保险装好,工具层就从"最脆弱的环节"变成"最皮实的环节"。

评估工具配置是否合理,有个简单的观测法:统计一段真实使用里各工具的调用分布与成功率。某把工具从不被调用,要么描述不行要么根本多余;某把工具失败率高,先修它;调用集中在一两把上,说明职责划分可能太粗。让数据替你决定工具箱的取舍。

六、常见问题

工具调用失败会怎样?

失败信息会回到模型,它可能重试、换工具或如实报告失败。生产上要防连锁失败:对不稳定的工具设置重试与超时,对关键路径准备降级回答。

能接公司内部系统吗?

可以。自定义工具就是普通的 Python 类或函数,包一层调用内部接口的逻辑即可,第 3 章扩展定制一节会展开做法。注意权限最小化:智能体只需要完成任务的接口,不要顺手把管理权限给它。

怎么判断"该加工具"还是"该换更强模型"?

看缺的是"知道"还是"想到"。缺实时或私有数据,是"知道"的问题,加工具;推理质量差、不会拆步骤,是"想到"的问题,换模型或改指令。两者症状不同,先分清再动刀。

从单工具到工具生态

工具智能体做顺之后,自然会长出一个"工具生态"的问题:公司里不同项目各写各的工具,重复造轮子、行为不一致。治理思路是给工具分层:最底下是通用工具(搜索、网页提取、文件解析),全公司共享一份实现;中间是业务工具(查订单、查库存),按业务域封装、接口契约清晰;最上面是场景工具(某个活动页专用),允许快速堆叠不求复用。层与层之间只许上层调用下层,不许横穿。

这个分层的收益在半年后显现:新人接手项目时,看到的工具都是熟面孔;某把通用工具修了个缺陷,所有项目同步受益;而快速试错的场景工具烂在顶层也无所谓,反正影响半径被层隔离了。智能体应用的工程化成熟度,看工具治理就能判断个七八成——散装工具堆的项目,再炫的智能体配置也撑不了多久。

个人开发者同样适用,只是规模缩小:自己的常用工具收进一个文件夹、统一命名与描述风格、定期清理不再用的。工具箱的整洁度,就是开发者的段位证书。

工具调用的可观测实践

工具智能体进入日常使用后,建议尽早给每次工具调用打上三类标签:调用了哪把工具、成功还是失败、结果被模型采纳了多少。累积一段时间就能回答关键问题——哪把工具是顶梁柱、哪把在吃干饭、失败集中在什么场景。这些观测不需要专门平台,在工具封装里加几行日志、每周用文本工具汇总一次就够,但它能把"感觉工具挺多"变成"这两把工具贡献了八成调用",后续的工具箱治理从此有了依据。

还有一个调试细节:当模型该调工具却不调时,先别急着改指令,把该问题的用户表述抄下来看看——口语化、带错别字的提问最容易让模型误判为无需工具。在指令里补一条"涉及时间敏感信息时必须先检索",比反复重写整段指令见效快得多。

最后提一句工具的"作息管理":外部接口有高峰期,智能体也有。把高频工具的调用限额、时段偏好纳入配置考量,高峰期自动降级到缓存或备用源,工具层的稳定性就从"看运气"变成"有预案"。这套思路在第 3 章性能优化里会正式展开,这里先埋个种子。

本章回顾

  • 要点一:工具机制 = 模型决策 + 框架执行 + 结果回传,模型不亲自执行
  • 要点二:内置工具 pip 安装后实例化即用,自定义函数直接传参挂载
  • 要点三:show_tool_calls 是开发期排查利器
  • 要点四:docstring 是模型理解工具的依据,写清参数与返回
  • 要点五:工具宁少勿多,按任务需要挂载
  • 要点六:工具失败要有兜底指令,权限最小化

智能体"会干活"了,下一节让它"有知识"——挂上知识库,回答它没学过的内容。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U