技术文章

Codex 工作流实战:缺陷复现、回归测试与 AGENTS.md

用一个关键风险未解决却得到 95 分的真实缺陷,说明 Codex 怎样复现问题、修改规则和验证交付。附可下载的模块、6 个回归测试、AGENTS.md 示例,并说明与 TDD 的区别。

大家好啊,我是 jianpeng。今天和大家聊一下 Codex 工作流:怎样从一个能复现的缺陷,走到有测试依据的修复。

我用本站任务检查工具的一次修改来讲:旧版里,一项关键风险没有解决,总分却能达到 95。下面先看错误怎样出现,再看回归测试怎样把它留住。你可以下载文中的模块和测试,用 Node.js 22 在本地重跑,不需要本站完整仓库。

缺陷复现:为什么凭据边界未确认,仍然得到 95 分?

本站旧版 AI 工作流体检有 20 道题,每题 0–3 分。把“凭据与敏感信息边界”设为 0,其余 19 题设为 3,就会得到 19 × 3 ÷ 60 × 100 = 95,界面给出“可验证”。关键风险虽然另列,但很高的总分会掩盖这个尚未解决的问题。

我想修的是这个判断方式。因此,工具改为围绕一次任务填写状态和依据,在报告中逐项保留未确认的问题。你可以打开AI 编程任务说明与检查:把其他项填为“已确认”并写明依据,再把凭据边界设为“待核实”,检查它是否仍出现在待处理事项中。

给 Codex 的任务说明,要写到什么程度?

我会把错误输入、预期结果和修改边界放在同一份说明里。这个案例可以这样交代:

问题:其余检查都通过时,单个凭据风险会被综合分数掩盖。
目标:取消综合分数,导出逐项状态与待处理事项。
输入:任务类型、目标、修改范围、限制、检查状态和证据位置。
状态:已确认 / 待补充 / 不适用 / 待核实。
验收:即使其他项已确认,凭据边界待核实时仍在报告中出现。
补充:已确认但没有依据,需要补充;不适用需要写原因。
边界:不上传填写内容,不调用模型,不把填写记录当作自动审计。
交付:说明改了什么,运行了哪些检查,还有哪些没有验证。

这已经能指向规则、页面和导出功能。Codex 开始修改前,我还会让它先找到相关函数与调用方;如果问题在共享规则里,就在那里修复,避免只改按钮文案或某一处页面显示。

检查代码差异:未解决的问题有没有被保留下来?

本站把任务数据、可用状态、待处理项和 Markdown 导出放在 task-checklist.js,界面模块负责输入、会话保存和复制下载。规则可以在 Node 中独立运行,浏览器交互另行检查。

// 规则缩写:没有依据时,“已确认”也不能悄悄消失。
if (!entry.evidence.trim()) {
  return [{ ...check, reason: '补充依据或证据位置' }];
}
if (['待补充', '待核实'].includes(entry.status)) {
  return [{ ...check, reason: entry.status }];
}

看 diff 时,我关注四件事:是否还在计算综合分数;导出是否列出待处理项;切换任务类型是否误删已填内容;是否出现了不需要的网络请求。代码能执行,只回答了其中很小的一部分。

下载示例:用一个回归测试检查凭据风险

先把任务规则模块和回归测试文件下载到同一目录,再运行:

node --test task-checklist.test.mjs

当前文件包含 6 个用例,覆盖空任务、单项凭据风险、缺少依据、切换任务类型、损坏或过长的数据,以及没有会话记录时的初始化。成功时,测试摘要应显示 tests 6、pass 6、fail 0。

如果只想看最关键的一项,把下面代码另存为同目录下的 regression-demo.mjs,再运行 node regression-demo.mjs:

import assert from 'node:assert/strict';
import { activeChecks, emptyTask, pendingItems } from './task-checklist.mjs';

const task = emptyTask();
for (const check of activeChecks(task.type)) {
  task.checks[check.id] = { status: '已确认', evidence: 'evidence/test.md' };
}
task.checks.secrets = { status: '待核实', evidence: '模型端点资料政策尚未确认' };
const pending = pendingItems(task).map(item => item.id);
assert.deepEqual(pending, ['secrets']);
console.log('待处理项:' + pending.join(', '));

预期输出是 待处理项:secrets。示例中的证据路径只是测试数据。如果实现错误地忽略这项风险,断言就会失败;它检查的是可观察的结果。

在本站仓库里,我还会运行 npm run check。这条命令依赖完整项目,下载两个示例文件后不用运行它。规则测试通过后,浏览器里的填写、切换、刷新恢复、复制失败回退和下载仍需分别检查。

这算 Codex TDD 工作流吗?

这篇案例能证明的是缺陷复现与回归验证。现有记录不足以确认当时先写测试、再改实现,所以我不把它称作完整的 TDD 实测。

如果希望让 Codex 按测试驱动开发推进,可以把顺序写进当前任务:先补一个表达预期行为的测试,在旧实现上运行并确认它因目标缺陷失败;再做最小修复,让同一个测试通过;最后整理代码并重跑相关测试。保留每一步的实际命令与结果,尤其不要把依赖缺失、路径错误造成的失败当成“成功复现”。

测试的价值在于约束结果。只检查实现里用了哪个函数名,或把新实现的每一行再抄进断言,都很难防住原来的问题。想把测试、工具调用和权限放到同一套流程里理解,可以继续看Harness 怎样组织 Agent 的执行与验证。

AGENTS.md 写什么,才能让下一次任务用得上?

我把反复适用的约束放进 AGENTS.md,把单次任务的输入、日志和取舍留在任务记录里。下面是适用于本站的简化示例,换到你的仓库时需要替换路径和命令:

修改生成页面时,编辑 content/ 中的数据或生成器,再重新生成。
修改前查看工作区差异,保留已有改动。
规则改动运行对应回归测试;交付前运行 npm run check。
交互改动在真实浏览器验收,并记录未覆盖的路径。
不要在仓库、示例或日志中写入密钥。

按 OpenAI 的说明,Codex 会读取从项目根目录到当前工作目录这一路上的指导文件,更深目录的规则可以覆盖上层。因此发现约束没有按预期生效时,也要检查工作目录和附近的指导文件。常驻说明保持简短,可复用的多步流程再交给相应 Skill,不必为了一个小修复新建一套流程。需要接入更低成本的模型时,见Codex 接入 DeepSeek Flash:配置、API 价格与费用计算。

如果接下来还想调整模型供应商,可以继续看Codex 接入 DeepSeek 的配置与费用计算。无论使用哪个模型,先用一个明确的缺陷和一个会失败的测试界定任务,再看它能否交付。

参考链接