揭秘 Function Calling:LLM 真的会“调用”工具吗?底层机制与执行流程全解析

大家好,我是你们的技术博主。

在如今的大模型(LLM)应用开发中,Function Calling(函数调用) 无疑是最核心的能力之一。它让原本只能“纸上谈兵”的聊天机器人,变成了能查天气、搜数据库、甚至控制智能家居的“实干家”。

很多开发者初接触时会有一种误解:“是不是 LLM 内部直接执行了这段 Python 代码?”

答案是否定的。

今天,我们就透过现象看本质,从底层机制执行流程工程实现,彻底讲清楚 Function Calling 到底是如何工作的。这不仅有助于你写出更稳定的 Agent 应用,也能帮你建立起对“大模型+工具”闭环系统的深刻理解。


一、核心认知:LLM 并不执行代码

首先,我们要纠正一个关键概念:

Function Calling 不是 LLM 真的去“执行函数”,而是:

LLM 负责生成结构化的“调用意图”(JSON),外部 Runtime(运行时环境)负责真正执行工具。

你可以把 LLM 想象成一个极其聪明的调度员,而真正的执行者是后端的工人。调度员只负责决定“该派谁去干活”以及“带什么参数去”,但他自己不动手搬砖。


二、底层机制:LLM 是如何学会“叫外援”的?

LLM 之所以能输出标准的函数调用格式,主要依赖于两个层面的训练和对齐。

1. 训练层面:学会“结构化输出”

在预训练和指令微调(SFT)阶段,模型见过大量类似这样的数据对:

  • 输入:用户问“北京今天天气怎么样?” + 工具定义(获取天气的 API schema)。
  • 输出{"tool_name": "get_weather", "arguments": {"city": "Beijing"}}

通过这种训练,模型学会了一种新的“语言技能”:当遇到需要外部信息的问题时,不要直接瞎编,而是输出符合约定格式的 JSON 文本。

👉 本质:LLM 输出的依然是一段文本,只不过这段文本恰好符合 JSON Schema 规范。

2. 对齐机制:强化学习的作用

为了让模型更精准地判断“什么时候该调工具”、“参数怎么填”,通常还会引入 RLHF(基于人类反馈的强化学习)或 RLAIF。

模型被训练成具备以下直觉:

  • 识别意图:这个问题是需要计算/查询,还是闲聊?
  • 参数提取:从自然语言中提取出 patient_id="123" 这样的关键参数。
  • Fallback 机制:如果不确定,或者工具无法解决,该如何回退到普通对话。

三、Function Calling 完整执行流程(五步法)

这是理解 Agent 系统最关键的部分。一个完整的 Function Calling 过程,通常包含以下 5 个步骤。我们用“查询病人血常规”这个场景来演示。

Step 1:用户输入

用户发起请求:

“帮我查一下 A 病人的最近一次血常规结果。”

Step 2:Prompt 注入工具定义

在发送给 LLM 之前,系统会将可用的工具列表(Tool Schema) 拼接到 System Prompt 中。这相当于给调度员发了一份“可用工人名单”。

[
  {
    "name": "get_lab_result",
    "description": "获取医院检验科的化验结果",
    "parameters": {
      "type": "object",
      "properties": {
        "patient_id": {
          "type": "string",
          "description": "病人的唯一标识ID"
        }
      },
      "required": ["patient_id"]
    }
  }
]

👉 关键点:LLM 此时“知道”自己手里有哪些牌可以打。

Step 3:LLM 推理(决策时刻)

LLM 接收 prompt 后进行推理,此时会出现两种情况:

情况 A:不需要工具

如果用户问“你好”,LLM 直接生成文本回复。

情况 B:决定调用工具

LLM 识别出需要查询数据,于是输出结构化数据(注意:此时并没有执行查询,只是生成了计划):

{
  "tool_name": "get_lab_result",
  "arguments": {
    "patient_id": "A123"
  }
}

Step 4:外部 Runtime 执行工具

这里是真正的分水界点。

LLM 输出结束后,控制权交还给代码层(如 LangChain AgentExecutor、OpenAI SDK 或自研后端)。

  1. 代码解析 LLM 输出的 JSON。
  2. 根据 tool_name 找到对应的真实函数。
  3. 传入 arguments 执行真实的业务逻辑(如调用医院 LIS 系统接口)。
