TellWorldAI 世界档案
问档案English

首页›实践›实践

实践

smolagents 的工具调用智能体

smolagents 的 ToolCallingAgent 用 JSON 表达动作:结构严整、对接 function calling,适合简单系统;复杂任务归 CodeAgent。

智能体的每一步「行动」都要先过一道表示题:模型做出的决策,用什么格式交给执行器?主流答案有两种——让模型直接写一段可执行代码,或者让它吐出一个结构化的 JSON 对象。smolagents 把两种形态都做成了现成的类:CodeAgent 走代码路线,ToolCallingAgent 走 JSON 路线 [1]。

两种路线的差别,用一个具体任务看得最清楚:让智能体同时搜「哥谭市最好的餐饮服务」和「超级英雄派对主题创意」。CodeAgent 会生成并运行一段 Python 循环:

for query in [
    "Best catering services in Gotham City",
    "Party theme ideas for superheroes"
]:
    print(web_search(f"Search for: {query}"))

ToolCallingAgent 则输出一个 JSON 数组,每个元素只有工具名和参数两个字段:

[
    {"name": "web_search", "arguments": "Best catering services in Gotham City"},
    {"name": "web_search", "arguments": "Party theme ideas for superheroes"}
]

框架拿到这串 JSON 后解析并分发给对应工具执行,整个过程不碰任何代码解析器 [1]。

为什么要主推代码动作

smolagents 官方立场很明确:框架主推 CodeAgent,因为整体表现更好——他们为此专门发过论文(arXiv 2402.01030)。原因值得展开说。代码可以声明变量、复用中间结果、表达循环和条件;JSON 是纯声明式结构,嵌套一层就多一堆转义和括号,中间结果也无法跨调用复用。同一个任务,代码版本往往更短、更省 token,还能做 JSON 表达不了的控制流。

但 JSON 也有自己的舒适区。它的结构严格、解析简单,更重要的是各家模型服务商的原生 API 都支持 function calling 协议——模型训练时就见过大量「按 schema 吐 JSON」的数据,输出稳定性反而高。不需要变量处理、不需要复杂工具调用的简单系统,正是 ToolCallingAgent 的用武之地 [1]。

用起来什么样

ToolCallingAgent 与 CodeAgent 走完全相同的多步工作流:先想、再做、再观察,直到给出最终答案;唯一的差别在动作的表示形式——不是可执行代码,而是指明工具名和参数的 JSON 对象,由系统解析后执行 [1]。搭一个能联网搜索的版本只要几行:

from smolagents import ToolCallingAgent, WebSearchTool, InferenceClientModel

agent = ToolCallingAgent(tools=[WebSearchTool()], model=InferenceClientModel())

agent.run("Search for the best music recommendations for a party at the Wayne's mansion.")

运行时看 trace,CodeAgent 会显示「Executing parsed code:」,而这里显示的是一条调用公告:框架宣布正在调用 web_search 工具、参数是哪条查询。智能体生成结构化工具调用,系统处理后产出结果,全程没有代码执行环节 [1]。

工程上的几条经验

把 JSON 工具调用用稳,有几件事值得提前做。第一,很多服务商支持语法受限解码(schema 引导采样),能保证模型吐出合法 JSON,schema 违规一般在解析阶段就被拦下;把解析错误作为 Observation 喂回模型,比直接崩掉要好——下一轮它通常能自己改对。

第二,执行前校验参数。类型、取值范围、必填字段都过一遍,校验失败就返回一条人类可读的错误信息进对话,让智能体在下一个 Thought 步骤里自我修正 [1]。工具注册表也要保持干净:工具数量少、命名不歧义、描述具体,因为模型是靠 system 提示词里的描述选工具的,名字重叠或描述含糊会直接推高选错工具、传错参数的概率。

第三,选型凭经验法则:每一步都是单次、独立、参数固定的工具调用,用 ToolCallingAgent 足够;一旦出现循环、条件、算术或需要跨调用共享的中间状态,就该换 CodeAgent [1]。另外,WebSearchTool 封装的是 DuckDuckGo 搜索,结果天生不确定,依赖它的智能体轨迹在测试里应该用可重放的夹具评估,而不是每次都打真实请求。

顺带一提,Alfred 管家是这门课贯穿始终的示例角色:同一个派对筹备任务,先用 CodeAgent 写搜索循环解一遍,再用 ToolCallingAgent 吐两个 JSON 搜索调用解一遍,正好把「智能体类型」这个变量单独隔离出来对比。

本文改编自 Hugging Face agents-course 的 Writing actions as code snippets or JSON blobs 一节[1],原文以 Apache-2.0 许可发布。

来源

  1. 1

引用本页: smolagents 的工具调用智能体. TellWorld, https://www.tellworld.net/zh/practice/practice-smolagents-tool-calling. 更新于 2026-11-14

相关动态