name: verification-protocol description: 独立验证协议 - 消除自我证明 version: 1.0.0 applies_to: [all-agents] priority: critical
验证协议 - 消除自我证明
目的
问题: 代理自己验证自己的工作,并且默认总是返回 success: true。
解决方案: 由不同的代理进行独立验证,该代理不信任原始代理的声明。
规则: 只有当证据证明所有完成标准都满足时,verified=true。
核心原则
永远不要验证自己的工作。
总是用独立证据进行验证。
除非证明为真,否则假设声明为假。
没有证据就阻止完成。
验证协议
第1步:任务完成声明
代理声称任务已完成,并提供:
{
"task_id": "task-123",
"claimed_outputs": ["/path/to/file.ts", "/path/to/test.ts"],
"completion_criteria": [
"file_exists:/path/to/file.ts",
"no_placeholders:/path/to/file.ts",
"typescript_compiles:/path/to/file.ts",
"lint_passes:/path/to/file.ts",
"tests_pass:/path/to/test.ts"
]
}
第2步:请求独立验证
协调器发送给独立验证代理(不同的代理)。
第3步:验证执行
独立验证代理用实际证据检查每一个标准:
file_exists → fs.stat(path) && size > 0
证据:/path/to/file.ts, 1,247 字节,修改于 2025-12-02T14:30:00Z
no_placeholders → 扫描 TODO, TBD, FIXME, [INSERT]
证据:未发现占位符
typescript_compiles → npx tsc --noEmit [file]
证据:编译成功,0 错误
lint_passes → npx eslint [file]
证据:0 个 linting 错误
tests_pass → npm test -- [file]
证据:15 个测试通过,0 个失败
第4步:返回验证结果
{
"verified": true,
"evidence": [
{
"criterion": "file_exists:/path/to/file.ts",
"method": "fs.stat(path) && size > 0",
"result": "pass",
"proof": "文件:/path/to/file.ts, 大小:1247 字节"
},
// ... 更多证据 ...
],
"failures": [],
"verifier_agent_id": "independent-verifier-1",
"timestamp": "2025-12-02T14:30:00Z"
}
第5步:任务状态更新
verified=true→ 任务标记为完成,记录证据verified=false→ 任务返回给代理并附带失败列表- 代理有3次机会修复并重新提交
- 3次失败后 → 升级到人工审核
验证方法
文件验证
方法: fs.existsSync(path) && fs.statSync(path).size > 0
证据: 文件路径,字节大小,最后修改时间戳
失败触发器:
- 文件不存在
- 文件为空(0字节)
- 文件无法访问(权限错误)
占位符检测
方法: Regex 扫描 TODO, TBD, FIXME, [INSERT], [IMPLEMENT] 证据: 占位符数量和行号 失败触发器:
- 发现任何占位符(不是“看起来足够完整”)
- 不完整的实现标记仍然存在
TypeScript 编译
方法: npx tsc --noEmit [file]
证据: 编译器输出,错误数量,错误详情
失败触发器:
- 编译错误(任何类型不匹配,缺少导入)
- 类型检查失败
Linting
方法: npx eslint [file] --format json
证据: Lint 输出,错误/警告数量
失败触发器:
- ESLint 错误(不是警告)
- 代码风格违规
测试执行
方法: npm test -- [file] --run
证据: 测试输出,通过/失败数量,覆盖率
失败触发器:
- 测试未通过
- 测试文件不存在
- 测试数量少于预期
API端点验证
方法: HTTP请求到端点,检查状态码和响应结构 证据: 状态码,响应时间,响应体样本 失败触发器:
- HTTP 404, 500, 或超时
- 意外的响应格式
证据要求
每次验证都必须产生证据
| 标准 | 证据类型 | 示例 |
|---|---|---|
| file_exists | 文件路径,大小,时间戳 | /src/lib/file.ts, 2,541 字节,2025-12-02 14:30:00 |
| no_placeholders | 扫描结果 | 未发现占位符 或 发现2个:第15行,第42行 |
| compiles | 编译器输出 | 0 TypeScript 错误 |
| lint_passes | Linter 输出 | 0 错误,2 警告 |
| tests_pass | 测试结果 | 15 通过,0 失败 |
| endpoint_responds | 状态码 + 响应 | 状态 200,响应时间 45ms |
禁止模式
❌ 自我证明
// 错误 - 代理给自己打分
return { verified: true, message: "I completed it" };
❌ 假定成功
// 错误 - 实际上没有检查
if (claimedFile) {
return { verified: true }; // 没有证据!
}
❌ 跳过检查
// 错误 - "这个检查很慢,现在跳过"
if (criterion === 'tests_pass') {
return { verified: true }; // 永远不要跳过检查
}
❌ 宽松验证
// 错误 - "看起来差不多"
if (output.includes('success')) {
return {
verified: true
}; // 没有证据!
}
✅ 好的验证
// 正确 - 实际收集证据
const result = await fs.stat(filePath);
if (result.size > 0) {
return {
verified: true,
evidence: [{
criterion: 'file_exists',
proof: `文件大小:${result.size} 字节`
}]
};
}
失败处理
验证失败时
代理收到详细的失败报告:
{
"verified": false,
"failures": [
{
"criterion": "tests_pass:/tests/unit/feature.test.ts",
"reason": "测试执行失败",
"proof": "预期10个测试通过,3个失败"
}
],
"retry_count": 1,
"max_retries": 3
}
代理必须解决问题
- 阅读失败详情
- 修复根本问题(而不是验证)
- 重新提交验证
- 最多重复3次
3次失败后
任务升级到人工审核:
{
"status": "escalated_to_human",
"reason": "验证失败3次",
"failures_history": [...]
}
示例
好的示例:完整的文件验证
任务: 代理声称文件已创建并准备部署
收集的证据:
✓ file_exists:/src/lib/agents/new-agent.ts
大小:3,847 字节,创建于 2025-12-02 14:30:00
✓ no_placeholders:/src/lib/agents/new-agent.ts
扫描发现0个 TODO/TBD/FIXME 标记
✓ typescript_compiles:/src/lib/agents/new-agent.ts
tsc --noEmit 完成成功
✓ lint_passes:/src/lib/agents/new-agent.ts
eslint: 0 错误,0 警告
✓ tests_pass:/tests/new-agent.test.ts
npm test: 12 通过,0 失败
结果: verified: true ✓ 所有证据确认完成
坏的示例:不完整的文件验证
任务: 代理声称功能已完成
收集的证据:
✗ file_exists:/src/lib/features/new-feature.ts
文件未找到:ENOENT: 没有这样的文件或目录
✗ tests_pass:/tests/features/new-feature.test.ts
测试文件未找到:ENOENT: 没有这样的文件或目录
✗ typescript_compiles:/src/lib/features/incomplete.ts
编译失败:缺少返回类型(第42行)
结果: verified: false ✗ 多个标准失败,代理必须修复
在你的代码中实现
导入并使用独立验证器
import { independentVerifier } from '@/lib/agents/independent-verifier';
// 不要直接返回成功
// 要调用独立验证器
const result = await independentVerifier.verify({
task_id: 'my-task-123',
claimed_outputs: ['/path/to/file.ts'],
completion_criteria: [
'file_exists:/path/to/file.ts',
'no_placeholders:/path/to/file.ts',
'typescript_compiles:/path/to/file.ts'
],
requesting_agent_id: this.agent_id
});
// 返回验证结果(而不是你自己的评估)
return result;
在协调器中
// 在标记任务完成之前:
const verification = await independentVerifier.verify({
task_id: task.id,
claimed_outputs: task.outputs,
completion_criteria: task.criteria,
requesting_agent_id: task.agent_id
});
if (!verification.verified) {
// 将任务返回给代理进行修复
task.status = 'verification_failed';
task.failures = verification.failures;
task.retry_count++;
if (task.retry_count >= 3) {
task.status = 'escalated_to_human';
}
return;
}
// 只有验证证据后才标记为完成
task.status = 'complete';
task.verification = verification;
健康端点用于验证
端点: GET /api/health
状态: ✓ 工作
用途: 基本系统健康检查
端点: GET /api/health/deep
状态: ✓ 工作
用途: 综合依赖检查
端点: GET /api/health/routes
状态: ✓ 工作
用途: 验证所有API路由是否可访问
所有健康端点返回可验证的系统状态证据。
成功指标
实施验证协议后:
| 指标 | 之前 | 之后 |
|---|---|---|
| 未经证据验证的任务 | 100% | 0% |
| 接受虚假完成 | 未知 | 0% |
| 有证据的完成声明 | 0% | 100% |
| 自动升级到人工 | N/A | 发生在3次失败后 |
| 审计跟踪完整性 | 部分 | 完整,有证据 |
关键规则
1. 永远不要验证自己的工作
2. 总是使用独立验证器
3. 总是提供证据
4. 永远不要假定成功
5. 没有证据就阻止完成
6. 3次失败后升级
状态: 生产就绪(v1.0.0) 最后更新: 2025-12-02 关键: 是 - 没有证据就阻止所有任务完成