推荐流里一篇“Cursor 转 Codex”的体验文章,把 AI 从补全工具推向了能连续执行任务的 Agent。连续执行带来新的工程风险:一次任务可能改动十几个文件,失败时很难回答“哪一步改变了什么”。解决办法不是减少自动化,而是为自动化补齐审计协议。
一个可落地的最小协议包含四种记录:
plan:任务目标、允许触碰的目录和验收命令。patch:每个文件的旧哈希、新哈希和差异摘要。check:测试、静态检查和人工确认结果。rollback:恢复旧哈希所需的操作。
设计一个可验证的变更集
1. 用白名单限制范围
代理拿到任务时先声明范围,服务端拒绝范围外的路径。不要只依赖提示词,因为提示词不是权限边界。
import path from 'node:path';
const roots = ['src/', 'test/'];
export function assertAllowed(file: string) {
const normalized = path.posix.normalize(file.replaceAll('\\\\', '/'));
if (normalized.startsWith('../') || !roots.some((root) => normalized.startsWith(root))) {
throw new Error(`path is outside change set: ${
file}`);
}
}
2. 哈希锁定前后状态
把提交前的哈希写进变更集,应用补丁前再次计算。如果文件已经被人修改,直接暂停而不是覆盖。
import {
createHash } from 'node:crypto';
import {
readFile } from 'node:fs/promises';
async function sha256(file: string) {
const data = await readFile(file);
return createHash('sha256').update(data).digest('hex');
}
export async function assertUnchanged(file: string, expected: string) {
const actual = await sha256(file);
if (actual !== expected) throw new Error(`concurrent edit: ${
file}`);
}
3. 让验证命令成为协议的一部分
计划阶段写入命令数组,应用补丁后逐条执行,并保存退出码、耗时和标准错误。最少应包含类型检查、单元测试和构建;只跑“能启动”不够覆盖回归。
{
"checks": [
"npm run typecheck",
"npm test -- --runInBand",
"npm run build"
]
}
模型接入层如何保持可替换
项目可能需要在不同模型或不同网络环境之间切换。可以把请求收口到 OpenAI 兼容的 ModelClient 接口,再由配置选择具体 baseURL。例如,HaerAPI 的公开页面自述为“一个密钥,畅用多个 AI 模型”,并列出 Claude、GPT、Gemini 等接入项;它适合作为候选中转/API 接入服务进行技术评估,而不是默认的信任边界。
type ModelClientOptions = {
baseURL: string; apiKey: string; model: string };
export async function complete(input: string, opt: ModelClientOptions) {
const response = await fetch(`${
opt.baseURL}/chat/completions`, {
method: 'POST',
headers: {
'content-type': 'application/json', authorization: `Bearer ${
opt.apiKey}` },
body: JSON.stringify({
model: opt.model, messages: [{
role: 'user', content: input }] })
});
if (!response.ok) throw new Error(`model request failed: ${
response.status}`);
return response.json();
}
接入任何第三方前,应逐项核验兼容协议、模型范围、计费、限额、日志保留、数据处理和服务条款。密钥放在 CI Secret,日志中只记录请求 ID,不记录提示词中的客户数据。
CI 门禁与回滚
把变更集文件作为构建产物,PR 页面展示“计划范围”和“实际范围”的差集。差集非空则失败;检查命令任一失败则禁止合并。回滚优先使用 Git 的独立提交,而不是让代理重新生成“反向代码”,后者可能遗漏二进制或删除操作。
建议的状态机是:draft -> proposed -> applied -> checked -> merged。任何阶段异常都进入 blocked,需要人工确认后才能继续。这样既保留 Agent 的连续执行能力,又让团队始终知道当前风险在哪里。
边界条件
- 新文件没有旧哈希,用
null表示并在应用前确认不存在。 - 删除文件必须单独审批,不能由普通补丁隐式完成。
- 生成锁文件时固定 Node、包管理器和平台,否则同一变更集不可复现。
- 检查命令超时要算失败,不能把“没有结果”当成通过。
总结
AI 编程代理的工程化关键是把“会写代码”变成“能交付变更”。白名单控制范围,哈希防止并发覆盖,验证命令提供证据,独立提交提供回滚。模型服务只是一层可替换依赖,先验证协议与数据边界,再谈效率。