
一个人、九个月、20 万行代码、每个月烧掉 40 亿 token——这四个数字放在一起听起来像段子但这确实是我过去九个月的真实状态。我做的是一款采用 Harness 架构设计的应用整个开发周期里AI 辅助编码渗透到了需求分析、架构推演、代码生成、测试编写、文档维护的每一个环节token 消耗几乎贯穿了每天的工作流。这篇文章不是项目介绍也不是晒战绩而是想认真聊聊几件真正的硬核问题为什么一个人敢碰 Harness 架构、控制平面和执行平面怎么拆才不翻车、40 亿 token 的成本是怎么烧出来的又怎么压下去以及 20 万行代码的工程规模下一个人如何维持清醒和节奏。如果你正在独立开发中大型项目或者你所在的技术团队打算把 AI 辅助编码深度落到日常开发里这篇内容应该能给你一些别处找不到的实操参考。1. 九个月之前为什么一个人要做 Harness 架构应用1.1 一个被低估的决策从脚本工具到可生长的应用最早这个项目并没有这么宏大的野心。我最初只是想做一个内部效率工具把日常开发和运维里重复性高的操作自动化掉。但跑了大概两周之后我发现脚本式的单体代码根本撑不住需求——功能越加越多模块开始互相牵扯改一个定时任务的逻辑可能会影响到数据同步模块的行为调试成本直线上升。这时候摆在面前的选择有两个一是继续堆脚本用更仔细的命名和注释来维持混乱中的秩序但我知道这条路走到 3 万行就会崩二是推倒重来换成一种能支撑长期演进的架构方案。我选了后者而 Harness 架构就是我在权衡了插件化架构、微服务架构、事件驱动架构之后确定的路线。之所以没有选微服务是因为一个人没有运维多服务的精力和成本之所以没有选传统分层架构是因为这个应用需要高频接入各种外部能力——AI 接口、数据源、第三方工具——如果按分层架构写每一层都要为这些外部能力的差异做适配代码会爆炸式增长。Harness 架构的核心思路是用一套统一的控制核心去调度松耦合的执行单元外部能力以连接器或工具的形式插到执行层控制层完全不关心具体执行细节这正好命中了一个人开发时的最大痛点一次只关注一个模块其他的模块只要接口不变内部随便演进。1.2 一个人开发为什么反而更需要 Harness 架构很多人在中小型项目里看到 Harness 架构的第一反应是“过度设计”。但我的实际体感恰恰相反项目越是大开发人数越少越需要这种把控制流和执行流强行分开的架构。为什么因为一个人大脑的上下文窗口是极其有限的。九个月的开发周期里我不可能记住每一行代码的来龙去脉我必须借助架构约束来降低认知负荷。Harness 架构在这方面有天然优势。控制平面Control Plane只负责做决策和编排它不关心具体某个数据源怎么连接、某个工具怎么调用执行平面Execution Plane只负责把具体的事情干完它不关心当前整个系统处于什么状态。这种分离带来三个直接好处第一模块之间通过事件和协议交互一个人在写执行层某个连接器时完全不需要回忆控制层其他模块的内部实现第二每个模块可以独立测试回归范围可控不至于改一个 bug 牵出一串连锁问题第三AI 辅助编码的效率会大幅提升因为 AI 只需要看到某个模块的代码和接口定义就能给出针对性修改而不是被整个项目的大上下文拖入混乱。我在实际项目里还发现一个额外的价值Harness 架构天然适合做 AI 原生应用。控制平面本质上就是一个循环它读取输入、结合策略与上下文、决定调用哪个工具、收集结果、再次进入下一个决策而执行层则是各种工具和连接器的集合。这个模型既能让人类开发者清晰地掌控全局逻辑又能让 AI 在“决策调度”和“工具实现”两个层次上分别发挥作用。我后面会详细展开这个设计。2. Harness 架构落地控制平面与执行平面怎么拆2.1 核心模块划分Core 循环、Connector、Tool、Policy架构设计不能停在概念层面真正落地的时候必须把模块边界一刀一刀切清楚。我最终确定的模块结构是这样的模块职责关键约束Core Runtime主循环、状态机、任务编排、事件总线不直接调用任何外部服务Tool 层可复用的原子操作如代码检索、文件读写、API 请求不持有业务状态输入输出均为标准化消息Connector 层对接外部服务适配如AI 模型接口、数据库、消息中间件只做协议转换不做业务决策Policy 层策略与规则引擎如权限判断、token 预算控制、重试策略可独立配置支持热更新Event Bus模块间异步解耦通信消息结构版本化禁止跨版本透传内部字段这个划分的底层逻辑是让每一个模块都只做自己那一层的事并且只通过标准化的消息格式对外交互。比如 Tool 层的某个检索工具它接收的参数是一个 Query 消息返回的是一个 Result 消息它不知道也不关心这个 Query 是谁发来的、为什么要做这个检索Policy 层里的 token 预算控制同样是独立模块它只负责计算和决策“当前这个任务应该用哪个模型、预算上限是多少”具体的模型调用由下层的 Connector 执行。我在早期版本里犯过一个典型错误就是让 Tool 层直接判断“如果当前用户是管理员就直接放行”。这一行代码看似省事实际上把权限策略硬编码进了执行模块导致后来调整权限逻辑时要在十几个 Tool 里面来回改。重构之后强制约束所有权限判断必须通过 Policy 层下发决策执行模块只执行结果。这个规则一开始会让人觉得多绕了一层但九个月后回头看这条规矩至少帮我避免了上百次分布式改代码的悲剧。2.2 接口设计与状态管理的关键决策Harness 架构最容易翻车的地方不是模块划分而是模块之间的消息契约和状态管理。我踩过的第一个大坑是消息结构一开始定义得太随意字段命名不统一不同模块各自理解某些字段的语义结果一旦消息格式需要变更牵连的模块到处都是。后来我用三个原则稳住了接口设计。第一所有消息必须有明确的 message_type 和 version 字段相同模块的同一类型消息必须共用同一套 schema第二所有跨模块消息禁止携带模块内部私有字段比如 Connector 层临时生成的 request_id 就不允许透传到 Policy 层第三消息变更必须走迁移流程旧的 version 至少保留一个兼容周期而不是直接改字段。这些规矩看起来繁琐但它让 AI 辅助编码变得异常好用——因为 AI 在帮你改某个模块代码时能从消息 schema 上精确推断出该模块的对外契约而不需要全局搜索所有调用点。状态管理方面我采用了“控制核心集中持状态、执行模块无状态”的模型。Core Runtime 维护一个状态机记录当前任务处于什么阶段、已经收集了哪些信息、下一步需要什么执行层模块被调用时只能拿到任务相关的上下文完成操作后返回结果自己不留任何值得关心的状态。这样做的好处非常明显出问题的时候我只需要沿着状态机的路线图去检查哪一步出了岔子而不需要在一个模块内部寻找隐藏的缓存状态。2.3 让 20 万行代码睡得着觉的测试策略一个人写 20 万行代码最焦虑的不是写不完而是改了代码之后不知道自己有没有改坏东西。Harness 架构在测试上的核心优势就是“每个模块都可以独立于整个系统进行测试”关键在于测试必须分层且每一层的重点不同。我在项目里落地了三层测试策略。第一层是单元测试重点覆盖 Tool 层和 Connector 层的每个原子操作这一层要求覆盖率尽量高因为这些模块是系统的螺丝钉螺丝钉坏了整个机器都转不动第二层是契约测试专门验证消息 schema 的兼容性特别是升级版本后旧的消费者是否仍然可用第三层是集成测试模拟完整的任务链路从输入进入 Core Runtime 开始经过 Policy 决策、多个 Tool 调用、结果汇总直到最终输出确保整体流程不出错。这条测试路径说起来简单真正难的是对 AI 生成的测试代码保持警惕。AI 非常擅长生成“充满断言但什么都没测出来”的测试——比如断言一个函数调用后返回的变量不等于 null这种断言几乎没有任何防御价值。我的应对方式是在 prompt 中明确要求测试必须覆盖正常路径、异常路径、边界值三类场景并且提供具体的失败注入点让 AI 针对这些注入点生成断言。实测下来这样生成的测试质量会有质的提升。3. 每月 40 亿 token钱是怎么烧的又是怎么降下来的3.1 40 亿 token 都去哪了拆解一下烧钱构成每个月烧掉 40 亿 token听起来很夸张但拆解之后就很有画面感。我粗略统计过不同用途的 token 消耗占比AI 辅助编码对话大约占 55%包括让 AI 实现某个功能模块、解释报错、调整算法、重构代码、审查代码等等单元测试和测试数据生成大约占 15%AI 写测试需要先理解被测代码输入很大产出却往往只有几十行文档生成和维护大约占 10%模块 README、接口说明、架构决策记录日常问答和技术研究大约占 10%遇到不确定的 API 用法、设计模式选型直接问 AI其他调试辅助、日志分析、代码审查大约占 10%。从消耗结构就能看出来编码对话是绝对的大头但恰恰是这一类消耗最值得优化。按主流的模型 API 定价粗算假设输入输出混合成本在每百万 token 5-15 美元之间40 亿 token 的月度成本大约是 2 万到 6 万美元。这是一个很可观的数字所以第三个月我开始认真做优化目标是在不影响开发效率的前提下把 token 成本降低 40% 以上。3.2 降低 token 消耗的四板斧缓存、压缩、检索、分级第一板斧是Prompt 缓存。同一段上下文前缀如果反复出现很多模型服务商会提供 prompt caching 能力命中缓存的输入 token 价格可以降低一个数量级甚至更多。我的具体做法是在代码生成会话里维持一个稳定的系统提示词和项目约定说明不轻易变更前缀内容这样每次新对话都能命中前缀缓存长期下来节省的 token 非常可观。第二板斧是会话压缩。早期的习惯是把整个会话历史全部发给 AI 让它保持上下文连续但这有一个致命问题上下文越长输入 token 消耗越大而且 AI 的注意力会被无关内容稀释。我改成定期做中间摘要把已经讨论过的结论、决策过的方案提炼成简洁的要点只保留最近几轮完整对话。这个改动直接让长会话的 token 消耗减少了 60% 左右。第三板斧是RAG 按需取代码这也是我认为最核心的一招。面对 20 万行代码的项目AI 如果每次都要“看到”全部代码才能给出建议那 token 消耗就是天文数字。我做了个轻量级的代码库索引基于 AST 和关键词检索只把与当前任务相关的函数定义、类型声明、调用关系片段取出来塞进上下文。比如让 AI 修改某个支付回调函数它只需要看到这个函数本身、它的入参出参类型、以及被谁调用的几个关键点就足够了。这种按需取代码的方式让单次编码任务的上下文体积从几万 token 降到了几千 token。第四板斧是模型分级路由。不是所有任务都需要最强的模型我给不同任务配置了不同档次的模型简单样板代码、格式化、注释生成这类任务用入门级模型核心算法设计、复杂重构、跨模块影响分析才用旗舰模型。实测下来70% 左右的编码请求完全可以用入门级模型处理而这一部分 token 的成本只有旗舰模型的十分之一甚至更低。3.3 工程侧的 token 治理预算、监控、告警除了优化消耗工程层面还需要一套完整的 token 治理机制否则成本失控就是分分钟的事。我的做法是在应用里内置一个 token 计量模块每次调用模型 API 时记录模型名称、输入输出 token 数、调用场景、耗时等指标定期汇总分析。这么做的好处是我随时能知道哪一类任务在烧钱、哪个功能模块最耗 token。比如第五个月我发现日志分析这一场景的 token 消耗突然飙升排查后发现是日志采集逻辑出了问题大量冗余日志被送进了分析会话——这是靠监控发现的而不是等月底账单出来才被动应对。预算控制也一样我在 Policy 层写了一套动态配额规则每个月给不同场景设定 token 预算上限。当预算达到 80% 时告警达到 100% 时对非关键场景自动降级改用更便宜的模型或者切换到离线模板。这套机制让我的月 token 消耗从 40 亿级别逐步回落到 25 亿级别而开发效率几乎没有降低。我在实操中的一个体会是token 优化不能做成一次性清理而应该做成持续指标。每隔一两周就盯着 token 监控表看一遍找出消耗异常的任务类型再针对性地调整策略。这比一次性写一堆“省 token 技巧”实用得多。4. 20 万行代码背后的工程管理一个人怎么保持清醒4.1 先把规矩定下来目录结构与模块边界一览20 万行代码的规模下良好的目录结构不是美观问题而是生存问题。我在项目启动初期就强制自己遵守一套明确的代码组织规范这里放出实际结构的大致框架src/ core/ # 控制核心主循环、状态机、编排器 runtime.py bus.py exceptions.py tools/ # 原子操作集合 code_search.py file_operations.py api_client.py connectors/ # 外部服务适配 ai_provider/ # 对接不同 AI 模型服务商 database/ message_queue/ policies/ # 策略与规则 token_budget.py permission.py retry_policy.py models/ # 消息契约与数据结构 messages.py schemas/ utils/ # 与业务无关的工具函数 tests/ unit/ contract/ integration/这个目录结构最大的特点是所有模块通过 models 层定义的消息契约交互谁也不允许跨层调用。我把这条规矩写进了 AI 辅助编码的 prompt 里要求 AI 在生成新代码时严格按照这个目录约束来放置文件不允许自行创建不属于上述边界的新模块。几次执行下来AI 生成的文件位置和依赖方向基本都能符合预期。4.2 AI 辅助编码的边界哪些活能交哪些活必须自己来20 万行代码靠纯手工写不现实但我从第四个月开始彻底想清楚了一个问题AI 辅助编码不是全自动而是有明确边界的分工。有些活交给 AI 是效率倍增器有些活交给 AI 是埋雷。可以放心交给 AI 的包括样板代码CRUD 接口、配置读取、序列化反序列化、单元测试在明确的需求描述和边界条件下、文档注释、数据格式转换、常见算法的标准实现。这些场景要么模式固定要么有很强的确定性AI 犯错的概率低而且即使出错也容易被测试发现。不能交给 AI 的核心包括系统架构方向的调整、模块边界定义、安全策略决策、数据一致性方案设计。这些决策需要全局视野和深刻的业务理解AI 目前不具备这种“判断力”。实际操作中我会先自己把大的设计想清楚然后用非常具体的 prompt 让 AI 填充细节而不是让 AI 做任何方向性判断。比如我不会说“帮我优化一下这个模块的架构”而是说“把当前模块中与数据库直连的代码全部提取到 connectors/database 层并保持现有接口不变”。4.3 与 AI 协作的三个关键经验第一个经验是上下文要显式管理。AI 不会主动记住项目约定你在每个新对话里需要把最重要的项目背景、代码规范、当前任务目标完整地交代一遍。为此我准备了一个“项目上下文模板”里面包括项目简介、目录结构、模块职责、消息契约、编码规范、常见陷阱列表。每次开始新任务时先让 AI 读取这个模板再开始实际工作。这个习惯让 AI 的输出质量提升非常明显。第二个经验是AI 生成的代码必须走评审流程。一个人写代码很容易跳过代码评审但引入 AI 之后评审更加不能省。我会定期使用 AI 作为代码审查助手让它按“功能正确性、边界条件、性能隐患、模块依赖正确性”四个维度审查已有代码。更重要的是AI 审查完我还要自己做一轮抽样检查因为 AI 审查有时会被上下文迷惑给出误导性的修改建议。第三个经验是重构要谨慎不能频繁大改。一个人加 AI 的组合很容易陷入过度重构的陷阱——AI 总是能给出更优雅的写法。但九个月的周期告诉我优雅不是第一位的稳定才是。我把重构限制在两种情况一是新增功能确实需要调整模块边界二是运行时性能或资源消耗出现了明确问题。其他时候无论 AI 怎么写代码只要符合规范、通过测试、没有明显性能问题就放行。这个原则让我避免了很多由于频繁改代码带来的次生 bug。5. 踩坑记录token 失效、认证错误、代码覆盖冲突5.1 token exchange failed 系列错误的排查思路九个月里遇到最多的运行时错误就是形形色色的 token exchange failed。这类错误表面上是“token 交换失败”但根因可能各不相同。我整理过一条排查路径可以分享给你第一步看错误的具体阶段是登录时失败还是请求中刷新 token 失败还是某个 API 调用返回了认证错误。阶段不一样排查方向完全不同。第二步检查 refresh token 是否过期这是最容易忽略的点。很多系统的 access token 有效期只有几十分钟refresh token 可能持续几天但也会过期。一旦 refresh token 过期就会在某个关键时刻给你抛出 token exchange failed。第三步检查系统时间与时钟偏移JWT token 的签发和校验依赖时间如果本地机器时间与服务器时间偏差过大就会出现签名校验失败。这个问题在虚拟机里尤其常见。第四步检查网络链路和配置域名错误、代理配置错误、请求头丢失都会导致服务端无法确认你是你。第五步检查服务端策略某些服务商对请求来源有合规限制如果返回的地区策略错误应该从业务合规的角度检查服务配置而不是尝试绕开限制。5.2 refresh token 的正确管理续签、重试与缓存token 管理模块是我后期重点加固的地方。一开始图省事只在每次请求前检查 access token 是否过期过期就刷新一次。后来发现这种方案在高频调用下非常脆弱——多个任务并发刷新同一个 refresh token会导致部分请求失败。最终我实现了一个独立的 TokenManager 模块统一处理认证生命周期。它维护着一个 token 状态机初始态是未认证调用认证接口进入已认证access token 即将过期时进入刷新流程刷新失败时根据失败原因决定是重试还是回到未认证状态。刷新操作加了一个关键保护并发请求共享同一个刷新任务等待同一个结果而不是各自发刷新请求。另外刷新失败后采用指数退避策略不立刻重试避免在服务端临时故障时把连接打爆。本地缓存方面token 不会只存在内存里重启后需要丢掉重来而是加密存储到本地文件中且设置合理的提前过期时间。这样在应用重启时只要 refresh token 还有效就能无缝接管原会话不打断正在进行的任务。5.3 AI 生成代码的三大隐藏雷区20 万行代码里大约有超过一半的行数来自 AI 生成但 AI 生成代码最大的问题不是语法错误而是隐藏逻辑错误。我总结出三大雷区个个都踩过第一个雷区是“合理幻觉”。AI 经常生成看起来逻辑完整、变量命名规范、注释到位的代码但实际上有一些微妙的逻辑错误。比如某个边界条件没有处理或者某个分支的返回值与函数签名不匹配。这种错误单看代码很难发现必须靠测试兜住。第二个雷区是“上下文遗忘”。AI 在长会话中会逐渐忘记早期的约束条件比如你可能在会话开头告诉它某个字段的值必须是正整数但过了二十轮对话之后它可能生成一段对这个字段直接做字符串拼接的代码。所以关键约束我会放在项目上下文模板里每次对话都让它重新加载。第三个雷区是“风格漂移”。AI 在不同时间生成的代码风格可能差异很大——有的用类组织有的用函数组织有的显式处理错误有的直接抛出异常。这种风格漂移在代码量少时无所谓但长期积累会让整个项目越来越难维护。我的解法是在编码规范里写明风格偏好并且定期让 AI 对所有模块做一次风格检查和统一。九个月做下来我最大的感受是一个人完成 20 万行代码的项目靠的从来不是超出常人的意志力而是把架构决策、工具链、AI 协作方式、成本控制都变成了一套可复用的系统。Harness 架构给了我稳定的骨架token 治理让我不至于被账单压垮AI 辅助编码把单人产能拉到一个小团队的规模而明确的分工边界让我在疯狂迭代时还能保持对每一个模块的控制力。如果你也想一个人挑战中大型项目我的建议很直接先花时间把模块边界定清楚再花时间把上下文模板写到位最后才谈得上效率和代码量。边界不清AI 帮不了你只会让你的代码库更混乱边界清楚哪怕每天只写几百行九个月后也能堆出一个让人踏实的系统。