📖 Day 4 学习页:LLM API 调用与 Function Calling

Day 4:LLM API 调用与 Function Calling

🎯 今日目标:跑通 Function Calling 完整闭环——让 LLM 自己决定调用哪个 Python 函数、 你执行它、把结果喂回去、LLM 给出最终回答。这是"Agent 会用工具"的本质,今天用 mock 就能练,不需要 API Key。

📚 本日资源:📝 练习模板 | ✅ 验收脚本

⏱ 今日安排(约 2 小时)

时间内容方式
30min理论学习:API 结构 + Function Calling 时序阅读
40minPrompt 实验:System Prompt / Few-shot / ReAct 格式编码实验
50min动手实操:完成练习模板 7 个 TODO编码

📖 第一步:理论学习

1. OpenAI 兼容 API 的请求结构

DeepSeek / Qwen / Moonshot 都兼容这套格式。一次对话 = POST 一个 JSON:

POST https://api.deepseek.com/chat/completions
Authorization: Bearer 你的KEY

{
  "model": "deepseek-chat",
  "messages": [
    {"role": "system",    "content": "你是一个有用的助手"},   # 设定人设,放最前
    {"role": "user",      "content": "北京今天天气怎么样?"},
    {"role": "assistant", "content": null,
      "tool_calls": [ ... ]},                                # LLM 请求调工具
    {"role": "tool",      "content": "晴 25°C", "tool_call_id": "call_001"}  # 工具结果回传
  ],
  "tools": [ ... ]     # 告诉 LLM 有哪些工具可用
}

2. tools 参数:给 LLM 的"工具说明书"

[
  {
    "type": "function",
    "function": {
      "name": "get_weather",
      "description": "获取指定城市的天气信息",     # ← LLM 靠这句话决定选不选这个工具!
      "parameters": {                            # ← JSON Schema,Day 2 的 Pydantic 可以自动生成
        "type": "object",
        "properties": {"city": {"type": "string", "description": "城市名称"}},
        "required": ["city"]
      }
    }
  }
]

3. Function Calling 完整时序(今天的核心)

用户提问
   │
   ▼
① 带 tools 调 LLM ──────────────► LLM 不直接回答,返回 tool_calls:
   │                                {"name": "get_weather", "arguments": '{"city":"北京"}'}
   ▼                                 注意:arguments 是 JSON 字符串,要 json.loads!
② 你解析并执行真正的 Python 函数,得到结果 "晴 25°C"
   │
   ▼
③ 把结果作为 role="tool" 消息追加进 messages(带上 tool_call_id)
   │
   ▼
④ 再次调用 LLM ─────────────────► LLM 综合工具结果,给出最终回答
   │
   ▼
⑤ 循环:如果第 ④ 步又返回 tool_calls,回到 ②,直到给出最终回答
   (所以必须有 max_rounds 上限,防止无限烧钱)

4. Prompt 工程三原则(今天顺手练)

原则做法
System Prompt 精简只放人设 + 工具使用规则;太长 LLM 会忽略后面的
Few-shot在 prompt 里给 1-2 个输入→输出示例,格式遵循度大幅提升
格式约束让 LLM 按固定格式输出(如 ReAct 的 Thought/Action),后面才好解析

🛠 第二步:动手实操

  1. 打开模板:day04_practice_template.py。两个工具已注册好, mock LLM 也写好了(不需要 Key),你实现 4 个核心函数:
    • TODO 1.2:get_tools_for_api() —— 把注册表转成上面的 tools 格式
    • TODO 3.1:parse_tool_calls() —— 从响应里取 tool_calls,json.loads 解析 arguments
    • TODO 3.2:execute_tool_call() —— 查注册表、执行、返回结果
    • TODO 4.1:chat_with_function_calling() —— 按上面的 ①→⑤ 时序写主循环(最有价值的一题)
    • TODO 5.1(可选):有 DeepSeek Key 的话把 mock 换成真实 API
  2. 运行自测:python day04_practice_template.py,两个问题都应打出最终回答。
  3. 验收:python day04_practice_validator.py —— 验收用构造好的 LLM 响应直接喂你的解析函数, 并跑通你的完整闭环。

⚠️ 避坑

  • ❌ arguments 是 JSON 字符串不是字典——忘 json.loads 是新手第一坑
  • ❌ 工具结果忘以 role="tool" 回传 → LLM 不知道工具说了什么,永远循环
  • ❌ 主循环没有轮数上限 → LLM 反复要求调工具,token 烧个不停
  • ✅ 真实 API 的 JSON 可能格式错误:json.loads 必须套 try/except + 重试
  • ✅ 国内直连用 DeepSeek / Qwen / Moonshot,都有免费额度

🔗 延伸资源