成本、延迟优化与生产监控
前面的课程解决了“怎么让 AI 做对事”:prompt、context、RAG、tool、agent、eval、多智能体。这一讲解决“怎么让它在生产里稳定、可控、付得起、等得起”。
AI 系统上线后,质量只是第一道门槛。真正长期运行时,你还要关心:
- 每次请求花多少钱。
- 用户要等多久。
- 高峰期会不会被限流。
- RAG 和工具调用是否拖慢整体响应。
- Agent 是否循环调用工具。
- 缓存是否命中。
- 失败率、重试率、超时率是否异常。
- 线上行为是否和 eval 结果一致。
成本和延迟不是“最后再优化”的小事。它们会反过来决定你能不能使用长上下文、RAG、多 agent、复杂工具链和高质量模型。
本讲常见术语先按下面理解,详细定义和更多例子见 00.5-术语词典与最小用例。
| 术语 | 直觉解释 | 最小例子 |
|---|---|---|
| Token | 模型计费和处理文本的基本单位 | 输入越长,token 越多,成本越高 |
| Latency | 用户等待响应的时间 | 从发出请求到收到最终答案用了 4 秒 |
| P50 / P95 / P99 | 延迟分位数 | P95=8 秒表示 95% 请求不超过 8 秒 |
| TTFT | Time to first token,首 token 时间 | 流式回答 0.8 秒后出现第一段文字 |
| Prompt caching | 复用稳定输入前缀降低成本或延迟 | 系统规则固定,重复请求命中缓存 |
| Batch / Flex / Priority | 不同服务形态的成本和速度取舍 | 离线任务用 batch,交互任务用 priority |
| Rate limit | 单位时间内调用量限制 | 每分钟最多 500 次请求或一定 token 数 |
| Streaming | 边生成边返回内容 | 用户先看到开头,但完整答案时间未必缩短 |
一、直觉
一次 AI 请求的成本和延迟大致来自:
输入 token
-> 模型处理
-> 内部 reasoning / planning
-> 输出 token
-> 工具调用
-> RAG 检索
-> 网络往返
-> 重试
-> 日志和监控
优化不是只盯着模型价格,而是看整条链路。
一个常见误区是:觉得“换便宜模型”就是成本优化。实际上,便宜模型如果导致更多重试、更多人工复核、更长 prompt、更复杂工具补救,整体成本可能更高。
二、成本公式
生产系统里至少要估算下面几项:
单次成本 =
输入 token 成本
+ 输出 token 成本
+ reasoning token 成本
+ 工具调用成本
+ 检索 / 向量库成本
+ 批处理或缓存折扣影响
+ 重试成本
+ 人工复核成本
更实用的指标:
每成功任务成本 =
总成本 / 成功完成的任务数
不要只看单次 API 调用成本。Agent 可能一个用户请求调用 6 次模型、3 次工具、2 次检索;RAG 可能检索很便宜但生成上下文很长;多智能体可能并行很快但总 token 翻倍。
三、延迟公式
一次请求的用户感知延迟通常是:
端到端延迟 =
排队时间
+ 网络时间
+ 检索时间
+ 工具调用时间
+ 模型首 token 时间
+ 模型生成时间
+ 后处理时间
+ 重试时间
要分别看:
- P50:普通用户体验。
- P95:大多数用户最差体验。
- P99:极端慢请求。
- time to first token:用户多久看到第一个输出。
- time to final answer:完整答案多久完成。
流式输出可以改善“等待感”,但不能真正减少总计算量。它适合用户面对的长回答,不适合程序必须等完整 JSON 才能继续的任务。
四、优化优先级
一个稳定的优化顺序:
- 先用 eval 保证质量基线。
- 记录真实 token、延迟、工具调用和失败率。
- 找出最大成本项和最大延迟项。
- 优先减少无用输入和无用输出。
- 再考虑缓存、批处理、模型分层和并行。
- 最后做架构级优化。
不要在没有指标的情况下优化。没有 trace 和日志,你只能猜。
五、减少输入 token
输入 token 成本常常被低估,尤其是 RAG、长文档和 Agent 场景。
常用方法:
- 删除重复指令。
- 把稳定规则放在可复用的系统层或 Skill 中,而不是每次粘贴长说明。
- RAG 只放最相关片段,不把整篇文档塞进去。
- 使用 metadata 过滤减少检索噪声。
- 对长历史做摘要或 compaction。
- 把动态内容放后面,把稳定内容放前面,利于 prompt caching。
- 对工具结果做结构化精简,不返回整段日志和 HTML。
- 对多轮对话只保留当前任务真正需要的历史。
一个判断:
如果某段上下文不影响这次输出,它就是成本和干扰。
六、减少输出 token
输出 token 同时影响成本和延迟,因为生成 token 通常是用户等待时间的重要来源。
方法:
- 明确输出结构。
- 要求短答案优先,再给详细依据。
- 分离“给人看的摘要”和“给程序用的 JSON”。
- 不要求模型输出完整推理过程。
- 使用枚举、表格、JSON 等紧凑格式。
- 对 Agent 中间状态只记录 trace,不让模型每步都长篇解释。
- 给最大长度和停止条件。
不推荐简单写“越短越好”。更好的写法:
先给 3 句话结论;只有用户要求时再展开细节。
七、Prompt caching
Prompt caching 的核心思想是:如果很多请求都有相同前缀,系统可以复用已处理的前缀,减少成本和延迟。
以 OpenAI API 为例,prompt caching 通常在 prompt 达到 1024 tokens 或更长时自动生效;不同模型和平台可能有不同门槛、折扣和统计字段。学习时记住原则:稳定前缀越长、复用越多,缓存越有价值;短 prompt 不要为了缓存强行加废话。
适合缓存的内容:
- 稳定系统规则。
- 长工具说明。
- 固定 few-shot 示例。
- 固定政策、产品手册、参考资料。
- 多轮对话中前面稳定的历史。
- Agent 的固定工作流说明。
不适合放在缓存前缀里的内容:
- 用户本次问题。
- 实时检索结果。
- 本次工具返回。
- 用户私有动态状态。
- 时间敏感信息。
推荐顺序:
稳定系统规则
-> 稳定工具定义
-> 稳定示例
-> 稳定背景资料
-> 动态用户输入
-> 动态检索结果
-> 动态工具结果
这样更容易命中缓存。反过来,如果你把时间戳、用户 ID、随机请求 ID 放在最前面,就会破坏重复前缀。
Prompt caching 不是“为了缓存而把 prompt 写长”。它优化的是本来就需要重复传的大块稳定上下文。
八、缓存命中率怎么监控
缓存优化必须看指标:
- cached input tokens。
- cache hit rate。
- cache miss 原因。
- 稳定前缀长度。
- 缓存命中后的 P50/P95 延迟。
- 缓存命中后的输入 token 成本。
如果缓存命中率低,优先检查:
- 稳定内容是否放在请求前面。
- 动态内容是否混进了前缀。
- 工具定义顺序是否每次变化。
- few-shot 示例是否每次随机排序。
- RAG 片段是否放在稳定内容前。
- 请求是否太短,不符合缓存收益场景。
九、模型分层
不要让所有任务都用同一个最强模型。
可以按任务分层:
| 任务 | 模型策略 |
|---|---|
| 分类、路由、简单抽取 | 小模型或低成本模型 |
| 高风险总结、复杂推理 | 强模型 |
| 工具参数生成 | 选择工具能力稳定的模型 |
| 批量离线处理 | 低成本模型 + Batch / Flex |
| 最终高风险审查 | 强模型 + 人工复核 |
关键是用 eval 确认每层模型是否达标。
模型分层常见模式:
小模型路由
-> 命中简单任务:小模型直接处理
-> 命中复杂任务:强模型处理
-> 命中高风险任务:强模型 + 审查
十、批处理、Flex 和 Priority
不同任务对时间要求不同。
| 方式 | 适合场景 |
|---|---|
| 同步请求 | 用户正在等待 |
| 流式输出 | 用户需要尽快看到进展 |
| Batch | 离线任务、批量评估、数据清洗 |
| Flex | 低优先级、可接受变慢或偶发资源不可用的任务 |
| Priority | 高价值、用户面对、低延迟要求强且流量相对稳定的任务 |
不要用同步高优先级通道跑离线评估,也不要用慢速低成本通道承接关键实时对话。Priority 不适合离线数据处理、评估或高度不稳定的突发流量;Flex 更适合非生产、低优先级、异步或可重试任务。
十一、并行和合并
并行能降低端到端延迟,但会提高总成本和复杂度。
适合并行:
- 多来源检索。
- 多方案调研。
- 多 agent 独立评审。
- 工具之间没有依赖。
不适合并行:
- 后一步依赖前一步结果。
- 多个操作会写同一资源。
- 任务本身很短。
- 限流已经紧张。
并行优化要看:
端到端延迟是否下降
总 token 是否明显上升
工具调用是否可控
失败重试是否变多
十二、工具调用预算
Agent 的成本和延迟经常失控在工具调用上。
应该设置:
- 最大工具调用次数。
- 最大检索轮数。
- 最大子 agent 数量。
- 最大重试次数。
- 最大总 token。
- 最大运行时间。
- 高风险工具确认。
- 无新增信息时停止。
工具调用不是越多越严谨。没有停止条件的 Agent 会不断搜索、验证、再搜索,最后成本和延迟失控。
十三、生产监控
上线后至少记录:
请求层
- 请求量。
- 成功率。
- 错误率。
- 超时率。
- 重试率。
- P50/P95/P99 延迟。
- time to first token。
- time to final answer。
Token 与成本
- input tokens。
- output tokens。
- reasoning tokens。
- cached tokens。
- 每请求成本。
- 每成功任务成本。
- 每用户、每项目、每功能成本。
RAG
- 检索耗时。
- 检索片段数量。
- top-k 命中。
- 引用准确率抽样。
- 无答案率。
- 资料过期命中率。
Agent / Tool
- 工具调用次数。
- 工具失败率。
- 工具超时率。
- 高风险确认次数。
- Agent 循环或超预算次数。
- handoff 次数。
- trace 失败原因。
质量与安全
- 用户差评率。
- 人工复核失败率。
- 严重幻觉数。
- 提示注入命中数。
- 拒答率。
- 升级人工处理率。
十四、告警
建议设置告警:
- 单日成本超过预算。
- 某功能成本突然上涨。
- P95 延迟超过阈值。
- 错误率或超时率上升。
- 缓存命中率下降。
- RAG 无答案率异常。
- 工具失败率异常。
- Agent 平均工具调用次数上涨。
- 严重安全失败出现。
- 评估集回归失败。
告警要能定位到:
- 哪个模型。
- 哪个 prompt 版本。
- 哪个 RAG 索引版本。
- 哪个工具或 MCP server。
- 哪类用户请求。
- 哪次发布之后开始异常。
十五、常见优化误区
误区 1:先换最便宜模型
不一定。先找最大成本项,再用 eval 验证小模型是否达标。
误区 2:长上下文越多越安全
不对。长上下文会增加成本、延迟和干扰。RAG 应该给最相关证据,不是塞满。
误区 3:流式输出等于低延迟
不准确。流式输出改善首 token 体验,但完整答案时间可能没变。
误区 4:缓存命中自然会发生
不一定。请求结构不稳定、动态内容放前面、工具顺序变化都会破坏缓存。
误区 5:上线后只看错误日志
不够。AI 系统还要看质量、成本、延迟、token、缓存、RAG、工具和用户反馈。
十六、理解检查
请你试着回答:
- 为什么“每成功任务成本”比“单次 API 调用成本”更有意义?
- Prompt caching 为什么要求稳定内容尽量放在前面?
- 流式输出改善的是哪种延迟感受?它不能解决什么问题?
- Agent 为什么要设置最大工具调用次数和停止条件?
- 一个 RAG 系统上线后至少应该监控哪些指标?
十七、下一步
提示词工程主线已经覆盖 prompt、context、skills、RAG、tools、agent、eval、多智能体和生产优化。下一步可以做两件事:
- 阅读
../案例/综合实战/知识库问答Agent实战.md,把这些内容串成一个完整项目。 - 完成
../练习/中的 5 个练习,建立 prompt、schema、RAG、工具调用和 Eval 的最小闭环。