1. 先搞清楚这个项目到底在做什么一个人九个月20 万行代码每个月消耗 40 亿以上的 token最终交付的是一款基于 Harness 架构的应用。这几个数字摆在一起任何一个写过代码的人都会先愣一下20 万行代码是什么概念一个中等规模的商业项目五到十人的团队做一年大概也就是这个量级。而这里是一个人干出来的还附带每月 40 亿 token 的模型调用量。先把概念对齐。Harness 架构这个词最近在 Agent 开发圈子里出现频率很高但它并不是某个具体产品的名字而是一种组织 AI 应用的方式。你可以把它理解成给模型套上一副马具——模型本身是那匹力气很大但方向感一般的马Harness 就是缰绳、鞍具和路标的集合体负责把模型的原始能力约束到一条可预期、可复用、可调试的执行路径上。它管的事情包括任务怎么拆、上下文怎么喂、工具怎么调、结果怎么校验、失败怎么重试、状态怎么持久化。这个项目之所以值得拿出来拆是因为它踩中了当下 Agent 开发最核心的几个矛盾单兵作战如何对抗工程复杂度、模型调用成本如何控制、长期项目的知识如何不丢失、以及一个人怎么在没有团队 review 的情况下保证 20 万行代码不烂掉。这几个问题任何一个做 Agent 项目的人都会遇到只是大多数人选择绕开而这个项目选择正面硬刚。适合读这篇内容的人有三类。第一类是正在做或准备做 AI Agent 应用的开发者想知道别人是怎么把架构搭起来的第二类是重度使用 Claude Code、Obsidian 这类工具的知识工作者想看看把它们串起来能产生什么化学反应第三类是对一个人能不能撑起一个大项目这件事好奇的人想看看真实的工程账本长什么样。下面我会按架构思路、核心细节、实操过程、问题排查四个层面把这个项目拆开讲。2. 整体架构设计与技术选型思路2.1 为什么是 Harness 而不是裸调模型很多人做 Agent 的第一反应是直接写个循环把用户输入丢给模型模型返回工具调用执行工具把结果再丢回去直到模型说我完成了。这个循环写起来可能就几十行代码跑 demo 没问题但一旦任务变长、工具变多、状态变复杂就会迅速失控。裸调模型的核心问题是没有中间层来承载工程约束。模型是无状态的每次调用都是全新的你上一轮做了什么、失败了什么、哪些路径已经试过全靠你自己在外部维护。当任务只有三五步时你还能用变量记一记当任务有几十上百步、涉及文件读写、网络请求、代码执行、多轮校验时靠散落的变量根本管不住。Harness 架构的价值就在这里。它把模型调用这件事从一次性的函数调用升级成一个有生命周期、有状态机、有中间件管道的执行框架。具体来说它通常包含这几层任务编排层把一个大目标拆成可执行的子任务序列决定哪些能并行、哪些必须串行、哪些需要人工确认。上下文管理层决定每一轮给模型喂什么。这是最烧 token 也最考验设计的地方喂多了浪费钱还稀释注意力喂少了模型缺信息。工具执行层统一管理所有可调用的工具包括参数校验、权限控制、超时处理、结果格式化。状态持久层把执行过程中的关键状态落盘保证中断后能恢复也方便事后复盘。校验与重试层对模型输出做结构化校验不合格就带着错误信息重试而不是直接把脏数据往下传。这个项目选择 Harness 架构本质上是因为它要处理的任务足够复杂、足够长长到必须有一套工程化的骨架来兜底。如果只是做个问答机器人这套东西就是过度设计但要做 20 万行代码规模的应用没有这层骨架代码会在三个月内变成一团无法维护的泥球。2.2 技术栈的组合逻辑从热搜词能看出这个项目的技术栈轮廓Claude Code 作为主要的编码与执行环境Obsidian 作为知识库与文档层Markdown 作为贯穿始终的中间格式Harness 作为 Agent 编排框架。这个组合不是随便凑的每一环都有明确的职责。Claude Code在这里扮演的是执行引擎的角色。它本身就是一个带工具调用能力的编码 Agent能读写文件、执行命令、搜索代码。把它作为 Harness 架构里的一个执行单元等于直接复用了它成熟的工具链不用自己从零实现文件操作和命令执行。这也是为什么项目能在一个月烧掉 40 亿 token——大量的 token 消耗在代码读写、上下文理解和多轮修正上。Obsidian的角色容易被低估。它不只是一个笔记软件在这个项目里它是长期记忆的载体。Agent 项目最大的痛点之一是知识蒸发今天想清楚的一个设计决策两周后自己都忘了为什么这么定。Obsidian 的双向链接和本地 Markdown 存储让所有的设计文档、决策记录、踩坑笔记都能被结构化地组织起来而且能被 Agent 直接读取。这比把知识散落在聊天记录和临时文件里强太多。Markdown作为中间格式的选择也很关键。模型天然擅长生成和解析 Markdown它比 JSON 更宽松、比纯文本更有结构。项目里所有的任务描述、执行计划、结果报告、知识条目大概率都是 Markdown 格式。这样做的好处是人和机器都能读Obsidian 能渲染Claude Code 能解析转换成本极低。提示技术栈的选择永远服务于减少摩擦。如果一个格式需要你写转换脚本才能让上下游工具读懂那它就不该作为中间格式。2.3 一个人扛 20 万行代码的可行性边界这里必须泼一盆冷水。20 万行代码由一个人完成前提是其中绝大部分不是手写的。真实的构成大概率是这样手写的核心逻辑可能只占 10% 到 20%也就是两三万行剩下的是模型生成的业务代码、配置文件、测试用例、文档、以及各种胶水代码。这个比例关系很重要因为它决定了项目的风险点在哪里。手写的那部分如果架构错了后面生成的代码全是歪的生成的那部分如果缺乏校验会积累大量看似能跑实则脆弱的代码。所以一个人做大项目的核心能力不是写代码快而是设计约束的能力——你得设计出一套让模型生成的代码不容易跑偏的规则、模板和校验机制。九个月的时间分配我推测大概是前两个月搭 Harness 骨架和工具链中间五个月高速迭代业务功能最后两个月做整合、修 bug、补文档。这个节奏里最危险的是第三到第五个月那时候功能在快速堆叠架构债开始显现如果没有前两个月的骨架撑着很容易在这里崩盘。3. 核心细节解析与实操要点3.1 上下文管理40 亿 token 是怎么烧掉的每月 40 亿 token 这个数字换算下来平均每天 1.3 亿左右。如果按一次完整任务调用消耗 5 万 token 估算一天大概跑 2600 次任务如果单次消耗 20 万 token那就是 650 次。无论哪种都说明这个项目的调用频率相当高而且单次上下文不小。token 消耗的大头通常在这几个地方代码文件的反复读取Agent 每次要改一个文件都得先把文件内容读进上下文。如果文件有几千行读一次就是几万 token。改十个文件就是几十万 token。历史对话的累积如果不做上下文裁剪每一轮都把之前所有对话带上token 会随轮次线性甚至指数增长。工具返回结果的膨胀命令执行输出、搜索结果、文件列表这些如果不做截断和摘要会迅速撑爆上下文。重试带来的重复消耗一次任务失败重试三次token 就是三倍。控制成本的核心手段是分层上下文。我的经验是把上下文分成三层常驻层放最核心的系统提示和项目约定这部分每轮都带但尽量精简工作层放当前任务相关的文件和状态任务结束就清掉检索层放按需拉取的历史信息用的时候才查。这样能把单次调用的 token 压下来同时不丢关键信息。另一个关键是结果摘要。工具返回的长输出不要原样塞回上下文而是先用一个小模型或规则做摘要只保留关键信息。比如跑一次测试返回 500 行日志真正有用的可能就那几行报错摘要后能省 90% 以上的 token。3.2 Markdown 作为知识载体的实操细节Markdown 看着简单但在 Agent 项目里用好它有不少门道。热搜词里出现了markdown 换行markdown 语法markdown 表格转换 excel这些说明实际使用中这些细节确实会卡人。换行问题是最常见的坑。Markdown 里单个换行默认不生效要空一行才是新段落或者在行尾加两个空格强制换行。模型生成的内容经常在这上面翻车导致渲染出来的文档挤成一团。解决办法是在系统提示里明确约定换行规则或者在渲染前做一次规范化处理。表格处理是另一个高频需求。Agent 经常需要输出结构化数据Markdown 表格是自然选择但表格在纯文本里对齐麻烦转换成 Excel 又需要解析。我的做法是内部流转用 Markdown 表格需要给非技术用户看的时候写个小脚本转成 CSV 或 xlsx。转换时注意处理单元格内的竖线和换行这两个字符会破坏表格结构。知识库的组织上Obsidian 的双向链接是核心武器。每篇笔记用[[链接名]]关联到相关笔记时间长了会形成一张知识网络。对于 Agent 项目我建议至少维护这几类笔记架构决策记录每个重要选择为什么这么做、工具使用手册每个工具的参数和坑、任务模板常见任务的执行步骤、问题排查库遇到过的错误和解决方案。这些笔记 Agent 能直接读等于给模型外挂了一个项目专属的知识库。3.3 Claude Code 的配置与使用要点Claude Code 作为执行引擎配置得当能省很多事。几个关键点项目级配置要放在项目根目录让 Claude Code 每次启动都能读到项目约定。包括代码风格、目录结构说明、常用命令、禁止操作等。这份配置相当于给模型的项目入职培训写得好能大幅减少跑偏。权限控制要收紧。Claude Code 能执行命令和改文件如果不加限制一个误操作可能删掉重要文件。建议对危险命令删除、覆盖、批量修改设置确认环节或者限定在特定目录内操作。会话管理要有策略。长会话会累积大量上下文既费钱又容易让模型迷失。我的习惯是按任务切分会话一个任务一个会话任务结束就归档。跨任务需要共享的信息写进项目配置文件或知识库而不是靠会话历史传递。与 Obsidian 的联动上可以让 Claude Code 直接读写 Obsidian 库目录。这样模型生成的设计文档、任务记录能直接进知识库知识库里的资料也能被模型读取。注意 Obsidian 库里的文件命名和链接格式要保持一致否则模型容易生成断链。4. 实操过程与核心环节实现4.1 从零搭建 Harness 骨架的步骤假设你现在要从零开始搭一个类似的架构我会建议按这个顺序推进。第一步定义任务模型。先想清楚你的 Agent 要处理的任务长什么样。是单轮问答还是多步执行有没有人工介入环节任务之间有没有依赖把这些画成状态机明确每个状态的进入条件、退出条件和可能的转移。这一步不写代码就是画图和写文档但决定了后面所有代码的结构。第二步实现最小执行循环。先不管工具、不管状态持久化就实现一个最朴素的循环接收任务、调用模型、解析输出、如果是工具调用就执行、把结果回填、继续循环直到完成。这个循环可能就一百行代码但它是整个系统的核心后面所有东西都是围绕它加装饰。第三步加工具层。把你要用到的工具一个个注册进来每个工具定义清楚名字、描述、参数 schema、执行函数、返回格式。工具描述要写得让模型能准确判断什么时候该用这是工具调用准确率的关键。参数 schema 要严格模型传错参数时能直接报错而不是执行出奇怪结果。第四步加状态持久化。把执行过程中的关键状态存下来当前任务、已完成步骤、中间结果、错误记录。存成 JSON 或 Markdown 都行关键是能读回来。这样任务中断后能恢复出问题能复盘。第五步加校验与重试。对模型的每一步输出做校验格式不对、内容不合理就带着错误信息重试。重试要有次数上限避免死循环。重试时把之前的错误也带上让模型知道错在哪。第六步加可观测性。记录每次调用的输入输出、token 消耗、耗时、成功失败。这些数据是后续优化的依据没有它你根本不知道钱花在哪、哪里慢、哪里容易错。4.2 关键参数的计算与选择上下文窗口的分配需要算一笔账。假设模型上下文是 20 万 token你不能全用满得留出输出空间。我的经验分配是系统提示和项目约定占 5%当前任务描述占 10%相关文件内容占 50%历史摘要占 15%工具结果占 15%留 5% 给输出。这个比例不是死的任务类型不同要调整但核心原则是给最相关的信息留最大空间。重试次数的选择上我一般设 3 次。第一次失败通常是格式问题第二次失败可能是理解偏差第三次还失败说明任务本身有问题继续重试只是烧钱。三次失败后应该转人工或降级处理。并发度要谨慎。多个任务并行能提速但会争抢资源、互相干扰上下文。如果任务之间完全独立可以并行如果有共享状态老老实实串行。我踩过的坑是并行任务同时改同一个文件结果互相覆盖排查了半天才发现是并发问题。超时设置上单次模型调用给 60 到 120 秒工具执行根据类型给不同超时文件操作 10 秒网络请求 30 秒长时间任务单独处理。超时后要能优雅中断而不是卡死整个流程。4.3 一个完整任务的执行记录拿一个具体任务举例让 Agent 给项目加一个新功能涉及改三个文件、加一个测试、更新文档。任务开始Harness 先做规划读项目配置了解约定读相关文件了解现状生成执行计划。这一步消耗大概 3 万 token。然后进入执行。第一步改第一个文件读文件内容假设 2000 行约 2 万 token生成修改约 5000 token写回文件。第二步类似。第三步加测试读现有测试了解风格生成新测试。第四步更新文档。每一步都有校验格式不对就重试。全部完成后跑一次测试验证。测试失败的话把失败信息喂回去让模型修。修完再跑直到通过。最后生成任务报告记录改了什么、为什么改、测试结果存进 Obsidian 知识库。整个任务下来token 消耗可能在 30 万到 50 万之间耗时十几分钟到半小时。这个流程里最耗时的往往不是模型生成而是读文件和跑测试。所以优化方向很明确减少不必要的文件读取用增量方式改文件而不是全量重写测试只跑相关的而不是全量。5. 常见问题与排查技巧实录5.1 模型输出格式不稳定怎么办这是最高频的问题。模型有时候返回 JSON有时候返回带解释的 JSON有时候干脆返回一段自然语言。解决办法有三层第一层在提示里给死格式。不要只说返回 JSON而是给出完整的 schema 和一个正确示例。示例比描述管用得多。第二层做容错解析。写一个解析器能处理常见的格式偏差去掉代码块标记、提取第一个 JSON 对象、修复常见的括号不匹配。这能救回大部分格式问题。第三层校验失败就重试。把解析错误的具体信息告诉模型让它重新生成。通常一两次就能修好。如果某个任务反复格式出错说明提示写得不够清楚或者任务本身太复杂需要拆分。5.2 上下文超限与信息丢失长任务跑到后面上下文塞满了新信息进不来旧信息被挤掉模型开始失忆。应对策略主动摘要每完成几个步骤就把之前的执行历史压缩成一段摘要替换掉原始记录。外部存储把中间结果写到文件上下文里只留文件路径和简要说明需要时再读。任务拆分如果一个任务注定要跑很久就拆成多个子任务每个子任务独立上下文通过文件传递结果。我踩过的最大的坑是摘要丢关键信息。有一次摘要时把某个重要的参数值省略了导致后续步骤用了默认值结果全错。所以摘要要保留所有决策相关的信息宁可长一点。5.3 工具调用失败的处理工具调用失败的原因很多参数错、权限不足、目标不存在、超时、返回格式不符预期。排查顺序建议是现象可能原因排查方法参数校验失败模型传参格式错检查工具 schema 描述是否清晰权限拒绝操作越权检查权限配置和操作路径目标不存在路径或 ID 错让模型先确认目标存在再操作执行超时任务太重或卡死加超时并检查工具实现返回无法解析返回格式与约定不符检查工具返回格式并加容错关键经验是工具的错误信息要足够详细让模型能根据错误自己修正。如果工具只返回失败两个字模型只能瞎猜。返回参数 xxx 格式错误期望整数收到字符串模型下次就能改对。5.4 长期项目的知识管理九个月的项目最大的敌人是遗忘。三个月前的一个设计决策如果不记下来三个月后自己都会推翻重来。我的做法是每个重要决策都写一篇决策记录格式固定背景是什么、有哪些选项、选了哪个、为什么、有什么代价。这些记录存进 Obsidian用标签和链接组织。Agent 在需要做类似决策时能先检索这些记录避免重复踩坑。另外维护一个坑库每次遇到问题解决了就记一条现象、原因、解决、预防。这个库越厚项目后期越省心。注意知识管理最大的误区是等有空再整理。有空的时候永远不会来必须把记录变成执行流程的一部分做完就记不记不算完。5.5 成本失控的预警信号40 亿 token 一个月如果不管控很容易翻倍。几个预警信号要盯紧单任务 token 消耗突然上升可能是上下文没裁剪或者任务变复杂了。重试率上升说明提示或工具出了问题模型在反复试错。无效调用增多模型调了工具但结果没用上说明工具描述或任务规划有问题。缓存命中率下降如果用了提示缓存命中率低说明上下文变化太频繁。发现这些信号要立刻查不要等月底看账单才后悔。我一般设一个每日 token 预算超了就报警当天就排查。6. 一个人做大项目的几条真实体会先说一个反直觉的结论一个人做大项目瓶颈从来不是写代码的速度而是做决策的质量和保持方向的能力。模型能帮你写代码但帮不了你决定这个功能该不该做这个架构该不该改。九个月里真正消耗心力的都是这类判断。第二个体会是约束比自由更重要。给模型越多的自由它越容易跑偏。好的 Harness 架构不是让模型想干什么就干什么而是用清晰的边界、严格的校验、明确的模板把它的能力引导到正确的方向上。这跟带团队是一个道理规则清晰了执行效率反而高。第三个体会是文档不是负担是杠杆。很多人觉得写文档浪费时间但在一个人加 AI 的工作模式里文档是唯一能让过去的自己和现在的模型对齐的东西。你写的每一份决策记录、每一个任务模板都会在后续被反复复用回报率极高。最后分享一个具体的小技巧给项目建一个当前状态文件放在最显眼的位置每次开工前先读它收工前更新它。这个文件记录项目现在到哪了、下一步要做什么、有什么待解决的问题。它就像一个人的工作记忆外挂能极大减少我上次做到哪了的迷茫。这个习惯我坚持了整个项目周期是性价比最高的一个动作。至于这个项目后续还能怎么扩展我觉得有两个方向值得试一是把知识库做成可检索的向量库让 Agent 能按语义找历史决策二是把常见任务做成可复用的技能包新任务来了直接调用不用每次从头规划。这两个方向都能进一步降低单任务的 token 消耗和出错率等有精力了可以继续折腾。