ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Harness-of-Harness:用持久项目状态破解长周期自主开发难题

Harness-of-Harness:用持久项目状态破解长周期自主开发难题 项目标题像是一篇论文技术报告式的命名但这不妨碍我们把它当做一个真正能落地的工程方案来聊。我在实际接触长周期自主软件开发时最直观的感受是单论一次函数编写、单轮测试修复现在的模型工具链已经足够能打可一旦把任务拉长到“从零搭建一个模块、反复迭代、跨文件修改、被测试结果打断再回来继续”的程度几乎每个团队都会撞上同一堵墙——状态丢了。Harness-of-Harness 这个框架的思路恰好就是从“状态”这个最底层问题动手重新设计了整个自主开发的执行骨架。下面我结合自己的工程经验把这套框架的核心设计、运行机制和落地要点拆开讲。1. 长周期自主开发的真实痛点临时上下文会骗人先说一个我在多个自主开发实验里反复踩到的现象模型在最开始的五到十分钟里表现非常“聪明”能给出干净的设计、准确的接口定义但随着任务推进它开始频繁地“忘记”自己几分钟前刚定下的变量命名会把已经废弃的旧接口又调用回来甚至会为了通过一个测试而破坏另一个模块的语义。问题不出在模型智力上而是出在执行框架对“状态”的管理方式上。1.1 上下文窗口不是记忆是“正在滚动的工作台”很多人习惯把上下文窗口当成模型的记忆体这个类比在短任务里勉强成立在长周期开发里就是误导。上下文窗口更像一张不断滚动的工作台放得下最近拿出来的材料但放不下整个项目的完整脉络。当自主开发任务需要跨多个文件、多轮测试、多次设计调整时旧信息必然被新信息顶出窗口模型就进入“局部最优”状态——它只能依据眼前这几百行上下文做决策自然会产生与全局设计冲突的动作。Harness-of-Harness 的切入角度非常明确把模型在开发过程中产生的中间决策、项目结构认知、失败教训全部外置到一套持久化状态体系里而不是指望上下文窗口能兜住一切。这样即使某个瞬间窗口里只剩当前文件的内容模型也能通过状态查询准确拿回“这个项目现在到底处于什么阶段、哪些约束依然有效”。1.2 错误累积会引发雪崩而雪崩初期毫无征兆自主开发里最隐蔽的失败模式是“小错误滚雪球”。第一次文件写入时字段命名错了第二次依赖这个字段的模块跟着错第三次测试断言基于错误行为写出来竟然通过了第四次新的改动再基于这个错误测试继续叠。单看每一步都像是局部合理的合起来就是一个逐渐偏离需求的烂摊子。传统单体式 agent 无法遏制这种雪崩核心原因是它缺少一个“状态的稳定锚点”。每一步的决策都只发生在生成当下没有把“项目当前的真实语义状态”显式记录下来。Harness-of-Harness 的做法是让外层 harness 维护一份可查询、可校验、可回滚的项目状态快照一旦检测到当前动作与既有状态冲突例如引用了不存在的接口、修改了已冻结的依赖就强制中断并重新规划而不是让错误顺着链路继续传播。1.3 规划与执行脱节是长周期失败的最大比例来源我再强调一个容易被忽略的点长周期自主开发失败大多不是“写代码”这个动作失败而是“写代码之前定的计划”失效了。模型在最开始给出的开发计划往往基于初始理解但执行到中途一定会遇到现实反馈某个依赖装不上、某个设计在现有代码里不好落地、某处业务逻辑比预想复杂。如果执行过程不能把新认知反馈回计划层最初的规划就成了一张废纸。Harness-of-Harness 通过双层结构让规划层和执行层保持了持续的闭环。内层 harness 负责具体执行执行中产生的新信息会向上同步到外层 harness 的项目状态外层 harness 再根据最新状态判断原计划是否仍然成立必要时主动切换策略、调整任务分解甚至回退到更早的稳定节点。这个“规划-执行-状态修正-再规划”的循环才是它能在长周期任务中保持稳定输出的根本原因。2. Harness-of-Harness 的架构骨架双层 harness 与状态分层如果只记住一件事我希望你记住Harness-of-Harness 不是某个特定的提示词模板也不是单一模型的行为调整而是一套“用外层脚手架去管理内层脚手架”的工程架构。标题里的“Harness-of-Harness”字面意思就是“脚手架之上的脚手架”这是理解整个框架的钥匙。2.1 Harness 到底是什么先统一概念在 AI agent 开发里harness脚手架/约束框架指的是“把模型能力稳定输出为有效行动”的那层工程结构。它包含模型调用接口、工具调用规则、错误处理策略、输出格式约束等。没有 harness模型只是一个能对话的引擎有了 harness模型才能在环境里安全地读文件、改代码、跑测试。大多数自主开发框架只有一层 harness模型 工具列表 循环控制。这层 harness 在短任务里够用但在长周期任务里会暴露出“所有问题都挤在同一层处理”的混乱。Harness-of-Harness 最核心的架构差异就是它把这一层拆成了内层执行 harness 和外层管理 harness并把项目状态独立放置形成真正的三层协作。2.2 内层 harness单个开发动作的执行闭环内层 harness 是直接面向具体开发任务的执行单元本质上是一个“感知-规划-行动-观察”的循环。它负责的事情包括理解当前子任务的目标和约束调用工具完成文件修改、命令执行、测试运行等动作将工具返回的结果整理成结构化反馈判断当前子任务是否完成或是否需要请求更多信息内层 harness 的特点是“短视但高效”。它不需要关心整个项目的宏大叙事只需要在一个子任务范围内做正确决策。它的所有输入当前目标、相关上下文、项目约束都从外层状态读取执行结果也写回外层状态而不是在自己的局部上下文里累积。2.3 外层 harness长周期开发的中枢调度外层 harness 扮演的角色类似“项目的技术负责人 进度管理员”。它不直接写代码而是管理多个内层 harness 的工作。它的职责包括将顶层需求拆解为可执行的子任务序列为每个子任务分配合适的内层执行环境监控执行结果与项目状态的偏差在任务失败、需求变化、资源受限时重新调整计划维护项目的全局语义一致性防止各子任务之间互相踩踏这个“执行由内层做管理由外层做”的分工让两种决策模式各司其职。内层可以保持很短的上下文和很快的反应速度外层可以加载更完整的项目状态来做全局判断。二者通过状态层解耦而不是通过一段超长的对话硬绑定。2.4 状态层连接两层 harness 的旋转枢纽状态层不是简单的“数据库”或者“记忆文件”它是整套框架的信息中枢。每次内层 harness 完成一个动作都会产生状态变更新增了哪个文件、修改了哪个函数、测试结果如何、留下了哪些待办。这些变更被结构化地合并进全局状态。外层 harness 在做任何规划决策前也要先查询当前状态的权威版本。这样设计最大的好处是任何一个内层 harness 崩溃、失联、或产生错误输出都不会直接污染全局。外层可以从状态快照回滚或者重新拉起一个全新的内层 harness 接着干。项目的“记忆”不再依赖某个模型的上下文窗口是否还记得而是依赖状态层是否完好。3. 持久项目状态到底存什么、怎么存细说状态设计很多人一看到“持久项目状态”就觉得是加一个数据库存聊天记录这种理解偏差很大。Harness-of-Harness 里的状态不是一个聊天历史而是一个“结构化的项目世界模型”。它要回答的核心问题是如果明天整个模型全部换成新的仅凭这份状态一个新模型能不能无缝接手这个项目如果答案是能你的状态设计才算合格。3.1 项目状态的五大实体意图、工件、依赖、进度、教训我从实际落地角度把一套合格的项目状态划分成五类实体意图Intent项目最初要解决什么问题、当前阶段要满足哪些验收标准。这是所有代码动作的意义锚点防止模型在实现过程中“好高骛远”或者“偏航”。工件Artifacts已经产生的文件、函数、配置、测试用例等。这里的关键不是简单地记录“有哪些文件”而是要记录每个文件的职责边界、关键接口的语义、设计权衡说明。依赖Dependencies模块与模块之间的依赖关系、数据流向、外部服务依赖。自主开发时模型经常犯的错就是改了 A 模块却不检查依赖它的 B 模块状态层把这张依赖图显式维护起来就能在执行前后自动做影响面分析。进度Progress哪些任务已完成、哪些进行中、哪些被阻塞、哪些已经废弃。进度信息不是简单的待办列表还要包含“这个任务的验收标准是什么”以及“当前距离完成还有哪些差距”。教训Lessons这个项目特有的坑。比如“这个代码库的测试必须用 Python 3.10 跑”“这里不能直接用第三方库格式化需要自定义规则”。教训是模型在探索中付出的真实代价不沉淀下来就是纯浪费。3.2 状态存储的工程选型从轻量到重量不同规模的项目适合不同量级的状态存储方案我给出一套自己验证过的选型参考项目规模推荐方案理由小型脚本/单一模块Git 仓库 Markdown/JSON 笔记轻量状态可随 commit 回溯中型多模块项目SQLite 文件系统快照结构化查询方便事务保证状态一致性大型多仓/团队协作PostgreSQL/文档数据库 对象存储多人多 agent 并发访问需要强一致性和权限控制无论哪种方案我强烈建议把状态文件和项目代码放在同一个版本控制体系里也就是“状态本身也要可回溯”。这样当模型做一个错误决策后你不仅能回滚代码还能回滚“决策过程”从根源上避免同样的错误重演。3.3 状态的更新节奏同步、异步与冲突处理状态更新的频率直接决定了系统的行为特征。我在实践中总结出三条原则关键节点同步更新文件写入完成、测试执行结束、任务标记完成这三个节点必须同步落库任何中间过程的异步延迟都可能导致状态不一致。中间过程异步归并模型每生成一批 token 就写一条状态既不现实也没必要应该把“一个完整动作”作为最小更新单元避免状态库被高频小写刷爆。冲突时必须显式举手两个内层 harness 同时修改了同一个模块时状态层不能静默覆盖而要把冲突标记出来交给外层 harness 裁决。这个“显式冲突报告”机制能避免大量隐性状态损坏。我还想额外提一点关于上下文管理的细节持久状态的一个重要职责就是充当上下文窗口的“外挂索引”。当内层 harness 需要某个历史决策细节时不需要在有限上下文里翻找聊天记录而是直接按实体 ID 去状态库精确加载相关片段。这其实是一种“按需召回”的记忆模式Token 消耗反而比把所有历史硬塞进窗口更低。4. 一次完整的长周期自主开发旅程从需求到交付的运行实录理论讲完我用一个虚构但高度典型的场景来串一遍整个流程假设我们要做一个内部数据看板系统包含数据接入、指标计算、API 服务、前端展示四个模块预计要完成的时间跨度相当于一个真实团队两到三周的开发量。Harness-of-Harness 会如何推进4.1 初始规划为什么外层要先建“意图树”而不是立刻写代码启动阶段外层 harness 接到需求后做的第一件事不是让内层 harness 去新建项目文件而是先构建一棵“意图树”。顶层意图是“数据看板系统上线”往下拆出四个子意图对应四个模块每个子意图再细化出若干可验证的里程碑。这套“先意图后实现”的顺序对长周期开发至关重要。当执行到第二周时内层 harness 可能会被某个具体的 API 设计问题卡住产生“要不换个技术栈”之类的偏航冲动。这时候外层 harness 只需要查一下意图树就能判断这个冲动是否和顶层目标一致。如果一致就走计划变更流程如果不一致就强制拒绝。意图树在这个场景里起到的是“北极星校验器”的作用。4.2 子任务执行内层 harness 的“短线程”工作模式外层规划完成后会为每个子任务启动一个独立的内层 harness。以“实现指标计算模块”为例内层 harness 拿到的是这样一份任务单目标计算活跃用户数、留存率等指标、输入数据位置、输出接口规范、相关依赖模块、完成验收标准。这份任务单由外层从状态库中组装不携带任何无关的聊天历史。内层 harness 开始工作后它会按部就班地读取数据源、设计数据结构、编写计算逻辑、补测试用例。每一步的输出都会在完成后回写状态层。如果中途发现某个数据结构与预期不符它会把这个异常作为“状态更新”上报给外层而不是自己盲目改数据源。这种“短线程”工作模式带来的直接好处是每个内层 harness 的上下文窗口永远保持精炼不会被跨模块的无关信息污染执行质量和速度都更稳定。4.3 验证与回滚状态快照让失败变成可遍历的节点任何自主开发都不可能一帆风顺。在这个虚构场景里有一个典型问题某个内层 harness 在实现 API 服务时为了追求响应速度引入了一个内存缓存方案但没意识到数据接入模块会高频更新底层数据。这个缓存逻辑会导致前端看到过期数据。如果没有状态快照这类问题的排查会非常痛苦因为模型可能已经改了十几个文件。但在 Harness-of-Harness 体系里每次关键动作前后的状态快照都在外层 harness 可以做“二分定位”先对比“引入缓存之前的状态”和“当前状态”确认问题出在哪个变更节点然后回滚那个节点再给内层 harness 追加一条教训这类跨模块交互必须走统一数据失效机制。整个排查过程不是靠模型“回忆”改了什么而是靠状态快照“精确指出”改了什么。这省下了大量试错成本也是长周期任务里最难被替代的工程价值。4.4 集成验收跨模块一致性检查如何执行到了项目后期四个模块都完成了独立开发真正的大考是集成。很多自主开发系统在这一步崩溃因为每个模块单独看都对合在一起就互相打架。外层 harness 在集成阶段会做一套“一致性扫描”检查每个模块对外的接口签名是否和调用方期望的一致检查数据流路径上的字段命名、类型定义是否统一检查测试环境与生产环境的配置差异跑一遍端到端链路并对比结果与意图树里的验收标准任何不一致都会被记录为状态冲突并分配回相应的内层 harness 修复。整个过程完全不需要人为干预外层 harness 只需要按状态层提供的最新真相持续调度即可。最后项目交付时状态库里留下的不仅是代码还有一整份“为什么这样做”的完整决策档案这对后续维护和二次开发价值巨大。5. 实测观察持久状态到底带来了哪些可感知的提升说了这么多架构终究要看疗效。我在自己的实验项目里把 Harness-of-Harness 和传统的单体长对话模式做了对比虽然实验规模不算大但几个方面的差异非常显著。5.1 任务完成率与“偏航”概率的改进最直观的指标是任务完成率。单体模式下任务在 30 分钟以上的连续开发里完成率下降得非常快经常出现“开头思路清晰后期改着改着就不知道自己在干嘛”的情况。换用 Harness-of-Harness 后即便开发周期拉长到数小时完成效率也保持在一个相对稳定的区间原因就是状态层的持久化让模型始终能正确回答“我现在在哪、下一步去哪”这两个关键问题。另一个让我印象深刻的指标是“偏航概率”。单体模式里模型经常过度设计——比如一个简单工具函数它非要抽象出三层接口。Harness-of-Harness 里由于每次扩展都会触碰状态层的“意图-成本”校验这种无意义的功能蔓延能被显著抑制。5.2 调试成本的急剧下降长周期自主开发真正让人心累的不是“写代码”而是“出了问题以后怎么解释”。单体模式下模型改坏了某个地方你往往需要从几千行对话记录里翻找线索。而在 Harness-of-Harness 的状态体系里每次变更都有记录、有快照、有回滚路径。调试时间从“小时级”降到“分钟级”这对团队的实际生产效率是非常关键的增益。5.3 资源开销收益是否值得成本任何框架设计都有代价Harness-of-Harness 也不例外。最大的额外开销在于状态维护本身每次动作都要序列化状态、写入存储、做一致性检查这会增加一些延迟和 Token 消耗。但根据我的观察这部分开销换来的是更高的任务成功率和更低的重试成本整体算总账通常是划算的。如果一定要给建议任务时长在 15 分钟以内的简单开发完全不需要上这么重的框架单体模式反而更高效。一旦任务可能跨越小时级、需要多模块协作、或者要应对环境不确定性Harness-of-Harness 的持久状态设计就成了一种近乎必要的工程保障。6. 落地指南从零复刻一套 Harness-of-Harness 最小实例如果你不想等这个框架正式开源完全可以基于现有工具链搭一套简化版。接下来我分享一个经过验证的最小可行实现路径工具都是常见的不需要什么特殊资源。6.1 第一步用 Git 做项目状态的主存储规划一个 repo 结构分成两个互不可见的目录一个是代码工作区 agent 可以直接读写另一个是状态工作区。状态工作区里面放意图文件、进度文件、教训文件每个文件用 Markdown 或 JSON 格式写按固定 schema 组织。所有状态变更都通过 Git commit 记录commit message 就是变更说明。这套方案没有做复杂的状态同步但已经满足了最核心的需求可查询读文件、可回滚切 commit、可审计看历史。我建议初期先不要引入数据库文本文件加 Git 的方案足够支撑中小型项目的验证。6.2 第二步定义内层和外层两个 agent 的职责边界外层 agent 的 system prompt 要明确写几句话你负责制定计划、分配任务、评估结果你不直接写代码你的所有决策必须基于状态目录中读取的信息如果执行结果与预期计划冲突先更新状态再调整计划。内层 agent 的 system prompt 则相反你负责执行具体实现你的目标由外层分配的任务单定义你完成任务后必须更新状态文件你无权修改意图层的内容。边界清晰后两层 agent 就不容易互相越权状态也更容易保持一致。6.3 第三步设计最小但有效的状态 schema不用想得太复杂四个 JSON 文件就能跑起来intent.json顶层目标、验收标准、当前状态未开始/进行中/已完成/已废弃progress.json子任务列表每个任务包含状态、负责人、依赖、完成定义artifacts.json关键文件及模块的索引、职责描述、最近修改时间lessons.json踩过的坑每条记录包含场景、错误行为、正确做法这些文件由内层 agent 在完成关键动作后重写外层 agent 在做决策前读取。只要坚持“先读状态再行动、动作之后写状态”这个铁律最小实例的框架就能稳定跑起来。6.4 第四步在现有成熟框架基础上改造而不是从零发明其实现在主流的 agent 框架已经提供了很多底层能力比如工具调用循环、错误处理、多模型切换等。你完全可以在这些框架上叠加 Harness-of-Harness 的状态管理层。常见的组合方式是保留底层框架的 agent 执行内核在其之上写一个外部状态管理模块用文件系统或数据库做存储再用一个调度器串起整个流程。我个人的建议是不要一上来就追求“完全自动化的架构”。先用最小实例跑通一个真实的开发任务观察状态设计是否足够支撑决策再逐步加入更复杂的依赖分析、冲突检测和并行调度能力。从轻到重比一步到位要稳妥得多。6.5 落地中最容易被忽略的三个细节最后说几个我在实际落地中踩过的坑状态文件本身也需要模型权限控制内层 agent 默认不应该有写 intent.json 的权限避免它为了实现某个局部功能擅自改顶层目标。每一次状态变更都要语义化而不是只写“更新了文件”像“因为测试发现性能瓶颈将缓存策略由永不过期改为定时过期”这样的记录才有价值流水账式的状态更新对后续决策毫无用处。建议给每个子任务设置一个最大执行时长的硬限制如果内层 agent 在指定时间内没有完成任务外层要强制中止并介入而不是让它无限重试。这个硬终止机制能避免大量隐性资源浪费。等到整个流程跑顺了你甚至会慢慢感受到一种变化看着多个自主开发 agent 在统一的持久状态下各司其职、有条不紊地推进一个跨越多天的项目那种体验和围观单体 agent 打满鸡血地写代码然后突然崩掉完完全全是两个世界。持久项目状态不是某个高不可攀的学术概念它本质上就是一句话别让项目的重要记忆只存在于一个随时会消失的上下文窗口里。把这句话贯彻到工程结构里长周期自主开发这件事就从一个碰运气的问题变成了一个可管理、可度量、可持续改进的工程问题。
返回列表