我们已经学习了什么是工具。 现在我们通过工具调用循环,来看一看工具在实际场景中的运行逻辑。
当你为大语言模型(LLM)配置可用工具后,模型有两种输出形式: 一是直接生成文本回答;二是输出一段标准化的工具调用指令。 一旦模型发起工具调用,你编写的程序代码就需要执行对应的外部操作,并将执行结果回传给模型。如此往复,就形成了一套循环流程。 这套实现范式通常被称作函数调用(Function Calling)。
我们以日程安排场景举例: 如果用户提出需求 “预约午餐会面”,大模型可能会先调用工具查询日历空闲时段,再调取联系人信息,最后创建日程事件。模型还支持多工具联合调用。 若你的需求需要多份外部信息支撑,模型会依次串行调用多个工具,部分场景下也可并行调用,全部获取数据后再整合给出最终答复。
落到代码层面的运行逻辑如下: 程序维护一条消息列表记录全部对话上下文。 当大模型输出工具调用指令时,程序会遍历所有待调用工具,逐个执行操作,并把每条工具返回的结果追加到消息列表,再交给大模型做后续处理。
这里有一个关键要点:大模型本身并不运行任何代码,它只会用 JSON 格式输出想要执行操作的意图;真正完成外部操作、充当中间枢纽的,是你开发的应用程序。
分核心概念、代码逐行逻辑、完整运行链路、关键底层原理四部分讲清楚:
一、核心基础认知
- LLM 不具备执行能力大模型只会输出自然文本 / 标准化 JSON 工具调用意图(第二张图的 JSON),不会真的查日历、读写文件、调接口;执行外部操作的是你的 Python 应用代码。
- 两条输出分支给 LLM 传入
tools工具列表后,模型二选一输出:- 分支 1:直接输出纯文本,直接作为最终回答;
- 分支 2:输出
tool_callsJSON 结构化指令,触发工具循环。
- 消息队列
messages是上下文载体全程所有对话、工具返回结果都存在这个列表,保证每一轮 LLM 都能拿到完整历史上下文。
二、第一张图代码逐行解析(agent_loop.py)
# 1. 初始化对话上下文:用户原始提问 messages = [ {"role": "user", "content": "Schedule lunch"}, ] # 2. 第一次调用LLM,同时传入可用工具定义 tools response = llm.chat(messages, tools=tools) # 3. 判断:模型是否返回了工具调用指令 if response.tool_calls: # 遍历每一个待调用工具(支持多工具串行/并行) for tc in response.tool_calls: # 4. 应用代码执行外部工具:根据工具名、入参运行函数 result = execute_tool(tc.name, tc.arguments) # 5. 把工具执行结果追加进上下文,role固定为tool messages.append({ "role": "tool", "content": result }) # 6. 所有工具执行完毕、结果写入上下文后,二次调用LLM整合答案 final = llm.chat(messages)代码对应业务场景(预约午餐)
- 用户输入:
Schedule lunch(预约午餐)存入messages; - LLM 收到需求 + 工具清单,判断需要先查日历,输出第二张图的
check_calendarJSON; - 代码检测到
tool_calls不为空,进入循环:- 提取工具名
check_calendar、参数date/user,交给execute_tool运行(真实查询日历接口); - 拿到日历空闲时段结果,以
role:tool追加到消息列表;
- 提取工具名
- 上下文现在包含:用户提问 + LLM 工具调用意图 + 日历查询结果;
- 再次调用 LLM,模型基于完整信息生成最终回复(比如 “周三中午 12 点有空,已为你创建午餐日程”)。
三、第二张图:LLM 输出的工具调用标准 JSON 含义
{ "id": "call_abc123", "type": "function", "function": { "name": "check_calendar", "arguments": { "date": "2026-03-06", "user": "me" } } }id:本次工具调用唯一标识,用于多工具区分、结果配对;type: function:固定标识,代表这是一次函数工具调用;name:要执行的工具函数名称,代码靠这个匹配execute_tool里的逻辑;arguments:调用该工具需要的入参,由 LLM 根据用户需求自动填充; 下方注释关键点:LLM 只输出操作意图,不执行任何逻辑,JSON 只是结构化指令。
四、完整工具循环闭环流程
- 初始化上下文:用户提问写入
messages; - 首轮 LLM 推理:传入对话 + 工具定义,模型判断是否需要工具;
- 无需工具 → 直接返回文本,流程结束;
- 需要工具 → 输出
tool_callsJSON;
- 应用层执行工具:代码解析 JSON,循环调用外部函数 / 接口;
- 回填工具结果:每一次工具返回数据都追加到
messages; - 二次 LLM 整合:携带全部对话 + 工具数据再次请求模型,生成最终自然语言答复;
- 拓展:如果第二轮 LLM 又生成新的
tool_calls,会重复 3-5 步,形成多轮工具循环(Agent 核心能力)。
五、关键特性补充
- 多工具支持模型单次可输出多个
tool_calls,代码循环串行执行;部分模型支持并行工具调用,一次性返回多条函数指令。 - 上下文持久化
messages列表会保存用户、模型、工具三类角色记录,模型每一轮都能读取历史工具返回的数据,实现多步骤复杂任务(查日历→查联系人→创建日程三步连续调用)。 - 分层职责隔离
- LLM:决策 “要不要调用工具、调用哪个、传什么参数、怎么总结结果”;
- 应用代码:承担工具调度、外部接口访问、上下文管理的执行层角色。
六、通俗总结
你可以把这套流程理解成: 你(用户)告诉 AI “帮我约午饭”,AI 没有查日历的能力,于是写了一张标准化纸条(JSON)递给你的程序:“帮我运行 check_calendar,查 2026-03-06 我的日程”; 你的程序拿到纸条去查日历,把空闲时间写回纸条交给 AI; AI 看完日历数据,再整理出完整的预约回复给你。 中间反复递纸条、查数据的整套循环,就是图里的工具调用 / Function Calling Agent Loop。