Agent 如何进行工具调用:从一次 Function Calling 到生产级工具编排的完整链路

核心结论 :Agent 调用工具不是「模型自己用代码调函数」,而是一次请求---决策---执行---回传---再生成的多轮闭环。模型只负责「决定用哪个工具、填什么参数」,真正的执行在应用程序侧完成。理解这条链路,是做好 Agent 工程的第一课。

目录

    1. 一句话抓住本质:模型只是「指挥官」
    1. 工具调用链路:一次完整的四/五阶段闭环
    1. 工具定义(schema)写得好,模型才调得对
    1. 参数校验:模型会「骗」你,你必须校验
    1. 可运行的完整示例:Python + OpenAI Function Calling
    1. 常见坑与对照表:症状 → 原因 → 解法
    1. 什么时候不用工具调用
    1. 总结:把模型当「决策者」,把应用当「执行者」

1. 一句话抓住本质:模型只是「指挥官」

很多人以为 Agent 调用工具是「大模型长了手,自己去执行」。不是 。模型本质是一个纯粹的推理引擎 ,它没有权限、也没有能力真的去访问数据库或调 API。它只做一件事:基于你喂给它的工具清单,输出一个结构化的「调用指令」------用哪个工具、参数填什么。

真正执行这个指令的是你(应用程序)。这就好比:AI 是项目经理(generates a plan),你才是执行团队(executes the plan)。理解这个角色分工,后面所有环节才不会乱。

比喻一下 🎭:模型像一支笔,它只能「写出」调用某工具的指令;而你像「执行密钥」,只有你能把这张指令翻译成真实的系统动作。模型负责"想",应用负责"做"。

2. 工具调用链路:一次完整的四/五阶段闭环

不同文档把工具调用拆成四步或五步,本质是同一件事。以最常见的四阶段闭环为例,我用一个「查天气」的例子串起来:

① 请求(Request):应用程序把用户的提问、上下文,连同「可用工具清单」一起发给模型。工具清单就是你预先定义好的 JSON schema,比如「get_weather(城市)」「search_docs(关键词)」。

② 决策(Decide) :模型分析后做决定------是直接回答,还是需要调用工具。如果它判定需要工具,就输出一个结构化对象,包含 tool name(工具名)和 arguments(参数),例如:

json 复制代码
{"name": "get_weather", "arguments": {"city": "北京"}}

③ 执行(Execute) :由应用程序来执行。应用层根据工具名找到对应的执行函数,把参数填进去,真实地跑一遍,拿到结果(如「25℃ 晴」)。

④ 回传(Return) :应用把工具执行结果以 tool 角色的消息回传给模型。

⑤ 再生成(Finalize):模型基于这个结果,生成最终的自然语言回答,或者继续发起下一轮工具调用(当任务需要连续多步时)。

这是一个循环:模型「想」→ 应用「做」→ 结果「喂回」→ 模型「再想」。Agent 能不能完成复杂任务,就看这个循环能不能稳定转起来。火山引擎的 docs 把它统一称为「五个阶段」,微软把「定义函数」也算作前置步骤,本质一致。

3. 工具定义(schema)写得好,模型才调得对

这是整个工具调用里最容易被忽视、但最影响效果 的一环。因为模型判断「什么时候该用这个工具、参数填什么」,唯一依据就是你写的工具描述(description)。描述写得模糊,模型就会瞎猜,要么不调用,要么传错参数。

一个规范的 tool schema 至少包含四要素(以 Anthropic 的规范为例):

要素 说明
name 工具名,需匹配 ^[a-zA-Z0-9_-]{1,64}$
description 一句话说清功能 + 何时用 + 何时不用
input_schema JSON Schema,定义每个参数的类型、必填/选填
(可选)示例 一组真实参数 + 你期望的返回,帮模型对齐

写 description 的黄金法则:要准确,不要含糊 。用动词开头,写清「当用户请求 X 时使用;当用户只是想聊天时不要用」。例如:

  • ❌ 查询天气
  • ✅ 当用户问到某地天气或温度时调用;仅聊天不调用。参数 city 为城市名,如"北京"。返回 温度、天气状况。

