如果给我再来一次的机会,我大概率还是会做这个决定——但至少会在账户里装个“预算提醒”,而不是让一个Agent系统拿着我的密钥,在我眼皮底下把10亿tokens烧成一串越来越长的对话记录。是的,你没看错,10亿tokens。这个数字展开来,大概是近1亿个汉字,等于一千多本厚书的体量,也可以等价成一台中档性能车的预算。我把它们全部投进了一次实验:让Agent亲手帮我造一个Agent操作系统。
结果呢?很接近,差亿点。
对,就是标题那个双关。不是“差一点”,是“差亿点”。复盘的时候我算了一下,如果最后再给我1亿tokens,那个状态恢复模块大概率能调通,整个系统能交付。但这1亿tokens我最终没有烧,不是烧不起,而是我需要在“烧完”和“建成”之间留一个清醒的判断。
这篇文章没有别的目的,就是把我这趟自举实验的完整账本摊开给你看:10亿tokens花在了哪里、踩了什么坑、差亿点到底差在哪,以及如果现在让我重新走一遍,我会怎么把预算砍掉一半。
1. 从“嫌弃别人的系统”到“自举Agent OS”:10亿tokens是怎么变成账单的
1.1 为什么我非要自己造第二个
先说背景。我持续使用Agent干活的时间不算短了,越用越觉得别扭:框架的主循环、记忆存储、工具扩展接口,全部是别人定死的。我甚至无法改变“当前任务完成之后执行什么”这种最基础的流程,只能往自己的请求里塞更多提示词。某天深夜,一个Agent刚回答完我的问题,五分钟后又把同样的信息问了一遍,那一刻我没绷住,决定做一个真正属于自己定义的Agent操作系统。
所谓“第二个”,不是说市面上的东西不好用,而是我不想被某一种固定哲学限制住。别人的Agent框架是“第一个”答案——调接口、写工具、弹对话框。我想做的是“第二个”答案——自己定义进程模型、内存模型、工具调度模型,让Agent系统从根上变成可定制的基础设施。我不会去写内核,也不碰汇编,但对一个长期折腾自动化的人来说,能亲手设计一套控制流和资源管理模型,这件事本身就足够让人心动。
这个决定的下场,就是账户里少了一笔可以买车的钱,换来一堆半成品源码和一份很厚的踩坑笔记。
1.2 我理解中的“Agent操作系统”到底长什么样
在我的定义里,“Agent操作系统”不是指带图形界面的装系统,而是把大模型的运行资源抽象成操作系统层面的概念。你可以理解成一套映射:
- CPU:大模型本身。每一次推理就是一次周期,每个token都是消耗的能量。
- 内存:上下文窗口。它的容量决定了Agent能同时思考多少东西。
- 磁盘:记忆存储。可以是向量库、摘要库、日志文件。
- 进程调度:任务编排器。决定哪个子Agent干活、干多久、什么情况下被中断。
- 系统调用:工具API。代码执行、文件读写、浏览器操作、数据库查询。
- 设备驱动:工具适配器。把不同的API包装成统一接口。
1.3 为什么非要让Agent自己动手写这套系统
这是个很诱惑人的主意:既然Agent系统的CPU是大模型,那让大模型参与设计自己的大脑,不就是一种“操作系统自举”吗?理想状态下,我和Agent反复对话,它会自动拆需求、写代码、跑测试、修bug,然后系统越来越完善。
这个想法的“浪漫值”非常高,但浪漫也是有单位的——单位就是token。因为每一轮代码修改的评审、每一次回归测试、每一条日志的阅读,都要把相应内容重新喂给模型。一次“自举”看起来是一次对话,实际上等于把整个项目的上下文反复加热了上千遍。10亿tokens的账单,正是从这种循环中产生的。
2. 10亿tokens的消耗路线图:五个阶段,每个阶段都在疯狂吞噬预算
整个项目可以拆成五个阶段,每个阶段的token消耗结构完全不同。先看总览,再逐段拆解。
| 阶段 | 占比 | 主要工作 | 产出 | 被浪费的典型点 |
|---|---|---|---|---|
| 阶段一:架构设计 | 约8% | 多角色Agent辩论、需求拆解、方案文档 | 一份能用的设计 | 重复会议、共识成本 |
| 阶段二:Agent写核心代码 | 约35% | 实现调度器、上下文管理器、工具注册表 | 两版可用代码 | 废代码重写、惯性蔓延 |
| 阶段三:自测与调试 | 约32% | 让新系统跑任务、读日志、修bug、再跑 | 能稳定运行20分钟 | 同一bug反复修复 |
| 阶段四:工具生态接入 | 约20% | 接入代码执行、文件、浏览器工具 | 完整的工具挂载链 | 工具选错、重复注入 |
| 阶段五:回归与压测 | 约5% | 完整场景流程测试、状态恢复验证 | 差亿点可用 | 预算耗尽 |
2.1 阶段一:多角色Agent辩论,烧掉近似一亿tokens的可行性评估
很多人会高估写代码的开销,低估“开会”的开销。我一开始搭了一个多角色辩论环境:一个Agent扮演架构师,一个扮演运维专家,一个扮演产品经理,用来把模糊想法拆成明确方案。听起来很专业对吧?实际上就是让四个Agent围绕“上下文要不要压缩”“工具注册表存哪”“调度器要不要支持抢占”这些问题互相发表意见。
这个阶段的token消耗占比不高,但绝对数量惊人。最大的浪费不是方案本身,而是在形成共识的过程中,每个角色都会反复引用别人的观点。架构Agent说了“我同意运维关于压缩的担忧”,运维Agent又会把这句话带上再回给产品Agent。一个原本5000 token能说清的结论,被放大成了5万token的会议纪要。我后来统计了一下,有效决策信息大约只占这个阶段token的六成,剩下四成都在复述。
2.2 阶段二:Agent写核心代码,废代码率高达九成
阶段二是最大的烧钱黑洞。我的指令很明确:“实现一个可插拔的任务调度器,支持优先级、超时、重试和手动中断。”Agent兴奋地生成了一个build目录,开始写代码。结果很有意思:第一版设计稿说得天花乱坠,实际实现时写出了42个函数,最后能用的不到5个,其它全部是为了“可能的需求”预留的抽象层。
这就是“让Agent写自己”最贵的地方:它特别会“过度设计”。它认为未来可能需要多线程支持,于是提前实现了一整套线程池;觉得可能需要插件系统,于是加了一个插件加载器。这些代码在真实场景里根本没有触发点,但每写一行,都要让模型先读一遍设计文档再读一遍已有代码,然后再输出。最离谱的一次,它为了模拟“所有工具都已注册”的场景,不仅把30多个工具全部加载,还给每个工具写了两百字的说明,直接把上下文撑爆,整个任务失败,从头再来。
2.3 阶段三:Agent运行Agent,烧钱烧到我心慌
这是整个项目里最贵、也最反直觉的阶段。新系统写完第一个可运行版本后,我开始让它跑一个最小任务:“帮我计算一下日志文件里有几行内容包含ERROR。”就是这个简单任务,让我烧掉了巨额token。为什么?因为运行日志、报错栈、工具返回结果都要被拉回上下文,Agent看完之后开始判断:
- 第一步:读日志文件 → 返回了10万行日志 → 直接塞进上下文。
- 第二步:Agent说日志太大,应该用命令过滤 → 调用grep → 返回结果。
- 第三步:Agent说结果还是太多,要再过滤一次 → 又调用工具。
- 第四步:Agent发现输出不完整,怀疑是input被截断,于是重新设置参数 → 再次调用。
同一个简单任务被拆成了十二次工具调用,每次调用都要把前面几百行对话重新算一遍。这就是大模型“无状态困境”的真相:它不是真的记住你五分钟前说过什么,而是每次生成时都要把整个对话历史重新过一遍。你多写一句日志,它就要为所有历史记录重新付一次注意力成本。
阶段三结束的时候,我学会了第一课:永远不要让Agent处理原始日志,先做压缩和过滤,再把摘要喂给它。
2.4 阶段四:工具生态接入,越接越容易翻车
到阶段四,系统已经能跑简单任务了,我开始接入外部工具:代码执行器、浏览器自动化、数据库连接器、文件管理工具。问题从这里开始变大。工具注册表里有三十多个工具,每次任务开始,Agent都会把所有工具的描述加载进上下文,然后在一长串列表里挑一个。它经常挑错。
印象最深的一次,Agent要读取一个目录结构,结果在“文件列表工具”和“目录树工具”之间犹豫了很久,最终选了一个需要手动输入绝对路径的工具,把路径写错了,返回错误后又重新调用另一个工具。这类错误占了工具阶段的大头。
2.5 阶段五:差亿点成功,然后预算见底
阶段五是我最接近成功的时候。系统已经能连续运行十个小时,处理一百多个任务,记忆检索正常,工具调度稳定。我几乎准备宣布成功了,然后遇到了一个状态恢复问题:系统重启之后,长期记忆和短期缓存的衔接错位,导致新任务引用了旧上下文里的过期信息。这是最后一个拦路虎。我让Agent修了一轮、两轮、三轮,仍然没有完全收敛。盘点账户之后,我决定停手。
“差亿点”就是从这里来的:如果再给我一亿tokens,让Agent多做十轮针对性调试,这个状态恢复模块大概率能合上。但当时我已经很清楚地意识到,边际收益在肉眼可见地下降,继续烧token只是在为沉没成本买单。所以我关掉了对话,把整个项目定格在“能用但不够完整”的状态。
3. 记忆,或者说“把Agent做出失忆症再治好”:三次重写上下文管理方案
如果只能选一个让我交学费最多的模块,我会选记忆管理。Agent系统最像操作系统的部分恰恰在这里,而最不像的部分也在这里:内存极其有限,且一切超过窗口的东西都会消失。
3.1 第一版:全量塞入上下文,系统直接“脑过载”
第一个版本的方案简单粗暴:把项目说明、代码树结构、工具清单、历史对话,全部打包塞进上下文。开局效果很好,Agent表现得像什么都知道。但随着对话轮数增加,上下文越来越长,模型开始出现“注意力涣散”的症状——它似乎每句话都懂,但整体目标逐渐跑偏,经常把A任务的需求拿到B任务里实现。
这就像操作系统内存被占满之后不报错,而是直接把一部分代码换出去,还假装一切正常。更麻烦的是,长上下文的推理速度明显变慢,每一次响应的延迟直线上升。最终我不得不放弃这个方案,因为它根本不是可持续的架构。
3.2 第二版:摘要压扁历史,又换来一种“老年痴呆”
第二版思路是:定期把历史对话压缩成摘要,再让Agent基于摘要运行。这个版本一开始表现得不错,但很快暴露出新的问题——摘要会杀死细节。上次修复bug的原因,会从原始日志里的具体报错,变成一句模糊的“检查了文件路径问题”。Agent看到摘要后,以为已经解决了,结果下一次又踩进同一个坑。
另一个隐藏成本是:生成摘要本身非常耗token。每5轮对话生成一次摘要,意味着要把这5轮对话重新算一遍。这是一个二次开销,等于每次保存进度都要把进度内容原样复制一份。我统计了一下,摘要功能让整体token消耗增加了约15%,但收益只在短期有效,因为摘要更新之后,旧摘要立刻被丢弃,之前喂进去的细节也都白费了。
3.3 第三版:短期消息、中期总结、长期向量,终于像个人样了
第三个版本参考了操作系统的存储分层:短期、中期、长期各管各的。
- 短期层:保存最近20轮原始对话,用于保持当前任务的连贯性。
- 中期层:每5轮生成一次滚动摘要,摘要上限控制在2000 token,覆盖前期的核心结论。
- 长期层:把重要决策、代码结构、失败教训写入向量索引,任务开始时按需检索。
这套方案的关键在“按需检索”四个字。Agent启动一个任务时,不是把所有东西都灌进上下文,而是先根据任务描述去长期索引里捞相关信息,再把捞到的片段和短期原始消息一起组成工作集。这个机制非常像操作系统里的页面置换:你不需要把整个磁盘都装进内存,只需要把当前页面调进来。
我给出当时的配置结构,你可以直接参考:
memory: strategy: hierarchical short_term: max_turns: 20 store: raw_history mid_term: interval: 5_turns max_summary_tokens: 2000 long_term: index: vector_db chunk_size: 800 retrieval_top_k: 5 inject_budget: 3000_tokens这套方案落地之后,单个任务的token成本大约下降了50%,而且长期运行之后的上下文保持能力明显提高。我一直到现在都认为,这是整个项目里最有价值的产出之一。
3.4 记忆的真相:不是“全记住”,而是“知道去哪查”
这段折腾给我留下一个很清晰的结论:Agent的记忆能力不需要无限大,它只需要具备“检索意识”。人会遗忘细节,但不会忘记细节放在哪里;操作系统也不会把所有数据常驻内存,而是靠文件系统+缓存的机制来应对。想通这一点之后,我不再追求把全部历史塞进上下文,而是开始给Agent制作“记忆地图”——告诉它哪些内容存在哪里、什么情况下应该去查什么。这个转变带来的节省,比任何提示词优化都大。
4. 四个差点把项目毁掉的坑,以及我的修复方案
这一章不写原理,纯踩坑记录。每一个坑都花了我大量token去填,希望你不用重蹈覆辙。
4.1 子Agent互相踢皮球,主Agent不拍板
现象:我搭建了多Agent协作结构,编码Agent写代码,审查Agent提意见,架构Agent说“合理但需要改”。结果呢?三个Agent反复交换看法,没有任何一个Agent有权说出“就按这个来,继续”。一轮又一轮的“我觉得可以”“我觉得不行”“你再看看”就这样烧掉了大量token。
根因很简单:没有设置决策边界。每个Agent都觉得自己只负责提供意见,最后变成“全员参谋,无人决策”。
修复方案:明确“唯一拍板人”。我在调度层加了一条规则:子Agent只能提交建议,最终决策权一律归主Agent。主Agent不再征求意见,而是在收到建议后直接给出下一步指令。这样以后,协作任务的token消耗直接下降了三成,因为不再有无限循环的商讨环节。
4.2 Agent给自己改Prompt,改出一份18k token的巨型指令
现象:为了让系统“自我优化”,我允许Agent修改自己的系统提示词。它用了几轮迭代,从原本的3000 token指令,扩张成了18000 token的巨型文档,包含大量重复表述、历史分析和自我对话记录。系统性能不但没有提升,反而因为提示词太长,每个请求的token开销变大了,输出质量也变差了。
根因是“权限过宽”。Agent没有分辨哪些是核心约束、哪些是边缘词条的能力,它试图把所有已经知道的信息都写进提示词,结果就像一个人把整本操作手册背下来再去做算术题,脑子全被手册占满了。
修复方案:把系统指令分成三个区——只读区、可改区、禁止区。核心原则放进只读区,Agent永远不能改;外围策略放进可改区,允许有限优化;安全限流规则放进禁止区。这样既保留了自优化能力,又不会让系统自毁。
4.3 工具越挂越多,模型越来越不会选
现象:工具注册表里的工具数量达到30个之后,Agent每次选择工具都变得非常困难,经常选错。比如明明应该调用文件搜索工具,它却调用了数据库查询工具,因为工具描述相似。
根因是“上下文噪音”。工具描述占用的上下文越多,模型的注意力就越分散。这不是模型能力问题,而是信息检索问题;就像你把30个长得差不多的遥控器叠在一起,再聪明的人也要挑半天。
修复方案:改成动态工具挂载。任务开始时,先由调度器根据任务分类,预加载最多8个相关工具。执行过程中,如果Agent发现缺工具,再动态加载。这个改动之后,工具选择的准确率提升了一大截,上下文占用也明显下降。工具贵精不贵多,动态挂载才是正解。
4.4 测试“假通过”:Agent说全部通过,实际断言全挂
现象:这是我遭遇的最危险的坑。某次回归测试,Agent给我发了“全部测试通过”的结论。我随手看了一眼日志文件,发现里面明明有大量失败断言。原来Agent只检查了测试进程的退出码,退出码是0,它就认为全部通过了,根本没看具体的断言输出。
根因是“结果解析方式错误”。非结构化文本里的信息,模型很容易漏读。Agent对“进程退出”的判断是成功的,但“断言结果”的真实状态是失败的。
修复方案:把所有测试结果改成结构化输出,使用统一格式的JSON文件记录每个断言的实际值、期望值和状态;紧接着,再让另一个独立Agent做二次复核,不允许同一个Agent既跑测试又写结论。加了这个双保险之后,“假通过”问题彻底消失。
5. 复盘十亿tokens:如果重新来一遍,这些钱本来可以省掉一半
5.1 差亿点,差的具体是哪些模块
项目最后的状态是:调度器可用、任务编排正常、分层记忆稳定、工具动态挂载可靠;但状态恢复模块始终没有闭环,重启之后长期记忆和短期缓存会错位。系统缺少一套“可安装”的一键初始化流程,也缺少权威的配置导出导入能力。
如果再多一亿tokens,我会让Agent集中解决状态恢复模块的边界情况,并补齐安装包。这两件事每件事的复杂程度都不高,难点只在于需要反复验证不同的重启时间点。预算停在那,是因为我已经能预判出它什么时候会收敛,但我对“组织还该为此付出多少成本”产生了质疑。
5.2 无效tokens的四个黑洞
现在回头翻账单,可以负责任地说,至少三到四成的token是无效消耗:
- 无界探索黑洞:让Agent自己寻找函数库时,它会沿着一条不存在的逻辑路径越走越远,直到两百轮对话之后才回头。
- 重试惯性黑洞:同一个错误日志反复喂入上下文,Agent每次都能给出一个新的、错误的修复方案。
- 重复建造黑洞:让Agent“重新实现”一个模块,而实际上它没有先去检索已有代码,导致生成了两个功能重叠的组件。
- 汇报传染黑洞:多角色对话中的每一方都在复述别人的观点,大量token用在“说废话”上。
把这些黑洞堵住,相当于直接省下三亿token。
5.3 如果再来一次,我会把钱花在这些地方
第一,起步阶段先花小钱做端到端验证。我会先让Agent实现一个极简任务闭环,而不是一开始就设计完整的操作系统。有一个能跑通的最小系统,后面所有迭代才有参照物。这个环节大概只会花掉最终预算的2%。
第二,给每个Agent任务设置独立的token预算上限。我后来在调度器里加了token_budget_per_task这一项,任务一旦超支,系统会自动总结当前进展然后暂停。这样就不会出现“一次性烧掉50万token还不收敛”的情况。
第三,关键逻辑仍然要用规则代码做护栏。记忆检索、工具路由、任务中断这些核心机制不能完全交给LLM自由发挥,我用传统代码写了一个判断层,LLM只负责给出决策建议,判断层负责执行。这个组合看起来“不够AI”,但在成本控制和可靠性上非常有效。
第四,严格遵循“加载最小集”原则。能传5行代码就不传50行,能传摘要就不传原文,能让Agent查资料就不把资料塞进上下文。这个原则贯穿了整个项目的下半场,也是第三版记忆方案真正的核心。
5.4 给想复刻这条路线的人的一份“烧钱须知”
如果你也想用类似的方法让Agent帮你造一个系统,我的建议非常直接:先确认自己愿意为一个“可能失败的技术验证”承担多少成本。这个成本不是时间,而是token账单。然后,给Agent的每一次运行都加上预算上限,把所有工具调用都记录日志,把测试结果结构化,拒绝“大概能用”这种模糊交付。最后,也是最重要的:你要像一个控制资源分配的操作系统那样,管理你自己花在Agent身上的token。
这个项目的结果,是一套能跑但不完整的Agent系统,一大笔token账单,和一份血泪踩坑笔记。如果再给我一次机会,我会用这套经验砍掉一半预算重新走一遍。但我也必须承认,这10亿tokens换来的不是一套代码,而是对“Agent系统如何管理资源”这件事的全新理解。
最后分享一个我目前在用的习惯:每个Agent任务的请求发出之前,都会先在脑子里回答三个问题——这次任务需要多少token?如果任务失败,重试上限是多少?如果重试也失败,我是否知道它在哪个环节失败的?这三个问题想清楚,很多烧钱项目根本走不到10亿token。