# 伪代码:外部执行器
if response.tool_calls:
    tool_name = response.tool_calls[0].function.name
    args = json.loads(response.tool_calls[0].function.arguments)
    
    # 真正执行发生在这一行!LLM 此时是静止的
    result = get_lab_result(patient_id=args["patient_id"]) 

Step 5:结果回填与二次推理(Observation)

工具执行完后,会得到原始数据(比如一堆冰冷的指标数值)。系统将这些结果作为新的上下文,再次喂给 LLM。

第二次 Prompt 内容大致为:

用户问题:查血常规
工具返回结果:WBC: 12.3 ↑, CRP: 45 ↑
请根据结果回答用户。

LLM 进行二次推理,生成最终的自然语言回答:

“该患者白细胞(WBC)和 C反应蛋白(CRP)均升高,提示可能存在细菌感染,建议结合临床症状进一步诊断。”


四、整体闭环架构图

为了更直观地展示这个“思考-行动-观察”的闭环,我们使用 Mermaid 绘制流程图:

外部工具/API 大模型 (LLM) 应用层 (Runtime) 用户 外部工具/API 大模型 (LLM) 应用层 (Runtime) 用户 第一次推理 第二次推理 1. 发起请求 (Query) 2. 发送 Prompt + 工具定义 (Schema) 3. 返回调用意图 (JSON: tool_name, args) 4. 解析 JSON 并执行真实函数 5. 返回执行结果 (Observation) 6. 发送 Prompt + 用户问题 + 工具结果 7. 生成最终自然语言回答 8. 展示最终回答

👉 这就是业界常说的 ReAct (Reasoning + Acting) 模式的基础形态。


五、Function Calling vs 传统 Prompt Engineering

为什么我们要用 Function Calling,而不是直接在 Prompt 里让 LLM “假装”调用?

维度 传统 Prompt 方式 (Zero-shot/Few-shot) Function Calling (结构化输出)
输出格式 自由文本,难以解析 严格遵循 JSON Schema
可靠性 低,容易格式错误 高,由 SDK 保证解析成功
解析成本 高,需正则提取,易出错 低,直接映射为对象
幻觉控制 容易编造不存在的函数名 只能在给定 Schema 中选择
适用场景 简单问答、创意写作 复杂任务、API 调用、数据查询

六、工程实现中的常见坑与最佳实践

在实际落地中,Function Calling 并非一帆风顺,以下是几个高频痛点:

1. LLM 会不会乱调用工具?

会。 有时候模型会过度自信,明明可以直接回答却非要调工具。

  • 对策:在 System Prompt 中明确指示:“只有当用户问题涉及实时数据或复杂计算时才调用工具,否则直接回答。”

2. 参数幻觉(Hallucination)

LLM 可能会编造一个不存在的 patient_id,或者把日期格式搞错。

  • 对策
    • 在 Tool Layer 增加参数校验逻辑
    • 如果校验失败,将错误信息回填给 LLM,让它重试(Self-Correction)。

3. 为什么需要“二次 LLM”?

很多新手会问:“工具都返回结果了,我直接把结果发给用户不行吗?”

  • 原因:工具返回的是原始事实(Raw Data),往往是 JSON 或数据库记录,人类看不懂。
  • LLM 的价值:负责 Summarization(总结)Reasoning(推理)Explanation(解释),将数据转化为有温度的建议。

七、总结

Function Calling 的本质,并不是让 LLM 变成程序员去写代码,而是构建了一个**“大脑 + 手脚”**的协作系统:

  1. LLM(大脑):通过结构化约束训练,输出标准化的调用意图
  2. Runtime(手脚):在沙箱或后端环境中,安全地执行真实工具
  3. 闭环(神经反射):将执行结果回填,让 LLM 基于事实进行二次推理

理解了这个 “思考 → 行动 → 观察 → 再思考” 的闭环,你就掌握了构建现代 AI Agent 的核心钥匙。

希望这篇文章能帮你理清 Function Calling 的脉络。如果你在开发中遇到过工具调用的奇葩 Bug,欢迎在评论区交流!


参考资料

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