系统篇

25|生产运行:Trace、成本、队列、灰度与回滚

系统篇约 6.1 千字1 组分步图解
本章目录

本章预备知识

把运行分成可观察的跨度,才能找出慢在排队、模型、工具还是返工。成本要按成功完成任务计算,并与质量和尾延迟一起看。

本章各题列出所需基础。可先完成相应基础课,也可通过自检确认掌握程度。

进入深读前的小检查:读一份Trace时先重建依赖关系,独立并行跨度不直接求和;为失败任务照样计入实际消耗。

术语带虚线时可点击速查。公式中的字母先看定义;不要用猜缩写替代推导。

本章不把“加日志、做监控”当作答案。我们要能从一条慢任务的轨迹中分离等待、模型、工具、恢复和验证,并解释系统在哪个环节接近容量边界。所有数字都是教学假设,不是厂商报价或生产实测。

沿着对象与状态理解本章

性能图先用实际起止时间画,而不是将所有工具耗时直接相加。下图中缩短非关键路径的A不会缩短总时间;同样,降低单次Token价也未必降低成功任务成本。

下方图解的固定输入在“输入与适用条件”中声明。它用于解释本章机制,不与本章其他独立例子的数值暗中接续。

动态图解 · F38

Trace要告诉你因果,不只是时间戳

为何优化一个最显眼的步骤,整体却没变快?

执行轨迹像工程里的时间账,但更重要的是依赖关系。串行阶段会相加,并行阶段往往取关键路径;只有知道下一步在等谁,才能知道哪里值得优化。还要把排队、推理、工具、验证和重试分开,不能全算成模型慢。

Trace一条任务中各步骤及关联关系的记录。
墙钟时间从任务开始到结束真正经过多久。
关键路径决定完成时间的依赖链。
吞吐单位时间完成多少任务。

输入与适用条件:固定教学秒数,无真实产品耗时数据。第4帧只改变工具A时长,其他条件保持不变。

1 / 5 · 先看一条完整任务

第1步,共5步

窄屏可左右滑动图形,或点击“放大图形”。文字解释紧随图后。

Trace要告诉你因果,不只是时间戳:先看一条完整任务排队2s模型调用13s并行工具A3s并行工具B8s模型调用22s核验1s016秒

构造的任务从0到16秒:排队2秒、第一次模型3秒、并行工具A3秒/B8秒、第二次模型2秒、核验1秒。

基准墙钟16秒;工具工作量11秒

默认静止。用“下一步”看完解释再继续;播放到最后一步自动停止。键盘聚焦播放器后,可用左右键逐步查看、空格播放/暂停。图中颜色辅助区分,含义同时用文字注明。

为什么需要

把优化投入到确实支配成本或完成时间的环节。

怎样实现

按依赖关系画时间线,再用同负载实测对照。

可能的代价与误解

只看平均值会隐藏长尾;把并行跨度相加会错误夸大总耗时。

如何判断是否做对

按时间戳与依赖重算16秒,检查是否把等待和重试遗漏。

Q097|一个Agent任务应该怎样记录Trace,才能定位“慢、贵、错”?

核心回答

把一次用户任务作为逻辑根,把检索、模型调用、工具执行、压缩和验证作为子操作;记录因果关系、输入版本、输出状态和资源消耗。Trace回答“这次发生了什么”,指标回答“总体怎样”,日志和证据对象回答“具体细节是什么”。三者不能互相替代。[SRE][OTEL]

一条轨迹里的对象与关联键

设任务t7经过检索r2、模型请求m3、工具调用c19、恢复rec1。m3产出c19,但c19可能由另一个工作进程执行。关联应依赖稳定ID,而不是“看时间差不多”猜它们是一组。

任务 t7
  检索 r2:索引 rev42,命中 doc8@v3
  模型 m3:上下文 manifest17,生成 tool-call c19
  执行 c19:资源 fileA@r42 → 结果 unknown
  核验 rec1:读取 fileA@r43,确认副作用已发生
  模型 m4:看到核验结果,不重复修改
  验证 v9:在工作区 r43 上运行测试

