arXiv:2609.05364 · 2026-09-04 · cs.PL

Design Docs Are All You Need:技术学习文档

从“维护一套不断老化的性能建模代码”,转向“维护可执行语义的设计文档,并由 Agent 定期从零生成实现”。重点理解 SMART 的文档 DAG、符号化算子 IR、两级调度模型,以及这种研发模式真正成立所需的验证闭环。

AI-native Software Design-doc DAG Agentic Regeneration Symbolic IR ML Performance Modeling
研究对象机器学习系统性能建模库 SMART
作者机构Google DeepMind / MIT / Stanford / Google
阅读定位系统设计提案 + 工程经验报告
一句话结论 SMART 把自然语言设计文档当作长期资产,把代码当作一次构建的临时产物;可行性的关键不是“Agent 会写代码”,而是文档能给出无歧义的工作示例,系统能用参考模型、参数约束和测试把生成结果关进验证闭环。
最重要的思想变化

传统:代码是事实来源,文档追赶代码。

SMART:设计文档是事实来源,代码由文档全量派生。

最容易误解的证据

“舍入误差级一致”描述的是生成实现对人工参考模型的复现精度,不是模型预测对真实 TPU 运行时间的硬件实测误差。

01

为什么性能建模软件特别容易积累技术债

性能模型夹在两个高速变化层之间:上层模型架构不断出现 MoE、潜在注意力、异构推理阶段;下层加速器、内存层级和互连也持续变化。任何“当前看起来合理”的抽象,都可能很快失效。

失败模式发生机制长期后果
增量生成债务新版本不是从新规格独立生成,而是在旧实现上继续补丁旧约束、兼容层和局部妥协不断叠加
上下文窗口近视Agent 只能看到局部文件或片段,看不到全局不变量局部正确、整体结构却逐渐失去一致性
双向架构漂移模型语义与硬件语义同时变化中间抽象频繁重构,测试和文档快速失真
Ct = G(St)
Dt+1 = | G(St+1, Ct) - G(St+1) | S:当前规格 · G:人或 Agent 生成器 · C:实现 · D:增量修补与从零生成之间的“距离”

论文的做法是定期重新计算 C = G(S),不把旧实现 Ct 喂给下一轮,从流程上切断补丁历史。这里的“债务归零”是一个研发过程定义:它消除了由旧代码作为额外输入产生的偏差,但不会自动消除规格本身的错误、生成器随机性或验证盲区。

来源:PDF 第 1-2 页,公式(1)及 Introduction。

02

SMART 的全量再生成闭环

1自然语言变更

人只修改设计文档,不直接修改生成代码。

2依赖发现

只读 Agent 分析文档,推断依赖边,形成 DAG。

3拓扑生成

编排器按依赖波次分配“每文档一个编码子 Agent”。

4生成库

从干净状态构建符号化性能模型实现。

5验证与对账

参考模型、参数保护、单元测试和精确锚点共同验收。

6修正文档

歧义和错误回写为规格改进,再触发下一轮生成。

核心控制点 “能生成”不是完成条件;只有全部对账与测试通过,新的生成库才允许替换上一版构建产物。
1.5-3 h论文报告的一次全库干净再生成耗时
约 $100使用 Claude Code 完整重建的 API 成本

来源:PDF 第 2-3 页,Figure 1 与 Cost and iteration speed。成本是作者当时实践数据,不应外推为固定价格。

03

设计文档 DAG:把大代码库切成 Agent 可处理单元

主分支几乎不保存实现代码,而是保存可以组合成有向无环图的 Markdown 文档。依赖顺序由内容决定,例如拓扑和数值类型必须先于集合通信成本,后者又必须先于模型目录。

docs/00-core/ · 核心 IR、Tensor、符号与单位
└─ docs/10-system/ · TPU 拓扑、数值类型、资源容量
└─ docs/20-costs/ · MXU、VMEM、ICI、collective 成本
└─ docs/30-models/ · Dense、MoE、MLA、VLA 模型族
每个文档一个子 Agent

上下文被限制在一个自包含模块,降低单次任务长度和模型迷失全局的概率。

中央困难日志

编排器记录难以解释的描述和前序波次暴露的缺陷,告诉人类下一次应该改哪份规格。

拓扑波次

同层无依赖文档可以并行生成;下游只读取已通过验收的上游接口。

动态模型路由

核心 DSL 等高难文档交给更强模型,下游重复性模块交给成本更低的模型。

来源:PDF 第 2-3 页,Design docs as the source of truth。

04

可靠生成依赖怎样的设计文档

高层规则像“宪法”,能约束结构,却不一定固定细节语义。论文强调补上一种自底向上的表达:逐步工作示例。它既是人类可读的解释,也是生成 Agent 的上下文示范。

