大模型基础
LLM 应用开发核心知识体系
基于 JavaGuide《LLM 运行机制》与《大模型 API 调用工程实践》两篇文章整理
目录
一、LLM 运行机制
下面是 LLM 运行机制的整体架构图:
1.1 自回归生成原理
LLM 本质是自回归生成:每次预测 1 个 Token,追加到上下文后再预测下一个,循环直至生成完整回答。
三大基础概念:
- Token:模型每一步"补"的文本碎片
- 上下文窗口:单次调用可容纳的总 Token 上限
- 采样参数:控制模型挑选下一个 Token 的策略
自回归生成过程如下:
1.2 Token 体系
1.2.1 Token 是什么
- 由 Tokenizer(子词切分算法 BPE/Unigram)将文本切成大小不等的碎片
- 高频词保留为整体,低频词拆成更小片段
- 不同厂商 Tokenizer 不通用,相同文本 Token 数量可能不同
1.2.2 中英文 Token 换算
| 语言 | 换算关系 |
|---|---|
| 英文 | 1 Token ≈ 3~4 字符(1 字符 ≈ 0.3 Token) |
| 中文 | 1 Token ≈ 1~2 汉字(1 汉字 ≈ 0.6 Token) |
注意:"趋近 1 字 1 Token"只适用于高频词汇,不能当成本估算基准。
1.2.3 特殊 Token(隐形占用窗口)
| 特殊 Token | 用途 | 示例 |
|---|---|---|
| BOS | 标记序列开始 | <s> |
| EOS | 标记序列结束 | </s> |
| PAD | 批处理时填充短序列 | <pad> |
| 工具调用标记 | Function Calling 边界 | <tool_call /> |
1.2.4 多模态图片 Token 开销
| 模型 | 计算方式 | 1024×1024 图片约等于 |
|---|---|---|
| GPT-4o | 按分辨率+细节模式 | 低细节 ~85,高细节 7651105 |
| Claude 3.5 | 固定或全图 | ~5(缩略图)/ ~85(全图) |
| Gemini | 按分辨率 | ~258(标准) |
工程启示:OCR 场景建议先用专门 OCR 服务提取文字,再以纯文本送入模型。
1.2.5 计费规则
- 输出 Token 价格通常是输入的 2~5 倍
- 思维链模型的 reasoning 推理内容按输出价格计费
| 模型 | 输入价格(/1M) | 输出价格(/1M) | 输出/输入比 |
|---|---|---|---|
| GPT-4o | $2.50 | $10.00 | 4x |
| Claude 3.5 Sonnet | $3.00 | $15.00 | 5x |
| DeepSeek V3 | ¥0.5 | ¥2.0 | 4x |
| DeepSeek-R1 | ¥4.0 | ¥16.0 | 4x |
1.2.6 Prompt Caching 省钱机制
- 原理:供应商缓存请求中可复用的固定前缀,下次调用只收缓存读取费(原价 10%~50%)
- 适用场景:多轮对话、RAG 应用、批量评估
- 使用规范:不变内容放前面(System Prompt、工具定义、RAG Context),变化内容放后面(User Prompt)
| 供应商 | 功能名称 | 缓存时长 | 缓存命中折扣 |
|---|---|---|---|
| OpenAI | Prompt Caching | 5~10 分钟 | 输入价格约 50% |
| Anthropic | Prompt Caching | 5 分钟 | 输入价格约 10% |
| DeepSeek | Context Caching | 10~30 分钟 | 输入价格约 25% |
1.2.7 Token 预算公式
普通模型:
上下文窗口 ≥ input_tokens + max_output_tokens
思维链模型:
上下文窗口 ≥ input_tokens + reasoning_tokens + max_output_tokens
reasoning_tokens 难以精确预估,建议按 max_output_tokens 的 2~3 倍预留。
超预算处理策略:
- 优先减少 RAG 的 Top-K 或做片段去重
- 对长字段做摘要/截断
- 多段任务拆成多次调用
Token 预算决策流程:
1.3 上下文窗口
1.3.1 窗口包含的内容
- 静态层:System Prompt、Tool/Output Schema
- 动态层:User Prompt、Memory/History、RAG/Tool Results
- 输出层:Reasoning Output、Final Content
真正能塞进 Prompt 的"有效业务内容"远小于标称上限。
1.3.2 长上下文的计算约束
- Transformer 自注意力机制:计算需求与序列长度呈 O(N²) 平方级关系
- 输入 Token 翻倍,处理能力需求可能变为 4 倍
- 上下文越长,TTFT(首字延迟)越高
- 优化技术:FlashAttention、GQA/MQA、Sliding Window Attention、Ring Attention
1.3.3 上下文溢出的真实表现
- 忽略早期约束:System Prompt 要求输出 JSON,但因距离太远被忽略
- "中间丢失"现象:模型对开头和结尾最敏感,中间部分召回率显著下降
- 回答漂移:前半段围绕问题,后半段开始跑题
- RAG 失效:检索文档过多,关键信息被稀释或被截断
- 成本与延迟激增
1.3.4 思维链模型的特殊处理
reasoning_content(思考过程)通常不会自动包含在下一轮对话上下文中- 只有
content(最终回答)会参与后续对话 - 如需复用推理过程,需手动将 reasoning_content 拼接到消息历史
1.4 采样参数
采样参数生成流程如下:
1.4.1 生成流程
logits(原始分数) → softmax(转概率) → 采样参数筛选 → 抽签决定输出 Token
1.4.2 Temperature(温度)
公式:p(t) = softmax(logits / T)
- T < 1:分布更尖锐,更倾向高概率 Token(更"稳")
- T ≈ 1:保持原始分布
- T > 1:分布更平坦,低概率 Token 更容易被选中(更"野")
注意:仅设 Temperature=0 不能完全复现结果(GPU 浮点误差),需同时配置
seed参数。
1.4.3 Top-p / Top-k
| 参数 | 作用 | 特点 |
|---|---|---|
| Top-k | 固定保留概率最高的 k 个候选 | 灵活性差,不管概率分布 |
| Top-p(核采样) | 累加概率至阈值自动筛选候选 | 自适应候选数量,工程首选 |
常见组合:
| 组合 | 效果 | 适用场景 |
|---|---|---|
| T=0(贪婪解码) | 永远选最高分 | 结构化输出、可复现场景 |
| 低温 + Top-p=0.9 | 相对稳定,允许措辞变化 | 分析报告、摘要 |
| 中高温 + Top-p=0.95 | 多样性高,排除极端离谱选项 | 创意写作、对话 |
1.4.4 Penalty 惩罚参数
| 参数 | 作用 | 通俗理解 |
|---|---|---|
| Repetition Penalty | 降低所有已出现 Token 的概率 | “说过的词,再说就扣分” |
| Presence Penalty | 只要出现过就扣分(不看次数) | “鼓励聊新话题” |
| Frequency Penalty | 出现次数越多扣分越重 | “同一个词说三遍?重罚” |
工程陷阱:
- JSON 场景禁用 Repetition Penalty:字段名需要反复出现,会被惩罚导致输出残缺
- RAG 问答禁用 Presence Penalty:会鼓励模型"说新东西",降低对检索内容的忠实度,增加幻觉
1.4.5 其他关键参数
| 参数 | 说明 | 注意事项 |
|---|---|---|
| Max Tokens | 输出硬上限 | 到达强制截断,会出现半截 JSON |
| Stop Sequences | 自定义停止符 | 软终止,需避免提前截断关键字段 |
| 流式输出 | 逐 Token 实时返回 | 仅优化首字感知,总耗时/计费不变 |
| Logprobs | Token 对数概率 | 可用于置信度评估、异常检测 |
1.4.6 思维链模型的参数限制
DeepSeek-R1、OpenAI o1 等推理模型:
- 忽略
temperature、top_p、各类惩罚参数 - 采用模型内部固定采样策略
- 只能通过 Prompt 约束 输出格式
1.5 分场景参数配置
| 场景 | Temperature | Top-p | Penalty | 其他建议 |
|---|---|---|---|---|
| JSON/结构化输出 | 0~0.3 | 1.0 | 保持默认 | 配合 Strict Mode + 重试策略 |
| 代码评审/技术分析 | 0.4~0.7 | 0.9 | 保持默认 | 结合 CoT Prompt |
| 多轮对话 | 0.6~0.8 | 0.9 | 适度开启 | 控制历史消息长度 |
| 创意写作/头脑风暴 | 0.8~1.2 | 0.95 | 按需开启 | 接受多样性,做好后处理 |
| 思维链模型 | 不支持 | 不支持 | 不支持 | 通过 Prompt 控制 |
二、LLM API 调用工程实践
2.1 生产级调用 8 阶段
生产级调用 8 阶段流程如下:
1. 业务请求进入 → 2. 上下文组装 → 3. Token 预算预估 → 4. 模型网关路由
→ 5. 供应商 API 调用 → 6. 响应解析 → 7. 状态回写 → 8. 观测与告警
| 阶段 | 核心工作 |
|---|---|
| 业务请求进入 | 校验身份、租户、套餐、权限、请求大小 |
| 上下文组装 | 拼 System Prompt、用户输入、历史消息、RAG 证据、工具 Schema |
| Token 预算预估 | 估算输入 Token,预留输出 Token,决定是否裁剪或换模型 |
| 模型网关路由 | 选择模型、供应商、区域、超时、重试策略、限流桶 |
| 供应商 API 调用 | 同步返回或流式返回 |
| 响应解析 | 处理 delta、finish reason、tool call、usage、拒答、结构化 JSON |
| 状态回写 | 保存回答、增量片段、Token 用量、成本、失败原因 |
| 观测与告警 | 记录 traceId、TTFT、总耗时、重试次数、429 次数 |
核心建议:必须有统一的 LLMGateway 收口所有模型调用,不要让每个业务系统各自处理 API Key、超时、重试、限流。
2.2 同步 vs 流式返回
| 对比项 | 同步返回 | 流式返回 |
|---|---|---|
| 首字延迟 TTFT | 高,等完整结果 | 低,收到第一个片段即可展示 |
| 端到端总耗时 | 取决于完整生成时间 | 通常仍取决于完整生成时间 |
| 前端体验 | 像提交表单后等待 | 像聊天软件逐字出现 |
| 后端实现 | 简单 | 复杂,需处理增量、取消、断流 |
| 结构化解析 | 简单,完整 JSON 一次解析 | 需缓存完整内容或增量解析器 |
| 适合场景 | 短文本、后台任务、严格事务 | 聊天、写作、报告生成、长回答 |
关键认知:Streaming 降低的是 TTFT(首字延迟),不是总耗时,也不省钱。
2.3 三种流式协议
2.3.1 协议对比
| 方式 | 核心特点 | 适合场景 | 边界 |
|---|---|---|---|
| SSE | 浏览器原生 EventSource,单向推送,text/event-stream | 文本聊天、模型增量输出 | 单向;复杂双向控制需额外 HTTP |
| WebSocket | 双向长连接,双方都能随时发消息 | 实时语音、多人协作、频繁取消/插话 | 连接管理复杂 |
| HTTP chunked | HTTP/1.1 分块传输机制 | 后端到后端流式代理 | 是传输机制不是应用协议 |
2.3.2 SSE 关键细节
- 空行才是事件分隔符(
\n\n或\r\n\r\n),单个换行只是结束字段行 - 常用字段:
data(载荷)、event(事件名)、id(序号)、retry(重连间隔)
模型正文换行导致截断的解决方案:
// 出站前转义
chunk.replace("\n", "\\n").replace("\r", "\\r")
// 前端还原
text.replace(/\\n/g, "\n").replace(/\\r/g, "\r")
Nginx 流式配置:
location /api/ {
proxy_pass http://backend;
proxy_buffering off; # 必须关闭,否则流式变批量
proxy_cache off;
proxy_read_timeout 300s; # 守住长生成超时
proxy_set_header Connection "";
add_header Cache-Control no-cache;
}
2.3.3 流式异常四类场景
| 场景 | 处理方式 |
|---|---|
| 用户取消 | 同时取消供应商请求、解析流、后续 TTS/工具调用、落库任务 |
| 超时 | 分三层:连接超时、TTFT 超时、总时长超时,分开记录 |
| 断流 | 没有正常结束标记就标记为 INTERRUPTED,不要把半截内容当成功 |
| 重连 | 服务端缓存已发送片段,重连时补发;失效则提示重新生成 |
血泪教训:不要只在前端停止展示。前端停了,后端还在生成,账单照样跑。
2.4 重试与幂等
2.4.1 大模型重试的特殊性
- 请求贵:失败请求也可能消耗配额,甚至已消耗部分 Token
- 输出非确定:即使 Prompt 一样,第二次返回也可能不同
2.4.2 错误类型对照表
| 类型 | 示例 | 是否重试 | 处理方式 |
|---|---|---|---|
| 网络瞬断 | 连接重置、DNS 抖动、读超时 | 可以 | 指数退避+抖动,限制最大次数 |
| 供应商 5xx | 500/502/503/504 | 可以 | 短暂重试,超阈值切换模型或降级 |
| 供应商过载 | 529 overloaded | 可以 | 慢重试,必要时熔断 |
| 429 限流 | RPM/TPM/RPD 超限 | 谨慎 | 看 Retry-After,排队或降级 |
| 流式中断 | 未收到正常结束事件 | 视场景 | 用户可见任务不自动重试 |
| 400 参数错误 | Schema 不合法、上下文超限 | 不建议 | 修请求,不要重试同一 payload |
| 401/403 鉴权 | API Key 无效 | 不建议 | 告警并停用 Key |
| 安全拒答 | 内容策略拒绝 | 不建议 | 进入业务拒答流程 |
| 解析失败 | JSON 不完整、字段类型错 | 有限重试 | 带失败原因二次修复,最多 1-2 次 |
2.4.3 指数退避 + 抖动
sleep = min(maxDelay, baseDelay * 2^retryCount) + random(0, jitter)
硬约束:
- 最大重试次数通常 2~3 次
- 必须有总体截止时间(如用户 SLA 15 秒),不要因重试拖成 1 分钟
2.4.4 幂等 Key 机制
生成规则示例:
tenantId:userId:conversationId:messageId:attemptGroup
服务端处理逻辑:
- 已成功 → 直接返回历史结果
- 正在生成 → 返回同一流式任务的订阅地址
- 失败且允许重试 → 创建新 attempt,挂在同一业务消息下
- 失败但不可重试 → 直接返回失败原因
响应去重标识:
message_id:业务消息 ID(对用户可见)attempt_id:模型调用尝试 ID(对系统可见)provider_request_id:供应商请求 ID(用于排查)stream_sequence:增量片段序号(用于去重和补发)
落库时只允许一个 attempt 成为 final,其他保留为诊断记录,不污染下一轮 Prompt。
2.5 限流与配额
2.5.1 限流四层架构
| 层级 | 限制对象 | 核心目的 | 常见策略 |
|---|---|---|---|
| 用户级 | 单个用户/账号 | 防滥用、误操作、脚本刷 | 每分钟请求数、每日 Token 上限 |
| 租户级 | 企业/团队/项目 | 控制套餐成本和公平性 | 月度配额、并发上限、优先级队列 |
| 模型级 | 某个模型/模型族 | 避免热门模型被打满 | 模型维度令牌桶、降级备用模型 |
| 供应商级 | OpenAI/Anthropic/Gemini | 保护外部依赖和 API Key | 全局 RPM/TPM/并发、熔断 |
2.5.2 为什么不能只按 QPS 限流
- 请求 A:输入 500 Token,输出 100 Token
- 请求 B:输入 80K Token,输出 8K Token
- 都是 1 次请求,但资源消耗差 两个量级
必须同时监控:
- RPM(每分钟请求数)
- TPM(每分钟 Token 数)
- 并发数
- 上下文大小(单请求输入 Token)
- 最大输出(max_tokens)
- 日/月预算
核心原则:先扣预算,再发请求。扣不到就排队/降级/拒绝,不要发给供应商。
2.5.3 常见限流策略
| 策略 | 适合场景 | 优点 | 缺点 |
|---|---|---|---|
| 固定窗口 | 简单后台任务 | 实现简单 | 窗口边界突刺 |
| 滑动窗口 | 用户级请求限制 | 边界平滑 | 存储成本高 |
| 令牌桶 | 模型调用、Token 预算 | 支持突发,工程常用 | 参数需调优 |
| 漏桶 | 严格平滑出流量 | 输出稳定,保护供应商 | 突发体验差 |
| 并发信号量 | 流式生成、长任务 | 限制同时占用连接 | 不控制单请求 Token 成本 |
| 优先级队列 | 多租户、多套餐 | 保护高优先级请求 | 需处理饥饿和超时 |
生产通常组合使用,而非单选。
2.5.4 收到 429 的处理顺序
- 读取
Retry-After或限流头,尊重恢复时间 - 标记限流维度(请求数/Token/日配额)
- 短请求可排队,用户交互请求少重试
- 供应商连续 429 时熔断
典型降级链路:
优先模型可用 → 正常调用
优先模型 429 → 切备用同级模型
备用模型也限流 → 切轻量模型并缩短输出
仍不可用 → 排队或返回"当前请求繁忙"
降级要明确标记(如"当前为快速模式"),不要偷偷变差。
2.6 结构化返回
2.6.1 约束强度递进
| 方式 | 约束强度 | 工程价值 | 风险 |
|---|---|---|---|
| 普通自然语言 | 几乎没有 | 适合展示型回答 | 不适合程序解析 |
| Prompt 要求 JSON | 弱 | 简单、跨模型 | 易混入解释文本或缺字段 |
| JSON Mode | 中 | 保证语法是 JSON | 不一定符合业务 Schema |
| JSON Schema | 强 | 明确字段、类型、必填、枚举 | 各供应商支持子集不同 |
| Structured Outputs | 更强 | 解码/SDK 层增强约束 | 受模型/SDK/Schema 子集限制 |
| Function Calling/Tool Use | 面向动作 | 适合让模型选工具和参数 | 不是自然语言答案的万能替代 |
核心价值:把"模型生成"变成可校验的数据契约。
2.6.2 失败兜底四级
- 本地校验:JSON Schema、Jackson、Bean Validation 校验字段和类型
- 轻量修复:只让模型修复格式,不重新生成业务内容
- 降级 Schema:复杂对象拆成多个小对象,或先分类再抽取
- 人工/规则兜底:金融、医疗、法务等高价值场景不要完全依赖自动修复
原则:结构化输出失败时,不要把原始自然语言硬塞给下游系统。能展示给用户,不代表能被程序执行。
2.6.3 流式结构化返回处理
- 不要一边收到 delta 一边直接
JSON.parse()完整对象 - 增量阶段只展示文本或记录片段
- 等收到正常结束事件后拼成完整内容,再做 Schema 校验
- 若供应商支持结构化流式事件或 SDK accumulator,使用官方累积器
2.7 可观测性指标
2.7.1 核心指标
| 指标 | 含义 | 用途 |
|---|---|---|
| TTFT | 首个 Token 返回时间 | 判断排队、上下文过长、供应商抖动 |
| E2E Latency | 端到端完成时间 | 用户体验和 SLA |
| Input Tokens | 输入 Token | 成本分析、上下文膨胀排查 |
| Output Tokens | 输出 Token | 成本分析、异常长回答排查 |
| Retry Count | 重试次数 | 识别供应商不稳定或策略过激 |
| 429 Rate | 限流比例 | 判断配额和限流桶是否合理 |
| Parse Failure Rate | 结构化解析失败率 | 判断 Schema/Prompt/模型适配 |
| Cancel Rate | 用户取消比例 | 判断响应太慢或生成太长 |
| Provider Error Rate | 供应商错误率 | 路由、降级、熔断依据 |
2.7.2 日志必带字段
trace_id, tenant_id, user_id, conversation_id, message_id, attempt_id,
model, provider, prompt_version, input_tokens, output_tokens,
ttft_ms, latency_ms, retry_count, finish_reason, error_type, provider_request_id
三、面试高频问题
基础概念题
-
什么是 Token?中英文 Token 消耗差异怎么估算?
- Token 是模型处理文本的最小碎片,由 Tokenizer 子词切分
- 1 中文 ≈ 0.6 Token,1 英文 ≈ 0.3 Token;不同厂商 Tokenizer 结果不同
-
上下文窗口包含哪些内容?为什么 128K 模型不能无限塞文档?
- 包含 System Prompt、工具 Schema、对话历史、RAG 片段、输出内容
- Transformer 自注意力 O(N²) 复杂度,越长延迟和成本越高
- 会出现中间信息丢失、遗忘前置指令、回答漂移等问题
-
Prompt Cache 原理是什么?怎么使用最大化省钱?
- 固定前缀缓存,再次调用只收 10%~50% 费用
- 不变内容放前面,动态内容放后面;批量任务集中在缓存有效期内
-
输入输出计费有什么区别?怎么降低调用成本?
- 输出价格是输入的 2~5 倍
- 控制 max_tokens、精简 RAG 检索量、利用 Prompt Cache、长 Prompt+短输出更经济
采样参数题
-
Temperature=0 为什么结果还会变?如何保证完全复现?
- GPU 浮点误差仍可能导致非确定性
- 需同时配置 seed 参数;模型版本更新、跨区域调用也可能导致不一致
-
稳定输出 JSON,全套参数怎么配置?为什么不能开重复惩罚?
- Temperature=0~0.3,Top-p=1.0,Penalty 保持默认
- JSON 字段名需要反复出现,Repetition Penalty 会惩罚必须重复的字段名
-
Top-p 和 Top-k 区别,开发优先用哪个?
- Top-k 固定保留 k 个,Top-p 按累计概率自适应筛选
- Top-p 更灵活,工程首选
-
思维链模型为什么不支持温度参数?怎么控制输出格式?
- 推理模型采用内部固定采样策略,忽略用户传入的采样参数
- 只能通过 Prompt 约束输出格式
工程实践题
-
大模型 API 调用完整链路是什么?
- 8 阶段:业务进入→上下文组装→Token 预算→网关路由→供应商调用→响应解析→状态回写→观测告警
- 核心是不能只看作一个 HTTP 请求,而是需要治理的生产链路
-
Streaming 为什么能改善体验?
- 降低 TTFT(首字延迟),用户更早看到内容
- 不缩短总耗时,不省钱;后端需处理取消、超时、断流、重连
-
SSE 和 WebSocket 怎么选?
- 单向文本推送用 SSE(注意事件边界和 Nginx 缓冲)
- 双向实时交互(语音、插话、多人协作)用 WebSocket
-
哪些错误可以重试,哪些不能?
- 可以:网络瞬断、5xx、供应商过载
- 不能:400 参数错误、401/403 鉴权、安全拒答
- 谨慎:429 限流、流式中断、解析失败
-
为什么大模型调用必须做幂等?
- 重试、用户重复点击、网关超时都会导致同一业务请求执行多次
- 用业务消息 ID 做幂等 Key,多次 attempt 挂在同一消息下,只允许一个 final
-
限流为什么不能只按 QPS?
- 500 Token 和 80K Token 请求压力差两个量级
- 需同时看 RPM、TPM、并发数、上下文大小、最大输出、租户预算
-
JSON Mode 和 Structured Outputs 有什么区别?
- JSON Mode 保证输出是合法 JSON,但不一定符合业务 Schema
- Structured Outputs 约束更强,保证字段、类型、必填项、枚举等结构
-
流式结构化返回怎么处理?
- 增量阶段只展示文本,等结束事件后拼完整内容再校验
- 不要边收边 JSON.parse,使用 SDK accumulator 或自己维护 buffer
四、核心结论
LLM 运行机制三大权衡
- Token 是成本与性能的物理标尺:所有内容都按 Token 计费,不能按字数估算
- 上下文窗口是稀缺资源:标称大上下文不等于可以无节制填充,必须做好预算管控
- 采样参数是业务调音台:稳定业务压低温度、收紧候选池;创意场景放开随机性
API 工程实践六大判断
- 模型网关是稳定性入口:路由、限流、重试、幂等、观测全在这里收口
- Streaming 降低的是 TTFT 不是总成本:取消、超时、断流、重连都是新问题
- 重试必须和幂等绑定:能重试的错误有限,不能让重试制造重复业务结果
- 限流不能只按 QPS:Token 消耗差异巨大,需多维度限流
- 结构化返回是数据契约:解决的是"下游系统能稳定消费",不是"看起来像 JSON"
- 没有观测就没有稳定性:TTFT、usage、attempt、providerRequestId 缺一不可
大模型 API 调用,本质上是接入一个聪明但昂贵、偶尔排队、会被限流、输出还需要校验的外部系统。把这套工程治理做到位,AI 应用才算真正从 Demo 走向生产。
更多推荐

所有评论(0)