📖 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 时序 | 阅读 |
| 40min | Prompt 实验: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),后面才好解析 |
🛠 第二步:动手实操
- 打开模板: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
- TODO 1.2:
- 运行自测:
python day04_practice_template.py,两个问题都应打出最终回答。 - 验收:
python day04_practice_validator.py—— 验收用构造好的 LLM 响应直接喂你的解析函数, 并跑通你的完整闭环。
⚠️ 避坑
- ❌
arguments是 JSON 字符串不是字典——忘 json.loads 是新手第一坑 - ❌ 工具结果忘以
role="tool"回传 → LLM 不知道工具说了什么,永远循环 - ❌ 主循环没有轮数上限 → LLM 反复要求调工具,token 烧个不停
- ✅ 真实 API 的 JSON 可能格式错误:json.loads 必须套 try/except + 重试
- ✅ 国内直连用 DeepSeek / Qwen / Moonshot,都有免费额度
🔗 延伸资源
- OpenAI Function Calling 指南
- DeepSeek API 文档(免费额度)
- Prompt Engineering Guide(中文)
tutorial_03_real_api.py:真实 API 实战教程——配好 Key 后把今天的 mock 换成真调用(限流/超时/重试都在里面)