文档元素必须回答的问题对生成的作用
输入与符号维度、单位、取值域、分片含义是什么?防止形状和量纲漂移
逐步轨迹每一步的中间形状、值和资源动作是什么?把隐含语义变成可模仿过程
闭式表达式最终成本应化简成哪个精确符号表达式?提供强于样例输出的代数约束
边界与反例哪些参数组合非法?哪些直觉容易算错?生成参数保护与负向测试
对账锚点一个小型 preset 的精确期望输出是什么?将示例直接落成回归测试
论文中的典型示例 在 2×2×2 带回绕的 torus 上,单节点链路数是 3 而不是 6。这样的例子把“物理双向连接”和“独立维度链路”的歧义直接暴露出来,并要求随后给出 AllGather(V) 的精确成本。

实用判断:如果读者只能“理解大意”,却不能拿纸笔复演出中间状态和最终值,这份文档仍不足以作为可再生代码的规格。

来源:PDF 第 3 页,An opinionated way of writing design docs。

05

最小符号 IR:一个递归 Op 覆盖模型与系统

稳定再生成要求被描述的系统足够小、正交且不随架构变化频繁改形。SMART 将模型压缩为一种递归操作 Op:内部节点表达循环或子图,叶子节点表达硬件可定价的原子动作。

Op
├─ inputs  : List[Tensor]          # 符号形状
├─ outputs : List[Tensor]
├─ cost    : OpCost                # compute / memory / comm 的 SymPy 表达式
├─ rrt     : ResourceReservation   # 资源 × 周期占用表
└─ params
   ├─ InnerLoop(n_iter, body)      # 带迭代次数的循环
   ├─ GraphParams(graph)           # 普通子图
   └─ LeafParams(...)              # 系统定价叶子
算法侧负责组合

用循环、子图和 Tensor 数据流组合 leaf,不把 TPU 细节散落到每个模型定义中。

系统侧负责定价

为 MXU tile、VMEM tile load、ICI collective 等 leaf 定义 OpCost 与 RRT。

解耦结果:替换注意力算法主要改模型文档;替换互连或加速器代际主要改系统定价文档。递归结构不需要跟着每个模型家族重写。

来源:PDF 第 3 页,A minimal symbolic IR 与 The Op abstraction。

06

Builder DSL:从 Python 轨迹生成 IR

模型作者不直接手写 Op 树,而是在轻量 Python 内嵌 DSL 中写出可追踪的计算。装饰器 block 形成命名子图;两类 loop 则保留并行与归约语义。

构造语义Flash Attention 中的角色
@smart_map_loop彼此独立、可并行的 map遍历 query block,并沿指定轴收集输出
@smart_loop携带 accumulator 的真归约遍历 KV block,持续累加 attention value
builder leaf发出系统已定价的原子 Opload/store tile、MXU einsum、tensor add
SymPy dimensionshape 与 trip count 保持符号化同一 nest 覆盖 prefill 与 flash decoding
@smart_map_loop(n_iter = Tq / q_block)
def each_query_block():
    q_tile = load(q)
    acc = load(initial_value)

    @smart_loop(n_iter = Tkv / kv_block)
    def reduce_over_kv(acc):
        k_tile, v_tile = load(k), load(v)
        scores = mxu("Q × Kᵀ", q_tile, k_tile)
        partial = mxu("scores × V", scores, v_tile)
        return add(acc, partial)

    return store(acc)

关键不是 Python 语法,而是 trace 后保留了层级、循环类型、符号迭代次数和硬件 leaf。因为 Tq 与 Tkv 不被提前绑定,同一个图可表示 Tq=Tkv=T 的 prefill,也可表示 Tq=1, Tkv=Tctx 的 decoding。

来源:PDF 第 3-4 页,The builder DSL 与 Listing 1。示例为语义化缩写,并非原代码复制。

07

分片注解驱动通信推导

数据分布通过 Tensor 的 sharding annotation 表达,而不是由模型作者到处手插 collective。sharded einsum 根据输入、权重和输出的布局推断必要通信。

A收缩维权重被分片

在计算刚需要时推导 AllGather,恢复局部 einsum 所需数据。

B输出跨分片维归约

推导 ReduceScatter,将归约与目标输出布局结合。

C布局发生轴迁移

显式写出 collective;不能仅从 einsum 局部关系推出。

DMoE dispatch / combine

AllToAll 将 expert parallel 轴在 token group 与 expert 维之间来回移动。

抽象原则 “由数学算子必然导致的通信”交给规则推断;“改变数据布局语义的通信”保留显式表达。这样既减少重复,又避免隐藏关键系统决策。

来源:PDF 第 4 页,Distribution is expressed as sharding annotations。

08

从 Op 成本到墙钟时间:快慢两种模式

