Notes

结构化输出与 Function Calling

摘要:这是 AI Agent 从“聊天机器人”进化为“智能助理”的关键一步。本章将讲解如何让 LLM 不再只会闲聊,而是能够精准地输出 JSON 数据,甚至主动请求执行代码函数。

1. 结构化输出 (Structured Output)

默认情况下,LLM 输出的是非结构化的文本。但这对于程序来说是难以处理的。我们需要 JSON。

1.1 JSON Mode

这是最简单的让模型输出 JSON 的方式。 在请求中设置 response_format: { "type": "json_object" },并在 System Prompt 中明确要求“输出 JSON”。

适用场景:数据提取、文本分类、生成配置文件。

1.2 Function Calling (函数调用)

JSON Mode 只是让输出格式变了,而 Function Calling 则是让模型具备了意图识别参数构造的能力。

核心流程

  1. 定义工具:你告诉模型:“我有这几个函数(工具),如果你需要用,就告诉我。”
  2. 模型决策:模型根据用户的问题,判断是否需要调用工具。如果需要,它不返回文本,而是返回一个 tool_calls 对象,包含函数名和参数(JSON 格式)。
  3. 执行工具你的代码捕获到这个请求,执行真正的本地函数(如查询数据库、调用天气 API)。
  4. 回传结果:你把函数执行的结果(Result)再次发给模型。
  5. 最终回答:模型结合函数结果,生成给用户的最终自然语言回复。

2. 协议详解

2.1 定义 Tools Schema

你需要在 API 请求中增加 tools 字段。每个 tool 都是一个函数描述。

"tools": [
  {
    "type": "function",
    "function": {
      "name": "get_weather",
      "description": "获取某个城市的当前天气",
      "parameters": {
        "type": "object",
        "properties": {
          "city": {
            "type": "string",
            "description": "城市名称,如 Beijing, Shanghai"
          }
        },
        "required": ["city"]
      }
    }
  }
]

2.2 处理 Tool Calls

当模型决定调用工具时,返回的 JSON 结构如下:

{
  "choices": [
    {
      "message": {
        "role": "assistant",
        "content": null, // 注意这里内容为空
        "tool_calls": [
          {
            "id": "call_abc123",
            "type": "function",
            "function": {
              "name": "get_weather",
              "arguments": "{\"city\": \"Beijing\"}" // 模型生成的参数
            }
          }
        ]
      },
      "finish_reason": "tool_calls"
    }
  ]
}

2.3 提交 Tool Outputs

执行完函数后,你需要构造一个新的 message 发回给模型。注意:必须带上 tool_call_id,这样模型才知道这个结果对应哪次调用。

{
  "role": "tool",
  "tool_call_id": "call_abc123",
  "name": "get_weather",
  "content": "{\"temperature\": 22, \"condition\": \"Sunny\"}"
}

3. 为什么不直接用正则提取参数?

早期的开发者确实是用正则去匹配用户输入(例如匹配 "查询天气"),但这非常脆弱。Function Calling 的优势在于:

  1. 语义理解:模型能理解复杂的自然语言意图(例如“帮我看看那个有鸟巢的城市今天下雨吗” -> 提取出 Beijing)。
  2. 鲁棒性:模型经过专门训练,生成的 JSON 参数非常稳定,甚至能自动纠正拼写错误。
  3. 多步推理:模型可以一次性决定调用多个工具,或者根据前一个工具的结果决定下一步操作(Agent 雏形)。

下一步:我们将编写一段代码,亲手实现这个“模型 -> 代码 -> 模型”的闭环。

cd ..