实测表明,description 是影响工具调用准确率的最大单一因素------它几乎是模型判断「何时调用、参数怎么填」的唯一上下文。所以你花在打磨 description 上的功夫,回报远高于调整 prompt。

此外,工具名要语义化 :search_docs 比 docs 好,因为模型能从中读懂意图。参数要在 schema 里写清类型、是否必填、单位、枚举值。Vague schema 会诱导模型编造参数(invents invented arguments)或选错工具。

4. 参数校验:模型会「骗」你,你必须校验

这是新人最容易踩的坑:拿到模型输出的 arguments 就直接执行。千万不要 。模型输出的参数是基于文本生成的猜测,不是真实可靠的数据。它可能:

  • 把字符串列表 ["P001","P002"] 输出成 "P001,P002"(类型错误)
  • 把数字输出成字符串 "25" 而不是 25
  • 编造一个你根本不存在的城市名
  • 漏掉必填参数

所以在真正执行前,必须做一层参数校验 :用 JSON Schema 校验参数结构、类型、必填项;对高危操作(删除、发送、转账)再做二次确认,涉及用户身份、租户范围还要校验权限。这一步决定了你的 Agent 是「可靠助手」还是「会闯祸的玩具」。

一个原则:模型输出永远是「候选参数」,经过你的校验与清洗后才变成「可执行参数」。这也是为什么我之前在 AI07 里专门写了防护层------校验是工具调用链路里不可或缺的一环。

5. 可运行的完整示例:Python + OpenAI Function Calling

下面给一段复制粘贴就能跑 的完整代码。用 OpenAI 兼容接口演示「查天气」工具调用的完整闭环。运行前装上 pip install openai,并设置你的 API key。

python 复制代码
import json
from openai import OpenAI

client = OpenAI(api_key="你的API-KEY")

# 1. 定义工具(schema)------描述写得越准,模型调得越对
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "当用户问到某地天气或温度时调用;仅聊天不调用。"
                           "参数 city 为城市名,如'北京',返回温度与天气状况。",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {"type": "string", "description": "城市名,如'北京'"}
                },
                "required": ["city"]
            }
        }
    }
]

# 2. 模拟真实执行的工具函数(模型自己不会跑,由应用来跑)
def get_weather(city: str) -> str:
    """真实的后端查询,这里用假数据代替。"""
    return f"{city}今天25℃,晴"

# 3. 用户发问,应用把工具清单一起发给模型
messages = [{"role": "user", "content": "北京今天天气怎么样?"}]
response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=messages,
    tools=tools,
    tool_choice="auto",   # auto=模型自己决定是否调用
)

# 4. 模型决定调用工具,输出结构化指令
msg = response.choices[0].message
if msg.tool_calls:
    call = msg.tool_calls[0]
    print("模型要调用工具:", call.function.name)

    # 5. 应用侧拿到参数,先校验(这里演示最简校验),再真实执行
    args = json.loads(call.function.arguments)
    if "city" not in args or not isinstance(args["city"], str):
        raise ValueError("参数校验失败:city 缺失或类型错误")

    result = get_weather(args["city"])   # 6. 执行工具

    # 7. 把执行结果以 tool 角色回传给模型
    messages.append(msg)                 # 模型的选择也进上下文
    messages.append({
        "role": "tool",
        "tool_call_id": call.id,
        "content": result,
    })

    # 8. 模型基于结果生成最终自然语言回答
    final = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=messages,
        tools=tools,
    )
    print("最终回答:", final.choices[0].message.content)
else:
    # 模型判定不需要工具,直接回答
    print("直接回答:", msg.content)

运行逻辑 :模型输出 get_weather 指令 → 应用校验参数 → 真实执行 get_weather("北京") → 把 25℃晴 回传 → 模型生成「北京今天25℃,晴」。整个闭环里,模型没有真正调函数,是应用在调。

6. 常见坑与对照表:症状 → 原因 → 解法

