← 返回 Day 119 正文

Day 119 · 图解

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