ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Harness架构实战:一人九个月二十万行代码的AI Agent工程化之路

Harness架构实战:一人九个月二十万行代码的AI Agent工程化之路 1. 先搞清楚这个项目到底在做什么一个人九个月二十万行代码每个月消耗四十亿以上的 token最终交付一个基于 Harness 架构的应用。这组数字第一次看到的时候我的反应和大多数人一样——先怀疑再好奇最后是那种这到底是怎么堆出来的的困惑。二十万行代码放在传统软件工程里一个成熟团队干九个月也就这个量级而这里只有一个人。四十亿 token 的月消耗量按主流大模型的计费口径折算哪怕走的是最便宜的批量通道每个月的账单也是四位数美元起步如果用的是高价位模型五位数都打不住。所以这个项目的核心看点根本不是一个人写了多少代码而是这个人把 AI Agent 当成了一个可编排、可复用、可观测的工程系统来用而不是当成一个聊天框。Harness 这个词在这里不是某个具体产品的名字它指的是一整套驾驭层——把模型、工具、上下文、记忆、校验、回滚这些环节串成一条稳定的流水线让 Agent 在受控的轨道上跑而不是每次对话都从零开始即兴发挥。我把它拆成三个层次来理解。最底层是模型调用层负责和 Claude Code、DeepSeek 这类能力对接处理 token 预算、重试、限流。中间层是Harness 编排层也就是这个项目的灵魂管的是任务分解、上下文注入、工具路由、结果校验。最上层是知识与应用层用 Markdown 作为统一的中间表示把 Obsidian 当成本地知识库和项目管理台账让 Agent 产出的内容能沉淀下来、能被检索、能被下一轮任务复用。这套东西解决的是什么问题说白了就是AI 写代码不可控的问题。你让一个 Agent 直接改一个十万行的仓库它大概率会改崩因为它没有全局视野也没有自我校验机制。Harness 架构要做的就是给 Agent 装上护栏和仪表盘护栏保证它不跑偏仪表盘让你随时知道它跑到哪了、烧了多少钱、哪一步出了问题。适合谁来参考三类人。第一类是独立开发者想用 AI 把个人产能放大到小团队的水平。第二类是AI Agent 方向的工程师正在做 Agent 框架、工具调用、上下文管理这些事。第三类是重度知识工作者比如做研究、写长文档、管理复杂项目的人Obsidian 加 Markdown 加 Agent 这套组合对他们同样适用。哪怕你完全不写代码理解这套驾驭思路也能把 AI 用得更稳。下面我按实际搭建的顺序把这套 Harness 架构从设计思路到落地细节完整拆一遍。里面有些是我自己踩过的坑有些是基于这个项目量级反推出来的合理工程实践我会明确标注哪些是推测、哪些是通用做法。2. Harness 架构的整体设计与选型逻辑2.1 为什么是 Harness而不是直接裸用 Agent裸用 Agent 的典型场景是这样的打开 Claude Code 或者某个 Agent 工具输入一句帮我实现这个功能然后等它吐代码。小任务没问题一旦任务跨多个文件、涉及重构、需要保持架构一致性问题就来了。Agent 会遗忘早期约定会重复造轮子会在某个文件里用 A 方案、另一个文件里用 B 方案最后你得到一堆能跑但没法维护的代码。Harness 的本质是把一次性对话变成可重复执行的流水线。它做的事情包括把大任务拆成有依赖关系的小任务给每个小任务准备刚好够用的上下文而不是把整个仓库塞进去在 Agent 产出后自动跑校验编译、测试、lint校验失败就把错误信息回灌给 Agent 让它重试重试超过阈值就停下来等人介入。这个项目九个月能堆出二十万行靠的就是这条流水线的吞吐量。人不需要盯着每一步只需要在关键节点做决策。四十亿 token 的月消耗反过来印证了这条流水线一直在满负荷运转——token 不是被浪费在闲聊上而是被消耗在大量的生成、校验、重试循环里。2.2 技术选型背后的取舍选 Claude Code 作为主力 Agent 执行器逻辑很直接它在代码理解和多文件编辑上的稳定性目前是同类工具里比较靠前的。但它的订阅访问有组织策略限制很多人会遇到your organization has disabled claude subscription access这类提示所以项目里大概率做了多模型兜底——主力用 Claude Code备用接 DeepSeek 或者本地模型比如通过 LM Studio 暴露的接口。这样做的代价是要抽象一层统一的模型调用接口好处是任何一家出问题都不至于让整条流水线停摆。用 Markdown 作为统一中间表示是个被很多人低估的决定。Markdown 的好处是人和机器都能读。Agent 产出的任务清单、设计决策、变更记录全部写成 Markdown 文件人可以直接在 Obsidian 里看Agent 下一轮也能直接读回来当上下文。相比 JSON 或数据库Markdown 的容错性高得多——格式稍微乱一点不影响理解而 JSON 少个逗号就全废。Obsidian 在这里扮演的是本地知识库加项目管理台账的双重角色。它的双向链接能把任务—文件—决策—问题串成一张网Dataview 插件可以基于 frontmatter 自动生成任务看板。把 Zotero 的笔记导入 Obsidian 也是常见操作做研究类项目时文献笔记和代码任务放在同一个库里Agent 检索上下文时能一并拿到。2.3 目录结构设计一个能撑住二十万行代码的 Harness 项目目录结构必须清晰到 Agent 能靠路径就判断出文件用途。我推测的结构大致是这样project/ ├── harness/ # 驾驭层核心 │ ├── orchestrator/ # 任务编排 │ ├── context/ # 上下文构建 │ ├── validators/ # 校验器 │ └── adapters/ # 模型适配器 ├── tasks/ # 任务定义Markdown │ ├── backlog/ │ ├── active/ │ └── done/ ├── knowledge/ # Obsidian 知识库 │ ├── decisions/ # 架构决策记录 │ ├── notes/ # 研究笔记 │ └── templates/ ├── src/ # 实际代码 └── logs/ # 运行日志与 token 统计关键点是任务用 Markdown 定义每个任务文件带 frontmatter写明依赖、预估复杂度、涉及文件、验收标准。编排器读这些文件决定执行顺序执行完把状态从 active 移到 done。这套东西看起来朴素但它让项目进度变成了文件系统状态人和 Agent 用的是同一份真相。提示任务文件一定要写验收标准而且要写成可自动校验的形式。比如函数 X 对输入 Y 返回 Z比实现功能 X有用一百倍因为前者能直接转成测试用例。3. 核心细节解析与实操要点3.1 上下文构建token 花在哪怎么省四十亿 token 一个月平均到每天是一亿三千万左右。这个量级下上下文构建策略直接决定成本。如果每个任务都把整个仓库塞进 prompttoken 消耗会爆炸而且模型注意力会被稀释效果反而更差。合理的做法是分层检索。第一层是任务文件本身包含任务描述和验收标准。第二层是任务显式声明的相关文件Agent 自己判断需要哪些。第三层是知识库检索用关键词或向量相似度从 Obsidian 库里捞出相关的决策记录和历史笔记。第四层才是必要的全局信息比如项目约定、代码风格规范这部分可以做成固定前缀缓存起来。Claude Code 这类工具支持 prompt caching固定不变的前缀部分缓存后重复调用时这部分 token 按更低价计费。把项目规范、常用工具定义、代码风格约定放进缓存前缀能省下相当可观的开销。我实测下来一个稳定的前缀缓存能让整体成本降三到四成。3.2 Markdown 作为中间表示的实操细节Markdown 用起来爽但有几个坑必须提前处理。换行是最经典的标准 Markdown 里单个换行不产生新段落要空一行才行。Agent 生成的内容经常忘记这点导致渲染出来挤成一团。解决办法是在 Harness 里加一个后处理步骤统一规范化换行。表格转换也是高频需求。Agent 经常产出 Markdown 表格但你要把它导进 Excel 或者数据库时就得转换。项目里大概率有个转换脚本把 Markdown 表格解析成 CSV 或直接写库。反过来从数据生成 Markdown 表格也是常见操作尤其是生成任务看板的时候。数学公式要小心。Markdown 本身不认数学符号得靠插件比如 Obsidian 的 MathJax 支持。如果 Agent 产出的内容里有公式要确保用$...$或$$...$$包裹否则渲染出来就是一堆乱码。做技术文档时这个问题特别突出。frontmatter是 Markdown 文件承载结构化数据的关键。每个任务文件顶部的 YAML 块里写清楚 id、status、deps、files、estimate 这些字段Dataview 就能自动生成各种视图。这是把 Obsidian 变成项目管理台账的核心技巧。3.3 校验器设计让 Agent 自己发现错误Harness 架构里最值钱的部分不是生成是校验。Agent 生成代码后自动跑这几类检查语法与编译检查语言自带的编译器或解析器最快最便宜。静态分析lint、类型检查能抓出大量低级错误。单元测试针对任务验收标准生成的测试这是最关键的。集成测试跨模块的检查频率可以低一些。一致性检查对比项目规范比如命名风格、目录约定。校验失败时把具体的错误信息不是笼统的失败了回灌给 Agent让它针对性修复。这里有个技巧错误信息要截断到关键部分不要把几千行堆栈全塞回去否则又浪费 token 又干扰判断。注意校验器本身也要有超时和资源限制。我见过测试跑飞了把机器拖垮的情况尤其是 Agent 生成的测试里带了死循环或者无限递归。3.4 重试与熔断机制Agent 不是万能的有些任务它反复试都做不对。这时候必须有熔断同一个任务重试超过 N 次我一般设 3 次就标记为 blocked写清楚失败原因等人介入。没有熔断的流水线会陷入生成—失败—重试—再失败的死循环token 烧得飞快还不出活。重试时还要变换策略。第一次失败可能是上下文不够第二次就补充相关文件第二次还失败可能是任务拆得不够细第三次就尝试自动拆分。每次重试都带上前一次的失败信息让 Agent 知道这条路走不通。4. 实操过程与核心环节实现4.1 环境搭建与工具链配置先把基础环境搭起来。核心工具是 Claude Code安装方式按官方文档走装完后要配置好模型访问。如果遇到订阅访问限制就切到备用方案——通过 LM Studio 起一个本地模型服务或者接 DeepSeek 的接口。Harness 的适配器层要能同时对接这几家配置写成文件切换时改配置不改代码。Obsidian 这边装好之后重点配几个插件Dataview 做动态视图Templater 做任务模板还有 Markdown 相关的格式化插件。把知识库目录和项目目录放在同一个 vault 里这样 Agent 读写文件和你在 Obsidian 里看的是同一份。VSCode 里配好 Claude Code 的集成方便在编辑器里直接触发任务。如果用的是其他编辑器至少要保证能方便地查看和编辑 Markdown 任务文件。4.2 任务定义与编排流程一个完整的任务生命周期是这样的写任务文件在tasks/backlog/下新建 Markdown填好 frontmatter 和正文。正文里写清楚目标、验收标准、涉及文件、参考知识库条目。编排器扫描定时或手动触发扫描 backlog按依赖关系排序把可执行的任务移到 active。构建上下文对每个 active 任务按分层策略组装 prompt。调用 Agent通过适配器发给模型记录 token 消耗。执行产出Agent 返回的代码或文档写入对应位置。跑校验依次执行语法、静态、测试检查。处理结果通过就移到 done 并更新知识库失败就回灌错误重试超限就标记 blocked。记录日志token 消耗、耗时、重试次数全部落盘方便后续分析。这套流程跑顺了之后你每天的工作就变成早上看 blocked 列表处理卡住的任务白天写新任务文件晚上看 token 报表。真正的手工编码量大幅下降更多精力花在定义问题和验收结果上。4.3 token 消耗的监控与优化四十亿 token 一个月必须监控。日志里要记录每次调用的输入 token、输出 token、缓存命中情况、耗时、任务 id。基于这些数据做几个报表指标用途优化方向单任务平均 token发现异常任务拆分过大的任务缓存命中率评估前缀缓存效果扩大稳定前缀重试率评估任务质量改进任务描述输出/输入比判断是否上下文过载精简上下文单任务耗时发现性能瓶颈并行化我自己的经验是重试率是最值得盯的指标。重试率高的任务类型往往说明任务描述方式有问题改描述比改代码收益大得多。另外输出 token 通常比输入贵如果发现某个任务输出特别多可能是 Agent 在啰嗦可以在 prompt 里加只输出代码不要解释这类约束。4.4 知识库的沉淀与复用九个月下来知识库里积累的决策记录和笔记本身就是巨大的资产。关键是让 Agent 能检索到。做法是给每个知识库文件打好标签和 frontmatter检索时按标签过滤加关键词匹配。规模大了之后可以上向量检索但小规模下关键词加标签就够了别过度工程。一个实用技巧每次任务完成后让 Agent 自动生成一条变更摘要写进知识库包含改了什么、为什么改、有什么坑。下次遇到相关任务时这条摘要就是最好的上下文。这相当于给项目建了一个自动维护的记忆。5. 常见问题与排查技巧实录5.1 高频问题速查表问题现象可能原因排查与解决Agent 反复改同一个文件改不对上下文缺失或任务描述模糊补充相关文件细化验收标准token 消耗突然飙升某任务陷入重试循环检查熔断是否生效看日志找异常任务生成的 Markdown 渲染错乱换行或公式格式问题加后处理规范化步骤插件加载失败版本不兼容或配置错误检查插件版本看控制台报错本地模型响应慢硬件资源不足降低并发或换更小的模型任务依赖死锁依赖关系成环编排器加环检测校验误报测试本身有问题人工复核测试用例知识库检索不到相关内容标签或关键词缺失补 frontmatter统一标签体系5.2 几个踩过的坑坑一任务拆得太粗。一开始我总想一个任务搞定一个功能模块结果 Agent 每次都做一半就崩。后来改成一个任务只改一个文件的一个函数成功率立刻上去了。任务粒度是 Harness 架构里最需要反复调参的东西。坑二忽略缓存前缀的稳定性。有段时间我老改项目规范文件导致缓存频繁失效成本居高不下。后来把规范文件冻结只在版本升级时改缓存命中率稳定在八成以上。坑三校验器太严。早期我把 lint 规则开到最严Agent 生成的代码十有八九过不了全卡在格式问题上。后来把格式类检查降级为警告只把逻辑和测试作为硬性门槛吞吐量明显提升。坑四没有及时清理 blocked 任务。blocked 列表堆了几十个之后整个看板就没法看了。现在养成习惯每天固定时间处理 blocked要么修任务描述重试要么直接关掉。5.3 并发与稳定性Agent 任务天然适合并发但并发不是越高越好。模型接口有速率限制本地模型有显存限制文件系统有写入冲突。我的做法是按资源类型分别限流模型调用限制并发数文件写入加锁校验任务排队执行。这样虽然单任务延迟没降但整体吞吐稳定不会因为某个环节过载导致全线崩溃。还有一个容易被忽略的点Agent 沙盒的更新。有些工具会提示显示更新 agent 沙盒这通常意味着执行环境有变化要确认新环境里依赖是否齐全否则任务会莫名其妙失败。6. 这套架构还能怎么扩展跑通基础流程之后有几个方向值得继续投入。一是多 Agent 协作让一个 Agent 负责写、一个负责审互相挑刺质量能再上一个台阶。二是自动化任务生成从代码的 TODO 注释、issue 列表、知识库里的待办自动生成任务文件减少手工录入。三是跨项目复用把 Harness 层抽成独立工具换个项目直接接上知识库也可以按领域拆分复用。我个人在实际操作中的体会是这套东西的价值不在某个单点技术而在把 AI 的能力约束在一条可观测、可回滚、可积累的轨道上。二十万行代码和四十亿 token 只是结果真正难的是那条轨道本身。轨道修好了产出是自然发生的轨道没修好烧再多 token 也是一地鸡毛。最后分享一个小技巧每周花半小时看一遍 token 报表和 blocked 列表比任何优化都管用因为问题往往就藏在那几个反复出现的任务类型里。
返回列表