彻底搞懂大模型 Function Calling:核心原理与消息流转
彻底搞懂大模型 Function Calling:核心原理与消息流转
Function Calling 的本质是一个多轮对话流程,让模型、代码和外部工具(如 API)协同工作。其核心工作流如下:
(1)定义工具:首先,在代码中以特定格式(通常是 JSON Schema)定义好可用的工具,包括工具的名称、功能描述、以及需要的参数。
(2)用户提问:用户发起一个需要调用工具才能回答的请求。
(3)模型决策:模型接收到请求后,分析用户的意图,并匹配最合适的工具。它不会直接回答,而是返回一个包含 tool_calls 的特殊响应。这个响应相当于一个指令:“请调用某某工具,并使用这些参数”。
(4)代码执行:应用接收到这个指令,解析出工具名称和参数,然后在代码层面实际执行这个工具(例如,调用一个真实的天气 API)。
(5)结果反馈:将工具的执行结果(例如,从 API 获取的真实天气数据)包装成一个 role 为 tool 的消息,再次发送给模型。
(6)最终生成:模型接收到工具的执行结果后,结合原始问题和工具返回的信息,生成最终的、自然的语言回答。
1. 核心认知
Function Calling 的本质是:大模型负责决策,本地程序负责执行。
大模型不会直接执行代码、不会联网、不会查数据库。它只输出结构化调用计划,真正执行工具的是你的本地程序。
完整闭环:
LLM 下发调用指令 → 本地执行工具 → 结果回填上下文 → LLM 整合输出答案
2. 四大核心消息类型
Function Calling 的消息流转主要由四种消息组成。
SystemMessage
作用是给大模型设定规则,包括:
- 角色设定
- 可用工具
- 工具调用场景
- 回答约束
它是大模型决策的依据。
HumanMessage
用户的原始问题,是触发工具调用的业务输入。
AIMessage
AIMessage 有两种形态。
普通问答形态
没有工具调用,直接返回自然语言答案。
AIMessage(content="北京今天天气晴朗。")
工具调用形态
模型不直接回答,而是返回 tool_calls,要求本地程序执行工具。
AIMessage(
content="",
tool_calls=[
{
"id": "call_001",
"name": "get_weather",
"args": {"city": "北京"}
}
]
)
其中:
id:本次调用的唯一标识name:工具名称args:工具参数
ToolMessage
工具执行完成后,结果会被封装成 ToolMessage,回填到消息上下文中。
ToolMessage(
content="北京今日晴,25℃",
tool_call_id="call_001"
)
重点:ToolMessage 必须绑定正确的 tool_call_id。否则大模型无法判断这个结果对应哪一次工具调用。
3. 单轮 Function Calling 完整流程
以“今天北京天气怎么样?”为例。
第一步:组装初始消息
[
SystemMessage(工具规则),
HumanMessage(今天北京天气怎么样?)
]
第二步:大模型返回工具调用指令
大模型判断需要查询天气,返回带 tool_calls 的 AIMessage。
AIMessage(
content="",
tool_calls=[
{
"id": "call_001",
"name": "get_weather",
"args": {"city": "北京"}
}
]
)
第三步:本地程序执行工具
本地代码负责:
- 解析工具名
- 解析参数
- 调用真实函数或接口
- 获取返回结果
大模型在这一步并没有执行代码。
第四步:回填 ToolMessage
工具结果被封装成 ToolMessage,并绑定调用 ID。
ToolMessage(
content="北京今日晴,25℃",
tool_call_id="call_001"
)
此时完整消息结构为:
SystemMessage
HumanMessage(用户提问)
AIMessage(工具调用指令)
ToolMessage(工具执行结果)
第五步:大模型生成最终答案
大模型读取工具结果后,不再返回 tool_calls,而是输出自然语言答案。
AIMessage(content="北京今天天气晴朗,气温25摄氏度。")
4. 多轮工具调用消息结构
有些问题需要连续调用多个工具。
例如:对比北京和上海的天气。
消息结构会变成:
SystemMessage
HumanMessage(对比北京上海天气)
AIMessage(调用 get_weather(北京))
ToolMessage(北京天气结果)
AIMessage(调用 get_weather(上海))
ToolMessage(上海天气结果)
AIMessage(对比总结答案)
规则很简单:
多轮调用 = 多组 AIMessage + ToolMessage 顺序叠加
5. 工具无限循环的三大原因
模型重复调用同一个工具,常见原因只有三个。
1. tool_call_id 不匹配
ToolMessage 的 tool_call_id 与 AIMessage 中的 id 不一致。
模型会认为工具没有正确执行,从而再次调用。
2. 工具返回异常
工具结果为空、报错、格式混乱,模型无法识别有效信息。
3. 系统提示约束不足
没有明确告诉模型:拿到工具结果后直接回答,不要重复调用。
6. 核心本质
Function Calling 不是大模型直接执行代码,而是一套消息交互协议。
它的核心逻辑是:
LLM 下发结构化任务 → 本地程序执行 → 结果回填上下文 → LLM 整合回答
7. 最简伪代码
messages = [SystemMessage(工具规则), HumanMessage(用户输入)]
while True:
ai_msg = llm.invoke(messages)
messages.append(ai_msg)
if not ai_msg.tool_calls:
break
for call in ai_msg.tool_calls:
res = run_tool(call.name, call.args)
tool_msg = ToolMessage(content=res, tool_call_id=call.id)
messages.append(tool_msg)
print(messages[-1].content)
结语
掌握 Function Calling,关键不是记住某个框架 API,而是理解消息如何变化。
核心重点:
- 大模型只负责决策
- 本地程序负责执行
- AIMessage 下发工具调用
- ToolMessage 回填结果
tool_call_id必须一一对应- 每一次工具调用都由一组
AIMessage(tool_call) + ToolMessage组成
更多推荐


所有评论(0)