资讯动态

Agent 项目越做越重?从 Skills、子代理到工具优化,砍复杂度省额度

发布时间:2026/9/26 7:12:17 来源:尧图企业网站定制
先问一句你是不是也把 Agent 项目越做越重了子代理套子代理、工具挂了几十个、上下文里堆满历史对话结果功能没上去额度倒是肉眼可见地见底。这半年我帮团队做过几个 Agent 项目反复折腾下来发现一个反直觉的结论——大部分额度不是被智能烧掉的而是被复杂度烧掉的。真正让 Agent 跑得又稳又省的关键恰恰是从 Skills、子代理到工具优化这些环节上做减法。这篇文章就把我踩过的坑和验证过的做法完整摊开照着调整你的额度利用率大概率能直接提升至少 20%。先说清楚一件事这里说的额度提高 20%指的不是充值变多而是同样的预算能跑出更多有效的 Agent 任务。说白了就是单位任务成本降下来。我后面所有的优化策略衡量的唯一标准就是每个有效任务消耗的 token 数有没有下降。1. 先搞清楚额度都烧在哪了Agent 开销的三个隐形黑洞做优化之前必须先把支出结构看清楚。很多人以为 Agent 烧钱是因为模型单价贵其实单次调用只是冰山一角。真正让额度失控的是下面三个几乎无人察觉的黑洞。1.1 上下文越长越贵token 的复利效应模型按 token 计费而 Agent 是一个多轮循环的过程思考、调用工具、看结果、再思考。每一轮模型都要把整个对话历史重新处理一遍。问题就在这里——对话历史是越来越长的。我之前接手过一个项目Agent 处理一份 50 页的合同过程里不断地把合同全文塞回上下文跑了大概 15 轮才结束。我拉了下账单实际消耗的 token 差不多是合同原文的 9 倍。这不是夸张多轮 Agent 任务的 token 消耗接近轮数 × 单轮上下文长度的乘积如果上下文一直不清成本几乎是指数级往上叠。打个比方打车明明是直达的单程结果你每过一个路口都要绕回去再把全部行李搬一遍最后这个车费当然是天价。所以第一刀永远是上下文瘦身。我常用的做法有三个超过一定轮数就把历史对话压缩成摘要工具返回的长文本只保留关键片段每 5 轮清理一次日志类的临时内容。这不算什么高深技巧但效果立竿见影下面第 5 章我会给出一套完整的记忆管理方案这里先把问题定位到。1.2 工具调用的轮询式消耗第二个黑洞藏在工具的调用决策里。模型每次决定要不要调用工具、调哪个工具、传什么参数时都需要读取并处理所有工具的描述信息。也就是说哪怕你这次只需要用到 1 个工具模型也得把 20 个工具的描述全部扫一遍。这个开销有多夸张我做过一次真实审计项目里挂了 18 个工具但实际日常任务只会用到其中的 6 个。我把这 6 个工具保留其余 12 个暂时注释掉同一个任务跑下来输入侧的 token 消耗直接少了接近 30%。为什么因为模型在做工具选择时不再需要去理解那 12 个用不上的工具是什么、什么时候该用、参数怎么填。这部分推理成本被完整省掉了。这件事让我意识到一个原则工具的存在感本身就是成本。工具不是越多越好而应该是越精越好。与其把 50 个工具全挂着祈祷模型自己会挑不如只留 10 个高频的剩下的放进 Skills 里按需加载。1.3 失败重试的隐蔽成本探索性燃烧第三个黑洞最隐蔽因为它藏在异常路径里。Agent 的调用失败之后最常见的行为是自动重试。但重试的代价不是多调用一次那么简单——Agent 失败后往往会换思路、换工具、拆步骤每一次尝试都是一次全新的多轮对话。这就是我所说的探索性燃烧。我自己遇到过的真实场景一个 Agent 在调用某个 API 时因为返回格式里多了一个字段导致解析失败。理论上这次失败完全可以快速返回结果 Agent 却开始怀疑是不是自己的 JSON 格式写错了、是不是应该换个工具一连试了 6 次白白烧掉了大约 4000 token。后来我给工具加上了显式的错误处理提示告诉 Agent如果返回内容不符合预期立刻返回失败不要重试或换工具同样的场景一次失败只消耗 300 token。这个教训我后面会展开说因为它属于工具优化里最容易被忽略的部分。2. Skills 的正确食用方式会装、会选、会自己写很多人听到 Skills 这个词第一反应是这不就是高级一点的提示词吗。如果你也这么想那说明你还没理解 Skills 能省钱的根本逻辑。2.1 Skills 和普通提示词的本质区别按需加载 vs 常驻上下文普通提示词Prompt是常驻上下文里的只要它在系统提示词里模型每轮都要处理它一次。哪怕这次任务根本用不上那些规则这些文字也在持续消耗推理资源。Skills 则完全不同。它本质上是一组按需加载的上下文包Agent 遇到特定场景时才把对应的 Skill 文件内容注进去没用上时它就是一个躺在磁盘上的文件对上下文毫无影响。这就是省钱的核心逻辑把低频但必要的知识从桌面上挪到抽屉里。同样的一整套数学建模步骤说明如果写进提示词每一轮对话都在烧钱如果做成一个数学建模 skills只有触发数学建模任务时才被加载成本可能直接降到原来的十分之一。我之前用 Claude Code 跑一个数据类项目就试过这种方式。项目里我最开始把各种代码规范、项目结构说明全部塞进 CLAUDE.md后来全部拆成对应场景的 Skills。同样的迭代任务跑一周下来 token 消耗下降了大概 25%而且模型在处理无关任务时的噪音也明显少了很多。2.2 手动安装 GitHub 上的 Skills别被目录结构卡住现在网上有很多现成的 Skills 库比如 awesome claude skills 这类索引仓库还有 superpower skills 这种打包好的一整套技能集。很多人卡在第一步怎么把 GitHub 上的 Skills 手动装进自己的环境里。以 Claude Code 为例手动安装其实就几步# 找一个放技能的目录一般是项目根目录下的 .claude/skills mkdir -p .claude/skills # 把远程仓库克隆到对应的子目录 git clone https://github.com/example/some-skill.git .claude/skills/some-skill装完关键不是完事而是要检查目录结构是否合法。一个能被识别的 Skill 必须具备一个独立的文件夹文件夹名就是技能名文件夹里的 SKILL.md 文件且里面要有 YAML frontmattername 和 description 字段可选的支持文件脚本、模板等但路径必须相对 SKILL.md 所在目录。我见过很多人装完 Skills 却发现 Agent 毫无反应十有八九是 SKILL.md 里的 name 或者 description 写得不对。尤其是 description模型是靠它来判定这个技能什么时候该被触发的。如果 description 写得又长又空模型根本不知道该不该加载它。所以我会建议先把 description 写成当任务涉及 XX 时使用适合处理 YY 场景再测试触发。2.3 选 Skills 的三条标准限定不是坏事网上有人统计过现在可选的 Skills 早就超过几千个。但我自己的体会是Skills 装得多不等于好用甚至可能拖慢 Agent 的加载和决策。我选 Skills 有三条硬标准应用场景足够聚焦。比如图片生成 skills 安装包这种就是一个明确场景而那种试图覆盖所有前端开发的大杂烩技能包我会非常谨慎因为它的描述触发条件太宽很容易在不该用的时候弹出来抢上下文。初始化步骤少。有的 Skill 加载时需要先跑一堆前置脚本、读一堆外部配置文件实际跑起来比不用它还慢。维护活跃。GitHub 上的 Skills 好用的通常是近期还在更新的那些一年多没动静的很可能已经不适配当前模型版本。顺便提一句现在 Claude Code、Codex、opencode 这几类 Agent 环境对 Skills 的格式要求其实不完全一样。比如 codex skills 的目录约定和休息规则就跟 Claude Code 有差异。如果你手头同时用几套环境不要把同一份 SKILL.md 直接复制粘贴完事至少要看看对方要求的 frontmatter 字段是不是一致。2.4 自己写一个最小可用的 Skills数学建模实例自己写 Skills 其实没有想象中难。拿数学建模举例我可以给你一个最简单的模板--- name: math-modeling description: 当用户请求进行数学建模建模方案设计或论文排版使用时适合处理问题分析、模型选择、结果呈现等数学建模任务。 --- # 数学建模辅助 你是一名数学建模竞赛辅导专家。收到任务后按以下流程处理 1. 先分析题目明确优化目标与约束条件 2. 给出候选建模方法如回归、优化、仿真说明选择的理由 3. 产出可运行的代码骨架注意变量命名清晰 4. 输出结果解释时附带图表生成建议。 ## 注意 - 优先使用项目内已有数据工具 - 如果数据缺失明确指出而不是强行建模。写好后保存为 .claude/skills/math-modeling/SKILL.md 即可。注意第一行的name要唯一description要先说什么时候用再说能做什么。值得一提的是热词里有人提过怎么做一个 latex 排版 skills——这件事和上面是同一个套路只是把 skill 的指令替换成将内容输出为符合 IEEE 双栏格式的 LaTeX 代码之类。真正决定 Skills 好不好的是你指令写得是否足够具体而不是语法多花哨。2.5 需要定期清理卸载比安装更需要纪律Skills 装多了Agent 在判断触发条件时会出现内耗。之前也有人问过我关于清理 Skills 的方法我的建议是每个月清理一次要么把半年来从未触发过的 Skill 删掉要么把触发频繁但效果不佳的 Skill 改版。我自己会留一个skills-usage.log可以在 Skills 里加一条每次被加载时追加写入日志的指令这样用量就有数据可查清理时不会凭感觉。3. 子代理是把双刃剑什么时候拆什么时候千万别拆子代理Subagent是我见过最容易矫枉过正的优化手段。很多人一听子代理可以并行处理、隔离上下文就恨不得把所有任务都拆出去跑。但子代理本身是有成本的而且还有不少稳定性坑。3.1 先分清 harness 和 agent这不是同一个东西热词里有一条是harness 和 agent 区别我在实际带新人时发现这两个概念确实容易被弄混。简单说harness 是控制逻辑它决定任务怎么跑先做什么、后做什么、失败怎么处理agent 是执行主体它决定每一步怎么做调用什么工具、生成什么内容。好的架构是 harness 做编排agent 做执行。如果让一个 agent 既做编排又做执行他就要同时管理全局目标和局部动作上下文占用会快速膨胀额度自然失控。换到子代理场景里harness 是主进程子代理是被派出去干活的执行体。明确了这个分层你才知道哪些东西该由主进程管哪些该丢给子代理。3.2 dsh headless 跑子代理导致主进程退出的坑具体踩坑实录来了。有一阵子我在一个自动化环境里用 headless无头方式跑 Agent 任务为了让某个独立任务不占用主上下文我把它拆成了子代理。结果现象非常诡异子代理跑着跑着主进程直接退出连报错都只给一句笼统的话。排查了半天最终定位到核心原因是headless 模式下主进程对子代理解析器的控制逻辑写得比较弱子代理在运行中尝试输出交互式确认而 headless 环境下根本没有交互通道于是子代理的异常处理直接把整个进程带崩了。这条经历让我养成了几个固定习惯分享给大家headless 模式下跑子代理一定要先确认子代理内部没有使用任何交互式确认机制给子代理设置独立的超时时间和断点保护避免它裸奔关键是要有退出码约定子代理正常结束返回 0资源不足返回 1内部逻辑错误返回 2。主进程根据退出码决定是否恢复而不是一律当成崩溃。如果你也遇到 agent execution terminated due to error. 这类报错先别急着怀疑模型能力按这个顺序排查最快复现现场抓住完整的输出日志看错误是发生在工具调用环节还是模型输出解析环节检查工具返回的内容是否符合约定的 schema比如 JSON 字段是否完整检查是不是上下文被截断导致模型没接上上一轮的信息最后再考虑是不是模型这次真的犯傻了必要时缩小到最小复现集来试。我见过大量所谓Agent 不稳定的案例最后查出来要么是工具返回格式不干净要么是子代理进程的异常没被捕获。这两个原因通常占掉 70% 以上的崩溃场景。3.3 子代理的额度账本拆出去反而更贵的情况从省额度角度说子代理本质上是用额外通信成本换上下文隔离。每次派发子代理你至少要付出两部分成本一是把必要的上下文信息传递给子代理二是接收它的结果并合并回主进程。所以我一般用下面这个经验阈值来判断是否拆分如果子代理的任务预计不超过 3 轮工具调用别拆。拆了反而多付一次交接费如果主进程的上下文已经接近窗口上限且子代理任务可以独立完成拆。这是隔离上下文、防止主进程被迫压缩的最有效方式如果任务需要频繁和主进程同步状态别拆。这种任务拆出去通信成本比上下文成本还要高。说白了子代理是用来挡上下文洪水的不是用来显得架构高级的。我见过把 5 行文本格式化也丢给子代理的操作那种纯粹是拿额度换新鲜感。3.4 子代理的退出崩溃之外还有编排复杂度失控还有一个我认为更危险的问题子代理一多编排逻辑就变成了意大利面条。父代理要等子代理 A、B、C 的结果然后决定要不要再派生 D。这种编排一旦写复杂排查难度会指数级上升。所以我的建议是子代理层级最多两层。第一层是主进程第二层是干活的任务代理不要再让任务代理去派生子代理。多出来的层级不仅烧钱而且几乎无法调试。框架层面现在很多 Agent 框架与编排工具都提供 DAG 式任务编排能力但我的建议还是能不编排就不编排线性流程比花哨的并行扎实得多。4. 工具优化三板斧砍数量、写描述、管失败工具是整个 Agent 系统里最务实的部分也是优化空间最大、见效最快的地方。我把它拆成三板斧数量、描述、失败管理。4.1 砍工具按 80/20 法则来做瘦身前面提到过我有个项目从 18 个工具砍到 6 个输入侧 token 直接降了快三成。具体怎么砍我一般会先做一个星期的工具调用日志统计看看真实使用频率分布。一套常见的使用率表格可以这样记录工具名调用次数使用率评估结果文件读取4831%保留代码执行4227%保留网页搜索2516%保留数据库查询1812%保留图片生成96%视场景保留链路追踪21%移除或按需加载浏览器控制10.6%移除或按需加载定时任务00%移除注意那类 0% 使用率的工具。它们挂在列表里每次工具决策模型都要为它们付一次注意力税。我的原则是使用率低于 5% 的工具除非业务强依赖否则一律移出主工具列表改放进 Skills 里按需加载。4.2 描述是给模型看的第一印象写坏等于没这个工具工具数量砍完真正决定模型什么时候用、怎么用的是工具描述。这部分很多人直接写一句话了事但我体验下来一个好的工具描述至少要包含三层信息触发时机什么场景下应该用这个工具输入要求参数的类型、格式、可选值返回约定正常结果的结构以及失败时会返回什么错误结构。举个例子。同样是查询订单状态的工具差的描述查询订单状态。好的描述当用户询问订单物流、状态或签收信息时使用。参数 order_id 为字符串格式为SO-2024-xxxx。成功返回 JSON包含 status 和 est_delivery失败返回 {error: reason}此时直接告知用户原因即可不要重试。第二种描述下模型不仅知道什么时候调它而且失败后也知道怎么处理。这一步彻底改变了后续的错误行为直接消灭了一批失败后反复重试的开销。4.3 失败路径设计告诉模型失败了就回来我之前在一次 Agent 项目里踩过一个非常典型的坑Agent 调用某 API 时工具返回了带 error 的 JSON但因为描述里没写明这是预期内失败模型当成普通结果继续分析又花了大量 token 去猜测原因。后来我在描述里加了当返回 error 字段时代表预期内失败返回该错误给用户并停止当前分支。就这么一句话类似的失败场景 token 消耗下降了近 60%。所以给每个工具写失败语义是优化里性价比最高的操作。它本质上是在给 Agent 划定最低成本路径成功就往下走失败就立刻返回不要原地打转。4.4 给工具结果加缓存重复劳动的金额叠加同一份数据被反复读取是很容易被忽视的浪费。比如 Agent 在处理一个 20 万字符的日志文件时如果连续几个步骤都需要读取结果每次重新读取一遍来回搬运的 token 累计起来非常可观。我的做法是在工具层套一个简单的缓存以参数哈希为 key把最近 10 次相同请求的结果缓存起来。文件读取、网页抓取、数据库查询这类只读型工具都适合加缓存。注意缓存只在同一次任务会话内有效避免跨任务使用过期数据引发逻辑错误。之前测过一个场景原本一个任务里某文件被读了 7 次加了会话级缓存后实际只读了 1 次。那个任务的整体 token 消耗省了大概 12%而且由于少了几次 I/O速度也快了。5. 从记忆到安全两个容易被忽略的隐形扣费项最后聊聊两个很多人压根不会往额度方向想的部分记忆机制和安全防护。它们不像上下文和工具那么直观但对额度的长期影响其实非常大。5.1 记忆到底怎么管别让全量历史烧掉预算Agent 记忆机制现在是热门话题各类框架实现也不同。但落地到额度上记忆只有两件事需要管存什么、怎么取。我最开始的做法很粗暴把每一轮对话都存起来需要时全量塞回上下文。结果一个复杂的多日项目跑到第三天每次会话的上下文都接近 4 万 token其中一半是历史垃圾。后来我改成三层记忆结构短期记忆当前任务轮次的原始消息任务结束后清空摘要记忆每完成 5 轮或一个任务阶段由 Agent 生成一段 200 字的摘要存进长期记忆事实记忆只存明确的用户偏好、项目关键参数、决策结论用结构化 KV 形式存储。这套结构跑了大半个月最大的收益不是省了多少钱这么简单而是 Agent 在长程任务里的准确率也变高了。原因不复杂全量历史里噪音太多模型经常被早期的错误信息干扰做了摘要之后记忆里留下的反而是决策精华。如果你在用一个现成的框架优先找它的记忆压缩开关。很多框架默认打开全量证据保留类功能如果不关你怎么优化上下文都是白费。5.2 记忆安全为什么防御机制能间接省额度记忆安全跟额度有什么关系关系大了。LLM Agent 最容易被攻击的点其实是记忆和工具返回的内容——你从外部抓回来的文本里可能藏着恶意指令。如果 Agent 把这些内容当成系统指令执行了轻则做出一堆错误操作重则陷入死循环疯狂调用工具。我之前调研过 a-memguard 这类面向 LLM Agent 记忆的防御框架。它的思路是在记忆写入和读取之间加一层守卫识别并剥离可疑指令阻止注入攻击进入模型上下文。这种防御之所以和额度有关是因为它能避免两类成本一是被注入后 Agent 执行错误工具调用的直接消耗二是调试这类安全问题所需的大量人工分析和回归测试的隐性成本。哪怕不做这么重的防护也至少要做到以下两点工具返回的外部内容进入上下文之前先经过一道数据清洗剥离看起来像指令的文本对 Agent 能执行的敏感操作删除、写入、转账等设置二次确认或白名单机制。这些措施看似和省钱无关但每避免一次安全事故省的额度可能比优化一整周上下文都多。5.3 一张可复制的优化清单照做就行最后把这套优化动作汇总成一张清单我自己每次接手新项目都会过一遍上下文瘦身历史对话超过 5 轮就做摘要长文本只保留关键片段Skills 精选只保留触发频率高且描述聚焦的技能包定期用日志清理子代理闸门任务预计超 5 轮工具调用或主上下文接近上限时才拆层级不超过两层工具砍数量保留使用率前 80% 的高频工具其余移进 Skills 或直接下线工具描述升级每个工具写明触发时机、参数要求、正常返回和失败语义失败语义落地在工具返回结构里区分预期内失败和异常错误引导 Agent 快速终止失败分支加一层会话级缓存对只读型工具按参数哈希缓存结果记忆三层化短期、摘要、事实三层分治避免全量历史常驻安全防线外部内容进上下文之前先做注入清洗敏感操作加白名单。这套清单看起来项数不少但实际落地可能就一个下午。它的效果是叠加的上下文瘦身省一波工具精简省一波失败管理又省一波。我这边跑完整个流程的项目最少的也省了 21% 的有效任务成本多的能做到接近 40%。最后再分享一个我自己的小习惯我会在每个 Agent 项目的配置里加一个批次预算上限当单次任务的 token 消耗超过预估值的 1.5 倍时强制 Agent 停下来汇报。这个措施能拦下很多失控型烧额度场景尤其是子代理异常和失败重试导致的探索性燃烧。钱不是靠事后心疼省出来的是靠机制在事前挡掉的。Agent 做得好不好从来不是看它的架构有多复杂、拆了多少层子代理、挂了多少工具。我见过太多团队把精力花在让 Agent 看起来更强上最后额度烧完了才发现真正的问题是复杂度失控。把上面这些基本功做扎实你的 Agent 会比想象中更稳、更快也便宜得多。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