工具调用循环(Function Calling)完整流程拆解

我们已经学习了什么是工具。 现在我们通过工具调用循环,来看一看工具在实际场景中的运行逻辑。

当你为大语言模型(LLM)配置可用工具后,模型有两种输出形式: 一是直接生成文本回答;二是输出一段标准化的工具调用指令。 一旦模型发起工具调用,你编写的程序代码就需要执行对应的外部操作,并将执行结果回传给模型。如此往复,就形成了一套循环流程。 这套实现范式通常被称作函数调用(Function Calling)

我们以日程安排场景举例: 如果用户提出需求 "预约午餐会面",大模型可能会先调用工具查询日历空闲时段,再调取联系人信息,最后创建日程事件。模型还支持多工具联合调用。 若你的需求需要多份外部信息支撑,模型会依次串行调用多个工具,部分场景下也可并行调用,全部获取数据后再整合给出最终答复。

落到代码层面的运行逻辑如下: 程序维护一条消息列表记录全部对话上下文。 当大模型输出工具调用指令时,程序会遍历所有待调用工具,逐个执行操作,并把每条工具返回的结果追加到消息列表,再交给大模型做后续处理。

这里有一个关键要点:大模型本身并不运行任何代码,它只会用 JSON 格式输出想要执行操作的意图;真正完成外部操作、充当中间枢纽的,是你开发的应用程序。

核心概念、代码逐行逻辑、完整运行链路、关键底层原理四部分讲清楚:

一、核心基础认知

  1. LLM 不具备执行能力 大模型只会输出自然文本 / 标准化 JSON 工具调用意图(第二张图的 JSON),不会真的查日历、读写文件、调接口;执行外部操作的是你的 Python 应用代码
  2. 两条输出分支 给 LLM 传入 tools 工具列表后,模型二选一输出:
    • 分支 1:直接输出纯文本,直接作为最终回答;
    • 分支 2:输出 tool_calls JSON 结构化指令,触发工具循环。
  3. 消息队列 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)

代码对应业务场景(预约午餐)

  1. 用户输入:Schedule lunch(预约午餐)存入 messages
  2. LLM 收到需求 + 工具清单,判断需要先查日历,输出第二张图的 check_calendar JSON;
  3. 代码检测到 tool_calls 不为空,进入循环:
    • 提取工具名 check_calendar、参数 date/user,交给 execute_tool 运行(真实查询日历接口);
    • 拿到日历空闲时段结果,以 role:tool 追加到消息列表;
  4. 上下文现在包含:用户提问 + LLM 工具调用意图 + 日历查询结果;
  5. 再次调用 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 只是结构化指令

四、完整工具循环闭环流程

  1. 初始化上下文 :用户提问写入 messages
  2. 首轮 LLM 推理 :传入对话 + 工具定义,模型判断是否需要工具;
    • 无需工具 → 直接返回文本,流程结束;
    • 需要工具 → 输出 tool_calls JSON;
  3. 应用层执行工具:代码解析 JSON,循环调用外部函数 / 接口;
  4. 回填工具结果 :每一次工具返回数据都追加到 messages
  5. 二次 LLM 整合:携带全部对话 + 工具数据再次请求模型,生成最终自然语言答复;
  6. 拓展:如果第二轮 LLM 又生成新的 tool_calls,会重复 3-5 步,形成多轮工具循环(Agent 核心能力)。

五、关键特性补充

  1. 多工具支持 模型单次可输出多个 tool_calls,代码循环串行执行;部分模型支持并行工具调用,一次性返回多条函数指令。
  2. 上下文持久化 messages 列表会保存用户、模型、工具三类角色记录,模型每一轮都能读取历史工具返回的数据,实现多步骤复杂任务(查日历→查联系人→创建日程三步连续调用)。
  3. 分层职责隔离
    • LLM:决策 "要不要调用工具、调用哪个、传什么参数、怎么总结结果";
    • 应用代码:承担工具调度、外部接口访问、上下文管理的执行层角色。

六、通俗总结

你可以把这套流程理解成: 你(用户)告诉 AI "帮我约午饭",AI 没有查日历的能力,于是写了一张标准化纸条(JSON)递给你的程序:"帮我运行 check_calendar,查 2026-03-06 我的日程"; 你的程序拿到纸条去查日历,把空闲时间写回纸条交给 AI; AI 看完日历数据,再整理出完整的预约回复给你。 中间反复递纸条、查数据的整套循环,就是图里的工具调用 / Function Calling Agent Loop

相关推荐
8Qi81 天前
HelloAgents学习笔记:智能体性能评估
llm·agent·ai编程·智能体
Esaka_Forever1 天前
AI 工作流六大核心范式完整梳理、对比与落地解读
llm
smartfish_liu1 天前
风过无言(Silent Wind)
llm·agent
Esaka_Forever1 天前
工作流 vs 智能代理 架构选型完整梳理(精简总结 + 实操判断)
llm
在水一缸1 天前
深度解析 GPT-Live:实时语音交互的技术变革与实践指南
gpt·llm·交互·多模态·端到端·实时语音交互·gpt-live
先吃饱再说1 天前
LLM 流式输出的“中间商”方案:BFF 层到底在做什么?
llm·vite
周末程序猿1 天前
万字长文谈谈Loop Engineering
llm·agent
小月土星2 天前
(实战篇)RAG-demo 深度解析:162行代码中的检索增强生成全景 (含Top-k法)
javascript·数据库·llm
武子康2 天前
OpenAI 为什么需要 FDE:模型公司正在变成交付公司
人工智能·llm·openai