1. 先搞清楚这个项目到底在做什么一个人九个月二十万行代码每个月消耗四十亿以上的 token最终交付的是一款基于 Harness 架构的应用。这几个数字摆在一起任何一个写过代码的人都会先愣一下——不是因为二十万行代码有多夸张而是因为“一个人”和“九个月”这两个限定词。正常来说二十万行代码的工程量放在一个五人到八人的团队里做一年半到两年是常态。一个人九个月干完意味着这个人几乎把所有能自动化的环节全部自动化了而四十亿 token 的月消耗量恰恰说明自动化不是靠手写脚本堆出来的是靠大模型驱动的 Agent 流水线跑出来的。这里说的 Harness 架构不是某个具体框架的名字而是一种设计思路把大模型当作一个需要被“约束”和“驱动”的执行引擎外面套一层完整的控制层负责上下文管理、工具调用、状态持久化、错误恢复和任务编排。你可以把它理解成给一匹野马套上缰绳和马鞍——模型本身能力很强但如果没有 Harness它就是一个聊天框有了 Harness它才是一个能持续干活的生产力工具。Claude Code 就是这种思路的一个典型代表它把文件读写、命令执行、代码搜索这些能力封装成工具让模型在一个受控的循环里反复调用直到任务完成。这个项目适合谁来参考如果你是一个独立开发者正在琢磨怎么用 Agent 的方式把自己的工作效率拉高一个数量级那这篇内容对你有直接价值。如果你是一个小团队的负责人想知道一个人怎么干出一个团队的产出这里面的架构决策和踩坑记录同样值得看。哪怕你只是刚开始接触 Claude Code、Obsidian 这类工具想搞清楚它们之间怎么串起来下面的内容也能给你一条清晰的路径。2. 为什么是 Harness 架构而不是普通的脚本自动化2.1 普通脚本自动化的天花板在哪里大部分人第一次尝试自动化都是从写脚本开始的。比如用 Python 写一个脚本定时抓取某个数据源处理完之后写到文件里。这种模式在任务固定、输入格式稳定的场景下非常好用写起来快跑起来也稳。但问题在于一旦任务变得稍微复杂一点——比如需要根据中间结果动态决定下一步做什么或者需要理解自然语言描述的指令——脚本就开始力不从心了。我举个例子。假设你想让程序帮你整理一批 Markdown 笔记把里面所有关于“Agent”的段落提取出来按照主题重新归类然后生成一份摘要。用传统脚本怎么做你得先写正则表达式匹配“Agent”相关的关键词然后写一套规则来判断段落属于哪个主题再写一个模板来生成摘要。这套东西写出来光是规则维护就能把人逼疯而且换一批笔记规则可能就全废了。Harness 架构解决的就是这个问题。它不要求你预先定义所有规则而是把“理解”和“决策”交给模型你只需要定义好模型可以使用的工具以及这些工具的调用规范。模型在每一步都会根据当前上下文决定调用哪个工具、传什么参数然后根据返回结果决定下一步。这个循环就是 Agent 的核心执行逻辑。2.2 Harness 架构的三个核心组件一个完整的 Harness 架构至少包含三个部分。第一个是上下文管理器负责决定每一步往模型的输入里塞什么信息。这听起来简单实际上是最难的部分。模型的上下文窗口是有限的你不可能把所有历史记录都塞进去必须做筛选和压缩。常见的做法是保留最近几轮对话的完整内容对更早的历史做摘要同时把当前任务相关的文件内容按需注入。第二个是工具层。工具就是模型可以调用的函数比如读文件、写文件、执行命令、搜索代码。每个工具都需要有清晰的描述告诉模型这个工具是干什么的、参数是什么格式、什么情况下应该用。工具描述的质量直接决定了模型能不能正确使用它。我见过太多人抱怨模型“不听话”结果一看工具描述写得含糊不清模型根本不知道什么时候该调用。第三个是状态机与错误恢复。Agent 在执行任务的过程中一定会出错——工具调用失败、模型输出格式不对、任务陷入死循环。Harness 需要有一套机制来检测这些异常并决定是重试、跳过还是终止。这部分往往是最容易被忽略的但恰恰是决定一个 Agent 能不能长时间稳定运行的关键。2.3 为什么选择 Claude Code 作为执行引擎在众多可选方案里Claude Code 的优势在于它已经把工具层和上下文管理做得很成熟了。你不需要从零开始写一个 Agent 循环只需要在它的基础上做扩展。它内置了文件读写、命令执行、代码搜索这些高频工具而且工具调用的协议是稳定的。更重要的是它对 Markdown 文件的支持非常自然——这对于以 Obsidian 作为知识库载体的项目来说几乎是刚需。Obsidian 的笔记本身就是 Markdown 格式Claude Code 可以直接读取和修改这些文件不需要做任何格式转换。这意味着你可以让 Agent 直接在你的知识库里干活比如自动整理笔记、生成索引、提取待办事项。这种无缝衔接是很多其他方案做不到的。3. 二十万行代码是怎么堆出来的3.1 代码量的构成分析二十万行代码听起来很多但如果拆开看其实构成很清晰。根据我在类似项目中的经验这类 Harness 应用的代码大致可以分为几个部分。核心的 Agent 循环和上下文管理大概占百分之十五到二十工具层的实现占百分之二十五到三十剩下的百分之五十以上都是业务逻辑和适配层。业务逻辑为什么这么多因为 Harness 架构本身只提供了执行框架具体要做什么任务需要大量的领域代码来支撑。比如你要处理 Markdown 笔记就需要写 Markdown 解析、链接提取、标签管理、文件同步这些模块。每一个模块单独看都不复杂但加起来量就上去了。还有一个容易被低估的部分是配置和提示词工程。提示词本身不算代码但围绕提示词的管理、版本控制、A/B 测试、效果评估这些都需要代码来支撑。在一个成熟的 Harness 项目里提示词相关的代码和配置能占到总代码量的百分之十左右。3.2 九个月的时间线拆解九个月听起来很长但对于这个体量的项目来说时间其实非常紧。我试着还原一下合理的时间分配。第一个月基本上是在做技术选型和原型验证确定用 Claude Code 作为执行引擎确定 Obsidian 作为知识库载体跑通最基本的“读文件-处理-写文件”循环。第二到第四个月是核心架构的搭建期。这段时间要完成上下文管理器的实现、工具层的封装、状态机的设计。同时还要解决一个关键问题怎么让 Agent 在长时间运行中保持稳定。我试过不少方案最后发现最有效的做法是给每个任务设置明确的完成条件并且限制最大迭代次数防止 Agent 在一个问题上无限循环。第五到第七个月是业务逻辑的密集开发期。这段时间代码量增长最快因为大量的 Markdown 处理逻辑、Obsidian 插件适配、数据同步机制都是在这个阶段完成的。也是在这个阶段token 消耗量开始飙升因为每次调试都需要让 Agent 实际跑一遍任务。最后两个月是优化和打磨期。重点放在减少 token 消耗、提高任务成功率、完善错误恢复机制上。这个阶段代码量的增长放缓但质量提升明显。3.3 四十亿 token 到底花在哪里了四十亿 token 一个月平均下来每天一亿多。这个数字乍看很吓人但拆开看就合理了。假设你每天让 Agent 处理一千个任务每个任务平均消耗十万 token那一天就是一亿。十万 token 是什么概念大概相当于七万到八万个英文单词或者五万个左右的中文汉字。对于一个需要读取多个文件、进行多轮推理、生成结构化输出的任务来说这个消耗量是正常的。消耗的大头在上下文注入。每次 Agent 执行任务都需要把相关的文件内容、历史记录、工具描述塞进上下文。如果文件很大或者历史记录很长token 消耗就会急剧上升。我踩过的一个坑是早期没有做上下文压缩每次任务都把整个对话历史塞进去结果 token 消耗是现在的三到四倍。后来引入了滑动窗口和摘要机制消耗才降下来。另一个消耗大户是错误重试。Agent 执行失败的时候往往需要重新跑一遍这就意味着同样的上下文要再消耗一次。减少错误重试的关键是提高工具描述的清晰度和任务拆分的粒度。任务拆得越细单步出错的概率越低重试的成本也越小。4. 核心实操从零搭建一个 Harness 应用的完整路径4.1 环境准备与工具链配置第一步是安装 Claude Code。这个过程本身不复杂但有几个细节需要注意。安装完成后你需要配置模型访问方式。如果你使用的是本地模型比如通过 LM Studio 加载的模型需要在 Claude Code 的配置里指定本地服务的地址和端口。这里的一个常见问题是模型名称的映射——Claude Code 默认使用特定的模型标识你需要把它映射到你本地实际加载的模型名称上否则会报“模型不存在”的错误。Obsidian 的安装相对简单但插件配置需要花点心思。我推荐至少安装以下几个插件Dataview 用于查询笔记元数据Templater 用于自动化模板生成QuickAdd 用于快速捕获内容。这些插件本身不直接和 Agent 交互但它们生成的 Markdown 文件结构会直接影响 Agent 的处理效率。比如如果你用 Dataview 生成了结构化的查询结果Agent 读取这些结果时就比读取纯文本要容易得多。Markdown 的语法细节也值得注意。比如换行在标准 Markdown 里行尾加两个空格表示换行但很多编辑器对此处理不一致。Obsidian 默认使用严格的换行规则而 Claude Code 在生成 Markdown 时可能不会自动加空格。这个差异会导致生成的笔记在 Obsidian 里显示异常。我的做法是在 Agent 的输出环节加一个后处理步骤自动把需要换行的地方补上两个空格。4.2 上下文管理器的实现要点上下文管理器是整个 Harness 的核心它的质量直接决定了 Agent 的表现。实现的时候我建议采用分层策略。第一层是系统提示词这部分内容固定不变定义 Agent 的角色、能力边界和基本行为规范。第二层是任务描述每次执行任务时动态生成告诉 Agent 这次要做什么。第三层是相关文件内容根据任务类型选择性地注入。第四层是历史对话摘要对之前的交互做压缩后的记录。分层的好处是每一层可以独立优化。比如系统提示词可以单独做 A/B 测试文件注入策略可以按任务类型调整历史摘要的压缩比例可以动态控制。我实测下来分层之后 token 利用率大概提升了百分之四十左右。还有一个关键点是文件注入的粒度。不要一次性把整个文件塞进去而是先注入文件的结构信息比如标题层级、段落数量让 Agent 决定需要读取哪一部分然后再按需注入具体内容。这个策略对于大文件特别有效能把单次任务的 token 消耗降低一半以上。4.3 工具层的设计与实现工具层的设计原则是“少而精”。不要给 Agent 提供几十个工具那样只会让它选择困难。我建议核心工具控制在十个以内每个工具的功能要足够通用。比如“读文件”这个工具应该支持读取整个文件、读取指定行范围、按关键词搜索等多种模式而不是拆成三个独立的工具。每个工具的描述要包含三个要素功能说明、参数格式、使用场景。功能说明要一句话讲清楚这个工具是干什么的。参数格式要明确每个参数的类型、是否必填、取值范围。使用场景要告诉 Agent 什么情况下应该用这个工具什么情况下不应该用。我见过很多工具描述只写了功能说明结果 Agent 在不该用的时候也调用白白浪费 token。错误处理也是工具层的重要部分。每个工具都应该有明确的错误返回格式告诉 Agent 是参数错了、权限不够还是资源不存在。Agent 根据错误类型决定是重试、换参数还是放弃。如果错误信息含糊不清Agent 就只能瞎猜重试几次之后可能就陷入死循环了。4.4 与 Obsidian 知识库的集成方案Obsidian 的知识库本质上就是一个文件夹里面全是 Markdown 文件。Agent 要做的第一件事是建立索引扫描整个知识库提取每个文件的标题、标签、链接关系、修改时间这些元数据。这个索引可以存在内存里也可以持久化到文件里。我建议持久化因为知识库大的时候每次重新扫描很浪费时间。索引建好之后Agent 就可以根据任务需求快速定位到相关文件。比如用户说“帮我整理一下关于 Agent 的笔记”Agent 先查索引找到所有标签或内容里包含“Agent”的文件然后逐个读取处理。这个流程比让 Agent 自己遍历整个文件夹要高效得多。还有一个实用技巧是利用 Obsidian 的双向链接。Obsidian 的[[链接]]语法天然形成了一张知识图谱。Agent 在处理一个文件的时候可以顺着链接找到相关联的文件这样就能在整理笔记的同时发现内容之间的隐含关系。我试过让 Agent 自动生成“相关笔记”推荐效果比单纯的关键词匹配好很多。5. 踩坑记录与常见问题排查5.1 Agent 执行中断的典型原因Agent 执行到一半突然中断是最让人头疼的问题。常见原因有几个。第一个是上下文超限。当注入的内容超过模型的上下文窗口时模型会直接报错退出。解决办法是在注入前做 token 估算超过阈值就触发压缩或截断。我一般会把阈值设在模型上限的百分之八十留出余量给模型的输出。第二个是工具调用格式错误。模型有时候会生成不符合工具描述格式的调用请求比如参数类型不对、缺少必填字段。这种情况下Harness 需要捕获解析错误并把错误信息返回给模型让它重新生成。如果连续三次都失败就应该终止任务并记录日志而不是无限重试。第三个是网络或服务不稳定。如果模型是通过网络访问的网络抖动会导致请求失败。这种情况下简单的重试机制就能解决。但要注意设置重试上限和退避策略避免在服务不可用的时候疯狂重试。5.2 Token 消耗异常的排查思路Token 消耗突然飙升通常有几个信号。第一个信号是单任务消耗量翻倍。这往往意味着上下文注入策略出了问题比如某个文件的注入没有做截断或者历史摘要没有生效。排查方法是打印每次任务的 token 消耗明细看看是哪一部分涨了。第二个信号是重试率上升。如果 Agent 频繁重试token 消耗自然就上去了。重试率上升的原因可能是工具描述变得模糊了或者任务拆分的粒度变粗了。我遇到过一次是因为修改了系统提示词导致 Agent 对某个工具的理解出现了偏差频繁调用一个不该调用的工具。第三个信号是输出长度异常。模型有时候会生成特别长的输出比如把一个简单的确认信息写成了一篇小作文。这种情况下需要在系统提示词里明确限制输出长度或者在 Harness 层面对输出做截断。5.3 Markdown 处理中的常见坑Markdown 看起来简单但在 Agent 处理场景下有不少坑。第一个坑是表格转换。Markdown 表格的语法对对齐要求很严格Agent 生成的表格经常因为列宽不一致而显示错乱。我的做法是在输出后加一个格式化步骤自动调整表格的对齐。第二个坑是数学公式。Markdown 本身不支持数学公式需要依赖 LaTeX 扩展。如果 Agent 生成的公式没有用正确的定界符包裹Obsidian 就无法渲染。我建议在系统提示词里明确要求所有数学公式必须用$或$$包裹并且在输出后做一次校验。第三个坑是链接和图片路径。Obsidian 使用相对路径引用附件如果 Agent 生成的路径是绝对路径或者格式不对链接就会失效。解决办法是在工具层封装一个路径规范化函数所有涉及路径的操作都走这个函数。5.4 常见问题速查表问题现象可能原因排查方法解决措施Agent 执行中断上下文超限检查 token 消耗日志压缩上下文或截断注入内容工具调用失败参数格式错误查看工具调用日志修正工具描述或增加参数校验Token 消耗飙升重试率上升统计重试次数优化任务拆分粒度Markdown 显示异常换行或公式格式错误在 Obsidian 中预览增加输出后处理步骤任务陷入死循环完成条件不明确检查任务描述设置最大迭代次数和明确完成条件文件读取失败路径格式错误检查路径字符串使用路径规范化函数6. 一些实操心得和后续扩展方向6.1 关于提示词工程的几点体会提示词不是越长越好。我早期写过几千字的系统提示词结果发现模型反而更容易迷失重点。后来精简到几百字只保留最核心的行为规范效果反而更好。关键是要把提示词当成代码来管理每次修改都要有明确的假设和验证方法。另一个体会是示例比描述更有效。与其花大段文字描述“你应该怎么输出”不如给一两个具体的输入输出示例。模型对示例的模仿能力很强一个好的示例能顶十句描述。我在工具描述里都会附上一个调用示例Agent 使用工具的准确率明显提升。6.2 关于成本控制的实战经验四十亿 token 一个月成本确实不低。但通过一些策略可以在不影响效果的前提下把消耗降下来。第一个策略是缓存。对于重复性高的任务比如每天整理同一批笔记可以把上次的处理结果缓存起来只处理有变化的部分。第二个策略是分级处理。简单的任务用轻量模型复杂的任务才用大模型。第三个策略是批量合并。把多个小任务合并成一个大任务减少上下文重复注入的开销。我实测下来这三个策略叠加使用能把 token 消耗降低百分之五十到六十而任务成功率基本不受影响。6.3 这个项目还能怎么扩展Harness 架构的扩展性很强因为它本质上是一个通用的执行框架。除了 Markdown 笔记处理还可以用来做很多其他事情。比如接入代码仓库让 Agent 自动做代码审查和重构建议。或者接入邮件系统让 Agent 自动分类和回复邮件。甚至可以把多个 Agent 串联起来形成一个流水线每个 Agent 负责一个环节前一个的输出作为后一个的输入。我个人比较看好的方向是多 Agent 协作。单个 Agent 的能力有上限但如果把任务拆开让多个 Agent 并行处理整体吞吐量能提升很多。当然多 Agent 带来的协调成本也不低需要一套完善的任务分发和结果汇总机制。这个方向我还在摸索等有成熟经验了再单独写一篇来聊。6.4 给刚入门的同行的建议如果你刚开始接触 Harness 架构和 Agent 开发我的建议是先跑通一个最小闭环。不要一上来就想着做多复杂的功能先让 Agent 能读一个文件、处理一下、写回去。这个闭环跑通了再逐步增加工具和任务类型。我见过太多人卡在环境配置和工具调试上还没开始做业务逻辑就放弃了。另外日志一定要做全。Agent 的每一步决策、每一次工具调用、每一个错误都要有详细的日志记录。这些日志是你排查问题的唯一依据。我早期没重视日志结果出了问题只能靠猜浪费了大量时间。后来把日志做完善了排查效率至少提升三倍。最后不要追求一次做对。Agent 的行为有很大的不确定性同样的输入可能产生不同的输出。接受这种不确定性把重点放在提高成功率和降低失败成本上而不是试图消除所有错误。这个心态调整过来之后整个开发过程会顺畅很多。