这一卷解决什么问题
卷一把“AI 能力”写成了契约与流水线。但契约里有两项承诺最难兑现:延迟与成本。
卷二的 13 章围绕这两项承诺展开:
| 部分 | 章节 | 回答的问题 |
|---|---|---|
| 度量 | 第 1 章 | 延迟、吞吐与 goodput 到底怎么算 |
| 调度 | 第 2 章 | 请求怎么排队、并发多少、租户怎么公平 |
| 上下文 | 第 3 章 | 输入 token 花在哪,能否复用与压缩 |
| 输出 | 第 4 章 | 生成多长、何时停止、截断怎么办 |
| 缓存 | 第 5 章 | 什么值得缓存,缓存放在哪一层 |
| 替代 | 第 6 章 | 量化、蒸馏、级联各自省多少、损失什么 |
| 离线 | 第 7 章 | 哪些任务不该占用在线预算 |
| 容量 | 第 8 章 | 业务量如何翻译成 token、并发与机器 |
| 归因 | 第 9 章 | 钱花在哪个能力、租户与提示版本上 |
| 实验 | 第 10 章 | 如何做可信的对照实验 |
| 联合优化 | 第 11 章 | 质量、成本、延迟如何一起验收 |
| 稳定性 | 第 12 章 | 规模化后限流、降级与成本事故 |
| 收口 | 第 13 章 | 一套可交付的推理成本基线 |
前半卷建立度量与杠杆,后半卷做归因、实验与治理。第 1 章与第 9 章是全书的地基:不会测量、不会归因,后面的优化都是猜。
每章的四段式
每一节保持相同结构:
- 问题与判据:这一节要回答什么,什么算达标。
- 机制与取舍:为什么这样设计,代价是什么,备选方案为何不选。
- 可运行片段:
ai-lab中的模块与测试,展示判据如何落成代码。 - 边界与错误:什么时候不适用,常见误用是什么。
每章第三节固定是实验章:把前两节的判据合成一个可运行的检查或报告。
实验工程地图
ai-lab 在卷一已有 core、gateway、routing、stream、prompt、structured、tools、cache、degrade、security、observe 等模块。卷二新增:
| 模块 | 对应章节 | 职责 |
|---|---|---|
src/perf/metrics.ts | 1.1–1.3 | TTFT、TPOT、goodput 与负载模型 |
src/perf/scheduling.ts | 2.1–2.3 | 有界队列、优先级、并发与公平调度 |
src/perf/context.ts | 3.1–3.3 | 上下文成本、前缀复用与压缩 |
src/perf/output.ts | 4.1–4.3 | 长度上限、停止条件与提前终止 |
src/perf/cache-econ.ts | 5.1–5.3 | 结果缓存的经济性与分层 |
src/perf/compress.ts | 6.1–6.3 | 量化、蒸馏与级联的成本模型 |
src/perf/batch.ts | 7.1–7.3 | 离线批处理、分片与调度 |
src/perf/capacity.ts | 8.1–8.3 | 需求换算、峰值余量与配额 |
src/perf/cost.ts | 9.1–9.3 | 成本模型、归因与对账 |
src/perf/experiment.ts | 10.1–10.3 | 对照实验与结果解读 |
src/perf/quality.ts | 11.1–11.3 | 联合门禁、评测与灰度 |
src/perf/stability.ts | 12.1–12.3 | 限流、分流与事故复盘 |
src/perf/baseline.ts | 13.1–13.3 | 收口基线与 ADR 输入 |
模块之间可以互相引用,但不修改卷一已有模块。所有新增代码只用 node: 内置模块,零第三方依赖。
三级可运行性
延续卷一的分级:
| 级别 | 判定 | 卷二中的例子 |
|---|---|---|
| L1 | 纯函数与进程内逻辑 | 成本计算、队列模拟、容量公式 |
| L2 | 进程内端到端 | mock 推理器 + 调度器 + 观测记录 |
| L3 | 真实依赖 | 真实模型或推理服务;卷二不承诺 |
卷二以 L1、L2 为主。所有性能数字来自确定性模拟,目的是建立口径与对照方法,不是替代真实压测。
代码块约定
每个 TypeScript 代码块以三行注释开头:
// file: src/perf/metrics.ts
// tier: L1
// verify: node --test test/perf/metrics.test.ts
file是相对ai-lab的路径,正文代码块与该文件逐字节一致。tier标明该文件的最低验证级别。verify给出可复现的验证命令。
这样做的好处是:书里的每个片段都能在工程里找到原文,改一处必须同时改两处,避免“书上能跑、仓库里跑不了”。
数字口径
- 延迟单位毫秒,吞吐单位请求/秒,成本单位整数微元。
- 平均延迟必须与 p95 一起出现;只给平均值视为不完整。
- 成本对比必须写明对照基线与统计窗口。
- 模拟数据必须标注“示例样本上的运行结果”。
- 不写“约”“大概”来掩盖没有测量的事实;没有数字就写“需要实测”。
为什么还是 TypeScript
卷二的重心是调度、预算与成本模型,这些逻辑与语言无关。选择 TypeScript 有三个实际原因:
- 延续卷一的工程,读者不需要切换工具链。
- Node 26 原生类型剥离,零依赖即可运行测试。
- 模拟器需要频繁改参数、跑对照,TypeScript 的迭代成本低。
模型推理本身当然不是 TypeScript 实现的。书中用 MockProvider 模拟延迟与用量分布,把优化决策与具体推理引擎解耦。真实引擎的参数调优不在本书范围。
章间依赖
1 度量
├─ 2 调度
├─ 3 上下文 ── 5 缓存
├─ 4 输出
├─ 6 替代 ── 10 实验
├─ 7 离线
├─ 8 容量 ── 12 稳定性
└─ 9 归因 ── 11 联合优化 ── 13 收口
- 第 1 章是全书前置。
- 第 9 章依赖第 1 章的度量字段。
- 第 10 章依赖第 3–6 章的优化手段。
- 第 13 章依赖第 8、9、11 章的容量、归因与门禁。
跳读时至少补齐依赖链上的前置章节,否则实验结论无法对照。
团队怎么用
建议按“一次只改一个变量”的节奏使用本书:
- 用第 1 章统一团队的性能口径。
- 用第 9 章建立成本归因报表。
- 从第 3、4、5 章挑一个杠杆做实验。
- 用第 10、11 章验收,确认质量没有回退。
- 用第 8、12 章把结论写进容量与稳定性方案。
不要一次上四个优化。四个变量同时变,结果无法归因,团队会陷入“好像快了一点”的争论。
三个练习
- 度量练习:给定一组请求记录,计算 TTFT、TPOT、p95 与 goodput,并解释四个指标为何可能给出不同结论。
- 归因练习:给定一张按能力与模型拆分的账单,找出成本增长的主要来源,写出验证假设所需的最小实验。
- 容量练习:给定日活、人均请求数与长度分布,估算峰值 token 需求与所需并发,给出 30% 余量的配置。
三个练习的参考答案不附在书中,因为真实团队的参数不同。判据在第 1、8、9 章。
自检清单
读完一卷后,你应该能回答:
- TTFT 与端到端延迟分别在什么场景下决定体验?
- 为什么并发提高后 p95 可能先降后升?
- 前缀缓存命中需要哪些条件?提示改版为什么会破坏命中?
- 输出长度为什么是非线性成本?截断与重试如何互相放大?
- 结果缓存的键应该包含什么?命中率高为什么不等于成本低?
- 量化、蒸馏、级联分别适合什么替代场景?
- 离线批处理为什么不能简单搬到在线路径?
- 从日请求量到并发数,中间缺哪几个参数?
- 一次成本上涨,如何在一小时内定位到能力与提示版本?
- 质量-成本-延迟的联合门禁应该卡在哪一步?
答不上来的条目,对应章节需要重读。
勘误与反馈
书中的代码与数字都可以复现。如果发现代码无法运行、数字与脚本不符,以仓库中的脚本输出为准,并在勘误中记录命令、环境与输出。欢迎指出判据不成立的反例,这比指出错别字更有价值。
怎么验证书里的代码
每个代码块都能在 ai-lab 中找到同名文件,验证分三步:
- 按代码块头部的
// verify:命令运行单模块测试。 - 用
node --test跑全量,确认改动没有破坏其他章节的假设。 - 对照正文中的数字,确认它们来自测试输出而不是手工填写。
如果三步有任何一步对不上,以脚本输出为准。书是静态的,脚本是活的。
书中不提供“复制到生产就能用”的完整服务。实验工程刻意省略了持久化、鉴权、真实供应商连接与部署配置。这些部分与具体环境强绑定,写进书里会很快过期,也会让读者误以为照抄即可上线。
三个不做的优化
卷二会反复提到“不要做什么”,这里先集中说三条:
不做没有度量的优化。 没有基线、没有统计窗口、没有分母的优化,无法判断是否有效,也无法在回退时知道回到了哪里。
不做多变量同时上线。 一次改提示、缓存和模型,成本降了也不知道是哪一项的贡献;出了问题也不知道该回滚哪一个。
不做牺牲可解释性的节省。 把失败静默吞掉、把降级写成空结果、把超时算作成功,报表会变好看,系统会变脆。省下的成本会在下一次事故里加倍偿还。
三条约束的共同点是:它们都能被事后验证。度量缺失、多变量上线、错误被吞掉,都会在复盘时留下痕迹。
关于案例「回声」
「回声」是内容社区 + 私信 + 轻交易的组合产品。卷二使用它的五个 AI 能力:
| 能力 | 典型负载 | 对延迟的敏感度 | 对成本的敏感度 |
|---|---|---|---|
| chat.reply | 在线、流式 | 高 | 中 |
| search.rerank | 在线、短请求 | 高 | 低 |
| content.summarize | 半在线、可异步 | 中 | 高 |
| moderation.classify | 在线、批量 | 中 | 中 |
| support.assist | 在线、低频 | 低 | 低 |
五个能力的负载形状不同,同一项优化在它们身上的结论也不同。这正是卷二反复做对照的原因:没有一个全局最优配置,只有按能力分工的策略。
阅读节奏建议
45 篇不必一次读完。一个务实的节奏是每周一章:
| 周 | 内容 | 团队动作 |
|---|---|---|
| 1 | 第 1 章 | 统一延迟与吞吐口径 |
| 2 | 第 2 章 | 检查队列与并发上限 |
| 3 | 第 3–4 章 | 做一次上下文与输出审计 |
| 4 | 第 5–6 章 | 评估缓存与替代方案 |
| 5 | 第 7–8 章 | 整理离线任务与容量模型 |
| 6 | 第 9–10 章 | 建立归因报表,做一组对照实验 |
| 7 | 第 11–12 章 | 补联合门禁与稳定性清单 |
| 8 | 第 13 章 | 形成基线,准备进入卷三 |
八周是一个参考,不是承诺。团队规模小、能力少时,可以压缩到四周;能力多、跨团队时,可能更久。节奏可以调,顺序尽量别跳:度量与归因是所有后续动作的地基。
小结
卷二不是“调参手册”,而是一套把性能与成本变成可测量、可对照、可验收的方法。方法的核心只有一句:先让每一分钱和每一毫秒都能被解释,再谈优化。
常见错误与边界
- 把模拟数字当生产结论:模拟器建立口径,不替代压测。
- 只优化平均值:p95 与长尾才是用户体验与容量的关键。
- 一次改多个变量:无法归因,等于没做实验。
- 忽略质量回退:成本降了、质量掉了,不是优化。
- 把缓存当银弹:命中率受键设计与更新频率约束,容量不会因平均成本下降而自动变小。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。