九个月20万行代码一个月烧掉40亿个token——这是我自己从零写的一款AI原生应用的账本。它不是Demo也不是玩具而是一个真实跑在生产环境的Harness架构应用一套把LLM“套”在固定流程里执行任务的系统。今天想把这九个月的取舍、踩坑和可复现的骨架都摊开聊。先说结论如果你准备一个人独立做一个以AI为核心的复杂应用Harness架构是我目前试下来最稳的底子。它不追求花哨而是把所有不可控的东西关进笼子里让模型在预设轨道上运行。这篇文章我会把我为什么选它、20万行代码花在哪儿、40亿token是怎么烧掉的、以及九个月里踩过的那些真实问题全部按可复现的方式讲清楚。1. 项目为什么选Harness架构1.1 一个人开发时最怕的是“失控”单兵作战和团队作战最大的区别不是写代码速度而是出了问题之后有没有人帮你兜底。团队里你可以分模块、各管一摊一个人时所有模块都是你的孩子但你没有那么多精力同时盯着它们。尤其是AI应用模型输出天然有随机性同一个问题换个时间问结果可能完全不同。如果业务代码直接裸调LLM到处散落着判断逻辑和字符串拼接一旦模型输出格式变了整个系统就像多米诺骨牌一样倒掉。所以我一开始就确定必须有一个统一的控制层把所有模型调用收敛到一个闭环里。这个控制层就是我说的Harness。它的核心职责是接收一个目标而不是一段Prompt内部判断需要调用哪些工具、需要什么上下文调用模型得到结构化结果校验结果不合格就自动重试或换策略最终返回一个确定性的产出用大白话说Harness就是给模型戴上“笼头”让它在一个固定的流程里干活。它不能自己东跑西跑每走一步都要回到主循环里被检查一遍。这个设计让单人开发时的可调试性大大提升出问题只需要盯住一个循环而不是在全项目里翻找。1.2 Harness架构的核心理念把“不可控”变成“可控”很多人在AI应用里追求“智能最大化”让模型自由发挥。但生产环境恰恰相反我要的是“稳定可预期”。Harness架构的本质是把模型当作一个高度聪明但纪律性很差的员工你可以给它复杂的任务但必须用制度和流程约束它。具体来说我的Harness分成四层任务解析层把用户或上游的需求拆成原子指令执行循环层维护一个状态机决定当前该调用模型还是执行工具工具注册层所有外部能力查库、调API、文件操作都以标准接口暴露校验回退层对模型输出做schema校验不满足就重试或降级这四层中间通过统一的“Message”格式流转模型看到的永远是带历史上下文的对话工具调用结果会被序列化后追加进去。这样一来即使模型某次产生了幻觉Harness也能在下一轮纠正它因为校验回退层会强制要求模型基于工具返回值重新推理。我试过用LangChain之类的框架但发现大规模定制时还是有自己的架子最顺手。因为你需要改的往往不是“怎么调模型”而是“如何设计状态转换逻辑”。自己写Harness可以完全掌控每一处细节出错时也能很快定位。2. 代码与token的现实账本2.1 20万行代码都写在哪了20万行看起来很多但拆开看其实没那么吓人。我统计过大约只有6万行是核心逻辑剩下14万行都是“粘合代码”。具体分布Harness核心与工具链约4万行包括状态机、工具注册表、上下文管理器、缓存层、重试机制业务服务与API网关约3万行对外提供接口、处理鉴权、限流、任务调度数据层与迁移脚本约3万行因为要持久化对话历史、工具执行记录、Token用量明细前端管理台约4万行给运营看任务状态、手动干预、查看成本报表测试与仿真占位约6万行主要是为了模拟模型响应和工具故障为什么测试占这么多因为一个人没有QA所有回归验证都得靠自动化测试。我给Harness写了一套“仿真器”用预录的模型响应来跑全链路确保修改不会把旧流程搞坏。这也是我能连续迭代九个月不翻车的最大保障。2.2 每月40亿token到底从哪来40亿token听着很夸张但算下来完全合理。我的应用里跑着很多长链路agent每个任务平均要执行6到8轮回合每轮回合输入输出加一起约4000 token。一个复杂任务跑完就是3万token。如果线上每天处理1.5万个任务单是任务本身的token就是4.5亿。再加上工具执行时的文档检索、日志摘要、背景压缩以及失败重试带来的额外消耗40亿就出来了。做个简单估算日均任务量15,000每任务平均轮次7每轮平均token4,000基础消耗15,000 × 7 × 4,000 4.2亿/天月基础消耗约126亿不对我算岔了。让我重新算4.2亿/天 × 30 126亿这远超40亿。但“每个月40亿”对应的日均约1.3亿token说明平均任务量没那么高。实际上我的任务分成两类一类是重交互任务每天约2000个每个要消耗5万token另一类是轻量任务每天约5万个每个消耗2000 token。这样每天约2000×5万 5万×2000 1亿 1千万 1.1亿加重试和上下文压缩到1.3亿差不多一个月就是40亿。这里我想强调的是token消耗不是均匀分布的。我做过分析30%的token浪费在“重复读取历史上下文”上。任务越长每一轮都要把所有历史重新发一遍成本呈指数上涨。所以必须做上下文压缩和关键信息摘要否则token会失控。2.3 token成本优化的关键手段我后来把每月token消耗从无节制的70亿压到40亿主要靠三招智能上下文裁剪不是简单截断而是对历史消息做重要性评分。工具返回值、用户明确指令保留全文模型自言自语、重复推理摘要成一行。批量任务共用前缀很多任务的前置上下文是一样的我把它们做成缓存块用前缀缓存技术减少重复计费。模型分级轻量任务用便宜的小模型只有复杂推理才调用旗舰模型。这一个调整直接把成本砍掉近一半。优化token不是抠门是因为在Harness架构里token就是你的系统“燃料”。如果燃料烧得太快你根本不敢放大用户量。我甚至写了一个实时token计费面板每个任务跑完立刻显示消耗了多少、花了几美元。没有这个面板我根本不知道哪条流程在偷偷漏钱。3. 核心实现一个可复现的Harness骨架3.1 顶层循环设计一个最简但完整的Harness核心就是那个while循环。我贴一段我最初的骨架代码它比我现在的10万行业务代码更容易看懂class Harness: def __init__(self, model_fn, tools): self.model_fn model_fn self.tools {t.name: t for t in tools} self.messages [] def run(self, goal: str, max_steps: int 10) - str: self.messages.append({role: user, content: goal}) for step in range(max_steps): response self.model_fn(self.messages) if response[status] done: return response[answer] tool_name response[tool] tool_args response[args] if tool_name not in self.tools: self.messages.append({ role: system, content: f工具 {tool_name} 不存在请从以下列表选择: {,.join(self.tools)} }) continue try: result self.tools[tool_name].execute(tool_args) self.messages.append({ role: function, content: json.dumps(result, ensure_asciiFalse), name: tool_name }) except Exception as e: self.messages.append({ role: system, content: f工具执行失败: {str(e)}请更换策略 }) raise TimeoutError(超过最大步骤数) ...这段代码看起来简单但它是整个架构的“心跳”。模型每次返回要么是“我完成了”要么是“我要调用某工具”。Harness不信任模型会自己停下来所以用max_steps强制终止。所有外部副作用都发生在工具执行里模型本身没有权利触碰外部系统。3.2 工具注册与上下文管理工具注册不是简单的dict而是带schema的完整定义。我的工具类长这样class Tool: def __init__(self, name, description, parameters_schema, func): self.name name self.description description self.parameters_schema parameters_schema self.func func def execute(self, args): # 校验参数类型 validate(args, self.parameters_schema) return self.func(**args)为什么要带schema因为模型经常“手滑”传参类型不对、少字段、多字段。如果你的工具直接接住这些参数然后报错Harness会陷入“重试→再错”的死循环。带schema后Harness可以在调用前就拦截错误参数并直接告诉模型“参数不合法要求...”把纠正信息压缩到很短的系统消息里省token。上下文管理是最难的部分。我的做法是维护一个固定长度的“核心窗口”和可变长度的“备用记忆”核心窗口保存最近的模型往返消息最多20轮备用记忆保存关键结论、工具结果摘要、用户原始目标每轮调用前把备用记忆压缩成一段不超过500字的总览拼在核心窗口前面这样既保留了关键信息又不至于让历史无限膨胀。实测下来最长的任务跑了30轮token消耗比不做的版本低了60%。3.3 让模型稳定输出结构化结果Harness成败的关键在于模型输出的稳定性。我的经验是不要完全依赖模型原生function calling因为它偶尔会返回格式错误。我在系统提示词里强制要求模型输出纯JSON并且给出严格的schema示例。然后我用解析器去读取如果解析失败就返回一条错误消息让模型重新生成。我还做了一层“宽容解析”即使模型输出的是带markdown代码块的JSON或者夹杂了说明文字我也能通过正则提取。但宽容解析只是兜底更重要的还是在Prompt里反复强调“只输出JSON不要解释不要提前结束”。为了减少token浪费Prompt需要反复迭代压缩我的最终版系统提示词只有700字但包含了完整的工具列表和约束条件。4. 九个月里踩过的那些坑4.1 token耗尽与重新计数的坑有一段时间任务经常莫名中断日志里全是“token超限”错误。查了一圈才发现问题不是单次请求超限而是累计token被服务商按小时计费窗口卡住了。我一次跑大批量任务前一小时烧了太多后一小时被限流。后来我给Harness内部加了一个“预算令牌桶”每个任务申请一定数量的token预算用完了就暂停并排队而不是同时发起几十个请求。这个“预算令牌桶”其实就是普普通通的限流器但很多人会忽略它在AI应用里的必要性。如果你不做大促或高峰期一来所有任务一起抢token轻则接口报错重则直接被封号。我现在是把预算做成可配置的新用户的任务预算低一点老用户或重要任务预算高。4.2 上下文溢出与滑动窗口的困境另一个大坑是长任务跑到后半段历史消息里混入了太多“工具执行日志”结果模型给忘了最开始的目标。我试过滑动窗口只留最近几轮但模型会失去对任务的全局把握。最后我设计了一个“目标锚点”机制每轮调用前把最初的用户目标用超短的话复述一遍放在消息最前面。同时在每次模型返回时如果检测到它似乎偏离目标就插入一条系统消息提醒它“请重新阅读目标”。这套“目标锚点”看起来笨但极其有效。它相当于给这个健忘的“员工”不断递小纸条提醒他别跑偏。token成本只增加了几十个字但任务成功率从78%提到了96%。我强烈建议所有Harness都放一个目标锚点。4.3 模型返回异常时的兜底策略模型返回“工具不存在”或者“参数乱填”太常见了。我后来的做法是Harness内部维护一个“可恢复错误”列表。如果错误是可恢复的Harness会生成一条精准的纠错提示把模型重新拉回正轨如果是不可恢复的就快速失败并归档而不是无限重试烧钱。最让我头疼的是模型会“一本正经地胡说”。它明明没有调用成功的工具却声称已经完成了任务。为此我加了一个“结果验证”步骤若模型说“done”Harness会检查它上一轮是否真的拿到了所有必需的数据。如果没有就强制失败并要求它补充执行缺失的工具。这一招直接拦住了80%的假成功。5. 常见问题与排查实录一个人干活最大的痛苦是没有第二个人帮你查问题。我把这九个月里遇到频率最高的问题整理成了一张速查表希望你能少走几条冤枉路。现象可能原因排查思路与解决办法任务中途出现 token exchange failed登录态失效或token过期时间太短第三方API返回刷新失败检查refresh_token是否为空确认有效期使用jwt实现token续签提前在过期前刷新把刷新动作放到循环外上下文越长响应越慢越贵历史消息全量带上了实现智能压缩将旧消息摘要化只保留最近N轮完整内容模型总是返回无意义内容缺少约束或目标被淹没增加目标锚点系统提示词里强制JSON输出并给出示例工具调用参数频繁报错Tool的schema不够严格在Tool.execute前先做参数校验错误信息尽量具体让模型知道改什么任务预算超标没有做token预算控制引入预算令牌桶按任务申请预算设置最大重试次数突然所有请求失败限流或服务商额度耗尽检查当前窗口消耗量做冷启动降级暂停非关键任务优先保核心任务登录失败 login server errortoken exchange失败比如地域限制或端点错误检查api地址是否配置正确确认服务范围必要时切换到允许的地区端点这些问题里token相关的最容易让人崩溃。因为它是“软错误”不影响所有请求只是时不时冒出来一个。我的经验是把所有跟token相关的操作封装成一个独立的AuthClient然后统一处理刷新、重试、抛出异常。不要在业务代码里散落token逻辑否则你会被它折磨死。另外一个小技巧不要只在请求失败时才刷新token要做一个定时心跳提前把token续掉。这能规避很大一部分“执行到一半才发现token过期”的问题。虽然看似增加了开发量但它能显著减少生产事故。还有一个容易忽略的点日志里一定要记录每次请求的token使用量。不要怕日志大这是你优化成本的唯一依据。我会定期跑一个脚本分析哪个工具调用最烧token、哪类任务失败率最高然后针对性优化。写在最后这九个月最大的体会是一个人能做的比想象中多但前提是你选对架构。Harness架构让我在模型行为不可控、业务复杂度高、没有队友帮忙的情况下仍然保持了一个稳定的系统。它不完美但很适合单人团队。最后再分享一个小技巧如果你也要做类似的AI应用先从最小可用的Harness循环开始哪怕只有二十行代码。先让它跑起来再慢慢加工具、加校验、加成本控制。千万不要一上来就想着一口气写一个完美框架大概率会陷入“重写泥潭”。真实世界的工程永远是边跑边修正的。