成本、延迟与容量
一次价格低廉的模型调用,可能属于一个成本高昂的系统。首个 Token 很快返回,任务仍可能迟迟无法完成,甚至最终失败。平均利用率很低的服务,也可能因长尾任务、突发流量、重试或受限依赖而崩溃。只优化一项供应商指标,很少等于优化了用户真正需要的结果。
智能体系统让这个问题更加突出,因为一个被系统接受的任务可能产生数量不定的模型调用、检索、工具操作、审批、重试、产物和后续检查。任务运行期间,工作结构本身还可能发生变化。成本和服务时间都是分布,而非常数。
应把成本、延迟与容量作为一个受约束的整体运营问题来管理。在明确的质量、可靠性、安全、隐私、公平性和服务要求下,优化已接受结果所需的成本与时间,而不是只优化请求或 Token。需要呈现完整的工作结构,在资源饱和之前控制需求,为重要工作保留容量,并以具有代表性的结果和尾部表现验证每项优化。
这不意味着每个团队在制作原型前都必须建立财务模型或排队仿真。它意味着:在规模或后果让误导性指标变得昂贵之前,必须明确衡量单位、系统边界和约束条件。
优化之前,先定义衡量单位
Section titled “优化之前,先定义衡量单位”先找到能够代表所交付价值的最小单位。例如:在没有错误外部操作的情况下解决一个支持工单;通过测试和审查后被接受的一次代码修改;或者一份所需引用均已核实的研究简报。本文把这种单位称为已接受结果(accepted outcome):满足任务所规定的完成、质量、策略与实际结果标准的结果。
随后衡量:
单位有效结果成本 = 该工作负载可归集的总成本 / 已接受结果数量
有效吞吐量 = 已接受结果数量 / 单位时间
结果接受率 = 已接受结果数量 / 已准入任务数量请求、调用或 Token 对诊断和成本归集仍然有用,但它们是资源单位,并不能证明已经产生价值。FinOps Foundation 同样区分了“每 Token 成本”之类的资源效率单位与“每个已解决工单的成本”之类的业务单位(FinOps Foundation,Unit Economics)。
使用分母前,必须定义什么叫“已接受”。如果系统默认把每个生成答案都算作成功,较便宜的模型可能只是生成了更多无法使用的结果,却显得更高效。如果结果需要人工修正,就应计入修正成本和最终验收,或者把原始尝试归类为未接受。不要把被放弃、重复、受阻或违反策略的工作藏起来。
在还无法归集结果的早期实验中,可以使用逐级完善的指标,而不是假装已经精确:
- 每次调用或每个 Token 的供应商费用;
- 每个已准入任务的技术总成本;
- 每个已完成任务的总成本;
- 单位有效结果成本;
- 成本相对于结果价值、风险降低程度或替代流程的比例。
记录当前决策依据的是哪一级指标,以及它遗漏了什么。
描绘完整的工作成本
Section titled “描绘完整的工作成本”为一个逻辑任务建立成本树。根据系统情况,它可能包括:
| 成本类别 | 示例 |
|---|---|
| 模型工作 | 未缓存与已缓存输入、缓存写入、输出生成、推理、向量嵌入、重排序、内容审核、评估器调用 |
| 外部操作 | 搜索、检索、浏览器、代码执行、付费 API、消息、事务、数据传输 |
| 应用基础设施 | 计算、加速器、数据库、队列、对象存储与向量存储、网络、密钥、编排 |
| 运营证据 | 日志、追踪记录、指标、保留与脱敏、采样、评估套件、负载测试 |
| 人工工作 | 审批、审查、修正、升级处理、支持、事件响应、合规与领域保证活动 |
| 浪费与恢复 | 失败尝试、重试、推测性分支、重复影响、放弃的工作、缓存未命中、重放与修复 |
| 共享与固定成本 | 工程、许可、用量承诺、预留容量、安全、治理、未使用的最低容量 |
无需等到所有共享成本都完美分摊后才行动。先呈现主要的可变成本驱动因素,以及可能推翻当前决策的成本。比较产品、供应商、自托管、人员配置或长期可行性时,再纳入完整成本。
供应商返回的用量字段只是成本树的输入,并不等于成本树本身。不同模型的分词方式和计量规则可能变化。例如,Anthropic 明确建议根据目标模型重新计算提示词 Token,而不是复用早期分词器的计数(Anthropic Token counting)。保留原始供应商用量、价格版本、币种、折扣和归集规则,才能重新计算历史成本。
沿工作结构归集成本
Section titled “沿工作结构归集成本”为每个任务及其子操作赋予稳定的关联标识。每条成本记录至少应归集到:
- 逻辑任务与具体尝试;
- 在允许记录的情况下,对应用户、租户、产品与工作负载等级;
- 模型、供应商、区域、服务等级、提示词版本和策略版本;
- 操作类型、缓存状态、工具或依赖;
- 已接受、已拒绝、已取消、已过期、重复或结果未知;
- 该工作是否位于最终关键路径上、是否形成了有用的路径外证据,或者最终被丢弃。
共享基础设施可以按占用时间、调用次数、字节数、预留容量或已接受结果等有明确记录的依据进行分摊。不存在普遍适用的唯一正确依据。直接成本应单独保留,以免成本分摊公式变化时改写运营事实。
衡量端到端延迟,而不是单个 API Span
Section titled “衡量端到端延迟,而不是单个 API Span”为每个工作负载等级定义开始与结束事件。交互式任务可以从服务接受用户请求开始,到界面显示出有用响应结束。后台任务则可能只有在产物提交、检查通过且请求者收到通知后才算结束。
把总耗时分解为:
端到端延迟 = 准入与排队等待 + 上下文和输入准备 + 模型处理与生成 + 串行控制决策 + 检索与工具执行 + 人工或外部等待 + 重试、恢复与持久化 + 最终验证与交付适用时,至少分别报告以下三种时间:
- 首个有用响应时间:使用者或下游系统第一次收到与任务相关且可用的信息的时间。
- 完成时间:达到所定义终止结果的时间。
- 实际处理时间与等待时间:总耗时究竟花在了哪里。
Anthropic 的延迟优化文档把首个 Token 返回时间(TTFT)作为有用的供应商与流式传输指标,但 Token 不一定有用(Anthropic,Reducing latency)。迅速输出一段开场白可以改善 TTFT,却可能让真正的答案更晚出现。流式传输改变了信息何时可见,本身并不减少总工作量。
衡量尾部表现,并说明超时如何处理
Section titled “衡量尾部表现,并说明超时如何处理”平均值会掩盖最影响用户体验、资源占用和重试压力的情况。对每个工作负载等级,记录 p50、p90、p95、p99 等分布,并同时说明:
- 测量窗口与统计对象;
- 是否包含排队时间;
- 超时、取消、拒绝或仍在运行的比例;
- 冷启动、缓存命中与未命中,以及依赖状态;
- 输入大小、输出大小、工具数量和模型配置;
- 同一批次任务的结果接受率。
不要把超时任务从延迟分布中移除,只报告成功请求。应同时报告成功条件下的延迟以及超时或未完成比例。一次发布如果只是更早终止困难任务,让成功调用显得更快,并不一定是改进。
优化关键路径
Section titled “优化关键路径”把工作画成依赖关系,而不是一张平铺的调用清单。关键路径是决定完成时间的最长依赖序列,应优先减少这条路径上的工作。
OpenAI 当前的延迟优化文档把实用方法归纳为:提高处理速度、减少输出 Token、减少输入 Token、减少请求、并行处理、减少用户等待,以及不做不必要的模型调用(OpenAI,Latency optimization)。其中可长期沿用的结论,是检查整个工作结构,而不是机械套用每种技巧。
删除不必要的串行决策
Section titled “删除不必要的串行决策”每个串行模型调用或依赖调用都会增加往返与排队时间。如果一个决策能够安全地产生结构化结果,就不要拆成多个步骤。对于不需要模型理解的精确查询、验证、格式化、算术或策略检查,使用确定性代码。也不要只为把每个小步骤路由到更便宜的模型而拆分工作;新增调用可能抵消节省的费用。
只并行执行相互独立的工作
Section titled “只并行执行相互独立的工作”当各分支互不依赖时,并行执行能够缩短关键路径。但它也会增加瞬时并发量、配额消耗、并行分支数量、取消复杂度,以及至少一个依赖变慢的概率。限制分支数量,取消已经失去价值的工作,并衡量每个已接受结果消耗的总工作量。
推测性执行是一项有意的交换:现在多消耗容量,换取可能缩短一条高概率路径。只有在发生概率、可节省延迟、取消行为和浪费预算共同证明其合理时才使用。推测性操作绝不能直接提交外部影响。
以证据为依据减少输入与输出
Section titled “以证据为依据减少输入与输出”上下文选择属于上下文工程,本章只衡量其成本和性能后果。删除重复或无关材料,把输出限制在使用者真正需要的范围内,避免生成没有任何组件会使用的冗长中间文本。每次缩减后都要重新验证质量。遗漏决定性证据的短上下文,可能因修正或损害而产生更高成本。
使用成本最低的合格配置,而不是单次调用最便宜的配置
Section titled “使用成本最低的合格配置,而不是单次调用最便宜的配置”《模型策略与路由》定义哪些配置适合某项任务。运行时路由可以根据当前质量、延迟、成本、可用性和容量信号在合格配置中选择,但不能只为达到费用目标而越出已经评估的范围。
OpenAI 的成本优化文档明确把较小模型、较少 Token 和较少请求与成本及延迟联系起来,同时把准确性作为约束(OpenAI,Cost optimization)。Anthropic 同样建议先建立质量基线,再进行延迟优化(Anthropic,Reducing latency)。本地真正需要比较的是单位有效结果的成本和延迟,其中包括重试与审查。
建立工作负载等级与预算
Section titled “建立工作负载等级与预算”对所有任务使用同一个超时、队列、优先级或模型预算,通常并不合理。应根据使用者需求与后果定义工作负载等级,例如:
| 工作负载等级 | 典型目标 | 资源紧张时的处理方式 |
|---|---|---|
| 交互式 | 尽快给出有用的首个响应,并在有限时间内完成 | 预留低延迟容量、限制并行分支、输出有用进展,在已经不可能达到期限前拒绝或延后 |
| 事务型 | 可预测地完成,并保证实际结果正确 | 保留验证和外部影响控制;短暂排队或明确失败,不通过静默降级牺牲正确性 |
| 长时间运行 | 在较宽期限内持久保存进展 | 设置检查点、公平调度、暂停或恢复,并执行单任务及累计预算 |
| 批处理或评估 | 在期限内完成一定工作量 | 使用异步容量、填补低峰时段,并允许重要程度更高的工作抢占或使其延后 |
| 紧急或控制面 | 保证遏制与恢复能力 | 隔离并预留容量,不允许普通租户流量将其挤占 |
对每个等级定义:
- 准入规则以及最长排队或延后时间;
- 适用时的首个有用响应时间与完成目标;
- 不能被降级的质量、可靠性、安全和隐私要求;
- 单任务模型、Token、工具、总耗时与费用预算;
- 并发、速率以及租户或用户累计限制;
- 重试、分支和升级处理预算;
- 优先级与公平性规则;
- 降级、取消、过期和通知方式;
- 容量负责人、预测周期与复查触发条件。
服务等级目标(SLO)是可衡量的目标,而不是愿望。应从使用者关心的服务表现出发,并说明适用对象和测量方法,这与 Google SRE 关于服务等级目标的章节一致(Google SRE,Service Level Objectives)。即使质量与策略要求需要不同的证据,也应与延迟和可用性目标并列考虑。
理解需求、时间与容量之间的关系
Section titled “理解需求、时间与容量之间的关系”分别跟踪四种速率:
- 提交需求量:客户端尝试提交的工作;
- 准入需求量:系统接受的工作;
- 完成吞吐量:达到终止状态的工作;
- 有效吞吐量:符合接受标准的已完成结果。
这些速率之间的差距能够揭示负载削减、过期、失败或质量损失。系统可能维持原始完成吞吐量,但有效吞吐量已经下降。
对于稳定的任务总体,Little 定律给出了有用的一阶关系:
系统内平均任务数 ≈ 到达率 × 系统内平均停留时间N ≈ λWJohn D. C. Little 在 1961 年证明了这一通用排队关系(Little,“A Proof for the Queuing Formula: L = λW”)。如果每秒到达 2 个任务,而每个已准入但尚未完成的任务平均停留 20 秒,那么系统内预计约有 40 个任务。如果到达率不变而服务时间翻倍,并发任务量及其占用资源通常也会翻倍。
这不是容量保证。它使用平均值,无法预测突发流量、高百分位表现、优先级、有限队列、相关性,也无法描述积压会无限增长的不稳定系统。这些问题需要用分布和负载测试处理。
找到真正的瓶颈和饱和拐点
Section titled “找到真正的瓶颈和饱和拐点”整个工作结构中最先受限的资源决定了系统容量。它可能是:
- 供应商请求数、输入 Token、输出 Token、并发任务数或费用;
- 应用工作进程、CPU、加速器、内存、连接、文件描述符或存储 I/O;
- 队列分区、检索服务、浏览器、沙盒、第三方 API 或身份服务;
- 人工审查、审批、支持或领域专业能力;
- 特定租户、区域、合同、安全或数据驻留限制。
在受控环境中逐步增加提交负载,并绘制有效吞吐量、延迟百分位、队列等待时长、错误、重试和资源使用情况。饱和拐点是指继续增加负载开始引起不成比例的延迟、失败或有效吞吐量下降的位置。正常运行目标应低于该点,并为突发流量、故障转移、维护、模型波动和预测误差留出容量余量。
供应商限制不等于承诺容量。Anthropic 记录了请求、输入 Token 与输出 Token 限制、短时间窗口的突发限制,以及用量突然增长时的加速限制(Anthropic Rate limits)。OpenAI 也提醒,失败后的重试仍会消耗每分钟容量(OpenAI Rate limits)。应在发布前测量实际依赖并协商或分散容量,而不是等到资源饱和时才处理。
在过载替你做决定之前控制需求
Section titled “在过载替你做决定之前控制需求”自动扩缩容很有用,但它无法瞬时完成,也无法创造受限的外部依赖容量。因此需要分层设置控制措施。
在准入时限制工作
Section titled “在准入时限制工作”在尽可能靠前且掌握足够信息的位置,决定接受、启动、排队、延后、降级还是拒绝任务。决策应考虑工作负载等级、期限、预计工作量、当前饱和程度、租户配额、依赖健康状态,以及系统能否在结果失去价值前完成工作。
准入代表系统承诺消耗容量,不只是向队列插入一条记录。尽早拒绝并给出明确的重试或延后约定,通常好过接受一个最终会在消耗资源后过期的任务。
让背压传递到上游
Section titled “让背压传递到上游”当下游容量受限时,应减少上游新工作的产生。降低轮询速度、暂停批处理生产者、减少新分支、返回重试建议,并限制客户端并发。如果背压只到达内部队列,而客户端仍继续提交,过载只是换了一个位置。
Google 的客户端限流经验说明了为什么在更靠近生产者的位置拒绝请求,可以避免后端先消耗资源再拒绝同一请求(Google SRE,Handling Overload)。具体实现可以不同,但信号传播方向必须明确。
保持队列有界,并考虑任务期限
Section titled “保持队列有界,并考虑任务期限”队列可以平滑短时突发并解耦异步工作,但也会消耗内存、隐藏需求并增加延迟。记录队列深度、最老任务的等待时间、距离期限的剩余时间、任务等级、租户和取消状态。同时限制任务数量和预计工作量,因为十个大型智能体任务可能比一千个小请求消耗更多资源。
Google SRE 指出,排队会增加延迟并可能掩盖饱和;队列大小应匹配测得的突发与服务行为,而不是设成一个让人安心的大数字(Addressing Cascading Failures)。对已经不可能达到目标的工作,应让其过期,并让调用者明确知道这一状态。
执行优先级和公平性规则
Section titled “执行优先级和公平性规则”优先级决定哪些工作先处理;公平性防止一个来源耗尽所有共享资源。可以根据工作负载需要,使用按租户配额、加权调度、并发分区、等待时间补偿或预留资源池。控制面与恢复任务应避免被普通流量挤占。
测试任务饥饿和优先级反转(priority inversion):低优先级工作可能占有高优先级工作需要的稀缺工作进程、锁、连接或人工审查资源。没有资源隔离,只有准入优先级并不能提供真正保证。
有计划地主动削减超出容量的负载
Section titled “有计划地主动削减超出容量的负载”主动削减超出容量的负载(load shedding),是指有意拒绝、延后或取消一部分超额工作,使系统仍能完成最有价值的已准入任务。应在服务耗尽用于拒绝请求的资源、让所有客户端超时或进入重试反馈循环前开始削减。
具体顺序取决于产品策略,一种可能的顺序是:
- 拒绝无效、重复、过期或未授权的工作;
- 停止推测性分支和可选分支;
- 暂停可以延后的批处理;
- 限制成本高昂的可选功能;
- 执行租户配额,并削减优先级较低的超额负载;
- 拒绝已经不可能按期完成的新工作;
- 保留恢复、通知和控制路径。
Amazon 与 Google 的生产经验都强调,过载可能降低有效吞吐量,并通过队列和重试自我放大;负载削减必须可观察且经过测试(Amazon Builders’ Library;Google SRE)。不要设计一条复杂的降级路径,却等到事件发生时才第一次运行它。
只在已批准范围内降级
Section titled “只在已批准范围内降级”平稳降级可以减少搜索范围、降低数据新鲜度、去除可选补充信息、缩短输出,或使用成本更低的模型。但它必须保留该工作负载等级所要求的安全、授权、正确性和披露要求,并在结果明显缩减时告知使用者。
有些工作负载必须延后或默认拒绝。使用未经评估的低成本模型、陈旧缓存、跳过审批或不完整的合规检查,并不会因为接口返回了 200 就成为平稳降级。
把缓存视为正确性与经济性决策
Section titled “把缓存视为正确性与经济性决策”缓存可以避免重复工作、减少延迟并提高有效容量,也可能返回陈旧或跨范围数据、掩盖来源、增加写入和存储成本,或者在供应商更改匹配规则时失效。
至少区分以下类型:
| 缓存类型 | 复用对象 | 主要正确性问题 |
|---|---|---|
| 供应商提示词缓存或前缀缓存 | 精确输入前缀对应的计算 | 是否理解该供应商和模型的匹配、有效期、隔离、价格与速率限制规则? |
| 应用精确缓存 | 相同键下先前计算的结果 | 键是否包含会改变有效性的所有输入、策略、模型、租户、授权和版本? |
| 语义缓存 | 根据语义相似度判断可以复用的结果 | 相似是否足以满足本任务,且范围、新鲜度、来源和不确定性是否得到控制? |
| 检索或工具缓存 | 外部数据或操作结果 | 权威的新鲜度规则是什么?操作是否具有用户特定行为或会产生变化的实际影响? |
为每种缓存定义:
- 键与匹配规则;
- 租户、主体、用途、区域和数据类别隔离;
- 来源及转换过程记录;
- 新鲜度、缓存失效与删除规则;
- 否定结果和错误的缓存方式;
- 写入、读取、存储、查询、未命中与陈旧结果的成本;
- 绕过、发布、回滚与可观测性;
- 缓存命中的正确性评估,而不只是命中率。
供应商提示词缓存说明了为什么实现细节必须带有日期。OpenAI 当前会缓存符合条件的精确前缀,公开缓存写入与读取用量,并记录组织隔离以及不同模型系列的有效期和计费方式(OpenAI Prompt caching)。Anthropic 公开缓存创建与读取 Token、可配置有效期、失效规则、隔离方式和缓存对速率限制的影响(Anthropic Prompt caching)。两者都是当前重要的产品文档参考,但都不定义应用缓存的正确性,而且其行为都可能变化。
只有满足以下关系时,缓存才具有经济价值:
有效命中所避免工作的期望价值 > 写入 + 存储 + 查询 + 失效处理 + 未命中 + 陈旧结果成本应按可复用前缀或键、模型、租户、工作负载与时间间隔拆分命中率。很高的总体命中率,可能掩盖某个关键工作负载毫无收益或复用了错误结果。
分离交互式、异步与批处理容量
Section titled “分离交互式、异步与批处理容量”并非每个任务都需要立即执行。异步处理可以用更长完成时间换取更低价格、更平滑的利用率和独立容量。OpenAI 与 Anthropic 当前都为可以接受较宽完成窗口的工作提供折价批处理(OpenAI Batch API;Anthropic Batch processing)。折扣和时间窗口属于带日期的产品行为,应保留其背后的通用设计问题。
批处理或延后任务仍然需要:
- 截止期限和最长排队时间;
- 输入、策略、模型与价格版本记录;
- 单项标识、幂等性、取消方式和结果状态;
- 部分失败与重放策略;
- 预留容量或抢占规则;
- 通知与结果保留;
- 对延后数据是否仍然有效的评估。
批处理可以通过分摊固定开销或使用较便宜容量提高吞吐量,但也会增加等待、扩大单次失败范围并延迟反馈。不要只因为一次供应商调用更便宜,就把交互式工作改成批处理。
使用真实工作负载预测并测试容量
Section titled “使用真实工作负载预测并测试容量”容量计划应说明:
预测周期与置信范围工作负载等级与到达分布任务大小与服务时间分布结果接受率与放弃率假设峰值、突发、事件、增长和区域规律缓存命中/未命中以及冷/热状态假设模型、供应商、工具、人工与基础设施限制故障、维护、故障转移与恢复预留量计划容量余量,以及增加或转移容量的触发条件不要只根据月度 Token 总量预测。Token 总量相同的两个工作负载,可能具有不同的请求速率、输出量、工具等待、并行程度和并发量。应按工作负载形态预测,并把得到的资源需求与供应商限制、基础设施、人员和费用相核对。
对完整工作结构进行负载测试
Section titled “对完整工作结构进行负载测试”使用符合生产分布且经过隐私处理的任务,以及受控的合成用例。测试应包括:
- 常规任务组合,以及大输入、长输出和大量工具步骤;
- 冷启动、缓存未命中、缓存频繁变化与热点键集中;
- 突发、逐步升高的流量、租户集中和不同优先级组合;
- 变慢、失败、受速率限制或不可用的依赖;
- 重试、取消、超时与结果未知路径;
- 跨越部署或工作进程丢失的长时间运行任务;
- 超过饱和拐点的负载,用于验证负载削减与恢复;
- 恢复正常负载,用于发现卡住的队列或未释放的并发资源。
衡量提交、准入、完成和有效吞吐量,以及尾部延迟、队列等待时长、饱和度、拒绝原因、成本、浪费、质量和外部影响正确性。如果测试在第一个延迟目标不达标时就停止,就无法证明过载行为是安全的。
供应商托管模型还会带来共享服务波动。记录观察时间、服务等级、区域、模型快照、限制以及可用的响应头。重复测试,不要把一次短暂测量发布成永久模型排名。
通过受控变更进行优化
Section titled “通过受控变更进行优化”把优化视为对已评估系统的一次变更。发布前记录:
工作负载与已接受结果定义:基线配置与观察窗口:假设以及变更的机制:质量、可靠性、安全、隐私与公平性要求:成本边界与归集方法:延迟开始/结束事件与要求的百分位:容量与过载假设:预期影响与不确定性:评估、负载测试与发布计划:回滚与失效触发条件:负责人和复查日期:比较相同的工作负载分布;如果重新赋予了权重,就明确说明。在模型行为对结果影响较大时,报告置信区间或重复运行的波动。分阶段发布,并观察已接受结果,而不只是供应商费用。
出现以下情况时,应质疑这项优化:
- 降低了单次调用成本,却增加了每个已接受结果的尝试次数;
- 改善了 p50,却恶化了 p99、超时或放弃率;
- 提高了原始吞吐量,却降低了结果接受率;
- 提高了缓存命中率,却返回陈旧或跨范围结果;
- 把工作从已测量的关键路径移到未被记录的人工修正;
- 通过让某个租户或重要任务等级长期得不到资源来满足平均预算;
- 把明确拒绝变成漫长排队;
- 使用未经评估的模型,或移除必要控制。
常见失效模式
Section titled “常见失效模式”只盯着 Token
Section titled “只盯着 Token”团队优化 Token 价格,但总成本主要来自工具调用、重试、审查或失败。应对方式:在 Token 指标旁同时发布成本树和单位有效结果成本。
首个 Token 很快,有用结果很慢
Section titled “首个 Token 很快,有用结果很慢”流式输出立即开始,但答案、产物或已提交的实际结果迟迟未到。应对方式:从使用者边界衡量首个有用响应与完成时间。
并行分支失控
Section titled “并行分支失控”每个任务都大量分支,有些运行变快了,却耗尽供应商配额并制造大量废弃工作。应对方式:限制分支与全局并发,取消过时工作,并衡量每个结果所需的有效工作量。
原始尝试仍在占用容量时,超时又触发重试。应对方式:使用可靠性章节中的有界重试与幂等规则,施加背压,并把所有尝试计入需求。
用队列隐藏问题
Section titled “用队列隐藏问题”接口接受所有任务并宣称可用,但队列等待时长已经超过任务价值。应对方式:限制队列,显示等待时长与期限,并如实拒绝或延后。
按平均值规划容量
Section titled “按平均值规划容量”月度平均值看似安全,但突发流量、长任务或输出 Token 限制使服务饱和。应对方式:对分布和每个受限维度建模,并测试峰值与尾部情况。
缓存没有有效性规则
Section titled “缓存没有有效性规则”团队只追求命中率,却没有把租户、授权、策略、新鲜度或版本编码到规则中。应对方式:把有效性纳入缓存键,并测试错误命中率。
只依靠自动扩缩容
Section titled “只依靠自动扩缩容”队列形成后工作进程开始扩容,但供应商、数据库或人工审查容量仍然固定。应对方式:在扩缩容之外,同时使用容量余量、准入、背压、配额和负载削减。
低成本降级违反原有约定
Section titled “低成本降级违反原有约定”资源紧张时,系统切换到尚未满足该任务接受标准的模型或数据路径。应对方式:预先定义并评估允许的降级范围;否则就延后或默认拒绝。
为节省存储而失去可观测性
Section titled “为节省存储而失去可观测性”团队删除遥测数据以节省存储,导致浪费、尾部行为和事件都无法看见。应对方式:根据决策价值、采样、脱敏与保留期限优化采集,而不是删除必要证据。
实用检查清单
Section titled “实用检查清单”衡量单位与边界
Section titled “衡量单位与边界”- 是否以完成、质量、策略和实际结果标准定义了已接受结果?
- 是否明确区分请求、Token、已完成任务和已接受结果指标?
- 成本边界是否包括重要的工具、基础设施、重试、浪费、评估与人工工作?
- 是否能够根据用量与价格版本重新计算历史成本?
延迟与工作结构
Section titled “延迟与工作结构”- 是否为每个工作负载等级定义了开始与结束事件?
- 是否分别衡量首个有用响应、完成、排队等待与实际处理时间?
- 报告尾部百分位时,是否同时报告超时、取消与结果接受率?
- 是否已经识别关键路径,并说明每个串行调用的必要性?
- 并行与推测性工作是否有界且可以取消?
- 是否能够看到提交、准入、完成与有效吞吐量?
- 是否衡量服务时间和任务大小分布,而不是假设它们恒定?
- 是否记录了每个供应商、基础设施、工具、人工、租户与区域瓶颈?
- 是否使用真实负载测出了饱和拐点?
- 容量余量是否对应突发、故障转移、维护、增长与预测误差?
- 准入、背压、队列、公平性与负载削减规则是否明确且经过测试?
- 控制面和恢复容量是否得到保护?
缓存与延后任务
Section titled “缓存与延后任务”- 每种缓存是否都有匹配、隔离、新鲜度、失效、删除和来源规则?
- 是否衡量缓存写入、读取、未命中、存储、陈旧结果和错误命中?
- 供应商缓存假设是否绑定到带日期的模型和文档版本?
- 异步和批处理任务是否具有期限、单项标识、取消、部分失败处理与通知?
- 每个更便宜或更快的配置是否仍在经过评估的合格范围内?
- 比较是否使用具有代表性的工作负载组合和重复试验?
- 质量、可靠性、安全、隐私与公平性要求是否保持不变,或已经重新批准?
- 是否记录发布、回滚、负责人、预算与复查触发条件?
- OpenAI,“Latency optimization” — OpenAI 维护的 API 文档,面向 OpenAI 工作负载;本章用它检查 Token、请求、并行处理、用户等待和不必要的模型调用。它并不定义应用的端到端 SLO。
- OpenAI,“Cost optimization” — OpenAI 维护的 API 文档,用于说明 OpenAI 请求、Token、模型选择、批处理和弹性处理与成本及延迟的关系。它未计入完整任务或人工成本。
- OpenAI,“Prompt caching” — OpenAI 维护的 API 文档,用于说明精确前缀缓存、缓存计量、隔离、有效期和不同模型系列经济性。所有数值行为都应视为带日期的信息。
- OpenAI,“Batch API” — OpenAI 维护的 API 文档,用于说明 OpenAI 平台中以交互性换取折价异步处理与独立容量的机制。本文不把价格和限制推广为通用规则。
- OpenAI,“Rate limits” — OpenAI 维护的 API 文档,用于说明 OpenAI 平台上的多维配额管理与有界退避;供应商等级与执行方式可能变化。
- Anthropic,“Reducing latency” — Anthropic 维护的产品文档,面向 Claude 调用;本章用它说明 TTFT、模型选择、Token 长度、流式输出与先建立质量基线。它不覆盖完整智能体运行。
- Anthropic,“Prompt caching” — Anthropic 维护的产品文档,面向 Claude 提示词缓存;本章用它说明缓存计量、有效期、失效、隔离与有效吞吐量。细节因模型和平台而异。
- Anthropic,“Batch processing” — Anthropic 维护的产品文档,用于说明 Claude 折价异步工作;当前价格和支持模型可能变化。
- Anthropic,“Rate limits” — Anthropic 维护的产品文档,用于说明 Anthropic 平台上的请求和 Token 维度、短时突发、用量加速、费用限制以及缓存相关容量。
- Anthropic,“Token counting” — Anthropic 维护的产品文档,用于说明 Token 数取决于目标 Claude 模型与分词器。
- FinOps Foundation,“Unit Economics” — Linux Foundation 项目资料,用于把技术资源单位与结果及业务单位联系起来,并记录定义与维护成本归集证据。
- John D. C. Little,“A Proof for the Queuing Formula: L = λW” — 排队平均关系的原始同行评审证明,可用于并发量的一阶推理;它不能预测尾部或不稳定的过载。
- Google SRE,“Service Level Objectives” — Google SRE 章节,说明如何从使用者关心的表现出发、明确测量服务目标。
- Google SRE,“Handling Overload” — Google SRE 章节,说明客户端限流、配额以及如何减少后端拒绝开销。
- Google SRE,“Addressing Cascading Failures” — Google SRE 章节,说明队列管理、过载反馈、主动削减负载、平稳降级与演练低频路径。
- Amazon Builders’ Library,“Using load shedding to avoid overload” — Amazon 工程文章,涵盖饱和、重试放大、有界工作、优先级、可见性和过载测试;其中的实现选择不是通用默认值。