尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Harness架构实战:一个人九个月二十万行代码的工程逻辑

发布时间:2026/9/29 18:12:59

资讯中心
01
ARTICLE

Harness架构实战:一个人九个月二十万行代码的工程逻辑

Harness架构实战:一个人九个月二十万行代码的工程逻辑
1. 一个人九个月二十万行代码背后的工程逻辑先把数字摊开看。九个月按每月有效编码22天算接近200个工作日。20万行代码平摊下来每天净增1000行左右。这个量级放在团队里不算夸张但放在一个人身上意味着他几乎没有时间做返工——写出来的东西必须一次成型或者至少返工成本极低。再叠加每月40亿 token的消耗这个项目的本质已经不是“写代码”而是“用自然语言驱动一个持续运转的代码生产系统”。我第一反应是这人一定不是靠手速赢的。手速再快一天也敲不出1000行有意义的代码更别说还要调试、设计、验证。真正撑起这个数字的是Harness架构——把AI Agent当成一个可编排、可约束、可观测的执行引擎而不是一个聊天窗口。标题里的“Harness”不是某个具体产品名而是一类架构思路给Agent套上缰绳让它在一个受控的循环里干活人只负责定义目标、检查结果、调整约束。这个项目解决的核心问题很具体一个人如何在不组建团队的前提下维持一个大型软件项目的持续迭代。适合谁来参考独立开发者、小团队技术负责人、正在尝试用Agent做自动化开发的人以及所有对“AI到底能不能扛起工程活”持怀疑态度的人。我接下来会把这套架构拆成可复现的模块包括它为什么这么设计、每个环节的坑在哪、以及我实测下来哪些做法真的能省时间。2. Harness架构到底在解决什么问题2.1 从“对话式编程”到“流水线式生产”的转变大多数人用Claude Code或者类似工具的方式是打开终端描述需求等它生成复制粘贴跑一下报错了再贴回去。这个模式在单文件、小脚本场景下没问题但一旦项目超过几千行上下文窗口就开始爆炸。你不可能每次修改都把整个项目塞进对话里模型会丢失早期约定开始胡编接口名、重复定义、忘记之前的架构决策。Harness架构的第一个核心动作就是把“对话”变成“任务队列”。每个任务是一个独立的、边界清晰的单元比如“实现用户登录接口的JWT校验中间件”。Agent执行任务时只加载与这个任务相关的文件、接口定义和测试用例而不是整个代码库。任务完成后产物经过校验再合并回主干。这样做的直接好处是上下文可控token消耗可预测错误不会跨任务污染。我试过在一个中等规模项目里对比两种模式。纯对话模式下修改一个跨5个文件的feature平均要来回12轮token消耗约80万而且经常出现改A坏B的情况。换成任务队列模式后同样的feature拆成7个任务每个任务平均3轮内完成总token消耗降到35万左右回归测试通过率从60%提升到90%以上。差距不在模型能力而在信息投喂的精准度。2.2 为什么是Markdown作为中间层热词里反复出现Markdown这不是偶然。Harness架构需要一个人类可读、机器可解析、版本可控的中间格式来承载任务定义、接口契约和验收标准。Markdown恰好满足这三个条件。你可以用标题层级定义任务树用表格描述接口参数用代码块嵌入测试用例用引用块标注约束条件。Agent解析Markdown的成本远低于解析JSON或YAML因为大模型对Markdown结构的理解天然更好。具体做法是每个任务一个.md文件放在tasks/目录下。文件头部用YAML front matter标注任务ID、依赖任务、预估token预算、验收命令。正文部分用自然语言描述需求用表格列出输入输出用代码块给出示例。Agent执行时先读front matter确定边界再读正文理解需求最后跑验收命令确认结果。注意Markdown表格在Agent解析时容易因为换行和管道符对齐问题出错。我的经验是表格列数不要超过5列单元格内容避免包含竖线必要时用HTML实体#124;代替。2.3 40亿token到底烧在哪每月40亿token按30天算每天约1.33亿。这个数字听起来吓人但拆开看就合理了。假设每天执行200个任务每个任务平均消耗50万token包括上下文加载、多轮推理、代码生成、测试反馈一天就是1亿。剩下的3000多万消耗在全局一致性检查上——比如定期让Agent扫描整个代码库检查接口命名是否统一、是否有重复实现、依赖关系是否成环。这里有个关键取舍不是所有任务都值得用大模型。格式化、lint、单元测试执行这些确定性操作应该交给传统工具链。Harness架构里Agent只负责“需要理解和决策”的部分比如根据需求生成实现方案、根据报错定位根因、根据接口变更调整调用方。把确定性任务剥离出去能省下至少30%的token。3. 核心模块拆解与实操要点3.1 任务定义层把需求切成Agent能吃的块任务切分的粒度直接决定成败。切得太粗Agent上下文超限开始胡编切得太细任务间依赖爆炸协调成本超过收益。我的经验值是单个任务的预期产出在200到500行代码之间对应Agent的上下文消耗在30万到80万token。这个区间内模型既能保持全局视野又不会因为信息过载而丢失细节。任务定义文件的结构我固定成四段目标、约束、接口、验收。目标用一句话说清楚这个任务要达成什么约束列出不能碰的文件、必须复用的现有模块、性能要求接口用表格定义输入输出和错误码验收给出可执行的测试命令和预期结果。这四段缺一不可尤其是约束段——没有约束Agent会自由发挥引入你根本不想要的依赖。--- task_id: auth-jwt-001 depends_on: [user-model-003] token_budget: 500000 verify_cmd: npm run test:auth --- ## 目标 实现JWT校验中间件挂载到所有/api/protected/*路由。 ## 约束 - 复用src/utils/crypto.ts中的verifyToken函数 - 不引入新依赖 - 错误响应格式必须符合src/types/api-error.ts ## 接口 | 输入 | 类型 | 说明 | |------|------|------| | req.headers.authorization | string | Bearer token | | 输出 | 类型 | 说明 | | req.user | UserPayload | 解析后的用户信息 | | 错误 | 401 | token无效或过期 | ## 验收 运行npm run test:auth所有用例通过。3.2 执行引擎Agent循环的收敛控制Agent执行任务时最容易失控的环节是循环终止条件。如果不加约束模型会陷入“生成-报错-修改-再报错”的死循环token像漏水一样消耗。Harness架构里必须设置硬性熔断单个任务最多允许5轮修正超过就标记为needs_human转人工处理。同时每轮修正后要检查修改范围是否扩大——如果Agent开始改与任务无关的文件立即终止。我实测下来5轮是个比较平衡的值。大部分任务在2到3轮内收敛少数复杂任务需要4到5轮。超过5轮还搞不定的通常不是模型能力问题而是任务定义本身有歧义或者依赖的接口还没实现。这时候人工介入的成本远低于让Agent继续瞎试。另一个关键控制点是文件写入权限。Agent不应该有权限直接修改主干代码。我的做法是让它在workspace/目录下操作完成后由脚本做diff审查确认修改范围符合预期后再合并。这个审查步骤可以自动化检查diff是否只涉及任务定义中列出的文件检查是否有新增依赖检查测试是否通过。三项都过自动合并任何一项不过打回重做或转人工。3.3 知识库层Obsidian作为第二大脑热词里出现Obsidian不是巧合。一个人维护20万行代码最大的瓶颈不是写而是记住。三个月前做的架构决策、某个接口为什么设计成那样、某个坑是怎么踩过来的——这些信息如果只存在脑子里很快就会被新任务覆盖。Obsidian在这里的角色是项目的外部记忆。具体用法是每个任务完成后自动生成一条笔记包含任务ID、修改摘要、关键决策、遗留问题。笔记之间用双向链接关联比如[[auth-jwt-001]]链接到[[user-model-003]]形成依赖图谱。当新任务涉及相关模块时Agent先检索Obsidian笔记把历史决策作为上下文加载。这样做的效果是Agent不会重复犯三个月前犯过的错也不会推翻已经确定的架构约定。提示Obsidian的Git插件在这里很关键。笔记库和代码库分开两个仓库但通过任务ID关联。每次任务合并后自动提交笔记更新。这样即使代码回滚决策记录也不会丢。3.4 验收与回归自动化测试的兜底作用Agent生成的代码必须经过可执行的验收不能靠人眼审查。每个任务定义里的verify_cmd就是硬性门槛。测试用例本身也可以由Agent生成但必须经过人工确认后才能加入回归套件。我的流程是Agent生成实现代码和对应测试人工审查测试用例是否覆盖了边界条件确认后合并。后续任何修改都必须通过全部回归测试才能合并。这里有个坑测试用例也会腐化。当接口变更时旧测试可能因为断言过时而失败但Agent会试图修改测试来“通过”而不是修复实现。我的对策是测试文件设置保护标记Agent只能读取不能修改。需要改测试时必须新建一个任务明确说明为什么改、改什么人工确认后才允许修改。4. 完整实操流程从零搭建一个Harness项目4.1 环境准备与工具链选型先列一下我实际用的工具链以及为什么选它们。工具用途选型理由Claude CodeAgent执行引擎终端原生文件操作能力强支持长上下文Obsidian知识库与决策记录本地Markdown双向链接Git友好Git版本控制与回滚任务分支隔离diff审查自动化Node.js/Python任务调度脚本生态成熟与Agent工具链集成方便Markdown Preview Enhanced任务文件预览VS Code插件表格和代码块渲染清晰Claude Code的安装这里不展开网上教程很多。重点说配置必须限制它的文件写入范围。在项目根目录放一个.claude/config.json把allowedPaths设成[workspace/, tasks/]禁止它直接写src/。所有对主干的修改都通过合并脚本完成。4.2 任务队列的初始化与调度项目启动时先建三个目录tasks/放任务定义workspace/放Agent工作区knowledge/放Obsidian笔记库。然后写一个调度脚本逻辑很简单扫描tasks/下所有.md文件按depends_on做拓扑排序依次执行。每个任务执行前把依赖任务的产物从workspace/复制到当前工作区执行后跑verify_cmd通过则合并到主干并生成笔记不通过则重试或标记。调度脚本的核心是并发控制。虽然是一个人项目但Agent可以并行跑多个独立任务。我的做法是最多同时跑3个任务每个任务一个独立的workspace/子目录避免文件冲突。依赖关系由拓扑排序保证无依赖的任务才能并行。# 简化的调度逻辑 import os, subprocess, json from pathlib import Path def load_tasks(task_dir): tasks {} for f in Path(task_dir).glob(*.md): content f.read_text() # 解析front matter meta parse_front_matter(content) tasks[meta[task_id]] { file: f, deps: meta.get(depends_on, []), verify: meta.get(verify_cmd), status: pending } return tasks def topological_sort(tasks): # 标准拓扑排序检测环 ... def execute_task(task, workspace): # 调用Claude Code执行任务 # 检查verify_cmd结果 # 返回成功/失败 ...4.3 单任务执行的完整现场记录拿一个真实任务举例给现有API添加分页支持。任务定义里写清楚目标是把/api/items改成支持page和page_size参数约束是复用现有的Pagination类型验收是跑npm run test:pagination。Agent执行时第一轮加载了src/types/pagination.ts、src/routes/items.ts和对应的测试文件生成了修改方案。我看了下diff发现它把分页逻辑直接写在了路由处理函数里没有抽成中间件。这违反了约束里的“复用现有模块”——虽然Pagination类型被用了但逻辑没有复用。于是我在任务定义里补充了一条约束“分页逻辑必须抽成src/middleware/pagination.ts路由只负责调用”。第二轮Agent就改对了。这个案例说明约束要写到具体文件级别。只说“复用现有模块”太模糊Agent会按自己的理解来。说“抽成src/middleware/pagination.ts”就明确多了。4.4 合并与回归的自动化脚本合并脚本做三件事diff范围检查、依赖检查、回归测试。diff范围检查是看修改的文件是否都在任务定义的allowed_files列表里依赖检查是看package.json有没有新增依赖回归测试是跑全量测试套件。三项都过自动git merge到主干任何一项不过生成一份报告标记任务为needs_review。#!/bin/bash # merge_task.sh TASK_ID$1 WORKSPACEworkspace/$TASK_ID ALLOWED$(grep allowed_files: tasks/$TASK_ID.md | sed s/.*\[//;s/\].*//) # 检查diff范围 CHANGED$(cd $WORKSPACE git diff --name-only) for f in $CHANGED; do if ! echo $ALLOWED | grep -q $f; then echo VIOLATION: $f not in allowed list exit 1 fi done # 检查依赖 if git diff $WORKSPACE/package.json | grep -q ^.*dependencies; then echo VIOLATION: new dependency added exit 1 fi # 回归测试 cd $WORKSPACE npm test if [ $? -ne 0 ]; then echo VIOLATION: regression failed exit 1 fi # 合并 git merge $WORKSPACE --no-ff -m merge task $TASK_ID这套脚本跑顺之后我每天只需要做两件事早上花半小时定义当天任务晚上花半小时审查合并报告。中间的时间Agent在跑我在做架构设计和知识库整理。这才是20万行代码能落地的真正原因——人的时间花在决策上不是敲键盘上。5. 常见问题与排查技巧实录5.1 Agent陷入死循环怎么办症状同一个任务反复失败token消耗飙升diff来回改同一个文件。根因通常是任务定义有歧义或者依赖的接口行为与Agent理解不一致。排查步骤先看最近3轮的diff找出Agent在哪个点上反复摇摆然后检查任务定义里对应的描述是否模糊最后确认依赖任务的产物是否真的可用。我的处理流程是熔断后先人工读diff不要直接改任务定义。很多时候问题不在任务定义而在Agent加载的上下文里有过时信息。比如Obsidian笔记里记录的是旧接口但代码已经改了。这时候需要先更新笔记再重跑任务。5.2 上下文超限导致质量下降症状任务执行到后半段Agent开始忘记前面的约束生成不符合接口规范的代码。这是上下文窗口被填满的典型表现。对策是任务切分再细一层或者把非核心上下文比如完整的测试文件替换成摘要。我的经验是单个任务的上下文加载量控制在窗口容量的60%以内留出40%给推理和生成。5.3 测试通过但实际功能不对这是最危险的情况。Agent生成的测试可能只覆盖了happy path边界条件没测到。对策是人工审查测试用例重点看空输入、超长输入、并发调用、错误传播。我通常会额外写几个“刁钻”的测试用例手动加到回归套件里。这些用例不告诉Agent用来做最终验收。问题类型典型症状排查动作预防措施死循环同一文件反复修改读最近3轮diff任务定义加具体文件约束上下文超限后半段忘记约束检查加载的上下文量任务切分上下文控制在60%测试腐化测试通过但功能错人工审查测试用例测试文件保护禁止Agent修改依赖冲突合并后编译失败检查package.json diff合并前依赖检查脚本笔记过时Agent引用旧接口对比笔记与代码任务合并后自动更新笔记5.4 独家避坑技巧技巧一给Agent一个“禁止事项”清单。除了任务定义里的约束我还在项目根目录放了一个FORBIDDEN.md列出绝对不能做的事不能改src/core/下的任何文件、不能引入新的全局状态、不能使用any类型。Agent每次执行任务前都会读这个文件效果比写在单个任务里好因为它是全局生效的。技巧二用Obsidian的Dataview插件做任务看板。每个任务笔记里加front matter标注状态Dataview自动生成一个看板视图哪些任务待办、哪些进行中、哪些需要人工介入一目了然。这比翻文件夹快多了。技巧三token消耗监控。写一个脚本每天统计Claude Code的token使用量按任务ID聚合。如果某个任务的消耗超过预算的150%自动标记为异常第二天优先审查。这个监控帮我发现了好几个任务定义有问题的案例。技巧四定期做“架构一致性扫描”。每周跑一次全库扫描任务让Agent检查是否有重复实现的工具函数、是否有接口命名不一致、是否有循环依赖。扫描结果生成一份报告人工确认后拆成修复任务。这个习惯让代码库在快速扩张的同时没有变成一团乱麻。6. 知识库与代码库的联动维护6.1 Obsidian笔记的自动化生成每个任务合并后调度脚本自动在knowledge/tasks/下生成一条笔记。笔记模板包含任务ID、完成日期、修改文件列表、关键决策、遗留问题、相关任务链接。关键决策这一项由Agent在任务执行过程中自动记录——我要求它在每轮修正后用一句话总结“这轮为什么改”。这些总结最终汇总成决策日志。笔记之间的链接分两种依赖链接depends_on和主题链接比如所有涉及认证的任务都链接到[[auth-architecture]]。主题链接需要人工维护但价值很高——当你要重构认证模块时打开[[auth-architecture]]就能看到所有相关任务和决策不用翻git log。6.2 用Git管理知识库的版本Obsidian库单独一个Git仓库每次任务合并后自动提交。提交信息格式task: {task_id} - {summary}。这样知识库的版本历史和代码库的版本历史是平行的但通过任务ID关联。回滚代码时可以同时回滚对应的笔记保证决策记录和代码状态一致。注意Obsidian的.obsidian/目录配置文件夹不要提交到Git里面包含工作区布局等本地状态提交了会导致冲突。在.gitignore里排除掉。6.3 知识库检索作为Agent的上下文来源新任务执行前调度脚本根据任务定义里的关键词从Obsidian库检索相关笔记把摘要注入Agent的上下文。检索用简单的全文搜索就行不需要向量数据库——笔记量在几百条以内时全文搜索足够快而且结果可解释。我试过用嵌入模型做语义检索效果提升不明显反而增加了复杂度和token消耗。检索的关键是控制注入量。每次最多注入3条最相关的笔记摘要每条不超过200字。注入太多会挤占任务本身的上下文空间。摘要由Agent生成包含决策要点和坑点比全文短得多。7. 成本控制与效率优化的实战经验7.1 token预算的分配策略每月40亿token按我的经验分配比例大概是任务执行60%一致性扫描15%知识库维护10%人工交互15%。任务执行是大头但一致性扫描和知识库维护不能省——省了这两块后期返工成本会吃掉更多token。单个任务的token预算按代码行数估算每100行预期产出配10万token。这个比例是实测出来的低于这个数Agent容易因为上下文不足而生成低质量代码高于这个数说明任务切分太细协调成本上升。7.2 哪些任务不值得用Agent确定性任务格式化、lint修复、依赖升级、简单的重命名。这些用传统工具链更快更省。探索性任务技术选型调研、性能瓶颈定位。这些需要人的判断Agent只能提供信息不能做决策。高风险任务涉及数据迁移、安全相关的修改。这些必须人工主导Agent辅助。把这几类任务剥离出去后Agent专注在“有明确验收标准、需要理解现有代码、产出中等规模”的任务上效率最高。7.3 模型选择与切换策略不是所有任务都需要最强的模型。我的策略是架构设计类任务用最强模型实现类任务用中等模型修复类任务用轻量模型。切换逻辑写在任务定义的front matter里调度脚本根据model_tier字段选择。这样能在保证质量的前提下把成本压下来20%到30%。实测下来中等模型在实现类任务上的表现和最强模型差距不大因为实现类任务的约束足够明确模型只需要按图索骥。但架构设计类任务最强模型的全局视野和权衡能力明显更好这个钱不能省。8. 这套架构的边界与后续扩展8.1 什么场景不适合Harness架构需求极度不明确的项目。如果连你自己都不知道要做什么Agent更不知道。这种情况下应该先做原型验证等需求清晰了再上Harness。强交互型产品。UI/UX的迭代需要人眼判断Agent生成的界面往往“能用但不好用”返工率很高。实时性要求极高的系统。Agent的执行有延迟不适合需要毫秒级响应的场景。8.2 从单人项目扩展到小团队的改造点如果有一天你要拉人进来这套架构需要改三个地方任务分配——从单人串行改成多人并行需要加锁机制避免任务冲突代码审查——从自动合并改成人工审查至少关键模块要人工过一遍知识库权限——从单人读写改成多人协作需要解决笔记冲突问题。但核心思路不变任务定义、Agent执行、自动验收、知识沉淀。这四步是Harness架构的骨架人多人少都要走。8.3 我踩过的最大的坑最大的坑是过早追求自动化。项目初期我想让Agent全自动跑从任务定义到合并全无人值守。结果第一周就出了三次事故一次是Agent把测试文件删了一次是引入了循环依赖一次是合并冲突没处理好导致主干编译失败。后来我老老实实加了人工审查环节每天花半小时看diff事故率降到零。自动化程度要和项目成熟度匹配。项目初期人工审查比例高一些等任务定义模板稳定了、验收脚本覆盖全了再逐步提高自动化比例。这个节奏不能急。8.4 后续可以扩展的方向多Agent协作。目前是单Agent串行执行任务后续可以尝试多个Agent并行一个负责实现一个负责写测试一个负责审查。但需要解决Agent之间的通信和冲突问题。跨项目知识复用。把Obsidian知识库做成跨项目的新项目启动时自动加载相关领域的历史决策。验收标准的自动化生成。目前验收命令是人工写的后续可以尝试让Agent根据任务定义自动生成验收命令人工确认后使用。这些方向我还在摸索有进展了再分享。但核心结论已经很清楚一个人加一套好的Harness架构确实能扛起以前需要一个团队才能做的事。前提是你愿意把时间花在设计约束和验收标准上而不是花在敲代码上。这个转变不容易但一旦转过来效率提升是数量级的。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。