上个月我把那套基于 Cursor 迭代了三个多月的 Agent 项目拉出来做了一次完整复盘结论是综合成本降了 7% 左右。这个数字不是拍脑袋估出来的也不是换了更便宜的模型而是因为我动了五处脚手架。这里的“成本”我拆成两块看一块是跑 Agent 时实打实的 Token 账单另一块是工程师改需求、查日志、调 Prompt 花掉的人天。如果你最近也在用 Cursor 搭 Agent或者刚接了一个“让 AI 自己去跑流程”的需求这篇复盘应该能帮你避开不少弯路。1. 先算账7% 到底是什么降下来了1.1 成本口径API 费用加上调试人天很多人一说成本优化就盯单次请求价格这其实是误区。Agent 和普通 Chat 不一样一个需求往往要跑几十轮“计划-行动-观察”而且模型每轮都要把前面的对话重新发送一遍轮次越多Token 消耗越像滚雪球。我统计过项目里一个普通需求平均要烧掉六十万 Token其中大头不是单次生成贵而是来回空转太多轮。我把“单需求成本”定义成两部分一部分是 Token 账单另一部分是工程师的时间。第二部分特别容易被忽略但它对这次 7% 的影响反而更大。调一次系统提示词要花半天排查一个“Agent 不知道死在哪一步”的报错要花一天这些时间折算进去之后你就明白为什么脚手架层面的改动比换模型更划算。1.2 七个百分点是怎么测出来的这次复盘不是感觉而是跑了一组对照实验。我从需求池里挑了 40 个真实需求样本尽量控制类型相近修 Bug、加工具、调提示词各占一部分。优化前先记录每个需求从开始到测试通过的 Token 消耗和人工投入然后开始改脚手架改完再用同样的 40 个需求重跑一遍。统计项优化前优化后变化单需求平均 Token 消耗约 60 万约 55.8 万下降 7%单需求平均人工投入约 1.5 小时约 1 小时下降 33%综合成本折算基准下降约 7%按保守口径折算这里多说一句Token 数字其实挺稳定人工时间因为大家越来越熟练会自然下降所以我算综合成本时特意把第一次改造脚手架的一次性投入摊到一个月里避免把数字吹高。2. 第一处脚手架让 Agent 的主循环有边界2.1 自由循环是最隐蔽的烧钱点最初的 Agent 实现就是一个简单的 while 循环让模型自己决定下一步直到它觉得任务完成。听起来很灵活实测下来却有一堆任务在空转。我试过让它“查一下数据库里某张表的行数”它先自我怀疑两轮然后又思考“我是不是该先确认用户意图”再决定调用工具工具报错了它又反思一轮上下文越滚越大。吴恩达在 Agent 教程里专门讲过反思循环反思确实有用但前提是限次数。反思是给模型一个纠错机会不是让它无限钻牛角尖。我当时把反思改成最多一次之后效果立竿见影。后来拉日志统计优化前有将近 20% 的轮次属于无效轮次也就是“想多了”的轮次这部分的 Token 几乎全浪费了。2.2 改成显式状态机之后重构后的主循环变成五个显式状态PLAN、CALL_TOOL、OBSERVE、REFLECT、FINISH。每个状态都设了次数上限模型每一步只负责当前状态内的决策不再拥有“是否结束”的无限权力。STATE_LIMITS { PLAN: 2, CALL_TOOL: 8, OBSERVE: 6, REFLECT: 1, }这个改动在 Cursor 里做其实很快。直接把原始循环代码选上让 Cursor 按状态机重写然后人工把状态转移条件过一遍。关键是每个状态进入和退出都要打日志不然状态机出问题你根本不知道卡在哪里。这处改动跑了一周无效轮次占比从 20% 降到了 5% 左右对总成本的贡献大概有两到三个百分点。2.3 避坑状态别太细有人把状态细化到十几个模型反而更迷路。状态机对 Agent 来说是护栏不是束缚太细的护栏会让模型频繁转换、浪费 Token。建议先从五个左右的主状态开始跑一段时间看日志哪个状态经常反复进出再针对性地加限制。另外REFLECT 状态放在工具调用失败之后比放在每次计划结束后更有效失败后的反思有明显纠错价值计划结束后的反思大多是自我怀疑。3. 第二处脚手架工具调度层收敛成注册表3.1 散装 if-else 的隐形开销早期代码里的工具调度基本靠一堆 if-else每个工具附带一大段自然语言描述模型每轮请求都要把这些描述读一遍。一个工具的描述如果写得太发散模型经常选错。我记得有一次给“获取订单详情”写了两百字散文结果模型经常选成“查询用户信息”因为两个描述里的业务词太接近筛选成本很高。更麻烦的是大体积返回。画图工具直接返回 base64 图片模型上下文瞬间多几万 Token跑两轮就撑爆。这个问题并不少见我见过不少 Agent 项目死在“工具返回太大”上。3.2 注册表长什么样把所有工具收敛成一份可枚举的注册表每个工具就是一个 name、description、input_schema、handler 的结构。description 只写三件事这个工具是干什么的、什么时候该用、什么时候不该用控制在 300 字以内。input_schema 用严格的 JSON Schema模型按 Schema 填参数自由发挥的空间越小越省钱。{ name: get_order_detail, description: 按订单号查订单详情仅在下单流程或售后流程中使用, input_schema: { type: object, properties: { order_id: { type: string } }, required: [order_id] } }注册表的生成也自动化了每个 handler 文件写一个装饰器扫描后自动生成注册表 JSON不靠人肉同步。Cursor 在这里能帮上忙让它生成装饰器样板和 Schema 校验代码比自己写快很多。图片这类大返回统一改成对象存储上下文里只放 URL模型要用的时候再通过另一个工具拉取。跑了一周后单需求 Token 均值降了 1% 到 2%而且工具选错率明显下降。4. 第三处脚手架上下文压缩与记忆隔离4.1 别让所有历史都泡在窗口里Agent 对话越久上下文越膨胀每次请求都要重发一遍历史。最初我以为这是模型 API 的天性后来发现是记忆管理没做。历史里有的是关键约束有的是过程噪音混在一起让模型又慢又容易跑偏。我把记忆拆成三个区域短期上下文当前目标、最近两三轮操作放在窗口里用完就丢长期记忆库用户偏好、项目路径、权限信息等结构化记录存持久化存储滚动摘要每五轮把更早的对话压成一段摘要重新注入上下文这个思路对“Agent 记忆”这个热门话题很关键。很多实现把记忆做成了无限聊天记录模型越聊越笨。记忆应该是分级分区的而不是一把梭。4.2 摘要要能回答问题不是复述时间线当时让 Cursor 帮忙写摘要函数第一版写出来是“用户先问了 A然后做了 B又尝试了 C”这种摘要毫无用处。真正有用的摘要是“当前任务已完成到第 2 步第 3 步需要用户确认授权”。摘要要面向后续决策而不是流水账。关键字段要写成结构化记忆。比如用户说过“生产环境不要直接改数据库”这个约束必须进长期库每次注入系统提示词而具体的调试过程则压进摘要。向量检索只取相关片段不把整库里所有内容都塞进去。上下文平均体积降了 10% 左右这是五处改动里对 Token 费用贡献最大的一处。这里有个坑压缩前要保留当前正在进行的目标和用户最近授权信息。有一次我把用户刚刚同意的操作授权给“压缩掉”了结果 Agent 又重新问了一遍不仅多花一轮用户还觉得产品变笨了。压缩要分清“可扔”和“不可扔”任务进度和授权信息属于不可扔的。5. 第四处脚手架Prompt 模板放进版本管理5.1 系统提示词也是代码系统提示词写死在代码字符串里基本等于灾难。有一次产品要求微调语气我改了一行字符串上线后旧会话还在用旧模板排查起来很痛苦。后来把模板抽成独立目录一个模板对应一个版本号部署时随环境一起发布。system_prompts/ agent_v1.yaml agent_v2.yaml review_prompt_v1.yaml变量用占位符注入模型看到的永远是渲染后的字符串。原始模板里不允许出现密钥、内部域名、真实账号这些敏感信息这是安全底线。我一直强调防止“提示词泄露”这类问题模板内容可能会被模型原样印到对话里里面不能有任何不该出门的东西。5.2 Cursor 不是用来“一键生成 Prompt”的真要用好 Cursor干法是让它做模板的静态检查员检查有没有用到不存在的变量、有没有重复段落、有没有可能泄露的硬编码。新模板先 10% 灰度跑一上午看成功率、平均 Token 消耗和用户反馈没问题再全量。改一次 Prompt 的时间从半天缩到了半小时这部分的改进直接体现在综合成本里。另外模板里的“你是某个角色”这类身份描述也归入版本管理改完要做回归测试。身份描述变化会影响工具选择倾向曾经出现过模板里把“你是工程师助手”改成“你是编程专家”之后模型更倾向于滔滔不绝地解释而不去调用工具单日 Token 消耗飙了一截。6. 第五处脚手架可观测性与异常兜底6.1 每次 Tool Call 都要有账排查 Agent 问题最怕的是“不知道它死在哪一步”。日志里强制记录当前状态、思考摘要前 100 字、工具名、完整参数、返回内容前 200 字符、耗时、本轮 Token 数。有了这些再遇到 “agent execution terminated due to error.” 这类报错打开日志从最后一条往前翻基本十分钟定位。state崩溃前处于哪个状态summary模型打算做什么tool_name调了哪个工具param参数摘要return_preview返回内容前 200 字符cost_token本轮 Token 数这套字段看起来简单真正坚持下来不容易。最初开发图省事只记工具名和时间后来排查问题全凭猜才痛下决心补齐。6.2 超时、重试、熔断一起上模型 API 偶发抖动是常态工具接口五分钟不返回也常见。给外部工具统一设了 10 秒超时Agent 整体等待上限 15 秒。超时后不是立刻重跑整个 Agent而是先尝试修正工具返回格式。比如 JSON 解析失败就把报错片段摘出来再喂给模型做一次修复省掉一整轮重规划。坏工具要有熔断机制连续失败 5 次自动停用并通知人工介入。市面上常讨论“AI Agent 怎么扛并发”我的看法是 Agent 层的并发没什么魔法重点是排队和熔断。一上来就铺 100 个并发模型和工具都会先崩系统设计要给你自己的服务留退路。沙盒类问题也值得单独提一下。更新 Agent 沙盒后依赖不重建就会出现“显示更新 agent 沙盒后无法发送消息”这类怪问题。我在 Docker 容器里跑 ROS2 环境时也踩过类似的坑工具调度层如果走的是 micro-ROS Agent 这类桥接协议千万不要拿 HTTP JSON 的假设往上套协议栈完全不同排错思路也要跟着换。7. 踩坑速查表与框架选型的一点看法7.1 常见问题速查表现象可能原因处理办法agent execution terminated due to error.工具返回格式异常或主循环被终止看最后一条状态日志优先检查工具返回更新沙盒后无法发送消息环境依赖没重建清缓存、重建镜像确认依赖版本工具返回的不是 JSONhandler 做了任意类型返回在注册表里强校验 Schema解析失败让模型修复图片工具返回 base64 导致上下文爆炸大对象直接进窗口存对象存储上下文只放 URL模板改了不生效旧会话还在读旧模板模板版本化按版本过滤会话ROS2 容器里的 micro-ROS Agent 连不上协议栈不同用桥接层转换别复用 HTTP 假设7.2 框架选型能力边界比名字重要朋友圈里有人用现成的 Agent 框架也有人自己搭。名字不重要重要的是你选的框架有没有把“推理编排”和“运行骨架”分清楚。社区里常被问到的“harness 和 agent 区别”我的理解是harness 解决“这个 Agent 怎么跑起来、怎么被调度”agent 解决“拿到目标后怎么拆解任务”两件事最好解耦。不管选哪家框架五处脚手架的对齐思路都适用主循环有边界、工具注册表统一、上下文分区分级、提示词版本化、全链路可观测。架构顺手了就少折腾把精力留给业务本身。7.3 顺手把 Cursor 日常问题也收个尾如果你是从 VS Code 迁过来的一上来肯定想改中文界面。新版本直接在设置里找语言选项就行不用急着装汉化包。历史对话记得定期清理避免上下文污染。网上流传的第三方外观、集成类扩展我的建议是主线上少装花活先把 Agent 的脚手架稳住工具再好看也不解决烧 Token 的问题。这轮下来最让我意外的不是那 7%而是团队对改动的态度。上个月开会说要动主循环同事觉得现有代码能跑就别碰结果我把日志一拉二十几条任务里有六条在空转谁也没话说了。所以最后想说的是成本优化不是靠某个模型突然变聪明也不是换一个框架就一步到位它靠的是把每一处损耗都变成可见的数字。如果你想复现这条路线第一件事不是急着优化而是先把可观测性补齐。有了数据撑着后面每一步都有底气。