每次模型调用至少区分请求模型、返回模型标识、输入量、可观测的缓存量、输出量、响应状态和耗时。推理用量是否单列、如何计费取决于接口,不应自行由最终文本长度猜测。每次工具调用记录参数摘要或受控引用、权限结果、执行状态与外部操作ID。完整敏感参数不应默认进入公共日志。

若两个工具并行,各自耗时8秒和10秒,不能把18秒直接算成这段用户等待;关键路径可能约10秒加调度成本。若跨度间存在队列等待,却只给执行函数打点,监控会显示“工具很快”而用户仍等很久。应分别记录入队、开始、完成。

运行示例 · Q097

Trace里三个span加起来10秒,任务为什么只用了7秒

输入与条件。检索span A=[0,3]秒、B=[0,5]秒,整合C=[5,7]秒,父任务=[0,7]秒。

步骤与对象内部动作中间结果 / 新状态
1求span时长和3+5+210秒,表示各操作累计时长。
2求任务墙钟7−07秒。
3关键路径B后接C5+2=7,A不是当前关键路径。
4优化A把3秒压到1秒若B仍5秒,总任务仍7秒。
5优化B把5秒压到2秒此时等待A3秒,任务变5秒,不是4秒。

把过程连起来。优化应看关键路径和依赖,不是优先压缩所有span里最容易变短的一个。

边界与反例。忽略资源竞争的确定性时间线;异步Trace的父子关系还需与实际等待依赖区分。

依据与适用范围:[DERIVE]。示例输入和场景由本书明确设定。

追问:不存完整Prompt,还能调试上下文遗漏吗?

可以存上下文清单:片段ID、来源版本、角色、加载原因、Token估计、裁剪状态和最终排序。它不能重建全部文本,但可发现“本该加载的文件没有进入请求”。需要内容重放时,再使用有权限、有限保留的证据存储。清单与正文分离是诊断能力和隐私的折中。

追问:为什么不要把用户ID、完整Prompt放进指标标签?

这些值数量极大,会产生高基数时间序列,增加存储和查询成本;还可能泄露信息。指标适合有限集合,如工具类别、结果类型、版本组。单个任务的高基数字段放到受控Trace或日志中,用指标异常跳转查看。

追问:Trace里的“成功”应该由谁决定?

模型API成功只说明调用完成;工具成功只说明工具返回成功;任务成功应由验收结果决定。根跨度最好同时保存终止原因和业务验收结果。否则“生成了一段答案”会掩盖零测试、部分完成或外部写入失败。

Q098|为什么“每Token便宜”不等于“完成工作便宜”?成本应怎样算?

核心回答

成本单位应是满足质量要求的一次任务,而不是一次模型请求。总成本包含成功和失败尝试、检索、工具、验证、人工返工以及运行资源;缓存、模型路由和并行只有在质量与总成本一起比较时才有意义。[LATENCY][PCACHE][EVALS]

从单请求账单走到任务成本

设第i次调用的未缓存输入、缓存输入、输出分别为uᵢ,cᵢ,oᵢ,单价为pᵤ,p꜀,pₒ,则模型成本是各调用的pᵤuᵢ+p꜀cᵢ+pₒoᵢ之和。若产品另收缓存写入、工具或其他费用,需要按其口径加项,不能把未知费用默认为零。

两个教学方案:A每次尝试成本1单位,成功率0.8;B每次成本0.6,成功率0.4。假设失败后独立同分布重试、没有重试上限、成功质量相同,成功前期望尝试次数为1/p,所以成本分别1.25与1.5。B单次便宜,成功一次反而更贵。现实中独立假设常不成立:同样缺证据的重复运行可能持续失败,所以不能盲目用此公式预测生产账单。

实践应在同一任务集比较:总花费、成功数、失败类型、总延迟分位数、人工介入量。还要分层看简单与复杂任务;总体均值可能掩盖便宜模型在某类高风险任务上的明显退化。

运行示例 · Q098

一个方案少花Token,却增加两次工具往返

输入与条件。方案A:模型输入费用4单位、输出2、工具等待1秒一次;方案B:输入2、输出2,但多两次各1秒的串行工具读取。

