ARTICLE DETAIL

资讯详情

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

Harness架构实战:20万行代码的AI Agent工程化与上下文管理

Harness架构实战:20万行代码的AI Agent工程化与上下文管理 1. 先搞清楚这个项目到底在做什么一个人九个月20万行代码每个月消耗40亿以上的token最终交付一个Harness架构的应用。这组数字放在任何一个技术社区里都足够炸裂。我第一次看到这个项目描述的时候脑子里冒出来的第一个念头不是厉害而是这人到底怎么扛下来的。因为但凡自己动手写过超过一万行代码的人都知道代码量到了一定规模之后真正消耗你的不是写代码本身而是架构决策、上下文管理、调试排查和持续迭代的心力。这个项目的核心关键词是Harness架构。所谓Harness直译过来是挽具或者约束框架在AI应用开发语境下它指的是一种围绕大语言模型构建的工程化外壳——把模型能力、工具调用、上下文管理、状态持久化、错误恢复等环节全部编排在一个可控的框架里。你可以把它理解成模型是发动机Harness就是底盘、变速箱和方向盘的总成。没有Harness你只是在一堆零件里打转有了Harness你才有一辆能上路的车。这个项目之所以值得拆解是因为它触及了当前AI应用开发最核心的几个痛点如何让Agent在长周期任务中保持稳定、如何管理海量上下文而不丢失关键信息、如何用Markdown这类轻量格式承载复杂的知识结构、如何把Claude Code这类工具真正嵌入到日常开发流里。适合阅读这篇文章的人包括正在做AI Agent开发的工程师、想用Claude Code提升效率的独立开发者、用Obsidian管理知识体系的技术写作者以及所有对Harness架构好奇但还没动手的人。我接下来会从架构设计思路、核心细节拆解、实操流程、常见问题排查四个维度把这个项目的骨架和血肉尽量还原出来。不是泛泛而谈而是落到具体的技术选型、参数配置和踩坑经验上。2. Harness架构的整体设计与选型逻辑2.1 为什么是Harness而不是裸调API很多人做AI应用的第一步是直接调API写个函数传prompt拿返回结束。这在demo阶段没问题但一旦任务周期超过几分钟、涉及多轮工具调用、需要读写文件或维护状态裸调API就会迅速崩溃。原因很简单模型本身是无状态的它不记得上一轮做了什么也不知道当前环境里有哪些文件、哪些任务已完成、哪些步骤失败了。Harness架构要解决的就是这个问题。它本质上是一层编排层负责在模型和真实世界之间做翻译和调度。具体来说它要管四件事上下文组装每一轮调用模型之前把历史对话、当前任务状态、相关文件内容、工具定义等按优先级拼装成prompt。工具路由模型输出工具调用请求后Harness负责解析、执行、把结果回填给模型。状态持久化把任务进度、中间产物、错误日志写到磁盘或数据库防止进程崩溃后一切归零。错误恢复当模型输出格式错误、工具执行失败、上下文超限时Harness要有重试、降级、截断等策略。这个项目选择Harness架构本质上是因为20万行代码的规模不可能靠一次性对话完成。它必然是一个长期运行、多轮迭代、需要断点续传的系统。没有Harness这个项目在第三个月就会变成一团无法维护的乱麻。2.2 技术栈选型的背后考量从热词来看这个项目涉及的技术栈包括Claude Code、Obsidian、Markdown、Agent框架等。我基于常见实践推测一下选型逻辑Claude Code作为核心执行引擎。Claude Code的优势在于它原生支持文件读写、终端命令执行、代码搜索等操作而且对长上下文的理解能力在同类工具中属于第一梯队。用它作为Harness的底层执行器可以省去大量工具封装的重复劳动。你不需要自己写文件读写工具Claude Code已经内置了。Obsidian作为知识底座。Obsidian的核心价值是本地Markdown文件管理加双向链接。对于这个项目来说20万行代码产生的文档、笔记、决策记录如果散落在各处根本没法检索。Obsidian的vault结构可以让所有知识以Markdown形式存在本地同时通过链接关系形成图谱。热词里出现的如何将zotero的笔记导入obsidian和obsidian创建项目管理台账说明这个项目很可能用Obsidian做了项目管理和文献管理。Markdown作为通用交换格式。Markdown的好处是纯文本、可版本控制、人机皆可读。在Harness架构里Markdown可以作为模型输出和人类阅读之间的中间层。模型生成Markdown格式的任务清单、代码注释、决策日志人类可以直接在Obsidian里查看和编辑。热词里的markdown表格转换excel和markdown数学公式插件说明项目里涉及了结构化数据的展示和转换。Agent框架作为调度层。热词里出现了agent框架和吴恩达 agent 教程说明项目参考了主流的Agent设计模式。常见的Agent框架包括ReAct、Plan-and-Execute、Multi-Agent协作等。对于一个20万行代码的项目我推测它采用的是分层Agent架构顶层是规划Agent负责拆解任务中层是执行Agent负责具体编码底层是审查Agent负责质量检查。2.3 每月40亿token的消耗结构拆解40亿token一个月按30天算每天约1.33亿token。这个量级听起来吓人但拆开看就合理了。假设每天有效工作时间10小时每小时消耗1330万token。如果每轮对话平均消耗5万token包括系统提示、历史上下文、文件内容、工具定义那就是每小时266轮调用每分钟约4.4轮。对于一个需要持续读写文件、执行命令、检查输出的开发任务来说这个频率完全正常。token消耗的大头通常在三个地方一是长上下文的历史对话累积二是大文件的反复读取三是工具调用结果的回填。优化token消耗的核心思路是能摘要就不传全文能引用就不重复能缓存就不重算。这个项目能烧掉40亿token说明它在上下文管理上可能比较激进倾向于给模型更多信息以换取更高的输出质量。3. 核心细节解析与实操要点3.1 上下文窗口的精细化管理Harness架构最核心的技术难点就是上下文管理。模型的上下文窗口是有限的但项目的知识总量是无限的。你怎么决定每一轮给模型看什么、不看什么我自己的做法是三层过滤第一层是任务相关性过滤。当前任务涉及哪些文件、哪些模块、哪些历史决策只把这些内容放进上下文。比如你在改一个登录模块就不需要把支付模块的代码也塞进去。第二层是时间衰减过滤。越早的对话越可能被摘要或丢弃。通常保留最近5到10轮的完整对话更早的内容压缩成摘要。摘要的粒度可以是每10轮生成一个200字左右的概要。第三层是优先级排序。系统提示和工具定义永远在最前面然后是当前任务描述然后是相关文件内容最后是历史对话。这样即使上下文被截断被截掉的也是优先级最低的部分。注意上下文截断一定要从中间截不要从两头截。系统提示和最近一轮对话是最重要的中间的历史可以压缩。3.2 Markdown作为状态载体的具体用法这个项目用Markdown做状态管理我觉得是非常聪明的选择。具体来说可以设计几类Markdown文件任务台账。一个tasks.md文件用表格记录所有任务的编号、描述、状态、负责人哪个Agent、依赖关系。格式大概是这样任务ID描述状态依赖最后更新T001搭建项目骨架完成无2024-01-15T002实现用户模块进行中T0012024-01-18T003实现支付模块待开始T002-决策日志。一个decisions.md文件记录每个关键技术决策的背景、选项、最终选择和理由。比如为什么选PostgreSQL而不是MySQL、为什么用REST而不是GraphQL。这个文件在后续Agent做类似决策时可以直接参考避免重复推理。代码地图。一个codemap.md文件用层级列表记录项目的目录结构和每个模块的职责。Agent在需要找某个功能时先读这个文件定位再读具体代码比全局搜索高效得多。错误日志。一个errors.md文件记录每次失败的原因和解决方案。这个文件的价值在于当同类错误再次出现时Agent可以直接查表不需要重新推理。3.3 Claude Code的集成方式与配置要点Claude Code在这个项目里扮演的是手的角色——负责实际执行文件操作和命令。集成方式通常有两种一种是子进程调用。Harness通过命令行调用Claude Code传入任务描述捕获输出。这种方式简单直接但每次调用都要启动新进程开销较大。另一种是会话保持。Harness维护一个Claude Code的持久会话通过标准输入输出持续交互。这种方式效率高但需要处理会话状态同步的问题。从热词vscode配置claude code和claude code安装来看这个项目很可能是在VS Code环境里使用Claude Code的。配置要点包括设置合理的超时时间避免长任务被中断配置文件读写权限确保Agent只能访问项目目录开启详细日志方便排查问题配置模型参数比如temperature设为较低值以保证输出稳定性实操心得Claude Code在处理大文件时容易超时建议先把大文件拆成小块或者用摘要代替全文传入。3.4 Obsidian与Harness的联动机制Obsidian在这个项目里的角色是知识仓库和人类接口。Agent产生的所有Markdown文件都放在Obsidian的vault里人类可以随时打开查看、编辑、补充。同时Obsidian的插件生态可以提供额外的能力比如Dataview插件用查询语言动态生成任务列表、统计报表Templater插件自动化生成标准格式的文档Git插件自动提交变更形成版本历史Agent和Obsidian的联动通常通过文件系统实现。Agent写文件Obsidian监听文件变化并刷新界面。人类在Obsidian里编辑文件Agent下一轮读取时就能看到最新内容。这种松耦合的设计比直接调API更灵活也更符合本地优先的理念。4. 实操过程与核心环节实现4.1 从零搭建Harness骨架的步骤假设你现在要从零开始搭一个类似的Harness我会建议按以下顺序推进第一步定义状态模型。先想清楚你的系统需要维护哪些状态。通常包括当前任务ID、任务队列、已完成任务列表、当前上下文摘要、错误计数、重试次数。把这些状态用一个JSON文件或SQLite数据库存起来。第二步实现上下文组装器。写一个函数输入是当前状态输出是给模型的prompt。这个函数要处理优先级排序、长度截断、摘要生成等逻辑。建议先用简单规则实现后续再优化。第三步封装工具调用层。把文件读写、命令执行、代码搜索等操作封装成统一的工具接口。每个工具要有明确的输入输出格式、错误处理逻辑和超时设置。第四步实现主循环。主循环的逻辑是组装上下文 - 调用模型 - 解析输出 - 执行工具 - 更新状态 - 判断是否继续。这个循环要能处理各种异常情况比如模型输出格式错误、工具执行失败、上下文超限等。第五步接入持久化。把状态定期写入磁盘支持断点续传。同时把关键事件写入日志方便回溯。第六步接入Obsidian。把项目目录设置为Obsidian的vault配置必要的插件让人类可以随时介入。4.2 参数计算与配置示例以上下文窗口管理为例假设你用的是128K上下文窗口的模型你需要留出足够的空间给输出。通常建议输入不超过窗口的70%即约90K token。这90K怎么分配系统提示和工具定义5K当前任务描述2K相关文件内容50K历史对话摘要20K最近完整对话13K如果相关文件内容超过50K就需要做筛选或摘要。筛选的策略可以是按修改时间排序取最近的、按与当前任务的关键词匹配度排序、按文件大小从小到大取确保覆盖更多文件。注意不同模型对token的计算方式略有差异建议用官方提供的tokenizer做精确计算不要凭感觉估算。4.3 一次完整任务执行的现场记录我模拟一次典型的任务执行流程让你感受一下Harness是怎么工作的任务在用户模块中添加密码重置功能。第1轮Harness组装上下文包含任务描述、用户模块的文件列表、相关的数据库schema。模型输出一个计划先读用户模型文件再读路由文件然后写重置逻辑最后写测试。第2轮Harness执行文件读取工具把用户模型文件内容回填给模型。模型输出具体的代码修改方案。第3轮Harness执行文件写入工具把修改写入文件。然后执行测试命令捕获测试结果。第4轮测试失败Harness把错误信息回填给模型。模型分析错误原因输出修复方案。第5轮Harness再次执行文件写入和测试测试通过。Harness更新任务状态为完成写入决策日志。整个过程可能涉及几十轮调用消耗几十万token。但因为有Harness管理状态即使中间进程崩溃重启后也能从上次的状态继续。4.4 性能优化与成本控制40亿token一个月的成本不是小数目。优化方向主要有三个减少无效调用。有些调用是重复的比如反复读取同一个文件。可以在Harness层加缓存同一个文件在短时间内只读一次。压缩上下文。用更紧凑的格式表示信息。比如用YAML代替JSON用缩写代替全称用引用代替重复内容。选择合适的模型。不是所有任务都需要最强的模型。简单的格式转换、文件读写可以用小模型复杂的推理和代码生成再用大模型。这种分层策略可以显著降低成本。5. 常见问题与排查技巧实录5.1 Harness failed to load plugins的排查思路热词里出现了harness failed to load plugins这是Harness架构中常见的问题。排查思路如下可能原因排查方法解决方案插件路径配置错误检查配置文件中的插件目录路径修正为绝对路径或正确的相对路径插件依赖缺失查看插件目录下的requirements或package文件安装缺失的依赖插件版本不兼容查看Harness和插件的版本号升级或降级到兼容版本权限问题检查插件目录的读写权限修改权限或更换目录插件代码语法错误查看启动日志中的具体报错行修复插件代码实操心得插件加载失败时先把日志级别调到DEBUG通常能看到具体的失败原因。不要凭猜测改配置。5.2 上下文超限的应急处理上下文超限是Harness架构最常见的运行时错误。应急处理步骤立即停止当前调用避免浪费token检查当前上下文的组成找出占用最大的部分对大文件做摘要只保留关键函数签名和注释对历史对话做压缩只保留决策点和结论如果还是超限考虑拆分任务把一个大任务分成多个小任务长期解决方案是建立上下文预算机制在组装上下文之前就预估token数量超过预算就自动触发压缩。5.3 Agent输出格式错误的修复技巧模型有时候不按预期格式输出比如该输出JSON却输出了Markdown该调用工具却直接回答了问题。修复技巧包括强化格式约束在系统提示里用明确的示例说明期望格式增加校验层Harness在解析输出前先做格式校验不符合就重新请求使用结构化输出如果模型支持开启JSON mode或function calling降低temperature减少输出的随机性我自己的经验是格式错误80%是因为提示不够明确。与其在解析层做各种兼容不如把提示写清楚。5.4 长周期任务的断点续传实现20万行代码的项目不可能一次跑完断点续传是刚需。实现要点每个任务完成后立即写入状态文件不要攒批状态文件要包含足够的恢复信息当前任务ID、已完成步骤、中间产物路径启动时先读状态文件如果有未完成任务从断点继续定期做状态快照防止状态文件本身损坏注意断点续传的关键是幂等性。同一个步骤重复执行不能产生副作用否则恢复后会出现数据不一致。5.5 token消耗异常的监控与告警每月40亿token如果某天突然翻倍你需要能快速定位原因。建议做以下监控按小时统计token消耗画出趋势图按任务类型统计token消耗找出最耗token的任务设置阈值告警比如单日消耗超过2亿就发通知记录每次调用的token明细方便回溯排查token异常时重点看三个地方是不是有死循环导致重复调用、是不是有大文件被反复读取、是不是上下文压缩失效导致每次都传全文。6. 一些个人体会和后续扩展方向这个项目最让我佩服的地方不是20万行代码本身而是这个人能在九个月里保持节奏。做AI应用开发最容易陷入的陷阱是无限优化——总觉得提示还能再改改、架构还能再调调、模型还能再换换。但真正能交付的项目靠的不是完美主义而是持续迭代和快速试错。Harness架构的价值在于它把AI应用开发从手工作坊变成了流水线。你可以把上下文管理、工具调用、错误恢复这些通用能力沉淀到Harness里然后专注于业务逻辑本身。这个思路不仅适用于代码生成也适用于数据分析、内容创作、自动化运维等场景。后续如果要扩展我会考虑几个方向一是多Agent协作让规划、执行、审查三个角色互相制衡二是引入向量数据库做长期记忆解决上下文窗口的硬限制三是把Harness做成可配置的框架让不同项目能复用同一套基础设施。最后分享一个小技巧在Harness里加一个人类确认环节。对于高风险操作比如删除文件、修改数据库、执行部署命令先暂停并请求人类确认。这个环节看起来降低了自动化程度但实际上大大提高了系统的可靠性。我踩过的坑里有一半是因为Agent自作主张执行了不该执行的操作。加了这个确认环节之后类似问题再没出现过。
返回列表