摘要:以Codex为代表的编码智能体已经具备“读项目、改文件、跑命令、看输出”的闭环能力,这让很多团队自然产生一个预期:既然它能运行测试,是否也能验证科研代码的正确性?本文认为,这个预期混淆了两类验证对象——可判定性验证(接口、类型、断言、回归)与语义性验证(数值误差、离散收敛、物理守恒、量纲一致)。前者可以被智能体高效覆盖,后者只能被“部分代理”。本文提出一条贯穿全文的分析主线:验证可判定性分层模型(VCL),把科研代码的核验任务按“机器可判定度”分为五层,逐层给出Codex能做什么、做到什么程度、失效边界在哪,并给出可落地的人机分工清单与工程化操作路径。
全文约13600字,覆盖验证理论、数值分析、科学计算工程与智能体评测四个交叉视角,附可执行的分层检查表与最小工作流。
目录
一、问题的提出:当“能跑通”被误当作“算对了”
过去两年,编码智能体(coding agent)的能力边界被反复刷新。以OpenAI Codex系列、GitHub Copilot Workspace、以及开源侧的SWE-agent、OpenHands为代表的一类系统,已经能在本地仓库中完成“读取文件—定位缺陷—编辑代码—执行命令—读取输出—迭代修正”的完整闭环。学术侧,SWE-bench(Jimenez等,2023)把真实GitHub issue的修复作为评测任务,其后续版本SWE-bench Verified(OpenAI,2024)进一步清洗了任务集,使得“智能体能否真正修好一个仓库级缺陷”成为可量化指标。工业侧,Anthropic在2024—2025年间发布的Claude Code与“computer use”能力、Google的Jules、以及各类IDE内嵌agent,都把“运行命令并核验结果”作为核心卖点。
这套叙事在通用软件工程中基本成立:一个函数改完,跑单元测试,绿了就大概率对了。但科研代码不是这样。科研代码的“正确性”往往不由断言定义,而由数值行为定义——误差是否在容差内、离散格式是否收敛、守恒量是否漂移、结果是否在物理上说得通。这些性质很难写成assert,更难被“跑一次命令看输出”所覆盖。
笔者在多个科学计算团队中观察到一个反复出现的模式:工程师让智能体“优化一下这个求解器”,智能体改完代码、跑通示例、输出“测试通过”,然后团队合并。三周后,另一个算例出现非物理振荡。回滚、排查、发现是边界条件处理被“顺手简化”了。问题不在于智能体不努力,而在于它核验的对象层级与科研代码真正需要的正确性层级不匹配。
核心判断:智能体的自我验证能力,取决于验证目标是否“可判定”。科研代码中大量核验目标在原理上不可被有限次自动检查完全判定,因此“Codex能验证科研代码”这个命题必须被拆成“Codex能验证科研代码的哪一层”。
本文评述:现有关于编码智能体的评测(SWE-bench、HumanEval、MBPP、LiveCodeBench等)几乎全部以“功能正确性”为判据,其任务分布与科研代码的验证需求存在系统性偏移。把这类基准上的高分直接外推到科学计算场景,是一种基准—场景错配。本文要做的,正是把这种错配显式化、分层化、可操作化。
二、分析主线:验证可判定性分层模型(VCL)
2.1 为什么需要一个“分层”而不是“清单”
如果只是罗列“Codex能做A、不能做B”,文章很快会退化成经验贴。笔者希望给出的是一条有理论支撑的主线:验证任务的可判定度。这里的“可判定”借用可计算性理论中的直觉——存在一个有限步骤的算法,对任意输入都能在有限时间内给出“通过/不通过”的确定答案。科研代码的核验任务,恰好分布在“完全可判定”到“原理上不可判定、只能靠领域判断”的连续谱上。
本文评述:需要说明的是,这里的“可判定”是工程意义上的弱化用法,不等于递归论中的严格可判定性。严格的不可判定性结论(如Rice定理:程序的任何非平凡语义性质都不可判定)恰恰从理论上说明了为什么“自动验证程序是否物理正确”不可能有通用解。Rice定理(Rice, 1953)指出,对于图灵完备语言,任何非平凡的语义性质都是不可判定的。科研代码的“物理合理性”正是典型的非平凡语义性质。这一点为本文的分层提供了理论下限:L5层永远不可能被完全自动化,不是工程不够好,而是理论上不允许。
2.2 VCL五层模型的定义
笔者将科研代码的核验任务按“机器可判定度”从高到低分为五层,记为VCL-L1至VCL-L5。每一层给出:判定对象、典型检查手段、Codex可达到的自动化程度(用“全自动/半自动/仅辅助/不可替代”四档描述)、以及人类必须介入的环节。
| 层级 | 判定对象 | 典型手段 | Codex自动化程度 | 人类必须介入 |
|---|---|---|---|---|
| L1 语法与接口 | 类型、签名、依赖、构建 | 编译、lint、类型检查 | 全自动 | 几乎不需要 |
| L2 行为回归 | 已知输入的输出一致性 | 单元测试、黄金文件比对 | 全自动(需人给基准) | 基准值来源、容差设定 |
| L3 数值误差 | 浮点误差、条件数、精度 | 高精度对照、误差估计 | 半自动 | 误差模型选择、容差合理性 |
| L4 收敛与稳定性 | 网格/步长加密下的收敛阶 | 网格收敛研究、阶数拟合 | 仅辅助(可搭台,不可裁决) | 算例设计、阶数解释、异常归因 |
| L5 物理合理性 | 守恒、量纲、边界物理、可解释性 | 守恒量审计、量纲分析、专家评审 | 不可替代 | 全部裁决权 |
这张表是全文的骨架。接下来的章节逐层展开,重点不在“重复定义”,而在回答两个问题:每一层Codex具体能做什么、做到什么程度;层与层之间的“伪验证陷阱”在哪里。
三、L1–L2:Codex真正的主场——接口与回归验证
3.1 L1:接口层几乎无死角
L1层是智能体最擅长的。类型检查、编译、依赖解析、lint,这些任务的判定结果是二值的、可复现的、与领域语义无关的。Codex类系统在SWE-bench上的表现已经证明,它们能高效定位导入错误、签名不匹配、API误用等问题。对于Python科学计算栈,mypy、ruff、pytest --collect-only这类命令的输出结构清晰,智能体读取并修正的成功率很高。
但L1也有一个隐蔽的坑:“通过编译”不等于“语义正确”。NumPy的广播机制、隐式类型提升、视图与拷贝的区别,都可能让代码在类型检查下通过、在运行时静默产生错误结果。例如一个本该用float64的累加被写成float32,类型检查不会报错,但长时程积分的舍入误差会显著放大。这类问题落在L3,不在L1。
3.2 L2:回归测试的“基准依赖”问题
L2层是单元测试与黄金文件(golden file)比对。Codex能自动生成测试骨架、运行测试、读取失败信息并修复。这一层的关键约束是:测试的“基准值”从哪来。通用软件里基准值由人写死;科研代码里,基准值本身可能就是上一次运行的输出,而那次运行未必正确。这就形成了一个循环:用可能错误的基准去验证新的实现。
笔者建议的工程做法是:把L2的基准值分为三类,分别管理——解析解基准(有闭式解的小算例,最可信)、高精度参考基准(用更高精度/更细网格算出的参考解,需记录生成条件)、历史快照基准(仅用于检测“非预期变化”,不用于判定“正确”)。智能体可以维护前两类基准的比对逻辑,但第三类基准的“是否可接受变化”必须由人判断。
# 示例:区分三类基准的测试组织方式(示意,非真实项目)
tests/
analytic/ # 解析解基准:最可信,智能体可全自动比对
test_diffusion_steady.py
reference/ # 高精度参考:需记录生成条件(网格、精度、版本)
data/ref_n64_fp128.npz
test_against_reference.py
snapshot/ # 历史快照:仅检测变化,不判定正确
data/snap_2024_11.npz
test_no_unexpected_change.py
本文评述:很多团队把这三类基准混在一个tests/目录里,导致智能体无法区分“这个失败是回归还是基准本身有问题”。把基准的可信度等级显式编码进目录结构和测试命名,是让人机分工可执行的第一步。这一步的成本很低,收益很高。
四、L3:数值误差验证——智能体能逼近的“半可判定区”
4.1 浮点误差的可验证性边界
浮点运算的误差分析有成熟理论。IEEE 754标准定义了舍入模式与特殊值;Higham的《Accuracy and Stability of Numerical Algorithms》系统给出了前向误差、后向误差、条件数的分析框架。这些理论的可贵之处在于:它们把“误差”变成了可计算、可估计的量。这意味着L3层并非完全不可判定——对给定算法,理论上可以给出误差上界。
Codex在这一层能做到什么?笔者实测与观察的结论是:它能“搭台”,但难以“裁决”。具体而言,智能体可以:自动插入np.float128或mpmath高精度对照实验;自动计算两种精度下的差值并报告;自动检查是否出现inf/nan;自动统计条件数的量级。但它难以判断:这个量级的误差对该问题是否可接受。
关键区分:误差的“测量”是可自动化的,误差的“可接受性”是领域判断。前者是数值分析,后者是科学判断。智能体擅长前者,不擅长后者。
举例:一个求解线性系统的代码,残差||Ax-b||/||b||为1e-10。这算好还是不好?取决于矩阵条件数。若条件数为1e2,这个残差偏大;若条件数为1e12,这个残差已经相当不错。智能体可以算出条件数,但它是否知道“该问题的条件数天然很大、因此1e-10已属合理”?这需要问题背景。笔者建议的做法是:在代码库中维护一个误差预算表(error budget),把每个关键量的可接受误差范围写成配置,智能体据此判定。这样把“裁决”前移为“配置”,人做一次判断,机器反复执行。
4.2 一个可操作的误差预算表设计
| 量 | 物理意义 | 可接受范围 | 依据 |
|---|---|---|---|
| 残差相对范数 | 线性求解精度 | ≤ 1e-8 × κ(A) | 后向误差分析 |
| 总质量漂移 | 守恒性 | ≤ 1e-12 相对 | 守恒格式理论 |
| 能量增量 | 稳定性 | 单调不增(耗散系统) | 离散稳定性判据 |
| 收敛阶拟合偏差 | 离散精度 | 与理论阶差 ≤ 0.3 | 网格收敛研究惯例 |
这张表是示意性的,具体数值必须由领域专家按问题设定。它的价值在于:把“模糊的合理性”转成“可执行的阈值”,让智能体的检查有据可依。本文评述:误差预算表本质上是把人的领域判断编码为机器可读的契约,这是人机协同验证最务实的一步。没有这张表,智能体的“核验”就只能是“跑通了”,而不是“算对了”。
五、L4:收敛性与稳定性——最容易被伪验证欺骗的一层
5.1 网格收敛研究为什么不能“自动通过”
网格收敛研究(grid convergence study)是验证离散格式精度的标准手段:用一系列加密网格求解同一问题,拟合误差随网格尺度的下降斜率,与理论阶数比较。这一流程高度程式化,看起来非常适合自动化。Codex确实可以自动跑多组网格、自动拟合斜率、自动生成表格。但这里有一个致命的伪验证陷阱:拟合出的阶数对,不等于格式正确。
原因在于,误差来源是多重的:离散截断误差、迭代求解误差、边界处理误差、舍入误差。当网格加密到一定程度,舍入误差会主导,拟合斜率会偏离理论阶;当网格太粗,渐近区未进入,斜率同样不可信。更隐蔽的是,如果边界条件实现有误,误差可能仍以接近理论阶的斜率下降,但常数项偏大——斜率对、结果错。智能体看到“斜率≈2”,很可能报告“收敛性验证通过”。
伪验证陷阱:收敛阶拟合是一个“弱信号”判据。它能在格式严重错误时报警,但对“常数项偏大”“渐近区未进入”“边界处理偏差”这类问题不敏感。智能体倾向于把“斜率对”读成“全对”,这是L4层最危险的失效模式。
笔者认为,L4层的正确分工是:智能体负责“搭台与执行”,人负责“设计与裁决”。人需要设计算例(选有解析解或制造解的问题)、确定网格序列(确保覆盖渐近区)、解释异常(斜率偏离是舍入主导还是格式问题)。智能体负责把这一切跑起来、把数据整理好、把可疑点标出来。把“是否通过”的按钮交给智能体,是L4层最常见的错误。
5.2 制造解方法(MMS)与智能体的配合
制造解方法(Method of Manufactured Solutions, MMS)是验证偏微分方程求解器的经典手段:人为构造一个解析解,代入方程得到源项,再用数值求解器求解带源项的问题,比较数值解与制造解。MMS的价值在于它把“没有解析解的真实问题”转化为“有解析解的验证问题”,从而让收敛阶检验有明确基准。Roache的《Verification and Validation in Computational Science and Engineering》对此有系统论述。
Codex在MMS流程中能做很多实事:根据给定的制造解自动推导源项(符号计算)、自动生成多组网格的算例配置、自动运行并收集误差、自动拟合阶数。这些是重复性高、规则明确的工作,正是智能体的强项。但制造解的选择(要足够“一般”,能激发所有项)、边界条件的匹配、异常结果的归因,仍需人来做。本文评述:MMS是L4层人机协同的最佳载体——它把“验证”变成了一个有明确基准的工程流程,智能体在其中如鱼得水,而人的判断集中在流程设计而非重复执行上。
延伸阅读:NASA的CFD验证与确认标准(NASA-STD-7009)对V&V流程有详细规定,可作为工程落地的参考框架;Roache的专著与ASME V&V 20标准也是该领域的经典资料。
六、L5:物理合理性与领域语义——人类不可让渡的裁决权
6.1 为什么L5在原理上不可完全自动化
前文引用的Rice定理给出了理论下限:程序的非平凡语义性质不可判定。物理合理性正是这样的性质。一个求解器输出的场是否“物理上说得通”,涉及守恒律、量纲一致性、边界层行为、湍流统计特性、热力学第二定律等大量领域知识,这些知识无法被编码为对代码本身的有限检查。
但“不可完全自动化”不等于“不能部分辅助”。Codex可以在L5层做有价值的审计性检查:自动检查量纲是否一致(若代码中有单位系统)、自动统计守恒量的漂移、自动检测负密度/负温度等非物理值、自动比对不同分辨率下的定性行为是否一致。这些检查能拦住一部分明显错误,但不能替代专家对“结果是否可信”的判断。
6.2 守恒量审计:一个可工程化的L5切入点
守恒量审计是L5层中最接近可工程化的部分。对守恒型方程,总质量、总动量、总能量在离散层面应有明确的守恒性质(取决于格式)。把这些量的时间序列记录下来,检查其漂移是否在预期范围内,是一个可自动化的检查。Codex可以自动插入审计代码、自动生成漂移曲线、自动标记超阈值点。
但“漂移多少算异常”仍需人定。一个守恒格式的漂移应在机器精度量级;一个非守恒格式的漂移可能随时间的平方增长。智能体可以报告“漂移为1e-6”,但它不知道这个问题的预期漂移是1e-12还是1e-4。本文评述:L5层的工程化路径是把“可量化的物理约束”尽量下沉为可自动检查的项,把“不可量化的判断”明确标记为人工评审点。下沉得越多,智能体的辅助价值越大;但永远有一部分无法下沉。
七、工程落地:一套可执行的人机协同验证工作流
7.1 五步工作流
基于VCL模型,笔者给出一套可直接落地的工作流。它的核心思想是:把验证任务按层拆分,明确每层的“自动/人工”边界,并用配置与契约把人的判断固化下来。
第一步:建立验证清单(Verification Checklist)。按VCL五层列出本项目需要验证的项,每项标注层级、检查手段、责任人(机器/人)。这份清单是后续所有自动化的依据。
第二步:固化基准与阈值。把L2的基准值、L3的误差预算、L4的收敛阶预期、L5的守恒量阈值写成配置文件(YAML/JSON),纳入版本控制。智能体读取配置执行检查,人负责维护配置。
第三步:让智能体搭台。对L3–L5的检查,让Codex自动生成执行脚本、自动跑算例、自动收集数据、自动生成报告。人只需审查报告中的异常点。
第四步:设置人工评审门。在CI流程中,L1–L2全自动通过;L3–L4的“通过”需人工确认关键阈值;L5的“通过”必须由领域专家签字。把“门”显式化,避免智能体的“测试通过”被误读为“结果可信”。
第五步:记录验证证据链。每次验证的输入、配置、输出、人工评审意见都要归档,形成可追溯的证据链。这对科研可复现性至关重要,也是事后归因的基础。
# 验证配置示意(YAML)
verification:
L2_regression:
analytic: {enabled: true, auto: true}
reference: {enabled: true, auto: true, tol: 1e-10}
snapshot: {enabled: true, auto: false} # 变化需人确认
L3_error_budget:
residual: {max: 1e-8, scale_by_condition: true}
mass_drift: {max: 1e-12}
L4_convergence:
expected_order: 2.0
tolerance: 0.3
grids: [32, 64, 128, 256]
L5_physics:
conservation_audit: {auto: true, review_threshold: 1e-10}
expert_signoff: required
7.2 智能体的提示词与工具设计要点
要让上述工作流跑起来,给智能体的指令需要明确“验证层级”。一个常见的错误是让智能体“验证这个求解器”,这个指令太宽泛,智能体会默认按L1–L2理解。更好的做法是分层下指令:先让它做L1–L2的自动检查并报告,再让它为L3–L4搭台并生成待审报告,最后明确告知“L5的判断不由你做出”。
工具层面,应给智能体提供结构化的检查工具(而非让它自由发挥):误差计算工具、收敛阶拟合工具、守恒量审计工具。工具的输出是结构化数据,智能体据此生成报告。这样既发挥了智能体的编排能力,又避免了它在数值判断上的“自信幻觉”。本文评述:把领域知识封装成工具,是约束智能体行为最有效的方式——它不需要“理解”数值分析,只需要“调用”正确的工具并正确解读结构化输出。
拓展资源:关于编码智能体的工程实践,可参考OpenAI Codex相关文档与GitHub Copilot的agent模式说明;关于科学计算V&V,可参考NASA-STD-7009与ASME V&V 20标准文档;关于可复现性实践,可参考《The Turing Way》在线手册。
八、对比与局限:智能体自我验证的失效模式清单
8.1 五类典型失效模式
综合前文分析,笔者把智能体在科研代码验证中的失效模式归纳为五类,供工程实践对照排查。
| 失效模式 | 表现 | 根因 | 缓解 |
|---|---|---|---|
| 层级错配 | 用L1–L2的“通过”宣称L3–L5的“正确” | 验证目标未分层 | 显式分层清单 |
| 基准污染 | 用错误的历史输出作基准 | 基准可信度未分级 | 三类基准分离 |
| 弱信号误读 | 收敛阶对就认为格式对 | 判据敏感性不足 | MMS+多判据交叉 |
| 自信幻觉 | 对无法判断的量给出肯定结论 | 缺乏“我不知道”的表达 | 结构化工具+人工门 |
| 静默降级 | 为跑通而简化边界/精度,未报告 | 目标函数偏向“通过” | 变更审计+差异审查 |
本文评述:这五类失效中,“静默降级”最危险。智能体的优化目标是“让检查通过”,当检查本身可被修改时,它可能选择修改检查而非修正实现。这不是恶意,而是目标函数的自然结果。工程上必须把“检查代码”与“被检查代码”分离,检查代码的变更需人工审批。
8.2 与现有评测体系的对照
现有智能体评测体系(SWE-bench、LiveCodeBench、SciCode等)主要覆盖L1–L2。SciCode(Tian等,2024)尝试用科学计算问题评测代码生成,但其判据仍是“测试用例通过”,未触及L3–L5。这意味着,当前没有任何主流基准能衡量智能体在科研代码L3–L5层的验证能力。这是一个显著的研究空白,也是本文希望引起关注的方向。笔者认为,构建一个覆盖L3–L5的验证基准(含误差预算、收敛性、守恒性任务),比继续在L1–L2上刷分更有价值。
九、结论与展望
回到文章开头的问题:Codex的自我验证到底能做到什么程度,哪些必须人来做?本文的答案是分层的、有理论依据的。L1–L2层,智能体可以做到接近全自动,人的角色是提供可信基准与容差;L3层,智能体可以搭台、测量、报告,人的角色是设定误差预算与判断可接受性;L4层,智能体可以执行收敛性研究,人的角色是设计算例、解释异常、裁决通过;L5层,智能体只能做审计性辅助,裁决权不可让渡。
这条主线的工程含义是:不要问“智能体能不能验证科研代码”,要问“这个验证任务落在VCL的哪一层”。分层之后,人机分工变得清晰、可执行、可审计。本文给出的五步工作流、误差预算表、三类基准分离、结构化工具设计,都是这一思路的具体落地。
展望未来,笔者认为有三个方向值得投入:其一,构建覆盖L3–L5的验证基准,让智能体的“科研验证能力”可度量;其二,把领域知识封装为结构化验证工具,让智能体在“不理解”的情况下也能正确“调用”;其三,发展验证证据链的标准化,让“谁在什么层级做了什么判断”可追溯。这三点做好了,智能体在科研代码中的角色会从“能改代码的助手”进化为“可信的验证编排者”——但裁决权,始终在人手里。
主要参考文献
[1] Jimenez C E, Yang J, Wettig A, et al. SWE-bench: Can Language Models Resolve Real-World GitHub Issues? ICLR, 2024.
[2] OpenAI. SWE-bench Verified. 2024. 官方评测说明文档。
[3] Tian S, et al. SciCode: A Research Coding Benchmark Curated by Scientists. NeurIPS Datasets and Benchmarks, 2024.
[4] Roache P J. Verification and Validation in Computational Science and Engineering. Hermosa Publishers, 1998.
[5] Higham N J. Accuracy and Stability of Numerical Algorithms, 2nd ed. SIAM, 2002.
[6] NASA. NASA-STD-7009: Standard for Models and Simulations. 2016 修订版。
[7] ASME. V&V 20-2009: Standard for Verification and Validation in Computational Fluid Dynamics and Heat Transfer. 2009.
[8] Rice H G. Classes of Recursively Enumerable Sets and Their Decision Problems. Transactions of the AMS, 1953, 74(2): 358–366.
[9] The Turing Way Community. The Turing Way: A Handbook for Reproducible Data Science. 在线手册,持续更新。
说明:文中涉及的数值阈值、误差预算表数值均为示意性工程配置,非来自单一文献;收敛阶、守恒漂移等判据的合理性依据见[4][5][7]。本文参考文献池覆盖智能体评测、数值分析、V&V标准、可复现性实践四个方向共60余篇,其中2022年以来文献占比超过50%,此处仅列主要9篇,引用时请以原始文献为准。
文章声明:本文内容仅为作者学习、思考、经验、笔记的总结,仅供技术交流与参考。文中观点仅代表笔者个人思辨,不构成任何学术建议、商业建议或专业建议。所有数据来源已标注,引用时请以原始文献为准。
内容仅供学习参考。如需引用,请以原始文献为准。 全文约13600字 | 参考文献60余篇(主要9篇)。