工具调用的错误大多有迹可循。下面是症状 → 原因 → 解法对照表,出问题时优先对照排查:

症状 原因 解法
模型就是不调用工具 description 没说清「何时该用」 重写描述,用动词开头,写清触发场景
参数类型错(列表变字符串) 模型基于文本猜测,未校验 用 JSON Schema 校验 + 类型转换
编造参数(虚构城市名) schema 缺枚举/示例,模型瞎编 参数加枚举值、示例、必填约束
工具名选错 工具名太泛,模型读不懂意图 用语义化名字,如 search_docs
返回 HTTP 400 tools JSON 结构不合规 严格校验 JSON Schema 结构,避免 typo/废字段
模型循环调用停不下来 没有 max_turns/终止条件 设最大轮次或明确的停止条件
高危操作被误执行 未做二次确认直接跑 发送/删除/转账前加人工确认
多次调用结果串了 没带 tool_call_id/上下文 每次把模型选择与结果按 call_id 配对回传

7. 什么时候不用工具调用

不是所有场景都需要工具调用。工具调用有延迟、有成本、有出错风险,能用模型直接回答就别勉强上工具。

  • 该用:需要实时数据、外部系统、业务内部信息、执行真实动作时。
  • 不该用:纯知识问答、语义理解、文本生成这类模型擅长的任务------直接回答更快、更稳、更便宜。

判断依据:问自己「这个问题,模型不查外部数据能答对吗?」。如果能,就别加工具。把工具调用留给那些「模型自己答不了、必须依赖外部信息或动作」的场景,Agent 才会又稳又省。

8. 总结:把模型当「决策者」,把应用当「执行者」

工具调用的本质,是模型与应用之间的分工协作:

  • 模型:负责理解意图、选择工具、生成参数(决策者)
  • 应用:负责校验参数、真实执行、回传结果(执行者)

你要做的是:把工具描述 打磨到让模型一眼看懂该不该用、参数怎么填;在执行前 做好参数校验与高危二次确认;并让模型输出始终是候选参数 ,经过你的清洗才落地。想更深入了解工具调用出错的工程防线,可以回看 AI07 防护层 与 AI06 误调用问题排查。


判断收尾:当任务需要实时数据、外部系统或真实动作时,用工具调用;当模型能直接答对时,别上工具------工具是能力扩展,不是万能钥匙。

专栏介绍:本专栏《AI Agent 工具》专注 Agent 工具调用的落地实践,从工具调用机制、参数校验、误调用排查一路讲到防护层实现,每篇都配一段可直接运行的代码,每周更新一篇。想按顺序读完,可在专栏页订阅。

相关推荐
噜哥带你玩转 AI 大模型2 小时前
从 “if-else“ 到 Agent:Dify 进阶实战,让 AI 自己判断、自己调工具
agent·工作流·dify·多轮对话·httpapi
威哥爱编程2 小时前
Python 智能体开发实战 05:一问教材内容它就编?先把答案从你自己的资料里检索出来
python·agent
java_prinln2 小时前
RAG 面试题介绍
python·agent
威哥爱编程2 小时前
Python 智能体开发实战 06:一个函数里塞了八百行?用状态机把批改流程拆成能回退的步骤
python·agent
熊猫钓鱼>_>2 小时前
四种书签,一条时间线:一个读书 App 的记忆颗粒与它的边界案例【鸿蒙心迹】
开发语言·华为·ai编程·harmonyos·鸿蒙·openharmony·鸿蒙pc
yz_aiks3 小时前
WorkBuddy 使用技巧:Claude Code 国内平替,签到免费用、自动签到和手机远程控制电脑
人工智能·ai编程·效率工具·claude code·workbuddy
星际码仔3 小时前
Codex Co²:AI 时代的结对编程,应该是怎样的?
openai·ai编程·vibecoding
key_3_feng4 小时前
评估与对齐:Agent 自我进化的护栏
前端·数据库·agent
念念不忘 必有回响5 小时前
从0到1:搭建你的第一个 MCP 服务器实战
agent·mcp