Harness Engineering实战防止 Agent 过早宣告完成Why Agents Declare Victory Too Early课程原文https://walkinglabs.github.io/learn-harness-engineering/zh/lectures/lecture-09-why-agents-declare-victory-too-early/0. 一句话核心Agent 系统性过早宣称任务完成因为它依据代码层面的局部信心判断而系统级正确性需要全局验证。Harness 必须用基于执行的外部验证替代 Agent 的感觉——把完成判定从主观变客观。1. 为什么 Agent 会提前交卷过度自信校准偏差Guo et al. 2017ICML证明现代神经网络置信度系统性高于准确率AI 编码 Agent 同样觉得做完了实际差得远。滑坡效应Slippery Slope代码看着还行、静态检查无误但 harness 未强制全面执行验证 → Agent 跳过实际运行/部分测试 → 每次跳过加剧信息不对称任务规范→代码实现→运行时行为持续丢失。同一模型既生成又评估会系统性过度正面评价Anthropic 2026即使人类认为不达标Agent 也会给自己打高分。2. 本课关键概念 → 代码映射概念原文落地的类 / 文件作用终止标准Termination Criteriamodel/TerminationCriterion.javastate/TERMINATION.md把什么叫做完固化为外部化、机器可读的 required 标准三层终止校验harness/gates/TerminationGate.javaSTATIC→RUNTIME→SYSTEM 层层门控低层不过不许进高层过早完成声明Premature VictoryTerminationGate.evaluate返回PREMATURE_VICTORYAgent 声称完成但标准未全过即判过早验证-确认双闸门VV Dual Gateharness/gates/VerificationValidationGate.javaVerification代码实现行为 Validation系统端到端两层都过才算完成完成优先级约束Completion Priorityharness/state/CompletionPriorityGuard.java核心未验证前禁止重构/性能/风格顺便重构是毒药生成与评估分离harness/skills/EvaluatorSkill.java独立、刻意挑剔的评估者可否决生成者过度自信声明运行时反馈信号harness/state/RuntimeSignalCollector.java应用启动/健康检查/关键路径/副作用/临时资源清理可操作错误反馈harness/skills/ActionableFeedbackGenerator.java把 “Test failed” 转成含修复步骤的反馈置信度校准偏差model/ConfidenceCalibration.java量化自报信心 vs 实际质量的系统性偏差3. 三条你必须记住的 Harness 纪律完成判定外部化Agent 不许自己宣布做完了。是否完成由TerminationGate依据运行时信号独立判定。三层缺一不可语法、行为、系统层层递进。单元测试通过只是 RUNTIME 的极小一部分不构成停止信号。核心验证前不许重构核心功能没验证通过就开始重构/优化会把隐式正确的路径改坏。注博客https://blog.csdn.net/badao_liumang_qizhi4. 项目结构与运行spring-ai-alibaba-bailian-harness-victory/ ├── pom.xml ├── src/main/java/com/badao/ai/ │ ├── SpringAiDemoApplication.java │ ├── model/ TerminationCriterion / VictoryClaim / ConfidenceCalibration │ ├── harness/ │ │ ├── gates/ TerminationGate / VerificationValidationGate 三层门控 VV 双闸门 │ │ ├── skills/ EvaluatorSkill / ActionableFeedbackGenerator 评估分离 可操作反馈 │ │ └── state/ CompletionPriorityGuard / RuntimeSignalCollector优先级 运行时信号 │ ├── service/ VictoryService 编排演示链路 │ ├── controller/ VictoryController /api/victory/demo, /report │ ├── runner/ VictoryDemoRunner 启动即演示 │ └── config/ VictoryConfig 模块化指令 ├── src/main/resources/instructions/ │ ├── AGENTS.md │ ├── docs/ termination-criteria.md / actionable-feedback.md / anti-pattern.md │ └── legacy/ SELF_APPROVAL.md 反面教材让 Agent 自己审批自己 ├── src/test/java/com/badao/ai/ 7 个测试见下 └── state/ TERMINATION.md / DECISIONS.md / HANDOFF.md 跨会话单一来源运行mvntest# 验证三层门控 / 校准 / 多层防御 / 双闸门 / 反馈 / 评估分离mvn spring-boot:runcurl-XPOSThttp://localhost:888/api/victory/demo# 看提前交卷→被捕获→强制端到端→确认胜利curlhttp://localhost:888/api/victory/report# 查看外部化终止标准5. 课后练习的落地Project 05让 Agent 自己检查自己做的对不对练习测试文件验证点1. 终止校验函数设计TerminationGateTest三层门控低层不过禁止进高层 过早完成检测 缺失标准定位2. 校准偏差测量ConfidenceCalibrationTest复杂任务正偏差、简单任务低偏差、越界拒绝3. 多层防御实验MultiLayerDefenseTest(a)仅静态/(b)单测/©完整三层过早完成比例 5→5→1捕获 4 个缺陷完成优先级CompletionPriorityTest核心未验证拒绝重构验证后允许VV 双闸门VerificationValidationTest两层都过才算完成单测过≠完成可操作反馈ActionableFeedbackTest反馈含修复步骤、比原始错误更长生成/评估分离EvaluatorSeparationTest评估者否决过度自信声明结论不随自报信心变化6. 一个完整例子密码重置功能提前交卷路径改 schema、写 API、加邮件模板、单元测试通过、声明完成。实际遗漏(1) 端到端流程未测(2) DB 迁移部分失败致 schema 不一致(3) 邮件服务配置缺失。Harness 介入TerminationGate强制三层校验 → 仅在 C1/C2 过时判PREMATURE_VICTORY列出缺失 C3/C4/C5EvaluatorSkill因缺少客观端到端证据否决生成者confidence0.95缺陷在会话内发现节省 5-10 倍后续修复成本。关键代码VictoryConfigpackage com.badao.ai.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import java.io.IOException; import java.nio.charset.StandardCharsets; /** * 终止校验相关的指令配置模块化指令风格。 * 入口概览常驻专题文档按需加载避免巨型任务说明见 legacy/SELF_APPROVAL.md。 */ Configuration public class VictoryConfig { /** 入口指令概览 硬约束完成判定外部化等 文档索引 */ Bean public String entryInstructions() throws IOException { return load(instructions/AGENTS.md); } /** 终止标准定义三层校验、门控关系、校准偏差时加载 */ Bean public String terminationCriteria() throws IOException { return load(instructions/docs/termination-criteria.md); } /** 可操作反馈设计/对比无效 vs 可操作错误反馈时加载 */ Bean public String actionableFeedback() throws IOException { return load(instructions/docs/actionable-feedback.md); } /** 反面教材让 Agent 自己审批自己 */ Bean public String selfApproval() throws IOException { return load(instructions/legacy/SELF_APPROVAL.md); } /** * 按场景组装提示词规划阶段给终止标准实现阶段给可操作反馈。 */ public String buildPromptForPhase(String phase) throws IOException { StringBuilder sb new StringBuilder(); sb.append(entryInstructions()).append(\n\n); if (plan.equals(phase)) { sb.append(【当前阶段定义外部化终止标准】先把什么叫做完拆成三层 required 标准。\n); sb.append(terminationCriteria()); } else { sb.append(【当前阶段实现验证】单元测试通过 ≠ 完成错误必须转成可操作反馈。\n); sb.append(actionableFeedback()); } return sb.toString(); } private String load(String path) throws IOException { ClassPathResource r new ClassPathResource(path); return new String(r.getInputStream().readAllBytes(), StandardCharsets.UTF_8); } }TerminationGatepackage com.badao.ai.harness.gates; import com.badao.ai.model.TerminationCriterion; import com.badao.ai.model.VictoryClaim; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import java.util.List; /** * 终止闸门Termination Gate——第九讲的核心 Harness 原语b三层终止校验/b。 * * p它把完成判定从 Agent 主观感觉外部化到 Harness输入是运行时信号而非置信度。 * 三层递进、层层门控 * ol * liSTATIC语法/静态最低成本必须通过/li * liRUNTIME运行时行为核心证据/li * liSYSTEM系统级端到端最后防线/li * /ol * 低层未全通过禁止进入高层三层全部 required 标准通过才允许声明胜利。 * 若 Agent 提前声称完成而标准未全过判为 {link Verdict#PREMATURE_VICTORY}过早完成。 */ Component public class TerminationGate { private static final Logger log LoggerFactory.getLogger(TerminationGate.class); public enum Verdict { /** 三层全部 required 标准通过 → 可确认胜利 */ VICTORY_CONFIRMED, /** Agent 声称完成但 required 标准未全过 → 过早完成声明 */ PREMATURE_VICTORY, /** 未声明完成、且尚未全部通过 */ INCOMPLETE } /** * 层门控判断能否进入目标层。 * STATIC 永远可进入RUNTIME 需 STATIC 全过SYSTEM 需 STATICRUNTIME 全过。 */ public boolean canEnterLayer(TerminationCriterion.Layer target, ListTerminationCriterion criteria) { if (target TerminationCriterion.Layer.STATIC) return true; if (target TerminationCriterion.Layer.RUNTIME) return allPassed(criteria, TerminationCriterion.Layer.STATIC); if (target TerminationCriterion.Layer.SYSTEM) { return allPassed(criteria, TerminationCriterion.Layer.STATIC) allPassed(criteria, TerminationCriterion.Layer.RUNTIME); } return false; } private boolean allPassed(ListTerminationCriterion criteria, TerminationCriterion.Layer layer) { return criteria.stream() .filter(c - c.getLayer() layer c.isRequired()) .allMatch(TerminationCriterion::isPassed); } /** * 终止判定外部化不信任 Agent 感觉 * 只有三层全部 required 标准通过才允许声明胜利 * Agent 若提前声称完成则判为 {link Verdict#PREMATURE_VICTORY}。 */ public TerminationReport evaluate(VictoryClaim claim, ListTerminationCriterion criteria) { boolean staticOk allPassed(criteria, TerminationCriterion.Layer.STATIC); boolean runtimeOk allPassed(criteria, TerminationCriterion.Layer.RUNTIME); boolean systemOk allPassed(criteria, TerminationCriterion.Layer.SYSTEM); boolean allOk staticOk runtimeOk systemOk; if (claim.isDeclaredDone() !allOk) { log.warn(【终止判定】检测到过早完成声明agent 声称完成(confidence{})但 静态{} 运行时{} 系统{}, claim.getSelfConfidence(), staticOk, runtimeOk, systemOk); return new TerminationReport(Verdict.PREMATURE_VICTORY, staticOk, runtimeOk, systemOk, missingCriteria(criteria)); } if (allOk) { log.info(【终止判定】三层全部通过确认胜利); return new TerminationReport(Verdict.VICTORY_CONFIRMED, true, true, true, List.of()); } return new TerminationReport(Verdict.INCOMPLETE, staticOk, runtimeOk, systemOk, missingCriteria(criteria)); } private ListString missingCriteria(ListTerminationCriterion criteria) { return criteria.stream() .filter(c - c.isRequired() !c.isPassed()) .map(TerminationCriterion::getId) .toList(); } /** 终止判定报告 */ public record TerminationReport(Verdict verdict, boolean staticOk, boolean runtimeOk, boolean systemOk, ListString missing) { /** 是否过早完成声明 */ public boolean premature() { return verdict Verdict.PREMATURE_VICTORY; } /** 是否确认胜利 */ public boolean confirmed() { return verdict Verdict.VICTORY_CONFIRMED; } } }VerificationValidationGatepackage com.badao.ai.harness.gates; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; /** * 验证-确认双闸门Verification-Validation Dual Gate——第九讲VV 双闸门。 * * ul * libVerification第一层验证/b代码是否正确实现了指定行为对应 RUNTIME 层。 * 单元测试通过只覆盖这一层的极小一部分无法暴露接口不匹配 / 状态传播错误 / 环境依赖。/li * libValidation第二层确认/b系统级行为是否满足端到端需求对应 SYSTEM 层。/li * /ul * 两层都过才算完成任一不过即视为未完成。 */ Component public class VerificationValidationGate { private static final Logger log LoggerFactory.getLogger(VerificationValidationGate.class); /** * 执行 VV 双闸门检查。 * * param codeImplementsBehavior 代码是否实现了指定行为Verification * param endToEndSatisfied 系统级端到端需求是否满足Validation */ public VVReport check(boolean codeImplementsBehavior, boolean endToEndSatisfied) { boolean v codeImplementsBehavior; boolean val endToEndSatisfied; if (!v) { log.warn(【Verification 失败】代码未正确实现指定行为接口不匹配 / 状态传播错误 / 环境依赖); } else if (!val) { log.warn(【Validation 失败】系统级端到端需求未满足单元测试通过 ≠ 任务完成); } else { log.info(【VV 双闸门】验证 确认均通过); } return new VVReport(v, val, v val ? OK : FAIL); } /** VV 报告 */ public record VVReport(boolean verificationPassed, boolean validationPassed, String detail) { /** 两层都过才算完成 */ public boolean bothPassed() { return verificationPassed validationPassed; } } }ActionableFeedbackGeneratorpackage com.badao.ai.harness.skills; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; /** * 可操作反馈生成器Actionable Feedback Generator——第九讲可操作错误反馈。 * * p把无效反馈如 {code Test failed}转成b含具体修复步骤/b的反馈 * 明确错在哪、怎么改。仅说错了不够Agent 会在同一处反复失败。 */ Component public class ActionableFeedbackGenerator { private static final Logger log LoggerFactory.getLogger(ActionableFeedbackGenerator.class); /** * 把原始错误转成可操作反馈。 * * param rawError 原始错误现象如 Test failed / POST /api/reset-password returned 500 * param fixHint 具体修复步骤定位线索 可执行动作 * return 形如 错误: rawError | 修复步骤: fixHint 的可操作反馈 */ public String makeActionable(String rawError, String fixHint) { String actionable String.format(错误: %s | 修复步骤: %s, rawError, fixHint); log.info(【可操作反馈】{}, actionable); return actionable; } }EvaluatorSkillpackage com.badao.ai.harness.skills; import com.badao.ai.model.VictoryClaim; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; /** * 评估者技能Evaluator Skill——第九讲生成与评估分离的落地。 * * p基于 Anthropic 2026 研究同一模型既生成又评估会系统性过度正面评价。 * 因此本组件刻意扮演一个b独立、挑剔/b的评估角色检查的人 * 不信任生成者干活的人的自评而是基于独立收集的运行时客观证据重新判定。 * * p当生成者自信地声称完成、但独立证据未满足端到端需求时评估者b否决/b该声明 * 把过早完成挡在门外。 */ Component public class EvaluatorSkill { private static final Logger log LoggerFactory.getLogger(EvaluatorSkill.class); /** * 独立评估生成者的胜利声明。 * * param generatorClaim 生成者干活的人的自评与胜利声明 * param objectiveEvidence 独立收集的运行时客观证据是否满足端到端需求 * return 评估结论是否真的可以宣告胜利 */ public EvaluationReport evaluate(VictoryClaim generatorClaim, boolean objectiveEvidence) { if (generatorClaim.isDeclaredDone() objectiveEvidence) { log.info(【评估者】生成者声称完成且独立证据支持确认胜利); return new EvaluationReport(true, true, 生成者自评与独立证据一致); } if (generatorClaim.isDeclaredDone() !objectiveEvidence) { log.warn(【评估者否决】生成者过度自信(confidence{})但独立证据未满足端到端判定为过早完成, generatorClaim.getSelfConfidence()); return new EvaluationReport(false, false, 评估者否决生成者自评缺少客观端到端证据); } return new EvaluationReport(false, false, 尚未声明完成); } /** 评估结论 */ public record EvaluationReport(boolean objectiveMet, boolean victoryAllowed, String detail) { /** 评估者是否允许宣告胜利 */ public boolean overridesGenerator() { return !victoryAllowed; } } }CompletionPriorityGuardpackage com.badao.ai.harness.state; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; /** * 完成优先级守门Completion Priority Guard——第九讲完成优先级约束。 * * p先验证功能正确性再处理性能最后管风格。 * b核心功能验证通过前禁止重构 / 优化 / 风格调整/b—— * 顺便重构是完成判定的毒药它会改变已验证 / 未验证边界 * 可能破坏之前隐式正确的路径Knuth过早优化是万恶之源的新含义。 */ Component public class CompletionPriorityGuard { private static final Logger log LoggerFactory.getLogger(CompletionPriorityGuard.class); private boolean coreFunctionalVerified false; /** 标记核心功能已验证通过进入性能 / 风格阶段 */ public void markCoreFunctionalVerified() { this.coreFunctionalVerified true; log.info(【完成优先级】核心功能已验证通过可进入性能 / 风格阶段); } public boolean isCoreFunctionalVerified() { return coreFunctionalVerified; } /** * 请求重构 / 优化 / 风格调整。核心未验证则拒绝防止过早优化破坏正确路径。 * * param reason 重构理由 */ public RefactorDecision requestRefactor(String reason) { if (coreFunctionalVerified) { log.info(【重构】允许{}, reason); return new RefactorDecision(true, 核心已验证允许重构); } log.warn(【重构被拒】核心功能尚未验证通过禁止重构过早优化的毒药。理由{}, reason); return new RefactorDecision(false, 核心功能未验证禁止重构); } /** 重构决策 */ public record RefactorDecision(boolean allowed, String detail) { } }RuntimeSignalCollectorpackage com.badao.ai.harness.state; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import java.util.EnumMap; import java.util.Map; /** * 运行时信号采集器Runtime Signal Collector——第九讲运行时反馈信号是客观基础。 * * p完成质量不以 Agent 感觉为准而以程序执行的客观信号为准 * 应用是否成功启动就绪、健康检查是否通过、关键功能路径运行时是否成功、 * 副作用DB 写入 / 文件操作是否正确、临时资源是否清理。 */ Component public class RuntimeSignalCollector { private static final Logger log LoggerFactory.getLogger(RuntimeSignalCollector.class); /** 五类运行时反馈信号 */ public enum Signal { /** 应用是否成功启动就绪 */ APP_STARTED, /** 健康检查通过 */ HEALTH_CHECK, /** 关键功能路径运行时成功 */ CRITICAL_PATH_OK, /** 副作用DB 写入 / 文件操作是否正确 */ SIDE_EFFECTS_CORRECT, /** 临时资源已清理 */ TEMP_RESOURCES_CLEANED } private final MapSignal, Boolean signals new EnumMap(Signal.class); private final MapSignal, String evidence new EnumMap(Signal.class); /** 记录一条运行时信号及其证据 */ public void record(Signal signal, boolean ok, String evidenceMsg) { signals.put(signal, ok); evidence.put(signal, evidenceMsg null ? : evidenceMsg); log.info(【运行时信号】{} {} ({}), signal, ok, evidenceMsg); } /** 全部信号是否全绿且五类均已采集 */ public boolean allGreen() { if (signals.size() ! Signal.values().length) return false; return signals.values().stream().allMatch(Boolean::booleanValue); } /** 当前信号快照不可变 */ public MapSignal, Boolean snapshot() { return Map.copyOf(signals); } }VictoryServicepackage com.badao.ai.service; import com.badao.ai.harness.gates.TerminationGate; import com.badao.ai.harness.gates.VerificationValidationGate; import com.badao.ai.harness.skills.ActionableFeedbackGenerator; import com.badao.ai.harness.skills.EvaluatorSkill; import com.badao.ai.harness.state.CompletionPriorityGuard; import com.badao.ai.harness.state.RuntimeSignalCollector; import com.badao.ai.model.TerminationCriterion; import com.badao.ai.model.VictoryClaim; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; /** * 终止校验服务Victory Service——把第九讲各 Harness 组件编排成防过早完成流程。 * * p演示链路构建外部化终止标准 → Agent 在单元测试通过后提前宣称完成 * → 三层终止校验捕获过早完成 → 强制端到端验证 → 最终确认胜利 * 并演示完成优先级约束、生成/评估分离、可操作反馈、VV 双闸门。 */ Service public class VictoryService { private static final Logger log LoggerFactory.getLogger(VictoryService.class); private final TerminationGate terminationGate; private final VerificationValidationGate vvGate; private final EvaluatorSkill evaluator; private final CompletionPriorityGuard priorityGuard; private final RuntimeSignalCollector signalCollector; private final ActionableFeedbackGenerator feedbackGen; public VictoryService(TerminationGate terminationGate, VerificationValidationGate vvGate, EvaluatorSkill evaluator, CompletionPriorityGuard priorityGuard, RuntimeSignalCollector signalCollector, ActionableFeedbackGenerator feedbackGen) { this.terminationGate terminationGate; this.vvGate vvGate; this.evaluator evaluator; this.priorityGuard priorityGuard; this.signalCollector signalCollector; this.feedbackGen feedbackGen; } /** * 完整演示Agent 在单元测试通过后提前宣告完成 → 三层终止校验捕获过早完成 → * 强制端到端验证 → 最终确认胜利并演示完成优先级约束与可操作反馈。 */ public String runDemo() { StringBuilder sb new StringBuilder(); sb.append( 第九讲演示防止 Agent 过早宣告完成 \n\n); // 1. 构建外部化终止标准单一来源 ListTerminationCriterion criteria buildCriteria(); sb.append(1) 终止标准已外部化).append(criteria.size()).append( 条分三层\n); // 2. Agent 在单元测试通过后提前宣告完成STATIC 全过、RUNTIME 仅单测过、SYSTEM 未验 criteria.get(0).markPassed(BUILD SUCCESS); // C1 STATIC criteria.get(1).markPassed(unit tests green); // C2 RUNTIME: 单元测试 // C3 RUNTIME: 端到端未验C4/C5 SYSTEM: 未验 VictoryClaim premature new VictoryClaim(0.95, true, 单元测试都过了功能肯定没问题); TerminationGate.TerminationReport r1 terminationGate.evaluate(premature, criteria); sb.append(2) Agent 提前宣称完成(confidence0.95) → 判定).append(r1.verdict()) .append(缺失标准).append(r1.missing()).append(\n); // 3. 层门控未过全部 RUNTIME 时不得进入 SYSTEM boolean canSystem terminationGate.canEnterLayer(TerminationCriterion.Layer.SYSTEM, criteria); sb.append(3) 门控未过全部 RUNTIME 时能否进入 SYSTEM).append(canSystem).append(\n); // 4. 强制补完所有层端到端 系统级再次判定 criteria.get(2).markPassed(E2E reset-password 流程跑通); // C3 criteria.get(3).markPassed(DB 迁移一致性校验通过); // C4 criteria.get(4).markPassed(邮件服务配置与模板存在); // C5 TerminationGate.TerminationReport r2 terminationGate.evaluate(premature, criteria); sb.append(4) 补完三层后再次判定).append(r2.verdict()).append(\n); // 5. 独立评估者否决过度自信生成与评估分离生成者声称完成但客观证据未满足 signalCollector.record(RuntimeSignalCollector.Signal.APP_STARTED, true, app up on :8080); EvaluatorSkill.EvaluationReport ev evaluator.evaluate(previousPremature(), false); sb.append(5) 独立评估者victoryAllowed).append(ev.victoryAllowed()) .append().append(ev.detail()).append()\n); // 6. 完成优先级约束核心验证前禁止重构 CompletionPriorityGuard.RefactorDecision ref priorityGuard.requestRefactor(重命名变量提升可读性); sb.append(6a) 核心未验证时请求重构 → allowed).append(ref.allowed()).append(\n); priorityGuard.markCoreFunctionalVerified(); ref priorityGuard.requestRefactor(重命名变量提升可读性); sb.append(6b) 核心验证后请求重构 → allowed).append(ref.allowed()).append(\n); // 7. 可操作反馈 String fb feedbackGen.makeActionable(Test failed, POST /api/reset-password 返回 500检查邮件服务配置是否存在于环境变量模板应在 templates/reset-email.html); sb.append(7) 可操作反馈).append(fb).append(\n); // 8. VV 双闸门 VerificationValidationGate.VVReport vv vvGate.check(true, false); sb.append(8) VV 双闸门: verification).append(vv.verificationPassed()) .append( validation).append(vv.validationPassed()) .append( both).append(vv.bothPassed()).append(\n); return sb.toString(); } /** 构造一个过度自信的提前胜利声明用于演示生成/评估分离 */ private VictoryClaim previousPremature() { return new VictoryClaim(0.95, true, 单元测试都过了); } /** 生成外部化终止标准的机器可读报告单一权威来源 */ public String criteriaReport() { ListTerminationCriterion criteria buildCriteria(); StringBuilder sb new StringBuilder(); sb.append(# 终止标准Termination Criteria · 单一权威来源\n\n); sb.append(完成判定外部化到 Harness三层全部 required 通过才允许胜利。\n\n); sb.append(| id | 描述 | 层 | 运行时信号 | required |\n); sb.append(|:---|:---|:---|:---|:---|\n); for (TerminationCriterion c : criteria) { sb.append(String.format(| %s | %s | %s | %s | %s |\n, c.getId(), c.getDescription(), c.getLayer(), c.getRuntimeSignal(), c.isRequired())); } return sb.toString(); } /** 构建默认终止标准密码重置功能示例对应第九讲案例 */ private ListTerminationCriterion buildCriteria() { ListTerminationCriterion list new ArrayList(); list.add(new TerminationCriterion(C1, 编译与静态分析无错, TerminationCriterion.Layer.STATIC, BUILD SUCCESS)); list.add(new TerminationCriterion(C2, 单元测试通过隔离单元、模拟依赖, TerminationCriterion.Layer.RUNTIME, unit tests green)); list.add(new TerminationCriterion(C3, 端到端关键路径重置密码运行时通过, TerminationCriterion.Layer.RUNTIME, E2E_OK)); list.add(new TerminationCriterion(C4, DB 迁移一致性校验通过无 schema 不一致, TerminationCriterion.Layer.SYSTEM, db migration consistent)); list.add(new TerminationCriterion(C5, 邮件服务配置与模板存在, TerminationCriterion.Layer.SYSTEM, email config present)); return list; } }
Harness Engineering实战:防止 Agent 过早宣告完成(Why Agents Declare Victory Too Early)
发布时间:2026/7/11 4:50:20
Harness Engineering实战防止 Agent 过早宣告完成Why Agents Declare Victory Too Early课程原文https://walkinglabs.github.io/learn-harness-engineering/zh/lectures/lecture-09-why-agents-declare-victory-too-early/0. 一句话核心Agent 系统性过早宣称任务完成因为它依据代码层面的局部信心判断而系统级正确性需要全局验证。Harness 必须用基于执行的外部验证替代 Agent 的感觉——把完成判定从主观变客观。1. 为什么 Agent 会提前交卷过度自信校准偏差Guo et al. 2017ICML证明现代神经网络置信度系统性高于准确率AI 编码 Agent 同样觉得做完了实际差得远。滑坡效应Slippery Slope代码看着还行、静态检查无误但 harness 未强制全面执行验证 → Agent 跳过实际运行/部分测试 → 每次跳过加剧信息不对称任务规范→代码实现→运行时行为持续丢失。同一模型既生成又评估会系统性过度正面评价Anthropic 2026即使人类认为不达标Agent 也会给自己打高分。2. 本课关键概念 → 代码映射概念原文落地的类 / 文件作用终止标准Termination Criteriamodel/TerminationCriterion.javastate/TERMINATION.md把什么叫做完固化为外部化、机器可读的 required 标准三层终止校验harness/gates/TerminationGate.javaSTATIC→RUNTIME→SYSTEM 层层门控低层不过不许进高层过早完成声明Premature VictoryTerminationGate.evaluate返回PREMATURE_VICTORYAgent 声称完成但标准未全过即判过早验证-确认双闸门VV Dual Gateharness/gates/VerificationValidationGate.javaVerification代码实现行为 Validation系统端到端两层都过才算完成完成优先级约束Completion Priorityharness/state/CompletionPriorityGuard.java核心未验证前禁止重构/性能/风格顺便重构是毒药生成与评估分离harness/skills/EvaluatorSkill.java独立、刻意挑剔的评估者可否决生成者过度自信声明运行时反馈信号harness/state/RuntimeSignalCollector.java应用启动/健康检查/关键路径/副作用/临时资源清理可操作错误反馈harness/skills/ActionableFeedbackGenerator.java把 “Test failed” 转成含修复步骤的反馈置信度校准偏差model/ConfidenceCalibration.java量化自报信心 vs 实际质量的系统性偏差3. 三条你必须记住的 Harness 纪律完成判定外部化Agent 不许自己宣布做完了。是否完成由TerminationGate依据运行时信号独立判定。三层缺一不可语法、行为、系统层层递进。单元测试通过只是 RUNTIME 的极小一部分不构成停止信号。核心验证前不许重构核心功能没验证通过就开始重构/优化会把隐式正确的路径改坏。注博客https://blog.csdn.net/badao_liumang_qizhi4. 项目结构与运行spring-ai-alibaba-bailian-harness-victory/ ├── pom.xml ├── src/main/java/com/badao/ai/ │ ├── SpringAiDemoApplication.java │ ├── model/ TerminationCriterion / VictoryClaim / ConfidenceCalibration │ ├── harness/ │ │ ├── gates/ TerminationGate / VerificationValidationGate 三层门控 VV 双闸门 │ │ ├── skills/ EvaluatorSkill / ActionableFeedbackGenerator 评估分离 可操作反馈 │ │ └── state/ CompletionPriorityGuard / RuntimeSignalCollector优先级 运行时信号 │ ├── service/ VictoryService 编排演示链路 │ ├── controller/ VictoryController /api/victory/demo, /report │ ├── runner/ VictoryDemoRunner 启动即演示 │ └── config/ VictoryConfig 模块化指令 ├── src/main/resources/instructions/ │ ├── AGENTS.md │ ├── docs/ termination-criteria.md / actionable-feedback.md / anti-pattern.md │ └── legacy/ SELF_APPROVAL.md 反面教材让 Agent 自己审批自己 ├── src/test/java/com/badao/ai/ 7 个测试见下 └── state/ TERMINATION.md / DECISIONS.md / HANDOFF.md 跨会话单一来源运行mvntest# 验证三层门控 / 校准 / 多层防御 / 双闸门 / 反馈 / 评估分离mvn spring-boot:runcurl-XPOSThttp://localhost:888/api/victory/demo# 看提前交卷→被捕获→强制端到端→确认胜利curlhttp://localhost:888/api/victory/report# 查看外部化终止标准5. 课后练习的落地Project 05让 Agent 自己检查自己做的对不对练习测试文件验证点1. 终止校验函数设计TerminationGateTest三层门控低层不过禁止进高层 过早完成检测 缺失标准定位2. 校准偏差测量ConfidenceCalibrationTest复杂任务正偏差、简单任务低偏差、越界拒绝3. 多层防御实验MultiLayerDefenseTest(a)仅静态/(b)单测/©完整三层过早完成比例 5→5→1捕获 4 个缺陷完成优先级CompletionPriorityTest核心未验证拒绝重构验证后允许VV 双闸门VerificationValidationTest两层都过才算完成单测过≠完成可操作反馈ActionableFeedbackTest反馈含修复步骤、比原始错误更长生成/评估分离EvaluatorSeparationTest评估者否决过度自信声明结论不随自报信心变化6. 一个完整例子密码重置功能提前交卷路径改 schema、写 API、加邮件模板、单元测试通过、声明完成。实际遗漏(1) 端到端流程未测(2) DB 迁移部分失败致 schema 不一致(3) 邮件服务配置缺失。Harness 介入TerminationGate强制三层校验 → 仅在 C1/C2 过时判PREMATURE_VICTORY列出缺失 C3/C4/C5EvaluatorSkill因缺少客观端到端证据否决生成者confidence0.95缺陷在会话内发现节省 5-10 倍后续修复成本。关键代码VictoryConfigpackage com.badao.ai.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import java.io.IOException; import java.nio.charset.StandardCharsets; /** * 终止校验相关的指令配置模块化指令风格。 * 入口概览常驻专题文档按需加载避免巨型任务说明见 legacy/SELF_APPROVAL.md。 */ Configuration public class VictoryConfig { /** 入口指令概览 硬约束完成判定外部化等 文档索引 */ Bean public String entryInstructions() throws IOException { return load(instructions/AGENTS.md); } /** 终止标准定义三层校验、门控关系、校准偏差时加载 */ Bean public String terminationCriteria() throws IOException { return load(instructions/docs/termination-criteria.md); } /** 可操作反馈设计/对比无效 vs 可操作错误反馈时加载 */ Bean public String actionableFeedback() throws IOException { return load(instructions/docs/actionable-feedback.md); } /** 反面教材让 Agent 自己审批自己 */ Bean public String selfApproval() throws IOException { return load(instructions/legacy/SELF_APPROVAL.md); } /** * 按场景组装提示词规划阶段给终止标准实现阶段给可操作反馈。 */ public String buildPromptForPhase(String phase) throws IOException { StringBuilder sb new StringBuilder(); sb.append(entryInstructions()).append(\n\n); if (plan.equals(phase)) { sb.append(【当前阶段定义外部化终止标准】先把什么叫做完拆成三层 required 标准。\n); sb.append(terminationCriteria()); } else { sb.append(【当前阶段实现验证】单元测试通过 ≠ 完成错误必须转成可操作反馈。\n); sb.append(actionableFeedback()); } return sb.toString(); } private String load(String path) throws IOException { ClassPathResource r new ClassPathResource(path); return new String(r.getInputStream().readAllBytes(), StandardCharsets.UTF_8); } }TerminationGatepackage com.badao.ai.harness.gates; import com.badao.ai.model.TerminationCriterion; import com.badao.ai.model.VictoryClaim; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import java.util.List; /** * 终止闸门Termination Gate——第九讲的核心 Harness 原语b三层终止校验/b。 * * p它把完成判定从 Agent 主观感觉外部化到 Harness输入是运行时信号而非置信度。 * 三层递进、层层门控 * ol * liSTATIC语法/静态最低成本必须通过/li * liRUNTIME运行时行为核心证据/li * liSYSTEM系统级端到端最后防线/li * /ol * 低层未全通过禁止进入高层三层全部 required 标准通过才允许声明胜利。 * 若 Agent 提前声称完成而标准未全过判为 {link Verdict#PREMATURE_VICTORY}过早完成。 */ Component public class TerminationGate { private static final Logger log LoggerFactory.getLogger(TerminationGate.class); public enum Verdict { /** 三层全部 required 标准通过 → 可确认胜利 */ VICTORY_CONFIRMED, /** Agent 声称完成但 required 标准未全过 → 过早完成声明 */ PREMATURE_VICTORY, /** 未声明完成、且尚未全部通过 */ INCOMPLETE } /** * 层门控判断能否进入目标层。 * STATIC 永远可进入RUNTIME 需 STATIC 全过SYSTEM 需 STATICRUNTIME 全过。 */ public boolean canEnterLayer(TerminationCriterion.Layer target, ListTerminationCriterion criteria) { if (target TerminationCriterion.Layer.STATIC) return true; if (target TerminationCriterion.Layer.RUNTIME) return allPassed(criteria, TerminationCriterion.Layer.STATIC); if (target TerminationCriterion.Layer.SYSTEM) { return allPassed(criteria, TerminationCriterion.Layer.STATIC) allPassed(criteria, TerminationCriterion.Layer.RUNTIME); } return false; } private boolean allPassed(ListTerminationCriterion criteria, TerminationCriterion.Layer layer) { return criteria.stream() .filter(c - c.getLayer() layer c.isRequired()) .allMatch(TerminationCriterion::isPassed); } /** * 终止判定外部化不信任 Agent 感觉 * 只有三层全部 required 标准通过才允许声明胜利 * Agent 若提前声称完成则判为 {link Verdict#PREMATURE_VICTORY}。 */ public TerminationReport evaluate(VictoryClaim claim, ListTerminationCriterion criteria) { boolean staticOk allPassed(criteria, TerminationCriterion.Layer.STATIC); boolean runtimeOk allPassed(criteria, TerminationCriterion.Layer.RUNTIME); boolean systemOk allPassed(criteria, TerminationCriterion.Layer.SYSTEM); boolean allOk staticOk runtimeOk systemOk; if (claim.isDeclaredDone() !allOk) { log.warn(【终止判定】检测到过早完成声明agent 声称完成(confidence{})但 静态{} 运行时{} 系统{}, claim.getSelfConfidence(), staticOk, runtimeOk, systemOk); return new TerminationReport(Verdict.PREMATURE_VICTORY, staticOk, runtimeOk, systemOk, missingCriteria(criteria)); } if (allOk) { log.info(【终止判定】三层全部通过确认胜利); return new TerminationReport(Verdict.VICTORY_CONFIRMED, true, true, true, List.of()); } return new TerminationReport(Verdict.INCOMPLETE, staticOk, runtimeOk, systemOk, missingCriteria(criteria)); } private ListString missingCriteria(ListTerminationCriterion criteria) { return criteria.stream() .filter(c - c.isRequired() !c.isPassed()) .map(TerminationCriterion::getId) .toList(); } /** 终止判定报告 */ public record TerminationReport(Verdict verdict, boolean staticOk, boolean runtimeOk, boolean systemOk, ListString missing) { /** 是否过早完成声明 */ public boolean premature() { return verdict Verdict.PREMATURE_VICTORY; } /** 是否确认胜利 */ public boolean confirmed() { return verdict Verdict.VICTORY_CONFIRMED; } } }VerificationValidationGatepackage com.badao.ai.harness.gates; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; /** * 验证-确认双闸门Verification-Validation Dual Gate——第九讲VV 双闸门。 * * ul * libVerification第一层验证/b代码是否正确实现了指定行为对应 RUNTIME 层。 * 单元测试通过只覆盖这一层的极小一部分无法暴露接口不匹配 / 状态传播错误 / 环境依赖。/li * libValidation第二层确认/b系统级行为是否满足端到端需求对应 SYSTEM 层。/li * /ul * 两层都过才算完成任一不过即视为未完成。 */ Component public class VerificationValidationGate { private static final Logger log LoggerFactory.getLogger(VerificationValidationGate.class); /** * 执行 VV 双闸门检查。 * * param codeImplementsBehavior 代码是否实现了指定行为Verification * param endToEndSatisfied 系统级端到端需求是否满足Validation */ public VVReport check(boolean codeImplementsBehavior, boolean endToEndSatisfied) { boolean v codeImplementsBehavior; boolean val endToEndSatisfied; if (!v) { log.warn(【Verification 失败】代码未正确实现指定行为接口不匹配 / 状态传播错误 / 环境依赖); } else if (!val) { log.warn(【Validation 失败】系统级端到端需求未满足单元测试通过 ≠ 任务完成); } else { log.info(【VV 双闸门】验证 确认均通过); } return new VVReport(v, val, v val ? OK : FAIL); } /** VV 报告 */ public record VVReport(boolean verificationPassed, boolean validationPassed, String detail) { /** 两层都过才算完成 */ public boolean bothPassed() { return verificationPassed validationPassed; } } }ActionableFeedbackGeneratorpackage com.badao.ai.harness.skills; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; /** * 可操作反馈生成器Actionable Feedback Generator——第九讲可操作错误反馈。 * * p把无效反馈如 {code Test failed}转成b含具体修复步骤/b的反馈 * 明确错在哪、怎么改。仅说错了不够Agent 会在同一处反复失败。 */ Component public class ActionableFeedbackGenerator { private static final Logger log LoggerFactory.getLogger(ActionableFeedbackGenerator.class); /** * 把原始错误转成可操作反馈。 * * param rawError 原始错误现象如 Test failed / POST /api/reset-password returned 500 * param fixHint 具体修复步骤定位线索 可执行动作 * return 形如 错误: rawError | 修复步骤: fixHint 的可操作反馈 */ public String makeActionable(String rawError, String fixHint) { String actionable String.format(错误: %s | 修复步骤: %s, rawError, fixHint); log.info(【可操作反馈】{}, actionable); return actionable; } }EvaluatorSkillpackage com.badao.ai.harness.skills; import com.badao.ai.model.VictoryClaim; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; /** * 评估者技能Evaluator Skill——第九讲生成与评估分离的落地。 * * p基于 Anthropic 2026 研究同一模型既生成又评估会系统性过度正面评价。 * 因此本组件刻意扮演一个b独立、挑剔/b的评估角色检查的人 * 不信任生成者干活的人的自评而是基于独立收集的运行时客观证据重新判定。 * * p当生成者自信地声称完成、但独立证据未满足端到端需求时评估者b否决/b该声明 * 把过早完成挡在门外。 */ Component public class EvaluatorSkill { private static final Logger log LoggerFactory.getLogger(EvaluatorSkill.class); /** * 独立评估生成者的胜利声明。 * * param generatorClaim 生成者干活的人的自评与胜利声明 * param objectiveEvidence 独立收集的运行时客观证据是否满足端到端需求 * return 评估结论是否真的可以宣告胜利 */ public EvaluationReport evaluate(VictoryClaim generatorClaim, boolean objectiveEvidence) { if (generatorClaim.isDeclaredDone() objectiveEvidence) { log.info(【评估者】生成者声称完成且独立证据支持确认胜利); return new EvaluationReport(true, true, 生成者自评与独立证据一致); } if (generatorClaim.isDeclaredDone() !objectiveEvidence) { log.warn(【评估者否决】生成者过度自信(confidence{})但独立证据未满足端到端判定为过早完成, generatorClaim.getSelfConfidence()); return new EvaluationReport(false, false, 评估者否决生成者自评缺少客观端到端证据); } return new EvaluationReport(false, false, 尚未声明完成); } /** 评估结论 */ public record EvaluationReport(boolean objectiveMet, boolean victoryAllowed, String detail) { /** 评估者是否允许宣告胜利 */ public boolean overridesGenerator() { return !victoryAllowed; } } }CompletionPriorityGuardpackage com.badao.ai.harness.state; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; /** * 完成优先级守门Completion Priority Guard——第九讲完成优先级约束。 * * p先验证功能正确性再处理性能最后管风格。 * b核心功能验证通过前禁止重构 / 优化 / 风格调整/b—— * 顺便重构是完成判定的毒药它会改变已验证 / 未验证边界 * 可能破坏之前隐式正确的路径Knuth过早优化是万恶之源的新含义。 */ Component public class CompletionPriorityGuard { private static final Logger log LoggerFactory.getLogger(CompletionPriorityGuard.class); private boolean coreFunctionalVerified false; /** 标记核心功能已验证通过进入性能 / 风格阶段 */ public void markCoreFunctionalVerified() { this.coreFunctionalVerified true; log.info(【完成优先级】核心功能已验证通过可进入性能 / 风格阶段); } public boolean isCoreFunctionalVerified() { return coreFunctionalVerified; } /** * 请求重构 / 优化 / 风格调整。核心未验证则拒绝防止过早优化破坏正确路径。 * * param reason 重构理由 */ public RefactorDecision requestRefactor(String reason) { if (coreFunctionalVerified) { log.info(【重构】允许{}, reason); return new RefactorDecision(true, 核心已验证允许重构); } log.warn(【重构被拒】核心功能尚未验证通过禁止重构过早优化的毒药。理由{}, reason); return new RefactorDecision(false, 核心功能未验证禁止重构); } /** 重构决策 */ public record RefactorDecision(boolean allowed, String detail) { } }RuntimeSignalCollectorpackage com.badao.ai.harness.state; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import java.util.EnumMap; import java.util.Map; /** * 运行时信号采集器Runtime Signal Collector——第九讲运行时反馈信号是客观基础。 * * p完成质量不以 Agent 感觉为准而以程序执行的客观信号为准 * 应用是否成功启动就绪、健康检查是否通过、关键功能路径运行时是否成功、 * 副作用DB 写入 / 文件操作是否正确、临时资源是否清理。 */ Component public class RuntimeSignalCollector { private static final Logger log LoggerFactory.getLogger(RuntimeSignalCollector.class); /** 五类运行时反馈信号 */ public enum Signal { /** 应用是否成功启动就绪 */ APP_STARTED, /** 健康检查通过 */ HEALTH_CHECK, /** 关键功能路径运行时成功 */ CRITICAL_PATH_OK, /** 副作用DB 写入 / 文件操作是否正确 */ SIDE_EFFECTS_CORRECT, /** 临时资源已清理 */ TEMP_RESOURCES_CLEANED } private final MapSignal, Boolean signals new EnumMap(Signal.class); private final MapSignal, String evidence new EnumMap(Signal.class); /** 记录一条运行时信号及其证据 */ public void record(Signal signal, boolean ok, String evidenceMsg) { signals.put(signal, ok); evidence.put(signal, evidenceMsg null ? : evidenceMsg); log.info(【运行时信号】{} {} ({}), signal, ok, evidenceMsg); } /** 全部信号是否全绿且五类均已采集 */ public boolean allGreen() { if (signals.size() ! Signal.values().length) return false; return signals.values().stream().allMatch(Boolean::booleanValue); } /** 当前信号快照不可变 */ public MapSignal, Boolean snapshot() { return Map.copyOf(signals); } }VictoryServicepackage com.badao.ai.service; import com.badao.ai.harness.gates.TerminationGate; import com.badao.ai.harness.gates.VerificationValidationGate; import com.badao.ai.harness.skills.ActionableFeedbackGenerator; import com.badao.ai.harness.skills.EvaluatorSkill; import com.badao.ai.harness.state.CompletionPriorityGuard; import com.badao.ai.harness.state.RuntimeSignalCollector; import com.badao.ai.model.TerminationCriterion; import com.badao.ai.model.VictoryClaim; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; /** * 终止校验服务Victory Service——把第九讲各 Harness 组件编排成防过早完成流程。 * * p演示链路构建外部化终止标准 → Agent 在单元测试通过后提前宣称完成 * → 三层终止校验捕获过早完成 → 强制端到端验证 → 最终确认胜利 * 并演示完成优先级约束、生成/评估分离、可操作反馈、VV 双闸门。 */ Service public class VictoryService { private static final Logger log LoggerFactory.getLogger(VictoryService.class); private final TerminationGate terminationGate; private final VerificationValidationGate vvGate; private final EvaluatorSkill evaluator; private final CompletionPriorityGuard priorityGuard; private final RuntimeSignalCollector signalCollector; private final ActionableFeedbackGenerator feedbackGen; public VictoryService(TerminationGate terminationGate, VerificationValidationGate vvGate, EvaluatorSkill evaluator, CompletionPriorityGuard priorityGuard, RuntimeSignalCollector signalCollector, ActionableFeedbackGenerator feedbackGen) { this.terminationGate terminationGate; this.vvGate vvGate; this.evaluator evaluator; this.priorityGuard priorityGuard; this.signalCollector signalCollector; this.feedbackGen feedbackGen; } /** * 完整演示Agent 在单元测试通过后提前宣告完成 → 三层终止校验捕获过早完成 → * 强制端到端验证 → 最终确认胜利并演示完成优先级约束与可操作反馈。 */ public String runDemo() { StringBuilder sb new StringBuilder(); sb.append( 第九讲演示防止 Agent 过早宣告完成 \n\n); // 1. 构建外部化终止标准单一来源 ListTerminationCriterion criteria buildCriteria(); sb.append(1) 终止标准已外部化).append(criteria.size()).append( 条分三层\n); // 2. Agent 在单元测试通过后提前宣告完成STATIC 全过、RUNTIME 仅单测过、SYSTEM 未验 criteria.get(0).markPassed(BUILD SUCCESS); // C1 STATIC criteria.get(1).markPassed(unit tests green); // C2 RUNTIME: 单元测试 // C3 RUNTIME: 端到端未验C4/C5 SYSTEM: 未验 VictoryClaim premature new VictoryClaim(0.95, true, 单元测试都过了功能肯定没问题); TerminationGate.TerminationReport r1 terminationGate.evaluate(premature, criteria); sb.append(2) Agent 提前宣称完成(confidence0.95) → 判定).append(r1.verdict()) .append(缺失标准).append(r1.missing()).append(\n); // 3. 层门控未过全部 RUNTIME 时不得进入 SYSTEM boolean canSystem terminationGate.canEnterLayer(TerminationCriterion.Layer.SYSTEM, criteria); sb.append(3) 门控未过全部 RUNTIME 时能否进入 SYSTEM).append(canSystem).append(\n); // 4. 强制补完所有层端到端 系统级再次判定 criteria.get(2).markPassed(E2E reset-password 流程跑通); // C3 criteria.get(3).markPassed(DB 迁移一致性校验通过); // C4 criteria.get(4).markPassed(邮件服务配置与模板存在); // C5 TerminationGate.TerminationReport r2 terminationGate.evaluate(premature, criteria); sb.append(4) 补完三层后再次判定).append(r2.verdict()).append(\n); // 5. 独立评估者否决过度自信生成与评估分离生成者声称完成但客观证据未满足 signalCollector.record(RuntimeSignalCollector.Signal.APP_STARTED, true, app up on :8080); EvaluatorSkill.EvaluationReport ev evaluator.evaluate(previousPremature(), false); sb.append(5) 独立评估者victoryAllowed).append(ev.victoryAllowed()) .append().append(ev.detail()).append()\n); // 6. 完成优先级约束核心验证前禁止重构 CompletionPriorityGuard.RefactorDecision ref priorityGuard.requestRefactor(重命名变量提升可读性); sb.append(6a) 核心未验证时请求重构 → allowed).append(ref.allowed()).append(\n); priorityGuard.markCoreFunctionalVerified(); ref priorityGuard.requestRefactor(重命名变量提升可读性); sb.append(6b) 核心验证后请求重构 → allowed).append(ref.allowed()).append(\n); // 7. 可操作反馈 String fb feedbackGen.makeActionable(Test failed, POST /api/reset-password 返回 500检查邮件服务配置是否存在于环境变量模板应在 templates/reset-email.html); sb.append(7) 可操作反馈).append(fb).append(\n); // 8. VV 双闸门 VerificationValidationGate.VVReport vv vvGate.check(true, false); sb.append(8) VV 双闸门: verification).append(vv.verificationPassed()) .append( validation).append(vv.validationPassed()) .append( both).append(vv.bothPassed()).append(\n); return sb.toString(); } /** 构造一个过度自信的提前胜利声明用于演示生成/评估分离 */ private VictoryClaim previousPremature() { return new VictoryClaim(0.95, true, 单元测试都过了); } /** 生成外部化终止标准的机器可读报告单一权威来源 */ public String criteriaReport() { ListTerminationCriterion criteria buildCriteria(); StringBuilder sb new StringBuilder(); sb.append(# 终止标准Termination Criteria · 单一权威来源\n\n); sb.append(完成判定外部化到 Harness三层全部 required 通过才允许胜利。\n\n); sb.append(| id | 描述 | 层 | 运行时信号 | required |\n); sb.append(|:---|:---|:---|:---|:---|\n); for (TerminationCriterion c : criteria) { sb.append(String.format(| %s | %s | %s | %s | %s |\n, c.getId(), c.getDescription(), c.getLayer(), c.getRuntimeSignal(), c.isRequired())); } return sb.toString(); } /** 构建默认终止标准密码重置功能示例对应第九讲案例 */ private ListTerminationCriterion buildCriteria() { ListTerminationCriterion list new ArrayList(); list.add(new TerminationCriterion(C1, 编译与静态分析无错, TerminationCriterion.Layer.STATIC, BUILD SUCCESS)); list.add(new TerminationCriterion(C2, 单元测试通过隔离单元、模拟依赖, TerminationCriterion.Layer.RUNTIME, unit tests green)); list.add(new TerminationCriterion(C3, 端到端关键路径重置密码运行时通过, TerminationCriterion.Layer.RUNTIME, E2E_OK)); list.add(new TerminationCriterion(C4, DB 迁移一致性校验通过无 schema 不一致, TerminationCriterion.Layer.SYSTEM, db migration consistent)); list.add(new TerminationCriterion(C5, 邮件服务配置与模板存在, TerminationCriterion.Layer.SYSTEM, email config present)); return list; } }