步骤与对象内部动作中间结果 / 新状态
1费用比较仅模型部分A6,B4B模型费用低2。
2延迟比较B多2秒串行等待若模型本来只省0.2秒,总延迟仍增加1.8秒。
3质量比较B是否因分段读取漏了跨文件关系不能只看费用。
4缓存比较A稳定前缀可能可复用实际计费与逻辑输入量分开记录。
5决策按场景延迟约束和成功率选方案不是任何“少Token”修改都值得上线。

把过程连起来。上下文、工具调用、缓存与返工共同决定成本,优化指标必须对应用户目标。

边界与反例。单位和等待时间均是教学假设,不是实时价格;没有给成功率时不能声称哪一方案总体最优。

依据与适用范围:[DERIVE]。示例输入和场景由本书明确设定。

追问:缓存命中率越高越好吗?

不一定。不断携带大量无关历史可能提高缓存命中,但增加逻辑上下文、解码注意力读量或信息干扰。缓存命中是中间指标,最终仍看质量、账单和耗时。删除无用前缀也可能牺牲一次命中却降低后续长期成本。

追问:什么时候选更强模型反而更省?

当更强模型显著减少错误工具调用、无效搜索、返工或人工审查时。需要在控制任务和工具条件的对照试验中确认。不能只根据模型名称或单个精彩案例断定;也不应让简单确定性任务默认使用最大推理预算。

追问:预算耗尽时应该丢掉验证步骤吗?

通常先缩小承诺或停止新增修改,而不是把未验证结果包装为完成。可预留验证与收尾预算;若已不足,输出已完成、未验证、风险与恢复位置。一个“看起来完成”的未核验结果,可能把成本转嫁给后续维护者。

Q099|并发越大吞吐越高吗?怎样从排队理解Agent延迟?

核心回答

并发只在资源尚有余量时帮助提高利用率;超过模型、工具、数据库或配额的容量,新增任务主要进入队列。稳定系统中Little定律L=λW连接平均在途任务数、平均到达率和平均停留时间,但它不是无条件的容量规划保证。[SRE][SLO]

从请求进入到离开

任务到达后先入队,等待可用执行槽;取得槽位后仍可能等待模型配额或外部工具。若一个任务持有昂贵工作进程却长期等远程网络,会降低资源利用率。可将可恢复任务状态与短时执行资源解耦,但这会引入持久化和调度复杂度,不能为了架构漂亮而一开始全拆开。

教学例:平均每秒进入2个任务,平均停留30秒,在稳定观测范围内平均在途约60个。若只准备20个同步工作槽,系统能否稳定取决于每个任务实际占用槽位的时间,不能只用最终回答延迟推算。若每个槽完整占用30秒,理论服务率上限约20/30,低于到达率2,积压就会持续增长。

尾延迟来自长任务、服务时间方差、队头阻塞、重试风暴和资源争用。对交互式短任务和批量长任务采用不同队列或配额,可减少相互干扰;但优先级不能无限饿死低优先级任务。应有最大等待、取消传播、背压与明确拒绝,而不是无上限接收。

运行示例 · Q099

并发10个请求,队列为什么仍不断增长

输入与条件。稳定处理一项平均需要2秒,10个并发槽位,粗略最大完成率5项/秒;到达率为6项/秒。

步骤与对象内部动作中间结果 / 新状态
1容量估计10/2约5项/秒。
2流入对比到达6项/秒超过容量,平均每秒积压约1项。
3100秒后若这些均值持续新增积压约100项,等待不断变长。
4稳态条件先使有效到达率小于可服务能力限流、扩容或减少服务时长。
5Little关系在稳定系统L=λW例如λ=4、平均在系统停留W=3秒,平均系统内12项,包括等待与服务。

把过程连起来。增加并发只有在资源还能支持时才可能增加吞吐;超载系统不能盲用稳态公式预测固定等待。

边界与反例。10/2是粗略均值容量示例,不考虑长尾、共享瓶颈、重试风暴和不同请求大小。

依据与适用范围:[DERIVE]。示例输入和场景由本书明确设定。

追问:为什么增加超时可能让故障更严重?

它延长了资源占用与在途请求寿命。下游变慢时,上游继续接收并延长超时,内存、连接和工作槽会被堆满。超时应与任务语义和端到端截止时间匹配,重试有总预算,不能每层独立把重试次数成倍叠加。