维度Fast:分析汇总Slow:模调度
目标快速扫描数千设计点分析少量候选点的细粒度 schedule
基本方法leaf 成本乘以所有外层 trip count把循环 body 软件流水化进 RRT
重叠处理用 roofline 风格的可组合分析变换估计显式考虑依赖和各资源容量
核心输出闭式时间表达式 / 上下界达到的启动间隔 II,再递归向上汇总
优势速度快、适合大规模参数 sweep细节强、能看到资源争用与流水化
代价对时序和冲突做了粗化计算更慢,不适合穷举全空间

RRT 怎样工作

Resource Reservation Table 的行是资源(例如 MXU、VMEM、ICI),列是 cycle,单元格是该周期占用数量。Modulo Scheduling 寻找可重复启动循环迭代的最小可行间隔 II,同时满足数据依赖与资源容量,然后把该结果作为父级 Op 的成本继续向上汇总。

符号传播为什么重要

batch、序列长度、带宽、mesh 轴、数据类型宽度都保持为 SymPy 自由变量。构图一次,只有在设计空间边界才做数值替换。因此:

  • 同一模型结构可以服务大量参数 sweep。
  • 文档可直接声明期望的闭式成本表达式。
  • 测试不仅比较数值,还能比较符号化简后的结构或等价性。

来源:PDF 第 4 页,Rolling up the Op hierarchy 与 Symbolic propagation。

09

论文给出的证据,以及没有给出的证据

结论证据强度正确解读
全库可由设计文档再生成作者工程实践SMART 约 50 份文档、约 9,000 行规格 prose,按版本全量再生成
再生成成本可接受单项目观测约 1.5-3 小时、约 $100;依赖当时模型、工具和项目规模
生成实现可保持语义一致参考模型对账包括 DeepSeek-V3 on TPU pod slice 的人工参考模型,复现到舍入误差
性能预测准确PDF 未充分展示没有给出系统性的真实硬件测量表、误差分布或跨硬件验证
方法优于增量维护概念论证 + 经验没有消融实验或长期对照组来量化维护成本差异
可独立复现信息不足论文中没有提供明确公开代码仓库链接或完整生成提示词、测试资产
阅读结论 这是一篇极有价值的系统设计与工作流论文,但不能把它读成完整性能评测报告。最强证据是“规格驱动的生成实现能通过参考模型对账”;真实硬件预测精度与长期组织收益仍需要更多数据。

来源:PDF Abstract、Section 2、Section 4。上述“未给出”基于所附 5 页 PDF 的内容范围。

10

可落地的工程复现方案

不要第一天就删除生产代码。更稳妥的验证方式是选择一个边界清晰、可精确对账的模块,建立“规格 → 隔离生成 → 验证 → 发布”的旁路,再根据结果扩大范围。

PHASE 1 · 选择试点

选择 3-5 个依赖清晰的模块;要求有确定输入输出、可建立 oracle,且不存在隐式线上状态。

PHASE 2 · 规格化

为每个模块写自包含文档、符号/单位表、逐步示例、边界条件和精确对账锚点。

PHASE 3 · 发现依赖

让只读 Agent 输出候选依赖边,同时用静态 lint 阻止循环依赖、未声明符号和跨层导入。

PHASE 4 · 干净生成

每次在空目录或隔离 worktree 中生成;子 Agent 只获得当前 doc、已验收依赖接口与项目规则。

PHASE 5 · 多层验收

依次执行格式/类型检查、单元测试、锚点测试、差分参考模型、安全扫描和性能预算。

PHASE 6 · 原子发布

全部通过后才整体替换构建产物;失败时保留上一版,并把歧义记录到对应设计文档。

