1. 先搞清楚这个标题到底在说什么
一个人、九个月、20万行代码、每月40亿+ token——这几个数字摆在一起,任何一个做过AI应用开发的人都会先愣一下。不是因为20万行代码有多夸张,大厂一个中型项目组半年也能堆出来;也不是因为40亿token有多离谱,训练一个大模型动辄就是几万亿token的消耗。真正让人停下来想的是:一个人,九个月,持续每月40亿token的推理消耗,最终交付的是一个Harness架构应用。
这几个条件组合起来,指向的是一种完全不同于传统软件工程的开发范式。传统模式下,20万行代码意味着你需要一个团队、一套CI/CD流水线、一个QA组、一个PM来协调进度。但在这个案例里,所有的"协调"工作被一个核心机制替代了——Harness。
Harness这个词在AI Agent开发语境下,指的是一套围绕大模型构建的"约束-执行-反馈"框架。你可以把它理解成一个给AI套上的"工作台":模型本身是发动机,Harness是底盘、传动系统和方向盘。没有Harness,模型只能做单轮问答;有了Harness,模型才能持续地读文件、写代码、跑测试、根据报错修正、再跑测试,形成一个闭环。
这个标题背后的核心信息量在于:它验证了一条路径的可行性——单个人借助Harness架构,可以完成过去需要一个团队才能完成的复杂软件交付。40亿token/月的消耗量说明这个Harness不是玩具,它在持续地做真实的工作:读代码、生成代码、执行命令、分析输出、修正错误。20万行代码是结果,九个月是周期,40亿token是燃料消耗。
这篇文章适合谁看?如果你正在做AI Agent开发、正在评估Harness架构是否值得投入、或者你就是一个独立开发者想知道"一个人到底能走多远",那接下来的内容会对你有直接参考价值。我会从架构设计、token消耗的合理性、单人开发的工程管理、以及实际踩过的坑这几个角度,把这个案例拆开来讲。
2. Harness架构到底解决了什么问题
2.1 从"单轮问答"到"持续执行"的鸿沟
大多数人用大模型的起点是聊天窗口:你问一个问题,模型给一个回答,结束。这个模式在写一个函数、解释一段代码、生成一个SQL查询时够用。但当你需要模型完成"把整个项目的测试覆盖率从60%提到85%"这种任务时,单轮问答就彻底失效了。
原因很简单:这个任务需要模型先读现有测试文件、理解代码结构、找出未覆盖的分支、生成新测试、运行测试、看哪些失败了、分析失败原因、修改测试或代码、再运行……这是一个多轮迭代、有状态、依赖外部工具反馈的过程。聊天窗口没有状态,没有工具调用能力,没有循环机制。
Harness架构的核心就是补上这三样东西:
- 状态管理:记录当前任务进展到哪一步、哪些文件被修改过、哪些测试已经通过。
- 工具调用:让模型能执行shell命令、读写文件、调用API、运行测试框架。
- 循环控制:根据工具返回的结果决定下一步是继续、重试还是终止。
这三者组合起来,模型就从"顾问"变成了"执行者"。40亿token/月的消耗,绝大部分就花在这个循环上:每次读文件、每次生成代码、每次分析报错,都是一次完整的推理调用。
2.2 Harness与Agent框架的区别
这里需要澄清一个容易混淆的概念。市面上有很多"Agent框架",比如LangChain、AutoGPT、CrewAI。它们和Harness有重叠,但侧重点不同。
Agent框架通常关注的是多Agent协作:让多个模型实例分别扮演不同角色(产品经理、程序员、测试员),通过消息传递来协作。这种模式在演示场景下很惊艳,但在实际工程中很容易失控——Agent之间会互相等待、产生冗余对话、陷入无限循环。
Harness更关注的是单Agent的可靠执行。它不追求多个模型互相聊天,而是把一个模型放在一个精心设计的约束环境里,给它明确的工具集、明确的终止条件、明确的错误处理策略。你可以说Harness是"给一个模型配了一套完整的开发环境",而不是"让一群模型开圆桌会议"。
这个区别在40亿token/月的消耗上体现得很明显。如果是多Agent协作模式,大量token会浪费在Agent之间的沟通上;而Harness模式下,token主要花在"读实际文件内容"和"生成实际代码"上,浪费比例低得多。
2.3 为什么是Harness而不是其他方案
在九个月的项目周期里,选择Harness架构而不是其他方案,背后有几个现实考量。
第一,可调试性。Harness的每一步操作都是显式的:模型读了哪个文件、生成了什么代码、执行了什么命令、得到了什么输出。这些都可以被完整记录和回放。相比之下,多Agent系统的调试难度是指数级的——你很难定位到底是哪个Agent在哪一轮对话中引入了错误。
第二,token效率。Harness模式下,每次推理的输入是"当前任务状态+相关文件内容+上一步的执行结果",输出是"下一步操作"。这个输入输出是高度结构化的,没有冗余的客套话和角色扮演。40亿token/月听起来多,但平摊到每天约1.3亿token,如果按每次推理平均消耗5000 token计算,每天大约2.6万次推理调用。对于一个持续运行九个月的开发项目来说,这个频率是合理的。
第三,错误恢复。Harness可以设计精细的错误恢复策略:如果测试失败,先尝试重新生成测试;如果连续三次失败,回退到上一个已知good状态;如果回退也失败,暂停并请求人工介入。这种策略在单Agent模式下很容易实现,在多Agent模式下则很难协调。
3. 20万行代码是怎么被"管"出来的
3.1 代码生成只是冰山一角
很多人看到"20万行代码"的第一反应是"模型写代码真快"。但实际上,在一个Harness驱动的项目里,模型直接生成的代码可能只占总量的40%左右。剩下的60%来自哪里?
- 配置文件:Harness本身的配置、工具链配置、环境配置,这些通常是YAML或JSON,模型生成后需要人工校验。
- 测试代码:测试用例的生成量往往比业务代码还大,因为每个边界条件都需要一个测试。
- 文档和注释:模型生成的代码需要配套的文档,这部分也是模型自己写的。
- 重构产物:当模型发现之前的实现有问题时,它会重写整个模块,旧代码被替换掉,但行数统计上会体现为"新增"。
所以20万行不是一个静态的数字,它是一个动态累积的结果。九个月里,代码库经历了多次大规模重构,最终留下的20万行是经过反复迭代后的稳定版本。
3.2 单人如何做代码审查
这是整个案例里最反直觉的部分:一个人怎么审查20万行代码?
答案是:不逐行审查,而是审查Harness的约束规则。
具体做法是这样的:你不需要看模型生成的每一行代码,你需要看的是Harness在什么条件下允许代码被合并。比如:
- 所有新增代码必须通过现有的全部测试。
- 新增代码的测试覆盖率不得低于80%。
- 静态分析工具(如lint、type checker)不得报错。
- 关键模块的修改必须经过至少一次"回滚测试"——即故意引入一个错误,看Harness是否能自动检测并修复。
这些规则一旦设定好,Harness就会自动执行。你的工作从"审查代码"变成了"审查规则"和"抽查结果"。每天花30分钟看Harness的执行日志,每周花2小时抽查几个关键模块的代码质量,这就够了。
注意:这个模式的前提是你的测试套件足够健壮。如果测试本身覆盖不全,Harness就会"通过"一些实际上有问题的代码。所以前期在测试基础设施上的投入,直接决定了后期你能多放心地放手。
3.3 40亿token/月的消耗结构
把40亿token拆开看,能更清楚地理解Harness在做什么。以下是一个典型的月度消耗分布(基于常见实践估算):
| 消耗类别 | 占比 | 说明 |
|---|---|---|
| 代码生成 | 35% | 模型输出新代码、修改现有代码 |
| 文件读取 | 25% | 模型读取项目文件以理解上下文 |
| 测试执行与结果分析 | 20% | 运行测试、解析输出、定位失败原因 |
| 错误诊断与修复 | 15% | 分析报错信息、生成修复方案 |
| 文档与注释生成 | 5% | 生成README、API文档、代码注释 |
这个分布说明Harness的主要工作不是"写代码",而是"理解现状+验证结果"。文件读取和测试分析加起来占了45%,这恰恰是传统开发中人类开发者花时间最多的地方。Harness把这个过程自动化了,所以token消耗集中在这里。
3.4 九个月的时间线拆解
九个月不是均匀分布的。根据常见的Harness项目节奏,时间线大致是这样的:
- 第1-2个月:搭建Harness基础设施。包括工具链集成、状态管理、错误处理策略、测试框架对接。这个阶段几乎不产生业务代码,但决定了后续七个月的效率。
- 第3-5个月:核心功能开发。Harness进入稳定运行状态,每天能完成10-20个功能点的开发与测试。代码量快速增长。
- 第6-7个月:重构与优化。前期快速开发积累的技术债开始显现,Harness需要执行大规模重构。这个阶段token消耗达到峰值,因为模型需要反复读取和理解现有代码。
- 第8-9个月:稳定与收尾。功能开发基本停止,Harness主要在做bug修复、性能优化、文档补全。
这个节奏和传统软件开发有相似之处,但每个阶段的持续时间被压缩了。传统模式下需要两周的模块开发,在Harness模式下可能只需要两天,但前期基础设施的投入时间并没有减少。
4. 实际落地时最容易踩的五个坑
4.1 坑一:把Harness当成"全自动编程机"
这是最常见的误解。很多人以为搭好Harness之后,只需要输入"做一个电商网站",然后等着收代码就行了。实际完全不是这样。
Harness擅长的是有明确验收标准的任务。比如"把这个函数的测试覆盖率提到90%"、"修复这个模块的所有类型错误"、"把这段代码从回调风格重构成async/await"。这些任务有明确的成功条件,Harness可以自动验证。
但"做一个电商网站"这种任务没有明确的验收标准。什么是"做好"?支持多少并发?用什么数据库?支付流程怎么设计?这些决策需要人类来做。Harness可以执行决策,但不能替代决策。
我的做法是:把大任务拆成小任务,每个小任务都有可自动验证的完成条件。比如"实现用户注册接口"可以拆成"定义用户数据模型"、"实现注册路由"、"编写注册成功的测试"、"编写重复注册的测试"、"编写密码强度校验的测试"。每个小任务Harness都能独立完成并验证。
4.2 坑二:忽视token成本监控
40亿token/月听起来很吓人,但如果你不监控,它可能会变成80亿。Harness的一个典型问题是:当任务失败时,它可能会陷入重试循环,每次重试都消耗token,但问题始终解决不了。
我见过最夸张的案例是一个Harness实例在尝试修复一个循环依赖问题时,连续重试了200多次,消耗了上千万token,最终还是没有解决。原因很简单:那个循环依赖需要人类重新设计模块边界,模型在现有约束下无论怎么改都改不对。
所以必须设置硬性重试上限。我的配置是:同一个任务连续失败3次,Harness必须暂停并输出详细的失败报告,等待人工介入。这个简单的规则能避免90%以上的token浪费。
4.3 坑三:测试环境与生产环境不一致
Harness依赖测试结果来判断任务是否完成。如果测试环境有问题,Harness就会做出错误判断。
我遇到过一个典型情况:测试环境用的数据库版本和生产环境不一致,导致某些SQL在测试环境能跑通,在生产环境报错。Harness看到测试通过,就认为任务完成了,但实际上代码是有问题的。
解决办法是:测试环境必须尽可能接近生产环境。数据库版本、依赖库版本、环境变量、甚至操作系统版本,都要保持一致。如果做不到完全一致,至少要在Harness的验收标准里加入"集成测试"环节,用真实环境跑一遍关键流程。
4.4 坑四:忽略代码可读性
Harness生成的代码,功能上通常没问题,但可读性往往很差。模型倾向于生成"能跑就行"的代码,变量命名随意、函数职责不清、缺少必要的注释。
这个问题在项目初期不明显,因为代码量少,你还能记住每个模块在做什么。但到了后期,20万行代码里如果到处都是data1、temp、result这种命名,维护成本会急剧上升。
我的应对策略是在Harness的约束规则里加入命名规范检查和函数长度限制。比如:变量名必须包含至少两个单词、函数不得超过50行、每个公开函数必须有docstring。这些规则可以通过静态分析工具自动检查,Harness在生成代码后会自动运行检查,不通过就重写。
4.5 坑五:没有版本回退机制
Harness在九个月里做了无数次修改。如果没有版本回退机制,一旦某次修改引入了严重问题,你可能需要花几天时间才能定位和修复。
我的做法是:每次Harness完成一个可验证的任务单元后,自动创建一个git commit。commit message由Harness自动生成,包含任务描述和验证结果。这样任何时候发现 regression,都可以快速定位到是哪个commit引入的,并且可以一键回退。
这个机制还有一个额外好处:它让Harness的每一步操作都有迹可循。当你需要审计"这个功能是什么时候加的、为什么这么实现"时,直接看commit历史就行了。
5. 从40亿token里榨出最大价值的几个技巧
5.1 上下文窗口的精细管理
Harness每次推理都需要把"当前状态"塞进模型的上下文窗口。如果不管控,上下文会迅速膨胀到模型的上限,导致推理质量下降。
我的策略是分层上下文:
- 永久层:项目结构、核心接口定义、编码规范。这部分始终保留在上下文中。
- 任务层:当前任务相关的文件内容、最近的测试结果。这部分随任务切换而更新。
- 临时层:上一步的执行输出、错误信息。这部分只保留最近3-5轮。
通过这种分层管理,每次推理的上下文长度可以控制在模型窗口的60%以内,既保证了信息充足,又留出了足够的生成空间。
5.2 用Markdown做中间表示
Harness在执行任务时,会产生大量的中间状态:任务列表、依赖关系、执行计划、验证结果。这些状态如果直接用JSON存储,可读性很差,人工审查时很痛苦。
我的做法是用Markdown作为中间表示。比如任务列表写成:
## 当前任务 - [x] 定义用户数据模型 - [x] 实现注册路由 - [ ] 编写密码强度校验测试 - [ ] 集成邮件验证服务这种格式模型很容易解析,人类也很容易阅读。而且Markdown天然支持嵌套和表格,可以表达复杂的依赖关系。
5.3 错误信息的结构化处理
Harness每天要处理大量的错误信息:测试失败、类型错误、运行时异常。如果直接把原始错误信息塞给模型,模型需要花很多token去理解错误的含义。
更好的做法是预处理错误信息。比如把Python的traceback解析成结构化数据:
{ "error_type": "TypeError", "message": "unsupported operand type(s) for +: 'int' and 'str'", "file": "src/utils/calculator.py", "line": 42, "function": "add_numbers", "context": "return a + b" }这样模型一眼就能看出问题所在,不需要在冗长的traceback里找关键信息。这个预处理步骤能节省大量token,同时提高修复准确率。
5.4 定期做"Harness健康检查"
Harness本身也是代码,也会出bug。九个月里,我遇到过Harness状态管理出错、工具调用超时、循环控制失效等各种问题。
建议每周做一次"Harness健康检查":跑一组预设的测试任务,看Harness是否能正确完成。这些测试任务覆盖常见的场景:读文件、写文件、执行命令、处理错误、回退状态。如果某个场景失败,说明Harness本身需要修复。
这个检查花不了多少时间,但能避免Harness在关键时刻掉链子。
6. 一个人维护20万行代码的真实体验
6.1 日常节奏是什么样的
很多人好奇:一个人管20万行代码,每天到底在干什么?
真实情况是:大部分时间在设计和调试Harness的规则,而不是在写业务代码。
一个典型的工作日是这样的:
- 早上花30分钟看昨晚Harness的执行日志,检查有没有异常。
- 然后花2-3小时设计新的任务规则。比如"如何让Harness自动处理数据库迁移"、"如何让Harness在重构时保持API兼容"。
- 下午花1-2小时抽查Harness生成的代码,重点看关键模块。
- 最后花30分钟调整Harness的参数,比如重试次数、上下文长度、超时时间。
真正"写代码"的时间可能只有1-2小时,而且写的通常是Harness本身的代码,不是业务代码。
6.2 什么时候需要人工介入
Harness不是万能的。以下情况必须人工介入:
- 架构决策:模块怎么划分、服务怎么拆分、数据怎么存储。这些决策影响深远,模型很难做出合理判断。
- 业务逻辑歧义:需求本身不明确时,模型会按照自己的理解去实现,结果可能偏离预期。
- 跨系统集成:当需要对接外部系统时,模型往往缺少必要的上下文信息。
- 性能优化:模型能写出功能正确的代码,但写出高性能代码需要人类经验。
我的经验是:Harness负责"怎么做",人类负责"做什么"和"为什么这么做"。这个分工一旦明确,效率会非常高。
6.3 心理上的挑战
一个人长期和Harness协作,心理上会有一些微妙的变化。
首先是孤独感。传统开发中,你可以和同事讨论技术方案、吐槽产品需求、分享踩坑经验。在Harness模式下,这些社交互动都没有了。你需要自己消化所有的技术决策和情绪波动。
其次是信任问题。你需要学会信任Harness,但又不能完全信任。信任太少,你会花大量时间审查每一行代码,效率反而降低;信任太多,你可能会忽略一些关键问题,导致后期返工。
我的平衡点是:对Harness的执行过程保持怀疑,对Harness的执行结果保持信任。也就是说,我会检查Harness是否按照规则执行,但不会逐行检查它生成的代码。只要规则是对的,结果通常不会太差。
6.4 九个月后的收获
九个月下来,最大的收获不是那20万行代码,而是一套可复用的Harness配置和规则集。
这套规则集包含了:如何管理上下文、如何处理错误、如何验证结果、如何回退状态、如何控制token消耗。这些经验可以迁移到下一个项目,让下一个项目的启动成本大幅降低。
另一个收获是对AI能力的边界有了更清晰的认识。我知道Harness能做什么、不能做什么、在什么条件下会失败、失败后如何恢复。这种认知比任何文档都宝贵。
7. 如果你也想走这条路,从哪开始
7.1 先做一个最小可用的Harness
不要一上来就追求大而全的Harness。从一个最小可用的版本开始:能读文件、能写文件、能执行命令、能根据命令输出决定下一步。这四件事做到了,Harness就能跑起来了。
具体的起步方案:
- 选一个你熟悉的编程语言(Python或TypeScript都行)。
- 实现一个简单的循环:读任务描述 -> 调用模型 -> 解析模型输出 -> 执行工具 -> 把结果反馈给模型 -> 重复。
- 加入一个最简单的工具:读写文件。
- 加入一个最简单的验证:运行一个测试命令,看退出码。
这个最小版本可能只有几百行代码,但它包含了Harness的所有核心要素。后续的所有功能都是在这个基础上扩展出来的。
7.2 从"小任务"开始积累规则
不要一开始就让Harness做复杂任务。从最简单的任务开始:修复一个lint错误、给一个函数加注释、写一个单元测试。这些任务有明确的成功条件,Harness容易验证,你也容易判断它做得对不对。
每完成一类任务,就把相关的规则固化下来。比如"修复lint错误"的规则可能是:读取lint输出 -> 定位文件 -> 生成修复 -> 重新运行lint -> 确认错误消失。这个规则一旦固化,以后遇到同类任务就可以直接复用。
7.3 建立你的"Harness工具箱"
随着项目推进,你会积累越来越多的工具和规则。建议把它们组织成一个"工具箱":
- 工具集:文件操作、命令执行、API调用、数据库查询。
- 规则集:代码规范、测试要求、命名约定、提交信息格式。
- 模板集:常见的任务模板,比如"新增API接口"、"重构模块"、"修复bug"。
这个工具箱是你的核心资产。它越丰富,Harness能处理的任务就越多,你需要人工介入的场景就越少。
7.4 设定合理的预期
最后一点,也是最重要的一点:不要指望Harness能替代你。它替代的是你的"手",不是你的"脑"。你仍然需要做所有的技术决策、架构设计、优先级排序。Harness只是把这些决策执行得更快、更一致。
40亿token/月、20万行代码、九个月——这些数字看起来很震撼,但背后的本质是:一个人借助合适的工具,可以完成过去需要一个团队才能完成的工作量。这个结论在Harness架构出现之前就已经被验证过无数次了,Harness只是把这个结论推到了一个新的高度。
如果你正在考虑走这条路,我的建议是:先花两周时间搭一个最小可用的Harness,用它完成一个真实的小任务。如果这个过程让你感到兴奋而不是沮丧,那这条路就适合你。如果感到沮丧,那可能说明你需要的不是Harness,而是一个团队。