追问:CPU利用率不高,为什么仍然排队?

瓶颈可能是GPU显存、KV容量、每分钟Token配额、外部API并发、数据库锁或人工批准。监控应覆盖队列与稀缺资源,而不是只看CPU。大量等待型任务甚至会出现CPU很低、用户体验很差的组合。

追问:SLO应该只规定P95响应时间吗?

还应包含任务正确性、可用性或人工介入等目标,并定义哪些任务纳入分母。否则系统可以通过快速拒绝或输出空答案“优化延迟”。异步长任务可把受理延迟、有效进展与最终完成分开,不宜套用普通网页响应指标。

Q100|Agent系统上线时究竟要版本化什么?回滚为什么不只是换回模型?

核心回答

最终行为由模型、提示、工具Schema、技能、检索索引、记忆策略、权限、运行器和评测规则共同决定。上线要保存可追溯组合,灰度观察结果;回滚必须处理已写入状态和外部副作用,而不仅切换模型名。[EVALS][SLO]

一个能解释回归的版本清单

模型:明确版本或服务返回标识
上下文:组装策略、模板与技能版本
检索:语料版本、embedding版本、索引构建ID
工具:schema版本、执行器版本、权限策略
状态:checkpoint与记忆schema版本
验证:测试集、grader版本、验收规则

假设同一天更换模型、压缩摘要格式和代码索引,成功率下降。没有版本清单就很难区分原因;一次只改变可归因的少数变量,先离线回归,再小范围真实流量观察,更利于判断。灰度不是把危险操作随便分给少量用户;高风险能力仍应先有权限与验收保障。

回滚前检查新版本写入的记忆和checkpoint是否能被旧版读取。若摘要schema变化,旧运行器误读“unknown”为“failed”可能重复写入。外部订单、邮件、部署不会因程序回滚自动撤销;需要按业务语义核验与补偿。更安全的回滚可能是停止新增写操作,保留只读核验与人工接管,而不是继续跑不兼容旧代码。

运行示例 · Q100

只回滚Prompt,为什么故障还在

输入与条件。版本包V1={模型M1,提示P1,工具T1,索引I1};V2同时升级为M2/P2/T2/I2,出现失败。

步骤与对象内部动作中间结果 / 新状态
1观察变化四个组件都变了不能立即认定只是Prompt问题。
2仅回滚P得到M2/P1/T2/I2这既不是V1也不是原V2,兼容性未知。
3完整回退恢复已验证的兼容版本包确认环境和索引能共同工作。
4定位在受控任务中逐项或成组改变必要组件避免同时引入新变量。
5发布记录保存输入、版本、评测和回滚条件让下一次对比可复现。

把过程连起来。Agent行为由模型、上下文、工具、数据和执行环境共同决定,版本治理也应覆盖组合。

边界与反例。并非每次修改都必须冻结全部数据;动态数据需要明确版本或时间范围以便解释差异。

依据与适用范围:[DERIVE]。示例输入和场景由本书明确设定。

追问:为什么不能只用最新Benchmark分数选模型上线?

Benchmark任务、工具、资源和成功标准未必与你一致。应把候选模型放进自己的Harness和历史失败集测试,尤其检查结构化输出、工具遵循、长上下文和成本。公开成绩提供候选信号,不替代本地验收。

追问:提示只改了一个词,需要版本吗?

若该提示影响生产行为,就应能追溯具体内容;但不需要为每个文字变化建立复杂审批层。版本化用于归因与回退,审批深度取决于风险。不要把“可追溯”误解为“每次都要多级Review”。

追问:如何知道优化已经可以停止?

当主要失败模式已被解决,新增机制在代表性任务上没有可辨认收益,或收益小于成本与维护风险,就不应继续堆规则。保留监测与真实失败回流,等待新证据触发改动。这比持续追求完美流程更符合工程目标。

记录保存在本机浏览器。

输入关键词即可检索。

↑ ↓ 选择 Enter 打开Esc 关闭 · 仅本地搜索

阅读设置

阅读设置仅保存在本机浏览器,不上传任何数据。