project/
├─ design_docs/ # 唯一人工编辑的规格
│ ├─ manifest.yaml # 文档入口、层级、允许的依赖
│ └─ modules/*.md # 自包含设计文档
├─ anchors/ # 输入 preset 与精确期望输出
├─ references/ # 人工实现或黄金数据,只用于对账
├─ generated/ # 每轮从零产生,不作为人工事实源
├─ reports/ambiguity/ # Agent 困难日志与待改规格
└─ orchestrator/ # DAG、路由、隔离、门禁与发布

建议的硬门禁

  • 禁止生成任务读取上一版 generated/,避免旧实现成为隐式输入。
  • 依赖接口必须先验收再暴露给下游;同一波次只能依赖更早波次。
  • 所有数值模块至少包含一个符号对账和一个具体数值对账。
  • 关键路径采用多样化验证:测试生成者与代码生成者使用不同提示上下文或独立 oracle。
  • 发布采用全有或全无;不得把局部通过模块拼进生产分支。

工程方案依据论文工作流扩展而来;目录、门禁和分阶段试点属于可执行的工程推导,不是论文原样规定。

11

适合 Agent 再生成的设计文档模板

# 模块名称

## 1. 目标与非目标
- 必须实现什么
- 明确不负责什么

## 2. 公开接口
- 输入 / 输出 / 类型 / shape / 单位
- 错误与边界行为

## 3. 依赖与不变量
- 允许依赖的上游文档
- 跨模块必须始终成立的条件

## 4. 语义步骤
1. 从输入开始逐步执行
2. 写出每一步中间 shape、值、资源动作
3. 给出最终符号表达式

## 5. Worked Example
- 固定一组小输入
- 完整列出中间结果
- 写出唯一正确的最终输出

## 6. 反例与参数保护
- 非法输入
- 容易混淆的情况
- 应抛出的错误

## 7. Reconciliation Anchor
- preset
- exact_expected_output
- symbolic_equivalence_rule

## 8. 验收条件
- 类型 / 单元 / 属性 / 差分 / 性能 / 安全测试
文档完成判据 一个不了解历史代码的 Agent,仅凭当前文档、已验收依赖接口和项目公共规则,就能生成实现并通过独立 oracle;否则应继续改文档,而不是偷偷补充旧代码上下文。
12

哪些项目适合,哪些项目要谨慎

场景适配度原因
性能模型、编译器 IR、规则引擎高语义可形式化,容易建立符号或差分 oracle
SDK、协议适配层、代码生成器中高接口明确,但要处理兼容矩阵和真实端到端测试
普通业务 CRUD 模块中可以规格化,但全量生成的收益未必覆盖验证成本
长期有状态服务与数据迁移低历史状态本身就是事实,不能通过删除旧代码归零
极致手工优化 kernel低到中隐性硬件知识和性能技巧难完整写入自然语言
高合规、安全关键系统谨慎需要稳定可追溯构建、供应链控制和独立验证证据

六类主要风险

规格错误

文档是事实来源后,错误会被一致地传播到所有生成实现。需要独立 oracle,而不是只测试“是否符合文档”。

生成随机性

模型、温度、工具版本变化可能产生不同代码。需要锁定环境、保留生成清单并做行为哈希。

依赖误判

机器发现的 DAG 可能漏边或错边。应用架构层级规则、循环检测和接口访问审计约束它。

共同模式失败

如果代码与测试由相同上下文生成,二者可能一起误解。关键锚点应由人工或独立来源维护。

安全与供应链

全量生成扩大依赖注入、危险默认值和许可漂移风险。生成后仍需 SAST、依赖和许可证检查。

成本扩张

规模增加后,重建时间和 Token 成本可能超线性增长。需要缓存已验收接口、并行波次与模型路由。

13

建议学习路径:从读懂到做出最小原型

第 1 天 · 复述核心命题

用自己的话解释 S → G → C、增量生成债务、为什么旧代码不能进入生成上下文。

第 2 天 · 画出 IR

实现最小 Tensor / Op / OpCost / RRT 数据结构,并构造一个两层递归 Op 树。

第 3 天 · 做符号成本

用 SymPy 写 matmul、内存搬运和 AllGather 成本,验证代入不同 batch/带宽时无需重建图。

第 4 天 · 做 tracing DSL

用 decorator/context manager 记录 block、map loop、reduce loop 和 leaf。

第 5 天 · 写一份生成规格

选择 Flash Attention 的一个子模块,补齐逐步示例、闭式表达式与 reconciliation anchor。

第 6 天 · 搭再生成流水线

从空目录生成实现;自动运行 lint、单测、符号等价和参考差分。

第 7 天 · 做失败复盘

只改规格不改生成代码,观察失败能否通过文档澄清被永久修复,并记录成本、时间和失败类型。

对 Agent 开发能力的价值 这个练习会同时训练任务分解、依赖图编排、上下文隔离、模型路由、工具调用、验证门禁和可观测性,比单纯做一个“能调用工具的聊天 Agent”更接近生产级 Agent Engineering。
14

术语速查与资料

术语在这篇论文中的含义
Durable artifact跨版本长期保存、由人直接维护的事实来源;在 SMART 中是设计文档
Build product可由规格重新产生的实现产物;在 SMART 中是 generated library
Reconciliation anchor文档末尾的小型 preset 与精确期望结果,对应生成测试的黄金锚点
RRT资源预留表:描述每个周期对各类硬件资源的占用
Modulo scheduling让循环不同迭代重叠执行,并求满足依赖/容量的启动间隔 II
Symbolic propagation成本表达式携带自由变量向上汇总,直到设计点边界才做数值替换
Roofline-style bound用计算吞吐与数据移动瓶颈估计性能上界/时间下界的分析方式
主要资料
最终记忆框架 Docs 定义语义,DAG 控制上下文,Agent 负责再生,IR 稳定抽象,Symbolic Cost 支持设计空间,双模式 Scheduler 平衡速度与细节,Reconciliation 决定能否发布。
← 返回内容索引