Day 119 图解 — 大模型 API 调用
一、API 调用全流程
sequenceDiagram
participant User as 👤 用户
participant App as 📱 你的应用
participant API as ☁️ LLM API
participant Tool as 🔧 外部工具
User->>App: 输入问题
App->>API: POST /chat/completions<br/>(messages + tools)
alt 普通回复
API-->>App: choices[0].message.content
App-->>User: 显示回复
else Function Calling
API-->>App: tool_calls: [{name, args}]
App->>Tool: 执行函数(name, args)
Tool-->>App: 返回结果
App->>API: 发送 tool 结果
API-->>App: 最终回复
App-->>User: 显示回复
end
sequenceDiagram
participant User as 👤 用户
participant App as 📱 你的应用
participant API as ☁️ LLM API
participant Tool as 🔧 外部工具
User->>App: 输入问题
App->>API: POST /chat/completions<br/>(messages + tools)
alt 普通回复
API-->>App: choices[0].message.content
App-->>User: 显示回复
else Function Calling
API-->>App: tool_calls: [{name, args}]
App->>Tool: 执行函数(name, args)
Tool-->>App: 返回结果
App->>API: 发送 tool 结果
API-->>App: 最终回复
App-->>User: 显示回复
end
二、消息角色流转
graph LR
S[System] -->|设定规则| U[User]
U -->|提问| A[Assistant]
A -->|回答| U
U -->|追问| A
A -->|需要工具| T[Tool]
T -->|返回结果| A
A -->|最终回复| U
style S fill:#e1f5fe
style U fill:#fff3e0
style A fill:#e8f5e9
style T fill:#fce4ec
graph LR
S[System] -->|设定规则| U[User]
U -->|提问| A[Assistant]
A -->|回答| U
U -->|追问| A
A -->|需要工具| T[Tool]
T -->|返回结果| A
A -->|最终回复| U
style S fill:#e1f5fe
style U fill:#fff3e0
style A fill:#e8f5e9
style T fill:#fce4ec
三、Prompt Engineering 六大技巧
┌──────────────────────────────────────────────────────┐
│ Prompt Engineering 六大技巧 │
├──────────────────────────────────────────────────────┤
│ │
│ 1️⃣ 角色设定 2️⃣ Few-Shot 示例 │
│ ┌─────────────┐ ┌──────────────────┐ │
│ │ "你是专家" │ │ 输入→输出 示例1 │ │
│ │ 激活专业知识 │ │ 输入→输出 示例2 │ │
│ └─────────────┘ └──────────────────┘ │
│ │
│ 3️⃣ 链式思考 4️⃣ 结构化输出 │
│ ┌─────────────┐ ┌──────────────────┐ │
│ │ Step 1 → │ │ {"key": "value"} │ │
│ │ Step 2 → │ │ 便于程序解析 │ │
│ │ Step 3 → 答 │ └──────────────────┘ │
│ └─────────────┘ │
│ │
│ 5️⃣ 约束与边界 6️⃣ 分步骤指令 │
│ ┌─────────────┐ ┌──────────────────┐ │
│ │ "不要编造" │ │ 步骤1: 审查 │ │
│ │ "100字以内" │ │ 步骤2: 分析 │ │
│ └─────────────┘ │ 步骤3: 建议 │ │
│ └──────────────────┘ │
└──────────────────────────────────────────────────────┘
四、Function Calling 状态机
┌──────────┐
│ 开始 │
└────┬─────┘
▼
┌─────────────────┐
│ 用户发送消息 │
│ + 工具定义 │
└────────┬────────┘
▼
┌─────────────────┐
│ LLM 分析需求 │
└────────┬────────┘
▼
┌───────────┐
│ 需要工具? │
└─────┬─────┘
Yes │ No
┌───────────┤───────────┐
▼ ▼
┌──────────────┐ ┌──────────────┐
│ 返回工具调用 │ │ 返回文本回复 │
│ {name, args} │ └──────┬───────┘
└──────┬───────┘ │
▼ ▼
┌──────────────┐ ┌──────────┐
│ 执行函数 │ │ 返回用户 │
│ 获取结果 │ └──────────┘
└──────┬───────┘
▼
┌──────────────┐
│ 结果发回 LLM │
└──────┬───────┘
▼
┌──────────────┐
│ LLM 整合回复 │
└──────┬───────┘
▼
┌──────────┐
│ 返回用户 │
└──────────┘
五、上下文窗口管理
┌──────────────────────────────────────────┐
│ Token 上下文窗口管理 │
├──────────────────────────────────────────┤
│ │
│ Token 预算: 8192 (模型限制) │
│ │
│ ┌────────────────────────────────────┐ │
│ │ [System Prompt] ~200 tokens │ │
│ │ [历史消息1] ~100 tokens │ │
│ │ [历史消息2] ~150 tokens │ │
│ │ ... │ │
│ │ [历史消息N] ~120 tokens │ │ ← 自动截断
│ │ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │ │
│ │ [当前用户消息] ~80 tokens │ │
│ │ [预留输出空间] ~2000 tokens │ │
│ └────────────────────────────────────┘ │
│ │
│ 💡 策略: │
│ • 保留 System Prompt(始终不动) │
│ • 滑动窗口保留最近 N 条 │
│ • 预留 max_tokens 给输出 │
└──────────────────────────────────────────┘
六、错误处理与重试策略
graph TD
A[发起 API 请求] --> B{请求成功?}
B -->|是| C[返回结果]
B -->|否| D{错误类型?}
D -->|429 Rate Limit| E[指数退避重试<br/>1s → 2s → 4s → 8s]
D -->|5xx 服务器错误| F[等待后重试<br/>最多3次]
D -->|400 参数错误| G[检查参数<br/>修复后重试]
D -->|网络错误| H[检查网络<br/>稍后重试]
E --> I{重试次数 < 5?}
F --> I
I -->|是| A
I -->|否| J[抛出异常<br/>记录日志]
style C fill:#e8f5e9
style J fill:#ffebee
graph TD
A[发起 API 请求] --> B{请求成功?}
B -->|是| C[返回结果]
B -->|否| D{错误类型?}
D -->|429 Rate Limit| E[指数退避重试<br/>1s → 2s → 4s → 8s]
D -->|5xx 服务器错误| F[等待后重试<br/>最多3次]
D -->|400 参数错误| G[检查参数<br/>修复后重试]
D -->|网络错误| H[检查网络<br/>稍后重试]
E --> I{重试次数 < 5?}
F --> I
I -->|是| A
I -->|否| J[抛出异常<br/>记录日志]
style C fill:#e8f5e9
style J fill:#ffebee