阅读提示:这是主文《 用真实项目讲透:如何通过 Harness Engineering 从 0 到 1 开发 AI Agent 》的配套实操教学版。如果主文解决的是“什么是 Harness、为什么重要、整体架构怎么搭”,这篇文章只解决一件事:当我不再亲手写所有代码,而是开始把执行权放给一个强但非确定性的模型后,在真实项目里,我到底是怎么敲下每一行输入、怎么判断 Codex 回得对不对、以及怎么把它死死拉回正确轨道的。
0. 为什么要单独拆这一篇实操指南?
在主文中,我尽量把 Harness 的理念讲透,但为了保证文章的阅读节奏,隐藏了大量枯燥的交互细节。
这会带来一个天然的断层:看理念觉得“醍醐灌顶”,回工位一敲键盘依然是“让模型自己看着办”。
所以更好的做法,是把这部分单独剥离出来,写成一份实施手册。这一篇不再追求流畅的“文章感”,而是追求极致的“可操作性”。我会直接把 Aegis 项目里最真实的推进方式,提炼成可复用的输入节奏和判断框架。
也可以把它理解成:如果主文讲的是“为什么程序员必须从执行者迁移成控盘者”,那这篇讲的就是“当你真的开始放权以后,具体该怎么控盘”。
高亮排雷:关于
sdd-riper的误区开始前必须澄清:我这里使用的sdd-riper(或sdd-riper-one-light),绝对不是业界主流那种要求写大而全的 Spec、有着繁重 Phase 切换、充满仪式感的传统 SDD。在我的实战中,它更像是一套极简的实施层通信协议,只用来卡死下面这五个关键动作。总结一下层级关系:Harness是架构理念,负责回答"为什么要这样设计系统";而sdd-riper-one-light是实施协议,负责回答"我敲键盘时具体怎么把它控稳"。
0.5 先把视角拉回 Harness:我真正控制的到底是什么?
如果只把下面这些做法理解成“我很会跟模型说话”,那还是低估了 Harness。
我后来回头翻 Aegis 项目的本地资料,包括交接文档、分析笔记、以及 Codex 基目录下的一批原始 jsonl,越来越确定一件事:我真正反复在控制的,不是几句话术,而是一个面向非确定性执行的架构控制面。
Aegis 里最有代表性的真实 case,几乎都能按下面这 6 个控制面归类:
-
目标建模与轨道定义:项目刚起步时,我不是说“你先写一个 Agent 出来”,而是让它先读架构设计、再读参考项目、再复述主线。真实对话里一开始讨论的就是
reference_spike、backend detach、对话层迁移这些轨道,而不是“先写个接口试试”。 -
外部记忆与真相源:跨线程时,真实起手式经常只剩一句“阅读某份 handoff / spec 恢复任务”。这不是文档洁癖,而是在给系统提供一个可回读、可校验、可恢复的任务状态基座。
-
运行时 guardrail 与诊断能力:真正把项目拉开差距的,不是“能聊”,而是遇到
chat接口直接空结束、改完后频繁504 gateway timeout、更新后接口全是403这类问题时,系统有没有日志链路、事件链路和恢复路径。 -
执行回路与资产装配:很多看起来像 prompt 的问题,最后都会落到执行回路。比如
configkey查询到底是先召回再喂模型,还是整包直喂;two_stage和full_prompt怎么切;examples和cases到底会不会被加载、入口在哪里。 -
能力边界与业务骨架:项目往后走,问题不再是“模型会不会回答”,而是一个 skill 能不能从“查一个配置”长成“按组织批量检查管控项”,能不能被真实业务接口消费。
-
验证、发布、恢复闭环:真实收尾不是“代码写完了”,而是已经提到测试环境、跑过回归、看过日志、合过分支、确认能恢复。很多轮最关键的输入甚至不是“继续开发”,而是“我已经发布到 pre 环境了,接下来该怎么测试这些 case?”
你会发现,“反复复述核心目标”其实只是其中一个控制动作。它重要,但它服务的不是礼貌确认,而是整个 Harness 控制面的第一层:防止目标漂移。真正完整的 Harness,是把目标建模、状态恢复、执行门禁、运行时证据、验证闭环这些东西一起串起来。
1. 核心心法与全景 SOP 表
如果要把我带 Codex 干活的精髓浓缩成一句话,它绝对不是目前网上最流行的那句:
“这是一个需求,请你作为资深工程师,帮我把功能完整写出来并测试通过。”
而是极其克制的:
“我在每一个阶段只给你一个带边界的输入;你必须先给我一个中间产物;我用 Harness 控制点核对无误后,才允许你进入下一步。”
为了方便大家抄作业,我把整套方法的 8 个阶段浓缩成了下面这张 SOP 总览表:
建议把这张表保存在手边,接下来我们进入每一个阶段的拆解。
1.5 我真正盯的不是一句需求,而是“三层目标”
如果只把任务理解成一句大需求,你很容易在长链路里被骗。因为模型会显得很积极,也会不断产出东西,但它有可能已经偏离了你真正要收敛的主线。
我在真实项目里,真正盯的是三层目标:
-
总核心目标:整个项目或这一大阶段到底要完成什么,这是北极星,轻易不能变。
-
阶段性核心目标:当前这几轮对话,只允许收敛哪一个主问题。
-
本轮动作目标:这一轮具体只允许它做哪 1 到 3 个动作。
这三层不能混着用。真正危险的,不是模型不会做,而是它会绕过阶段目标,直接朝着自己理解的“总目标”乱冲,于是表面上很努力,实际上不断偏航。
Aegis 里有一个特别典型的真实例子。我们当时在交接文档里写得很清楚:
-
总目标:将对话层切到 LangGraph,执行层保持不变,并保留可回滚能力。
-
阶段目标:先恢复 handoff 和 spec,确认当前代码与开关状态;再跑 case 回归;最后按失败类型修复。
-
本轮动作目标:先定位为什么
chat接口会出现RUN_STARTED -> TEXT_MESSAGE_START/END -> RUN_FINISHED这种“直接空结束”的现象。
换句话说,总目标从来不是“把整个系统一口气做完”。总目标只负责指北;真正驱动你这一轮输入和判断的,是阶段性核心目标。
在另一个更贴近“手把手带模型干活”的案例里,这种分层会更明显。Aegis 某轮权限边界治理时,我最后给出的完成判断不是简单一句“做完了”,而是明确区分了两层:
“如果你问的是‘这次最小收敛任务是否完成’,答案是完成了。 如果你问的是‘整个项目所有类似权限边界是否彻底治理完’,那还没有,当前只是把这条 security policy 主链先收住了。”
这句话非常重要。因为它准确体现了 Harness 的一个核心动作:把‘阶段完成’和‘全局完成’严格分开。
2. 为什么这套“笨”方法反而最高效?
很多人在尝试 Agent 项目时感到挫败,并不是因为底层大模型智商不够,而是默认采用了极其随意的协作姿势:
-
一上来不给边界,直接甩需求让它梭哈。
-
做到一半,不要求它做状态沉淀。
-
遇到长链路任务,不强制它做拆分。
-
动手改关键代码前,不做 Checkpoint 确认。
-
收尾时,凭模型自己的一句“我已经完成了”就信以为真。
这种“放养模式”的致命缺陷是:模型每一轮的回复看起来都很积极、代码写得飞快,但整个系统正在加速腐烂,最终不可用。
我最终在实战中收敛出来的,不是某一段“能让 AI 顿悟”的魔法 Prompt,而是一套铁血纪律的输入节奏:
-
先让模型解释,不让模型马上实现。
-
先拿中间产物,不让模型直接声称完成。
-
先看外部证据,绝对不相信模型的自我评价。
-
每一轮都强制回写,为下一轮准备干净的恢复点。
从 Harness 架构的角度看,这套方法精准狙击了四个绝症:防止目标漂移、防止状态蒸发、防止长链路偏航、防止质量失真。
2.1 为什么我会不断逼它复述核心目标?
这是我在真实项目里最常做、也最有效的动作之一。
很多人听到“复述”会以为这只是礼貌确认,或者是为了显得流程更完整。但在真实工程里,复述不是客套,而是反漂移装置。我不是为了听模型说漂亮话,而是为了确认:
-
它理解的总目标是不是还对。
-
它当前盯的阶段目标是不是还对。
-
它这一轮准备做的动作,是不是还在服务这个阶段目标。
我一般不会让它每一轮都机械重复一遍,而是只在四个节点强制复述:
-
阶段开始时:先复述总目标和当前阶段目标,确认没有理解偏差。
-
执行前 checkpoint:先复述当前理解、核心目标、下一步动作和验证方式。
-
日志/测试反馈回来后:先复述“当前目标是否还成立、剩余差距是什么”,而不是直接继续乱修。
-
阶段收尾时:先复述“这次最小收敛是否完成、还有什么没完成、下一轮目标是什么”。
真正有效的不是“让模型记住一次”,而是在关键节点反复把它拉回同一个锚点。
2.2 这件事在真实对话里长什么样?
下面这些都不是我事后编的模板,而是 Aegis 项目里真实出现过的输入风格。
项目刚开始时,我不是让它直接做,而是先让它复述方向:
用户: “此项目是一个空的 python 项目,然后阅读架构设计文档,大体上了解一下我想做什么,然后向我复述需求并和我讨论。”
Agent: “我会先阅读你给的架构文档,然后用我的话复述需求并和你讨论实现方向。”
跨线程恢复任务时,我不是让它‘接着写’,而是先恢复目标:
用户: “阅读 2026-03-07_Chat_Handoff_FullLangGraph.md 恢复任务。”
这句看起来很短,但背后其实已经隐含了一个 Harness 动作:先恢复任务锚点,再决定下一步。
真正执行前,我会卡 checkpoint,而不是让它直接冲:
“先别改代码。你先总结当前理解、核心目标、下一步动作、风险和验证方式;我确认后你再执行。”
日志回来以后,我最关心的也不是‘修没修’,而是‘目标是不是还对’:
“不要主观判断是否完成。去看测试、日志和接口的实际回包,基于事实再告诉我现在是什么状态。”
如果你把这几句连起来看,你会发现我真正反复在做的,是同一个动作:不断把模型从“自由发挥”拉回“围绕当前核心目标办事”。
2.3 模型一旦开始偏,我怎么判断?又怎么拉回来?
这一点我觉得特别值得单独写,因为很多人以为 Harness 的价值只在于“让模型一开始别跑偏”。但真实工程里,更常见的情况是:它不是一开始就错,而是做着做着慢慢偏。
我自己最常盯的,其实是下面这 4 个偏航信号:
-
它开始绕过阶段目标,直接谈总目标。 比如这一轮明明只该定位
chat空结束,它却开始讨论“整个 LangGraph 迁移怎么一次补齐”。 -
它开始跳过中间产物,直接声称要改代码。 这通常意味着它已经不想被 checkpoint 约束了。
-
它开始用主观语气替代客观证据。 比如“我认为应该已经解决了”“看起来没问题了”,但没有日志、没有测试、没有回包。
-
它开始混淆阶段完成和全局完成。 明明只是收住了一条主链,却很容易在话术上制造“整个问题已经解决”的错觉。
一旦出现这几种信号,我一般不会和它争论,而是直接改成更硬的输入,把它重新压回当前阶段目标。我的真实句式通常就是这几类:
“先停,不要继续展开。你先复述:这轮阶段性核心目标到底是什么,不要谈总目标。”
“先不要改代码。把当前理解、下一步动作、风险和验证方式重新写一遍,我确认后你再动。”
“不要主观判断。去看日志、测试结果和接口实际回包,基于证据再回答。”
“不要把这次最小收敛和全局完成混为一谈。你明确告诉我:这轮到底完成了什么,还没完成什么,下一轮最小目标是什么。”
你会发现,我几乎从不靠“提醒它聪明一点”来纠偏,而是靠重新设门禁、重新压目标、重新要求证据来纠偏。 这就是为什么我一直说,Harness 不是说服模型,而是约束模型。
3. 分阶段详解:我是怎么一步步操纵 Codex 的
3.1 阶段一:先让 Codex 理解项目,不让它立刻写代码
这个阶段的核心绝不是“马上出活”,而是先排雷。我要确认它理解的目标对不对?它抓到的主线对不对?它会不会一开始就猛踩油门冲进死胡同?
我的真实输入格式:
“请先阅读架构设计文档,理解这个项目我要做什么。注意:不要急着实现任何功能。 先用你自己的话复述你的理解,并告诉我你认为当前的项目主线应该怎么收敛。”
我期待它返回: 任务目标的复述、主线路径的判断、它嗅到的技术边界和疑问。如果不对,就在这一步骂回去重来。
这不是一个“演示用模板”,而是 Aegis 起步时真实出现过的输入方式。更原始的一句是:
“此项目是一个空的 python 项目,然后阅读架构设计文档,大体上了解一下我想做什么,然后向我复述需求并和我讨论。”
注意这里最重要的不是“阅读文档”四个字,而是后半句:“向我复述需求并和我讨论。” 这决定了项目的起手式不是“先写点什么”,而是“先让目标不漂移”。
3.2 阶段二:把任务从聊天窗口搬到“外部真相源”
当任务跨天、或者对话轮次过长时,聊天窗口的 Context 已经成了糊涂账。这时候绝对不能让 Codex “凭印象接着干”。
我的真实输入格式:
“先阅读这份 Spec / Handoff 文档。读完后告诉我:现在任务整体做到哪里了?还剩什么没做?你准备从哪一段接着推进?”
我期待它返回: 已完成项、未完成项、当前的真实进度判断、它的接续点建议。这一步的本质,是让系统状态强行恢复。
Aegis 里这一步经常短到只剩一句话:
“阅读 2026-03-07_Chat_Handoff_FullLangGraph.md 恢复任务。”
但这个动作的工程含义非常重。因为 handoff 里不是流水账,而是明确写了:
-
本次总目标是什么
-
已完成什么
-
关键配置开关是什么
-
下一轮建议先做什么
像那份真实 handoff 里,下一轮建议就直接写成了:
-
先确认 pre 环境的
AGENT_GRAPH_*和NL2OPS_GRAPH_ENABLED开关。 -
跑
35 case的 contract-only 回归。 -
汇总失败分布,优先修复命中率问题。
这就是为什么我一直强调:Spec / Handoff 不是文档负担,而是 Agent 项目的外部记忆系统。
3.3 阶段三:让它自己点菜,拒绝上下文“整包投喂”
很多团队一遇到报错,就本能地把几万字的文档全贴进去。真正稳定的做法是给入口、给索引,让它自己说需要看什么,保护宝贵的 Context Window。
我的真实输入格式:
“当前先以这份 Spec 为主,你可以按需查阅 Handoff 和这组 Examples。要求:不要整包吞全部文档。 先评估一下,为了完成下一步,你当前最需要我提供哪几块具体的上下文?”
3.4 阶段四:强制拆动作,严禁“一口吃成胖子”
进入实现阶段前,坚决打断模型试图一次性写完几百行代码的冲动。
我的真实输入格式:
“先不要试图把整条链路一次做完。这一轮我们只处理 reference spike 的主链迁移。请把它拆成 1 到 3 个最小可推进的编码动作,然后逐一说明每个动作你要怎么验证。”
3.5 阶段五:设计执行链路,而不是无脑改 Prompt
遇到卡壳,很多人的第一反应是“是不是 Prompt 没写好?”但在真实工程里,往往是底层的调用链路(Pipeline)选错了。必须要让 Agent 明白:这里的链路,不是让它换种语气说话,而是在代码库里真实存在的、不同的执行图或脚本分支。
我的真实输入格式:
“针对这个问题,先分析这一步的物理执行流应该路由给哪个确定的管道:是走 two_stage(先检索再生成的预设脚本)还是 full_prompt(全量投喂脚本)?Examples 和 Cases 应该以什么机制装配进当前的物理链路里?如果需要优化该链路下的子 Prompt,你需要我提供哪些真实的回放数据(Replay)支持?”
这一类问题在 Aegis 里出现得非常频繁。真实对话甚至会更口语一些:
“我们刚才做了一版重构,把 skill 进行了拆分,examples 和 cases 可以加载吗,如何加载?”
还有一轮更能说明“这不是 prompt 文案问题,而是执行回路问题”:
用户: “我们在做 configkey 查询的时候,是先召回再喂大模型,还是一次性把所有东西都喂给大模型?”
Agent: “关键分界是:先用本地规则和配置目录做候选召回,只有多个候选还歧义时,才调用一次小范围 LLM 选择,不是把全量 catalog 直接扔给模型。”
而 Agent 的第一反应不是“我给你编一个说法”,而是:
“我先按 sdd-riper-one-light 的方式收敛一下:这次先不改代码,我会快速确认当前 refactor 后 skill 的加载链路,重点看 examples 和 cases 这两类内容现在是否会被扫描、入口在哪、实际该怎么触发。”
这才是我想强调的“手把手”细节:很多所谓的 prompt 问题,本质上其实是在问‘这类资产有没有进入执行回路、是自动注入还是按需读取、入口到底在哪里’。
3.6 阶段六:执行前 Checkpoint(极其重要!)
这是整个协议里含金量最高的一个动作。当它准备好一切要动手改代码前,强行踩一脚刹车。
我的真实输入格式:
“**先别改代码!**在动手前,请做一次 Checkpoint,向我总结:1. 当前理解 2. 核心目标 3. 下一步具体动作 4. 潜在风险 5. 你的验证方式。只有我回复确认后,你才可以进入执行。”
3.7 阶段七:看外部证据,拒绝模型的“主观滤镜”
到了验证阶段,大模型最喜欢当理中客:“代码已修改,我认为问题已经解决。”——这时候必须打断它的自我陶醉。
我的真实输入格式:
“不要主观判断是否完成!去看最新的单测结果、看运行 Log、看 SSE 链路的断点、看接口的实际回包。基于这些客观事实,再告诉我现在哪些结论是真的,哪里还在报错。”
Aegis 里这一步经常不是“跑个测试”这么简单,而是要根据问题类型换证据源。
如果是运行时异常,我会直接让它盯链路证据:
用户: “阅读代码,告诉我为什么 chat 接口直接结束任务了:RUN_STARTED -> TEXT_MESSAGE_START/END -> RUN_FINISHED”
Agent: “我先按现有代码把 chat 接口这条 SSE 链路找出来,重点看 RUN_STARTED -> TEXT_MESSAGE_START/END -> RUN_FINISHED 之间哪里会在没有文本输出时直接收尾;这次先做定位和原因分析,不改代码。”
同一类运行时 guardrail 问题,后面还连续出现过:
-
“此项目在昨天改动之后,就经常会报错
504 gateway timeout,这是为什么?” -
“为什么更新之后所有接口都是
403?”
这些都不是“再改一版 prompt 看看”的问题,而是已经进入了真实运行链路的故障诊断。到了这一步,你有没有日志、有没有链路视角、有没有分阶段恢复能力,决定了这个 Agent 项目到底是工程系统,还是聊天演示。
如果是常规验证,我也不会让它直接乱跑,而是先缩小验证范围:
用户: “运行单测。”
Agent: “我来先确认这个仓库的测试入口和构建方式,然后只跑最合适的单测命令,尽量避免做高开销的额外动作。”
后面它还会继续自己做一次小 checkpoint:
“当前理解:你要我在这个仓库里执行 Python 单测,而不是编译、打包或跑前后端全量链路。 核心目标:优先跑 tests/unit。 下一步:执行最小范围的 pytest。 验证方式:以 pytest 的退出码、通过/失败/报错统计为准。”
这一段特别能说明我的方法:我不是让模型“去验证一下”,而是让它先定义清楚‘这次验证到底验证什么、验证到什么粒度、什么算证据’。
3.8 阶段八:强制回写,防止经验蒸发
任务不是死在“做不完”,而是死在“今天做完了,明天全忘了”。
我的真实输入格式:
“任务暂停。请把这一轮我们具体做了什么、用什么客观手段验证了什么结论、以及还剩哪些 Bug/待办没做,全部规范地回写到 Spec / Handoff 文档里,保证下一轮能直接无损接着干。”
3.9 阶段九:阶段完成不等于结束,要把真实环境反馈再喂回模型
很多人做到这里就停了:本地单测过了、代码看起来也顺眼,于是宣布“这一阶段完成”。但在真实项目里,这通常还远远不够。阶段性核心目标真正完成的标志,不是模型说它做完了,而是它已经在真实链路里经受过 Review、测试环境验证、人工操作和日志回放。
我实际采用的节奏通常是这样的:
-
先 Review:确认这一轮改动有没有偏离最初的阶段目标,有没有为了修一个点顺手污染主架构。
-
再提测试环境:把模型认为“已经完成”的结果放到更接近真实运行时的环境里接受检验。
-
做手动测试:用真实的操作路径去点、去试、去复现,而不是只看模型挑过的那几个 happy path。
-
回收运行日志:把接口回包、报错堆栈、链路日志、异常现场整理出来,不靠印象判断。
-
把日志重新喂回模型:让它基于真实证据解释“问题到底解决到哪一步了、还差哪一步、下一轮最小核心目标是什么”。
这不是我事后总结出来的漂亮流程,Aegis 里真实就有过这种输入:
“查看此分支的提交,特别是最近的提交。我已经把代码发布、部署到了 pre 环境,我该如何测试这几个 case?”
注意这句的重心已经完全不是“继续写代码”,而是把代码推进到真实环境以后,如何把测试路径、验证证据和下一轮修复入口重新组织起来。
这一步非常关键,因为它把“模型执行”变成了“证据驱动的再收敛”。也正是在这个意义上,我理解的 Harness,不是放任模型一路做下去,而是不断设定阶段性核心目标,不断检查是否真的完成,不断把真实世界的反馈重新灌回这个闭环里。
这里我再放一个我非常喜欢的真实收尾句子,因为它最能体现“总目标”和“阶段目标”的区别:
“从这次约定的范围看,完成了。 …… 所以如果你问的是‘这次最小收敛任务是否完成’,答案是完成了。 如果你问的是‘整个项目所有类似权限边界是否彻底治理完’,那还没有,当前只是把这条 security policy 主链先收住了。”
这段话表面上像总结,实际上是 Harness 里非常硬的一步:把“阶段完成”明确说清,把“尚未完成的总目标”也明确说清。
如果你不逼模型做到这一点,它就会特别容易在阶段性交付时制造一种错觉:看起来好像一切都完成了,实际上只是某条主链暂时被收住,系统层面还有大量剩余工作没有被重新定义。
4. Mini Walkthrough:一轮真实的推进与纠偏推演
为了让大家感受这套节奏的连贯性,我把上述步骤串成一次提炼过的完整实战推演。
【起点】我绝不这样开场: “帮我把这个 Agent 的后端全写出来。”
【我的起手式】: “先读架构设计文档,理解我要做什么;不要急着实现,先复述你的理解,并告诉我你认为项目主线应该怎么收敛。”
【收敛后】我绝不说: “好的,开始写吧。”
【我的追问】: “好,既然对齐了,现在先把这轮任务压成一份最小 Spec,写清目标、范围和边界;没有我的允许,不要展开具体的实现细节。”
【第二天恢复】我不说: “接着昨天那个接口继续写。”
【我的强制拉起】: “先读昨天落盘的 Spec 和 Handoff 记录,告诉我现在做到哪里了、还剩什么、你建议从哪一段接着起手。”
【真正动手前】我不说: “那就按你的建议改吧。”
【我的门禁 Checkpoint】: “先别改代码。做一次 Checkpoint,总结当前理解、核心目标、下一步动作、风险和验证方式;我确认无误后你再执行。”
【改完代码后】我不接受: “我觉得已经修好了。”
【我的客观验证】: “不要用主观判断。去看测试、日志和接口的实际回包,基于事实再告诉我现在是什么状态。”
【阶段验收】我也不直接说: “那这轮就结束了。”
【我的真实闭环】: “先过一遍 Review,再提到测试环境做手动验证;把新的日志和现场现象再带回来,让模型基于真实证据重新判断:这一阶段的核心目标到底是不是已经真正完成了?如果没有,下一轮最小目标是什么?”
【准备下班】我不直接关网页。
【我的闭环约束】: “把这一轮实际做了什么、验证了什么、留了什么坑,全部回写到 Spec/Handoff 里去。”
5. 真实回合里最关键的不是顺利,而是纠偏
如果你去翻我在 Aegis 里的很多真实记录,会发现最有价值的部分往往不是“模型一路做对了什么”,而是它开始偏的时候,我怎么把它拽回来。
一个非常典型的真实链路,大致就是这样:
-
我先让它读 handoff 恢复任务。 这一步的目标不是“赶紧继续干”,而是先把总目标、阶段目标和当前状态重新对齐。
-
它开始想直接推进实现。 这时候我不会顺着它走,而是先卡一个 checkpoint,让它重新说清当前理解、下一步动作和验证方式。
-
跑到运行时,真实日志开始反咬。 例如
RUN_STARTED -> TEXT_MESSAGE_START/END -> RUN_FINISHED这种空结束,或者改完以后出现504、403。 -
我不会让它继续“顺手多修几个点”,而是重新压缩阶段目标。 原来更大的阶段目标可能是“收敛 LangGraph 对话层”;但在这一刻,本轮最小目标会被重新定义成“先定位 chat 为什么直接收尾”。
-
它定位完、修一轮以后,我也不会立刻认定完成。 我会把它推进到测试、日志、pre 环境和手动验证上,看这次最小目标是不是真的收住了。
-
最后我再逼它明确区分两件事。 这次最小收敛是否完成?整个系统性的总问题是否完成?如果没有,下一轮最小目标是什么?
这整条链路里,最关键的变化其实只有一句:
阶段目标不是一开始定完就不动了,而是要随着真实证据不断重新对齐。
所以我后来越来越不把 Harness 理解成“严格按预设流程走完”,而是更像一种动态控盘能力:
-
大方向靠总目标锚住
-
当前轮次靠阶段目标收束
-
一旦证据变了,就马上重定义这一轮的最小目标
这才是为什么我会不断让模型复述、不断让它 checkpoint、不断让它看日志、不断让它重新说“现在到底做到哪一步了”。 表面上看是在重复,实际上是在持续把非确定性的执行重新压回可控轨道。
6. 一个更完整的真实 session 拆解
如果前面的内容还是偏“抽象总结”,那我这里再给一版更接近真实工位现场的拆解。 这不是逐字稿,但节奏、判断点和 Aegis 里的真实推进方式是一致的。
Round 1:先收敛,不实现
我的输入:
“先读架构设计文档,不要实现;先复述你理解的目标,并告诉我当前项目主线应该怎么收敛。”
我想拿到的不是代码,而是这三样:
-
它理解的总目标
-
它看到的阶段主线
-
它识别出来的边界和疑问
这一轮如果它开始主动谈实现,我会立刻打断:
“先别实现。你先把目标和边界说清楚。”
Round 2:压成最小 spec
我的输入:
“现在把这轮压成一份最小 spec,写清目标、范围、约束和暂不处理项;没有批准不要进入实现。”
我真正想确认的是:
-
它是不是知道这轮只做 spec
-
它是不是已经把“先不做什么”说清楚
-
它有没有偷偷把总目标混进本轮范围
如果它范围开始变胖,我会这样压:
“只保留这轮最小范围,其他都放到暂不处理。”
Round 3:跨线程恢复
我的输入:
“阅读 handoff / spec 恢复任务,先告诉我现在做到哪里了、还剩什么、你建议从哪一段接着推进。”
我最在意的是两件事:
-
它能不能基于外部真相源恢复,而不是靠印象
-
它有没有把下一步建议压成当前阶段目标,而不是重新开大坑
这也是为什么 Aegis 里会反复出现这种非常短的起手式:
“阅读 2026-03-07_Chat_Handoff_FullLangGraph.md 恢复任务。”
Round 4:执行前 checkpoint
我的输入:
“先别改代码。你先总结当前理解、核心目标、下一步动作、风险和验证方式;我确认后你再执行。”
这一轮我实际在检查 5 件事:
-
目标是不是还对
-
动作是不是够小
-
风险有没有被提前看见
-
验证方式是不是客观
-
它是不是又开始偷跑实现了
如果这一步说不清,后面执行越快,偏得越远。
Round 5:运行时反咬,重新定义阶段目标
执行以后,真实工程最常见的不是“顺利完成”,而是日志开始反咬。 比如 Aegis 里最典型的一轮,就是链路直接出现:
RUN_STARTED -> TEXT_MESSAGE_START/END -> RUN_FINISHED
这时候我不会顺着原来的大目标继续推进,而是立刻改写本轮目标:
“先不要扩展修复范围。当前阶段目标改成:只定位 chat 为什么直接结束。先做原因分析,不改代码。”
这一步非常像驾驶: 原本你在走大路线,但真实证据告诉你前面路塌了,那你现在的阶段目标就不能还是“开到终点”,而必须改成“先判断路为什么塌、还能不能走”。
Round 6:基于证据做阶段验收
定位和修一轮以后,我也不会直接接受“应该好了”这种说法。
我的输入:
“不要主观判断。去看测试结果、日志、接口回包和测试环境现象,基于证据回答:这次最小目标是否完成?如果没有,还差什么?”
这一轮我只认三类东西:
-
测试结果
-
日志和链路现象
-
测试环境或手动验证的现场证据
这时如果它回答:
“这次最小收敛任务完成了,但全局同类问题还没有彻底治理完。”
我会认为它终于真正进入了 Harness 的节奏。
7. 可直接照抄的 Harness 句式清单
如果你只想把这篇文章变成可以立即上手的东西,那这一节最适合直接拿去用。 这些句式不是为了“写得像 prompt 大师”,而是为了在关键节点稳定地卡住控制点。
7.1 起手收敛
先读架构设计文档,不要实现。先用你的话复述你理解的目标,并告诉我你认为当前项目主线应该怎么收敛。
先不要写代码。你先说清楚:总目标是什么,当前阶段目标是什么,你看到的边界和疑问是什么。
7.2 压最小 spec
先把这轮任务压成最小 spec,写清目标、范围、约束、暂不处理项;没有我的批准,不要进入实现。
这轮只允许收敛一个阶段性核心目标,不要把总目标里的其他事情一起带进来。
7.3 恢复任务
先读这份 spec / handoff 恢复任务。告诉我现在做到哪里了、还剩什么、你建议从哪一段接着推进。
不要凭印象续写。先以 handoff 为准,恢复当前状态,再说下一步。
7.4 执行前 checkpoint
先别改代码。做一次 checkpoint:总结当前理解、核心目标、下一步动作、风险和验证方式;我确认后你再执行。
进入执行前,你先重新复述这轮阶段性核心目标,不要谈总目标。
7.5 发现偏航时
先停,不要继续展开。你先复述:这轮阶段性核心目标到底是什么,不要谈总目标。
你现在开始超出本轮范围了。把范围重新压回当前阶段目标,只保留这轮必须收敛的部分。
先不要改代码。重新写一遍当前理解、下一步动作、风险和验证方式。
7.6 基于证据验证
不要主观判断是否完成。去看测试、日志、SSE 链路、接口回包和现场现象,基于事实再回答。
先定义清楚:这次验证到底验证什么、验证到什么粒度、什么算完成证据。
7.7 阶段验收
不要把这次最小收敛和全局完成混为一谈。明确告诉我:这轮完成了什么,还没完成什么,下一轮最小目标是什么。
先过 Review,再提测试环境做手动验证;把新的日志和现场现象带回来,再判断这轮阶段目标是否真正完成。
7.8 收尾回写
任务暂停。把这一轮实际做了什么、验证了什么、还剩哪些问题没做,全部回写到 spec / handoff,保证下一轮能直接接着干。
请把本轮的完成项、未完成项、真实偏差、残留风险和建议的下一轮目标写回外部文档。
8. 总结:只要记住这三句话就够了
如果你看完整篇教程,只能带走三样东西,我希望是下面这三句话:
-
改变输入习惯:我不再是“给大模型提一个大需求”,而是在系统推进的每一个阶段,给它一个“带极强边界和约束条件的输入”。
-
拿回控制权:我坚决不让模型一路黑盒做到底。它必须先交出中间产物,由我通过 Harness 控制点判断能不能放行到下一步。
-
理清层级:
Harness是我做大工程的底层理念,而sdd-riper(一轻量版)是我用来把这套理念变成肌肉记忆的实施协议。
把这篇实战指南压缩成最后一句:
真正高段位的 AI Agent 开发,不是在赌“模型能不能自己奇迹般地做完”,而是用 Harness 设计出一套连续的轨道节奏,再用极其克制的通信协议把这套节奏卡死。

