文章指出绿色的cargo check不能证明AI生成的Rust代码达到生产质量,还需审查所有权、克隆滥用、锁竞争、panic、unsafe、性能预算与测试有效性。它强调应把人工复核和返工成本计入AI编码效率,而非只看首次编译速度。
AI 辅助编码看起来最快的时候,往往是我们过早停止计时的时候。
一个模型可以搭建 crate 的基本结构、实现 trait、生成测试,并且在人类工程师还没有理清现有所有权模型之前,就让 cargo check 通过。这是一种真实的能力,但它并不能很好地衡量工程工作是否已经完成。
资深系统开发人员关心的是后续的完整过程:
所有权模型是经过有意设计的,还是实现代码只是通过不断调用 clone 来绕过生命周期问题?
共享状态真的有必要吗?锁的作用域和竞争情况是否已经得到充分理解?
格式错误的输入是否可能引发整个进程范围的 panic?
这项变更是否仍然符合延迟和内存分配预算?
测试验证的是预期属性,还是仅仅复现了新的实现?
其他工程师能否还原出这一设计为何会被接受?
表面上的效率提升,究竟消耗了多少审查与补救成本?
2026 年 8 月 5 日,Rust 工程师 Erik-Jan van de Wal 准确描述了这一差距。他在文章中指出,当实际任务需要对所有权、并发和生产环境故障进行推理时,AI 智能体却会诉诸 .clone()、Arc<Mutex<T>>、不安全的 trait 实现以及 unwrap()。他还报告称,token 开销和额外十五个小时的清理工作,使其 AI 辅助开发方案的成本约为自己编写代码的两倍。这些是他报告的结果,并非通用的行业基准;本文的结论也属于我,而非他。请阅读 Erik-Jan van de Wal 的文章。
他更重要的观点很难被忽视:生成的代码被算作进展,而验证、架构修复和运维风险却仍未计入生产力账目。
我们正尝试在工作中通过 AI 智能体保障档案(Agent Assurance Profile,简称 AAP)来纠正这种核算方式。其前提很简单:
代码并不会仅仅因为能够编译,就值得在运维中信任。只有当重要声明与其他流程可以检查的证据建立关联,并且剩余的主观判断被明确记录时,代码才具备可审查性。
AAP 不会让模型理解 Rust。它不会把提示词变成证明,也不会取代资深工程师的审查。它改变的是 AI 智能体工作周围的协议,使看似合理的输出不能再被当成证明其自身正确性的证据。
在介绍具体机制之前,有必要区分讨论 AI 智能体保障时经常被混为一谈的三个层次。
第一层是 DAG-TOML 规范及其草案档案。公开的 agent-assurance 仓库定义了文档种类、档案、不变量和验证器。实现 DAG 和可追溯性文档来自核心规范,成本记录来自成本档案,而 AAP 将它们组合起来用于 AI 智能体保障。
第二层是发射器实现。agent-assurance-dsrs 是一个 Rust 工作区,我们在其中执行并评估 DSPy 风格的程序,然后将这些文档的一个具体子集作为 sidecar 发射出来。它展示了如何将运行时结果映射为与验证器兼容的保障制品,而不必让运行时类型与治理模式发生耦合。
第三层是团队的保障策略。诸如“不得让锁守卫跨越 await”“不得存在未经审查的不安全 trait 实现”,或“p99 延迟回退不得超过百分之五”之类的规则,并不会由 AAP 自动提供。团队必须定义这些声明、选择合适的证据、保护验收策略,并决定哪些剩余风险需要人工批准。
规范和档案提供一种语言。发射器以这种语言提供数据。策略决定这些数据必须证明什么。
仓库指令仍然很重要。应当告知 AI 智能体哪些模块对安全敏感、哪些 API 必须保持稳定、哪些位置需要关注内存分配,以及项目期望采用什么风格。
但是,指令存在于概率性的上下文之中。像下面这样的规则:
Do not introduce Arc<Mutex<T>> without architectural justification.
并不能确定模型是否注意到了这条规则、所编辑的路径是否受其约束、锁是否会一直持有到 .await 之后,或者竞争情况在负载下是否仍然可以接受。模型可能违反约束、道歉、修改补丁,然后宣布成功,却没有留下持久证据来证明最终结果符合要求。
AAP 将指令视为输入。只有当指令转化为精确的声明,并且具备强制执行或审查路径时,保障才真正开始。
claim: no synchronous lock guard crosses an async suspension point
scope: crates/runtime/src/**
evidence:
- clippy::await_holding_lock result
- targeted async integration tests
- reviewer approval for synchronization changes
即使是这项声明,也需要加以限定。Clippy lint 能捕获特定的结构模式,但它并不能证明所有并发交互都是安全的。测试覆盖的是已记录的案例,但无法遍历所有调度情况。人工审查仍然是证据链的一部分,因为架构尚未变成一种 lint。
这正是 AAP 所鼓励的纪律:准确说明声明的内容,明确支撑它的证据,并让其局限性保持可见。
当保障包中的文档能够形成一个相互连接的图,而不是一堆仪式性的文件时,它才真正有用。
requirement
|
v
implementation unit
|
v
changed code
|
v
verification command
|
v
test, analysis, or benchmark result
|
v
assertion
|
v
gate decision
审查者应该能够双向遍历这个图。从某项需求出发,他们可以找到声称满足该需求的实现和证据。从某个发生变更的同步原语出发,他们可以找到批准这项变更的需求,以及用于验证它的检查。
缺失的边本身就是有价值的信息。没有证据支撑的关键需求是不完整的。没有关联任何声明的测试可能无关紧要。没有映射到任何已授权单元的变更文件,可能意味着范围发生了扩张。
当分配的任务范围过于宽泛,以至于模型可以在工作过程中重新定义成功时,AI 智能体编码最为危险。
“改进运行时架构”并不是一份可执行的契约。它允许近乎无限的重新解释。
DAG-TOML 将实现过程表示为由有边界的单元构成的有向无环图。每个单元都可以包含:
一个具体目标;
依赖关系;
允许创建或修改的文件;
以及供后续单元使用的输出。
U01: establish provider-neutral error taxonomy
└─ U02: implement retry classification
└─ U03: add bounded retry wrapper
└─ U04: verify retry accounting
└─ U05: approve release gate
与普通检查清单相比,这种图具有多项优势。
首先,它明确规定了顺序。在重试行为尚不存在之前,AI 智能体无法令人信服地验证重试计数。
其次,它能揭示可以并行开展的工作,而不会凭空假定任务之间相互独立。只有当依赖边允许时,两项任务才能并发执行。
第三,它建立了范围边界。如果某个单元只授权修改 provider 适配器和测试,那么未经要求便重写运行时状态模型的行为,就会成为可检测的范围扩张。
第四,它为失败提供了明确位置。某个门禁可以因为特定单元缺少证据而失败,而不是由 AI 智能体含糊地报告“某些测试仍需关注”。
这无法阻止 AI 智能体做出糟糕的修改,但可以让这项修改更容易被归类为未经授权、缺少支撑或尚未完成。
这是该档案的预期用途,但并不意味着当前每个发射器都能生成内容丰富的计划。默认的 agent-assurance-dsrs 演示只会发射一个已完成的单元:它没有依赖边,文件范围也是空的。除此之外,我们使用一份手工编写、包含 34 个单元的实现 DAG 来记录并部分约束其开发。前者演示运行时发射,后者演示多单元规划。不应将二者描述为同一种能力。
agent-assurance-dsrs 实际实现的内容agent-assurance-dsrs 是一个由八个 crate 组成的 Rust 工作区:
dsrs-core 提供类型化示例、预测、签名、模块 trait、运行上下文、回调、批处理、参数遍历和状态持久化。
dsrs-lm 提供 LM 边界、结构化适配器、与 provider 无关的错误、缓存、使用量记录、重试处理、OpenAI 和 Anthropic 客户端、推理模块、工具、流式处理,以及可选的原生进程沙箱。
dsrs-evaluate 执行顺序评估并记录指标结果。
dsrs-optimize 实现 few-shot、ensemble、COPRO、MIPROv2、GEPA 和 SIMBA 优化接口。
dsrs-retrieve 提供精确余弦检索、LSH、ColBERT 风格检索和 HTTP 向量存储检索。
dsrs-datasets 提供数据集加载,以及 HotPotQA、GSM8K 和 MATH 的解析器。
dsrs-assurance 将评估数据和运行事件映射为保障 sidecar。
dsrs-cli 将各个部分连接起来,用于完全隔离环境以及可选的真实 provider 演示。
网络、异步和原生沙箱行为默认仍处于关闭状态。专用 CI 通道会对它们进行测试,同时避免常规工作区构建依赖提供商访问权限、Tokio 或平台特定的沙箱库。
默认演示使用确定性的 EchoLm 和 ExactMatchMetric 评估一个固定的 Predict 程序,为 MIPROv2 搜索和 LSH 检索使用同一个运行上下文,单独解析 SSE,并记录调用方声明的能力标签,而不是根据运行事件推断这些标签。另有一个使用凭证的独立工作流,用于测试真实的 OpenAI 调用,并在完成配置时测试 Anthropic 调用;随后运行在线演示并验证其伴随文件。
当前的生成器会写入八份 TOML 文档:
它还会写入原始评估 JSON 和运行事件 JSON。适配器契约包含声明式元数据(其中的沙箱、网络和时钟字段并非来自演示的观测结果)。威胁模型和回滚计划属于更广泛的配置体系,但当前这条运行时路径尚不会生成它们。
这是一个可运行的生成基础设施,并非完整保障论点的证明。它表明,评估结果可以转化为结构化、相互关联的伴随文件,同时运行时 API 仍可独立于文档序列化。仅凭这一点,并不能证明所有权设计质量、unsafe 健全性、并发架构或生产就绪程度。
该代码库的 CI 会检出固定提交版本的 agent-assurance,构建其 Rust 和 Go 验证器,生成演示伴随文件,并使用两种实现验证 TOML 包。
这很有价值。生成器和验证器属于不同的代码库,验证契约固定到特定版本,并且两种实现必须对文档的合规性达成一致。
但仍须准确说明这条边界。不同文档类型的覆盖程度各不相同;有些文档会接受专门的语义检查,另一些则接受共享模式和跨文档检查。验证器不会重新运行评估,不会判断基准测试是否具有代表性,不会确认某项 unsafe 证明是否健全,也不会判定所引用的测试是否确实支撑相关工程主张。
当前的门禁决策同样由 dsrs-assurance 生成。它的通过或失败值取决于记录的评估是否达到阈值。外部验证器可以拒绝格式错误或违反不变量的门禁文档,但不会独立重新计算该语义决策。
因此,生产环境的验收系统还需要另一条边界:
生产者生成证据和建议决策
|
v
受保护的 CI 重新运行必要检查
|
v
独立验证器检查包的合规性
|
v
策略评估必要主张和例外
|
v
在需要时由人工审批处理剩余的判断事项
最重要的运维规则是:实现 AI 智能体不能在同一个信任域内削弱自己的阈值、替换验证策略并批准结果。
agent-assurance-dsrs 当前会根据生成的内容派生多个哈希值:
raw_input_hash 覆盖序列化后的评估结果;
bundle_hash 覆盖断言记录;以及
evidence_root 根据一条带标签、预先计算哈希的 assertion-bundle.bundle_hash 记录派生。
实现测试会根据生成文件的内容重新计算这些值;外部验证器检查它们的格式和不变量,而不是重新计算整个包的哈希,并且 evidence_root 也不是每一份伴随文件的哈希。在这些限制范围内,哈希有助于检测意外修改,并约束其所覆盖内容中的引用关系。
但这并不会让自行生成的包变得可信。一个削弱证据并重新生成所有文档的 AI 智能体,依然可以生成一组新的、内部一致的哈希。只有当预期哈希存储在生产者无法改写的位置时,例如受保护的 CI 记录、签名证明、透明度日志或由独立主体控制的发布门禁中,篡改证据才具有实际意义。
哈希回答的是“与某个锚定值相比,这些字节是否发生了变化?”,而不是“这是否是正确的测试?”或“这个设计是否安全?”
最有用的 AAP 策略应当是局部且具体的。对于 Rust 项目,如果能够更诚实地检查范围更窄的主张,就应该避免使用“线程安全”或“生产就绪”这类泛化表述。
全面禁止 .clone() 会适得其反,因为克隆 Arc 或较小的配置值可能完全合理,而在热循环中克隆大型载荷则可能破坏预期的性能模型;二者之间的差异,恰恰属于绿色构建无法提供的判断。
项目可以要求:对指定热路径中新增的 clone 给出理由;使用计数分配器、DHAT 或同类工具测量内存分配;针对载荷复制进行基准对比;确认所有权变更不会破坏公共 API 契约;以及当 clone 被用来回避更深层的所有权重新设计时,进行明确审查。
编译器只能证明 clone 是合法的。证据应当证明其成本和设计后果是否可以接受。
Arc<Mutex<T>> 有时确实是正确的设计。但它不应成为未经说明的默认选择;一旦它成为默认选择,设计就已经用一种在负载下更难审计的并发模型,取代了所有权推理。
相关主张可以涵盖:为什么状态需要共享所有权;是否考虑过所有权转移或通道;锁的作用域是否有明确边界;同步锁护卫是否可能跨越 .await 存活;使用 std::sync::Mutex 时如何处理锁中毒;以及在目标工作负载下的锁争用情况。
静态检查、Loom 模型、集成测试和基准测试分别支撑这一论证的不同部分;任何一种都不应被描述成能够证明全部内容。
手动编写 unsafe impl Send 或 unsafe impl Sync,就是在代码中写下一项证明义务。
严肃的策略可以要求:记录不变量;链接到每个相关字段;在适用时提供 Miri 或模型检查结果;通过源码扫描展示完整的 unsafe 范围;以及由指定人员审批。如果缺少必要的审查或证据,门禁就应失败。
unwrap() 并非在所有场景下都是错误的。在测试中,或在前置条件由静态机制控制的初始化路径中,它可能是合理的。但在提供商解析器、流式处理循环、库边界或长期运行的服务路径中,它可能把格式错误的输入转化为服务中断。
有用的规则应限定适用范围:
测试可以使用 unwrap();
不可变的启动配置可以允许有记录的例外;
库和运行时路径必须使用类型化错误传播;
每个例外都要标明其位置和前置条件;以及
代码库检查需要记录策略是否得到满足。
这些是团队可以通过 AAP 表达的主张示例,并不是当前 DSRs 生成器会自动执行的检查。
对 AI 生产力主张最有力的质疑来自经济层面。Token 支出只是其中一个组成部分。更有用的核算模型包括:
获得可接受成果的成本 =
推理和编排成本
+ CI 和基础设施成本
+ 人工审查成本
+ 修复和重新测试成本
+ 预期事故损失
如果要将预期事故损失视为一个数值,而不只是一个提醒,就需要明确的概率和影响模型。重点并不是每个团队都能精确计算它,而是忽略运维风险并不会让风险归零。
agent-assurance-dsrs 已经会生成 cost-record 伴随文件,但其当前内容较为有限:它记录证据运行次数,以及一个值为零的计算时间占位符,并注明尚未测量实际耗时。当前它尚未记录 Token 成本、审查人员工时、修复循环或事故风险敞口。
我们工作中的一个内部数据点说明了为什么这些缺失字段十分重要,但它不足以支撑宽泛的生产力主张。在包含 34 个单元的 DSRs 实现 DAG 中,31 个单元达到完成状态,U32 被有意延期,U33–U34 仍处于待处理状态。最初包含 18 个单元的开发工作,只有在通过逐单元的 Codex 和 Grok 审查门禁后才完成;审查发现了多项缺陷,其中包括五个具体问题:NaN 奖励污染、可能把一个请求的响应返回给另一个请求的缓存哨兵、在 JSON 无效后仍执行工具、错误的集成平局裁决,以及某项保障主张超出了其证据所能证明的范围。后续沙箱审查又发现三个故障时放行缺陷,并将其修复为故障时关闭。其中两项修复与 U31 的五个后续修复或披露提交存在重叠。U31 的文件系统作用域拉取请求在两个修订版本中还产生了四次失败的 CI 工作流运行,之后才最终转为绿色。
从首个 U02 提交到初始批次合并,可观察到的实际时间窗口约为 6.1 小时;U31 从拉取请求创建到合并约为 3.2 小时。这些并非审查者投入的工时:它们没有区分人工投入与并行执行的 AI 智能体,也不是投资回报率基准。它们记录了审查与返工,而如果度量止步于生成代码或首次编译,这些工作就会从记录中消失。
因此,成本核算显然是一个有待扩展的方向,而不是一项已经完成的功能。目标指标应该是实现一个被接受且有证据支撑的结果所需的成本,而不是每行生成代码消耗的 token 数量,也不是首次编译所需的分钟数。
团队不必从第一天起就对整个开发生命周期进行建模。
可以先从一类反复产生审查债务的变更入手,例如并发、提供方适配器、授权、迁移、不安全边界或性能敏感型代码。
定义一组精简且范围明确的声明:
no_unreviewed_unsafe
no_sync_lock_guard_across_await
panic_policy_satisfied
latency_budget_preserved
all_requirements_traced
rollback_path_verified
将这些声明绑定到团队已经信任的工具:cargo test、针对性的 Clippy lint、Miri、Loom、模糊测试、Criterion、依赖项审计、集成测试以及仓库专用检查。
在受保护的 CI 中运行这些检查。记录准确的命令、版本、输入、输出和哈希值。独立验证制品包。对于策略变更和高风险越权操作,要求由外部主体作出决定。
最后,度量返工情况。记录未通过的门禁、审查时间、修复时间,以及 AI 智能体在哪些任务类别中起到了帮助或产生了负面影响。某些工作会被证明保障成本低,而且使用 AI 智能体确实更快。另一些工作则会表明,由人类主导实现仍然是更好的工程决策。
这两种结果都很有价值,因为它们都用证据取代了直觉。
Rust 开发者本就处在一种强调显式证明义务的文化中。编译器检查类型系统能够表达的内容;测试、模型检查、基准测试、审查和运维经验则分别覆盖类型系统无法表达的不同部分。
通过 AAP 使用的 DAG-TOML 技术栈,将这种规范延伸到了语言层之上。它可以把一项需求与一个有边界的工作单元、变更后的代码、验证结果、断言和发布决策连接起来。它可以让缺失的证据和未经授权的范围变更清晰可见。它还可以记录接受该制品包的策略和验证器版本。
它无法判断架构是否优雅、工作负载能否代表生产环境、不安全代码的证明是否可靠,也无法判断需求本身是否正确。这些限制应该始终得到明确强调,因为一旦允许保障证据声称超出其实际证明范围的结论,保障就会沦为营销话术。
目标不是证明 AI 辅助开发始终更快,而是不再把首次构建成功当作速度度量的终点。
在 agent-assurance-dsrs 中,我们正在构建这一未来的一个具体组成部分:一个 Rust 运行时,它能够生成可供审查的保障边车,同时避免把治理 schema 塞进核心类型。DAG-TOML 与 Agent Assurance Profile 草案共同将这些边车与计划、证据、成本和门禁连接起来。团队仍然需要自行提供策略、受保护的执行边界以及工程判断。
与其询问 AI 智能体听起来是否自信,或者补丁是否碰巧能够通过编译,这是一项可信度更高的标准。
真正重要的问题是:它的声明能否经受住独立受控证据的检验。
若要采取进一步措施,你可以考虑屏蔽此人和/或举报滥用行为。