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

Harness架构实战:九个月20万行代码构建AI Agent工程体系

发布时间:2026/9/29 5:23:39

资讯中心
01
ARTICLE

Harness架构实战:九个月20万行代码构建AI Agent工程体系

Harness架构实战:九个月20万行代码构建AI Agent工程体系
1. 先聊聊这个项目到底在做什么一个人九个月20 万行代码每个月消耗 40 亿以上的 token——这几个数字摆在一起的时候我第一反应不是牛而是这人到底在解决什么问题值得这么烧。先把结论放前面这个项目本质上是在做一款Harness 架构的应用。所谓 Harness 架构你可以理解成给 AI Agent 套上一副马具——模型本身是匹野马力气大但方向不定Harness 就是那套缰绳、鞍具和路标让它在一条可控的轨道上跑。它不是一个单纯的聊天界面也不是一个简单的提示词模板集合而是一整套围绕 Agent 执行、上下文管理、工具调用、状态持久化构建的工程体系。为什么这件事值得单独拿出来讲因为绝大多数人做 Agent 项目卡的不是模型能力而是工程化落地。模型能写代码、能查资料、能调工具这些早就不是新闻了。真正难的是怎么让它在几十轮、上百轮交互之后还记得自己是谁、在干什么、下一步该干嘛怎么让它的输出稳定可复现怎么把它的中间产物沉淀成可检索、可复用的知识资产。这个项目九个月烧掉 20 万行代码绝大部分精力其实都花在这些不性感但致命的地方。这篇文章适合谁看三类人。第一类是想自己动手做 Agent 应用但不知道从哪下手的开发者我会把架构选型、模块拆分的逻辑讲透。第二类是已经在做 Agent 但被上下文爆炸、状态丢失、工具调用混乱折磨过的工程师我会分享具体的排查思路和避坑经验。第三类是对 Harness、Claude Code、Obsidian 这套组合感兴趣、想搞清楚它们怎么串起来的人我会把每个环节的实操细节补全。需要提前说明的是下面涉及的具体参数、目录结构、配置方式有一部分是基于这类项目的常见工程实践做的合理补全因为原始信息里没有给出全部实现细节。我会明确标注哪些是通用做法、哪些是我个人经验推断你照着抄的时候记得结合自己的场景调整。2. 为什么是 Harness 架构而不是别的方案2.1 从提示词工程到马具工程的认知转变早期做 Agent大家的思路基本停留在提示词层面写一个足够详细的 system prompt把角色、任务、输出格式全塞进去然后祈祷模型别跑偏。这套做法在单轮任务里还行一旦任务变成多步骤、长周期立刻就崩。原因很简单——提示词是无状态的而真实任务是连续的。Harness 架构的核心洞察就在这里与其把希望寄托在模型记住上不如在模型外面搭一套脚手架主动管理它的输入输出、状态和工具。这就像训马你不能指望马自己记得路线你得给它套上缰绳、装上马鞍、沿途设好路标。模型负责跑Harness 负责往哪跑、跑多远、什么时候停。这个认知转变带来的直接后果是项目的重心从写更好的提示词变成了设计更好的执行框架。20 万行代码里真正跟提示词相关的可能不到 5%剩下 95% 全是状态管理、工具编排、上下文压缩、错误恢复这些工程活。2.2 为什么选 Claude Code 作为执行内核在众多可选方案里这个项目选择了 Claude Code 作为核心执行引擎这个选择背后有几层考量。第一是工具调用的成熟度。Claude Code 本身就是一个为读写文件、执行命令、搜索代码设计的 Agent 运行时它的工具集天然贴合在真实项目里干活这个场景。你不需要从零实现文件读写、命令执行这些基础能力直接复用就行。第二是上下文管理的可控性。Claude Code 对上下文的处理相对透明你能比较清楚地知道哪些内容进了上下文、哪些被截断、压缩策略是什么。这对一个要跑九个月、烧几十亿 token 的项目来说至关重要——上下文管理不当token 消耗会指数级失控。第三是可扩展性。Claude Code 支持通过配置扩展工具、自定义命令、挂载外部能力。这意味着 Harness 层可以在它之上叠加自己的逻辑而不是被它的能力边界锁死。提示选执行内核的时候别只看哪个模型最强。要看的是哪个运行时的工具生态、上下文策略、扩展接口最贴合你的场景。模型能力会迭代但架构选错了后面每一步都是逆风。2.3 Markdown 作为中间格式的战略价值这个项目里Markdown 不只是一个输出格式而是整个系统的中间表示层。Agent 的思考过程、任务拆解、执行结果、知识沉淀全部以 Markdown 形式落盘。为什么这么设计因为 Markdown 同时满足三个条件人类可读、机器可解析、工具生态丰富。你让 Agent 输出 JSON人看着累你让它输出纯文本机器解析难Markdown 卡在中间两边都照顾到了。而且 Markdown 的表格、列表、代码块这些结构天然适合表达任务清单参数对照代码片段这类 Agent 高频产出的内容。更关键的是Markdown 是 Obsidian 的原生格式。这就引出了下一个设计——用 Obsidian 做知识底座。2.4 Obsidian 承担的角色不只是笔记软件很多人把 Obsidian 当笔记软件用但在这个项目里它是Agent 的长期记忆和知识检索层。Agent 每完成一个任务产出的 Markdown 文件直接进入 Obsidian 库通过双链、标签、文件夹结构组织起来。下次遇到相关任务Agent 可以通过检索这些历史文件快速找回上下文而不是从零开始。这套设计的精妙之处在于它把记忆从模型内部不可控、会丢失、成本高转移到了外部文件系统可控、持久、检索便宜。模型不需要记住所有东西它只需要知道去哪找。这跟人类专家的做法其实一样——真正的高手不是什么都记在脑子里而是知道遇到问题该翻哪本书、查哪个文档。3. 核心模块拆解与实操要点3.1 上下文管理40 亿 token 是怎么烧掉的先算一笔账。每个月 40 亿 token按 30 天算每天约 1.33 亿 token。如果按单次交互平均消耗 5 万 token包含系统提示、历史上下文、工具返回结果那一天就是约 2660 次交互。九个月下来累计交互次数在几十万量级。这个量级下上下文管理不是优化项而是生死线。项目里主要用了三层策略第一层是滑动窗口加摘要压缩。保留最近 N 轮完整对话更早的内容压缩成摘要。N 的取值很讲究——太小Agent 会失忆太大token 爆炸。实践中 N 通常设在 10 到 20 轮之间具体看单轮平均长度。第二层是结构化外置。把任务状态、待办清单、关键决策这些必须记住的信息从对话历史里抽出来单独存成 Markdown 文件。每次新对话开始时只加载这个精简版状态而不是把全部历史塞进去。第三层是检索增强。需要历史细节时通过关键词检索 Obsidian 库按需加载相关片段。这比全量加载省 token 得多。策略作用典型 token 节省适用场景滑动窗口摘要压缩近期历史40%-60%连续多轮对话结构化外置精简状态加载60%-80%长周期任务检索增强按需加载历史70%-90%知识密集型任务注意摘要压缩是有损的。我踩过的坑是早期摘要策略太激进把一些看似无关但后续关键的细节压没了导致 Agent 反复问同样的问题。后来改成摘要关键实体保留把任务涉及的文件名、函数名、参数值这些硬信息原样保留只压缩叙述性内容效果好很多。3.2 工具编排让 Agent 知道什么时候用什么Agent 最容易出问题的地方不是不会用工具而是不知道该用哪个工具、什么时候用。工具一多选择困难就来了。这个项目里工具编排做了几件事工具分组与场景绑定。不是把所有工具一股脑丢给 Agent而是按场景分组。比如代码修改场景只暴露读写文件、执行测试相关的工具资料检索场景只暴露搜索、读取文档的工具。这样 Agent 的选择空间被收窄出错概率大幅下降。工具调用的前置校验。每次工具调用前Harness 层会做一次参数校验和权限检查。比如写文件操作会先确认路径在允许范围内、文件不是只读的、内容不是空的。这些校验看起来琐碎但能挡掉大量Agent 自信满满地执行了一个错误操作的情况。失败重试与降级。工具调用失败是常态不是异常。Harness 层需要定义清楚什么错误可以重试、重试几次、重试间隔多久、重试还失败怎么办。项目里对不同类型的工具调用设了不同的重试策略比如网络类操作重试 3 次文件类操作重试 1 次因为文件错误通常是逻辑错误重试没用。3.3 状态持久化Agent 的记忆怎么存状态持久化是这个项目最花功夫的部分之一。核心思路是把 Agent 的工作记忆和长期记忆分开存。工作记忆是当前任务的临时状态存在内存或临时文件里任务结束就清理。长期记忆是跨任务的知识沉淀存进 Obsidian 库永久保留。工作记忆的结构大概是这样# 当前任务状态 ## 任务目标 重构用户认证模块支持多因素认证 ## 已完成 - [x] 梳理现有认证流程 - [x] 设计新流程的接口 ## 进行中 - [ ] 实现 TOTP 验证逻辑 ## 待办 - [ ] 编写单元测试 - [ ] 更新文档 ## 关键决策 - 选择 TOTP 而非短信验证码因为不依赖外部服务 - 验证逻辑放在独立模块便于测试 ## 相关文件 - src/auth/authenticator.py - tests/test_authenticator.py这个结构的好处是Agent 每次恢复任务只需要读这一个文件就能快速回到状态。不需要翻几十轮对话历史。长期记忆的组织则依赖 Obsidian 的双链和标签体系。每个完成的任务生成一个 Markdown 文件文件里用[[双链]]关联相关概念用#标签标记领域。这样检索的时候既可以通过关键词搜也可以通过双链跳转还可以通过标签聚合。3.4 Markdown 处理那些不起眼但坑很多的地方Markdown 看着简单实际处理起来坑不少。项目里踩过的几个典型问题换行问题。Markdown 里单个换行不产生新段落需要空行或行尾两个空格。Agent 生成的内容经常在这上面出错导致渲染出来的格式跟预期不符。解决办法是在 Harness 层做一次规范化处理把 Agent 输出的换行统一成标准格式。表格转换。Agent 经常需要把 Markdown 表格转成 Excel 或其他格式。这个转换看着简单但涉及对齐、转义、合并单元格等细节。项目里专门写了一个转换模块处理各种边界情况。数学符号。涉及公式的时候Markdown 的数学符号渲染依赖特定语法。如果 Agent 输出的公式格式不对渲染出来就是一堆乱码。Harness 层需要做格式校验和修正。实操心得Markdown 处理这块别想着一次写对。最好的做法是写一套校验规则Agent 输出后自动检查不符合规范的自动修正或打回重写。我一开始想靠提示词让 Agent 自己注意格式效果很差后来改成程序化校验问题少了一大半。4. 完整实操流程与关键环节4.1 环境搭建从零到能跑起来假设你现在要从零搭一套类似的 Harness 应用第一步是环境准备。核心组件包括执行内核Claude Code 或同类、知识底座Obsidian、开发环境VS Code、版本控制Git。安装顺序建议这样走先装 Obsidian建好库结构。库的目录结构提前规划好比如tasks/放任务文件、knowledge/放知识沉淀、templates/放模板、archive/放归档。这个结构一旦定下来后面所有 Agent 产出都往这里放检索才有序。再配 VS Code 和 Claude Code。VS Code 里装好 Claude Code 扩展配置好 API 密钥、模型选择、工作目录。工作目录建议直接指向 Obsidian 库这样 Agent 读写文件跟知识库是打通的。最后搭 Harness 层。这是你自己写的部分负责上下文管理、工具编排、状态持久化。初期可以很简单一个主循环加几个工具函数就行后面逐步加功能。注意环境搭建阶段最容易犯的错是目录结构没想清楚就开干。我见过太多项目文件到处乱放跑了两周发现检索根本没法做只能推倒重来。花半天时间把目录结构设计好后面省的是几十个小时。4.2 核心循环Agent 是怎么跑起来的Harness 应用的核心是一个循环接收任务 → 加载状态 → 规划步骤 → 执行工具 → 更新状态 → 判断是否完成 → 循环或结束。这个循环看着简单但每个环节都有讲究。接收任务阶段要做任务分类。不同类型的任务加载的上下文、暴露的工具、使用的提示词都不一样。分类可以基于关键词也可以让模型自己判断。加载状态阶段从工作记忆文件里读取当前任务状态。如果是新任务初始化一个空状态如果是恢复任务加载已有状态。规划步骤阶段让模型基于当前状态和任务目标输出下一步要做什么。这里的关键是限制规划粒度——不要让模型一次规划十步那样很容易跑偏。一次规划一到三步执行完再规划灵活性和可控性都好很多。执行工具阶段根据规划结果调用相应工具。每次调用前后都要记录日志方便排查问题。更新状态阶段把执行结果写回工作记忆文件。这一步不能省否则任务中断后没法恢复。判断完成阶段检查任务目标是否达成。达成则归档到长期记忆未达成则继续循环。4.3 参数调优那些需要反复试的数字这类项目里有一堆需要调优的参数没有标准答案只能根据实际情况试。列几个关键的参数作用典型范围调优方向上下文窗口大小保留多少轮历史10-20 轮任务越复杂窗口越大摘要触发阈值何时开始压缩窗口 80% 满太早压缩丢信息太晚爆 token工具重试次数失败后重试几次1-3 次网络类多试逻辑类少试单次规划步数一次规划几步1-3 步步骤越多越容易跑偏状态保存频率多久存一次状态每步都存存太勤影响性能存太疏丢状态调这些参数的通用方法是先设一个保守值跑一批任务看哪里出问题针对性调整。别想着一次调到位那是幻想。4.4 知识沉淀让每次任务都变成资产这个项目最有价值的设计之一是每个任务完成后自动生成知识文件。文件内容包括任务描述、解决思路、关键代码、踩过的坑、可复用的模式。这些文件进入 Obsidian 库后通过双链和标签组织起来。下次遇到类似任务Agent 可以先检索这些历史文件站在过去的肩膀上而不是从零开始。知识文件的模板大概长这样# [任务名称] ## 背景 [什么场景下遇到的这个问题] ## 解决思路 [核心思路是什么为什么这么选] ## 关键实现 [核心代码或配置] ## 踩坑记录 [遇到什么问题怎么解决的] ## 可复用模式 [这个方案还能用在哪些场景] ## 相关 [[相关任务1]] [[相关任务2]] #标签实操心得知识沉淀这件事最大的敌人是懒得写。我的做法是把它做成自动化的——任务一完成Harness 层自动生成知识文件草稿Agent 只需要补充关键细节。这样人的负担降到最低坚持下来的概率高很多。5. 常见问题与排查技巧实录5.1 Agent 跑着跑着就失忆了这是最高频的问题。表现是Agent 在任务中途突然问一些之前已经确认过的问题或者做出跟之前决策矛盾的举动。排查思路分三步。第一步检查上下文窗口。是不是窗口太小关键信息被挤出去了。第二步检查摘要策略。是不是摘要把关键实体压没了。第三步检查状态文件。是不是状态没及时保存恢复时读到了旧版本。解决办法通常是加大窗口、优化摘要保留策略、提高状态保存频率。三个一起调效果最明显。5.2 工具调用失败但 Agent 不知道有时候工具调用返回了错误但 Agent 把错误当成了正常结果继续往下走导致后面全错。这个问题的根源是错误处理没做好。Harness 层需要在工具调用返回后判断结果是不是错误如果是错误要么重试要么把错误信息明确告诉 Agent让它决定怎么办。注意别让 Agent 自己判断这个结果是不是错误。模型对错误的识别能力有限经常把错误当正常。错误判断应该在 Harness 层用程序做确定是错误了再告诉 Agent。5.3 Token 消耗失控40 亿 token 一个月如果管理不当很容易翻倍。失控的常见原因上下文没压缩、工具返回结果全量塞进上下文、重复加载相同内容。排查方法给每次交互记录 token 消耗找出消耗大户。通常是某几类操作在偷偷烧 token比如读取大文件、搜索结果全量返回、历史上下文重复加载。优化手段大文件分块读取、搜索结果先摘要再返回、历史上下文用检索代替全量加载。5.4 常见问题速查表问题现象可能原因排查方向解决手段Agent 失忆上下文窗口小/摘要过度检查窗口和摘要策略加大窗口、保留关键实体工具错误被忽略错误处理缺失检查工具返回处理逻辑Harness 层做错误判断Token 消耗失控上下文未压缩/重复加载记录 token 消耗找大户分块读取、检索代替加载任务跑偏规划粒度过大检查单次规划步数减小规划粒度状态丢失保存频率低检查状态保存时机提高保存频率格式渲染错误Markdown 不规范检查输出格式程序化校验修正5.5 几个不那么常见但很坑的问题问题一Agent 在长任务里性格漂移。跑了几十轮之后Agent 的语气、风格、决策倾向跟开始时不一样了。这通常是上下文里积累了太多噪音把初始设定冲淡了。解决办法是定期重置——把核心设定重新注入上下文。问题二工具描述歧义导致误用。两个工具功能相近Agent 经常用错。解决办法是把工具描述写得更明确突出差异点或者在 Harness 层做路由根据场景自动选工具。问题三Obsidian 库大了之后检索变慢。文件多了全文检索性能下降。解决办法是建索引、分库、用标签缩小检索范围。6. 这套架构还能怎么扩展跑通基础版本之后这套 Harness 架构有几个明显的扩展方向。多 Agent 协作。单个 Agent 能力有限可以让多个 Agent 分工——一个负责规划、一个负责执行、一个负责审查。Harness 层负责协调它们之间的通信和状态同步。领域特化。针对特定领域比如前端开发、数据分析、文档写作定制工具集和提示词让 Agent 在垂直场景里表现更好。人机协作增强。在关键决策点引入人工确认Agent 提出方案人做选择。这样既保留了 Agent 的效率又保证了关键决策的可靠性。知识库自动化维护。让 Agent 定期整理 Obsidian 库合并重复内容、更新过时信息、建立新的双链关系。库越大这个能力越有价值。我个人在实际操作中的体会是这套架构最值钱的地方不是某个具体功能而是它把 Agent 从一次性工具变成了持续积累的系统。每跑一个任务系统就聪明一点每沉淀一份知识下次就快一点。这种复利效应才是九个月 20 万行代码真正换来的东西。最后再分享一个小技巧如果你也想做类似的项目别一上来就追求大而全。先用最小可行的 Harness 跑通一个简单任务然后逐步加功能。我见过太多人架构设计得天花乱坠结果连第一个任务都跑不通。能跑起来的最小系统永远比设计完美的空架子有价值。
02
RELATED NEWS

相关资讯

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

03
WHY YAOTU

想打造同款高转化官网?

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

◈

场景化定制

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

◐

营销型架构

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

▲

全周期服务

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

免费获取你的建站方案

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