30 分钟
实战专项

LLM 应用架构全景:从 API 到产品

掌握 LLM 应用的完整技术栈和架构模式,能设计 AI 产品的技术方案

  • 理解 LLM 应用的核心组件和架构
  • 就讲三个核心概念:Token、上下文窗口、温度。
  • 了解同步/流式/批处理调用模式
  • 理解 LLM 应用的成本和延迟优化

LLM 应用的技术栈

一个完整的 LLM 应用不只是「调 API」。它包含:模型层(GPT/豆包/ Claude)、编排层(Prompt 管理、链式调用)、数据层(RAG 知识库、向量数据库)、工具层(Function Calling、Agent)、缓存层(语义缓存)、监控层(Token 用量、质量评估)。

Python
# 最简单的 LLM 调用
from openai import OpenAI

client = OpenAI(
    api_key="your-api-key",
    base_url="https://ark.cn-beijing.volces.com/api/v3"  # 豆包/火山方舟
)

response = client.chat.completions.create(
    model="doubao-pro-32k",
    messages=[
        {"role": "system", "content": "你是一个专业的Python编程老师。"},
        {"role": "user", "content": "解释什么是装饰器"}
    ],
    temperature=0.7,
    max_tokens=1000
)

print(response.choices[0].message.content)

核心概念

Token:LLM 处理文本的最小单位。1 个中文约 1-2 个 Token,1 个英文单词约 1-2 个 Token。Token 是计费和上下文窗口的基本单位。

上下文窗口(Context Window):模型一次能处理的最大 Token 数(输入+输出)。豆包 Pro 32K、GPT-4 Turbo 128K、Claude 200K。超出窗口的内容会被截断或报错。

温度(Temperature):控制输出随机性。0是确定性输出,适合代码、事实问答;0.7是平衡,适合对话;1.0+是创造性,适合写作。生产环境通常设0-0.3。

Python
# 关键参数详解
response = client.chat.completions.create(
    model="doubao-pro-32k",
    messages=messages,
    temperature=0.3,        # 低温度=稳定可复现
    max_tokens=2000,        # 最大输出Token(控制成本和长度)
    top_p=0.9,             # 核采样,与temperature类似,通常只调一个
    frequency_penalty=0.0,  # 降低重复(-2到2,正值减少重复)
    presence_penalty=0.0,   # 鼓励新话题(-2到2)
    stream=True,            # 流式输出(SSE),用户体验更好
)

# Token 计数(用 tiktoken 或模型自带的计数)
# 成本 = (输入Token数 * 输入单价 + 输出Token数 * 输出单价)
# 优化成本:缩短Prompt、缓存重复请求、用小模型处理简单任务

流式输出(SSE)

用户等完整响应要10-30秒,体验差。流式输出是模型每生成几个Token就返回一部分,用户能像看打字一样逐步看到结果。

Python
# 流式输出
stream = client.chat.completions.create(
    model="doubao-pro-32k",
    messages=messages,
    stream=True  # 关键参数
)

for chunk in stream:
    if chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)

# FastAPI 中实现 SSE 流式接口
from fastapi.responses import StreamingResponse

@app.post("/api/chat")
async def chat(req: ChatRequest):
    async def generate():
        stream = client.chat.completions.create(
            model="doubao-pro-32k",
            messages=[{"role": "user", "content": req.message}],
            stream=True
        )
        for chunk in stream:
            content = chunk.choices[0].delta.content
            if content:
                yield f"data: {content}\n\n"  # SSE格式
        yield "data: [DONE]\n\n"

    return StreamingResponse(generate(), media_type="text/event-stream")

LLM 应用架构模式

模式1:直接调用(最简单)

用户输入 -> Prompt模板 -> LLM -> 输出模式2:RAG(检索增强生成)用户输入 -> 检索相关文档 -> 拼入Prompt -> LLM -> 带引用的回答适合:知识库问答、客服、文档助手模式3:Agent(智能体)用户输入 -> LLM思考 -> 调用工具 -> 观察结果 -> 继续思考 -> 最终回答适合:复杂任务、需要外部数据/操作模式4:工作流(Workflow)固定流程:步骤1(LLM) -> 步骤2(代码) -> 步骤3(LLM) -> ...适合:可预测的多步骤任务(翻译+审校+格式化)模式5:多Agent协作规划Agent -> 分配给专家Agent(代码/写作/搜索)-> 汇总Agent -> 输出适合:复杂的开放式任务

🐍架构选择原则

能用简单方案就不用复杂方案。直接 Prompt 能解决的不要上 RAG,RAG 能解决的不要上 Agent。Agent 不可控性高、延迟长、成本贵。绝大多数 LLM 应用用「Prompt + RAG + 少量 Function Calling」就够了。

成本与延迟优化

Prompt 缓存:相同的System Prompt只计算一次豆包/OpenAI 都支持 Prompt Caching,自动缓存重复前缀把不变的长指令放在前面,变化的用户输入放在后面 模型分级:简单任务用小模型分类/提取 -> 小模型(doubao-lite)复杂推理 -> 大模型(doubao-pro/gpt-4) 批处理(Batch API):非实时任务用批量接口,价格低50% 语义缓存:相似问题直接返回缓存答案用 embedding 计算相似度,>0.95 则返回缓存 限制 max_tokens:防止模型啰嗦,控制成本 流式输出首Token延迟(TTFT)优化用更近的API端点、减少Prompt长度、用更快的模型

⚠️LLM 应用的非确定性

LLM 每次调用可能返回不同结果(即使 temperature=0 也不保证完全一致,因为模型版本更新和分布式推理)。生产环境必须:对输出做校验和容错;关键操作用结构化输出+JSON Schema;有降级方案(LLM 不可用时的备用逻辑)。

选择题

LLM 中 Token 指的是?

选择题

Temperature=0 意味着?

选择题

RAG 主要解决什么问题?

资深工程师加餐

底层原理 · 大厂视角 · 工程经验,点卡片展开

纯向量检索懂「语义相近」,却对错误码、型号、专有缩写不敏感;纯关键词(BM25)精于字面却不懂同义。生产级 RAG 用混合检索把两路结果用 RRF 融合先宽召回(如 top-50),再用更贵但更准的交叉编码器 rerank 精排取 top-5 进上下文,兼顾「不漏」与「最相关在前」。检索质量往往比换更大的模型更能决定问答好坏。

挑战任务

设计 LLM 应用架构

简单+50 XP

给智能客服系统搭技术架构,要支持知识库问答、多轮对话、人工转接。先画架构,再讲技术选型。

设计 LLM 应用架构
3 个测试用例

课后作业

封装LLM客户端

中等+35 XP

封装一个带重试、超时、日志、成本统计的 LLM 客户端类,支持同步和流式调用,记录每次调用的Token用量和耗时。

封装LLM客户端
1 个测试用例