跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
编程语言Agent RuntimeToken BudgetContext EngineeringEval成本治理

《Agent Runtime 工程化》一次 Agent 任务为什么能烧掉几十次 LLM 调用?

一次 Agent 任务为什么能烧掉几十次 LLM 调用? 很多团队第一次算 Agent 成本,会算错。 他们按一次聊天请求算: 这个算法适合普通 Chatbot,不适合 Agent。 Agent 的成本通常长这样: 每一步都可能重新构造上下

陈堂会发布于 —2 浏览
《Agent Runtime 工程化》一次 Agent 任务为什么能烧掉几十次 LLM 调用?

一次 Agent 任务为什么能烧掉几十次 LLM 调用?

很多团队第一次算 Agent 成本,会算错。

他们按一次聊天请求算:

用户发一条消息
  ↓
模型回答一次
  ↓
成本 = input token + output token

这个算法适合普通 Chatbot,不适合 Agent。

Agent 的成本通常长这样:

第 1 步:模型判断要读哪些文件
第 2 步:模型根据文件内容决定搜索
第 3 步:模型根据搜索结果读另一个文件
第 4 步:模型决定执行测试
第 5 步:模型分析测试日志
第 6 步:模型修改代码
第 7 步:模型再次执行测试
第 8 步:模型总结结果

每一步都可能重新构造上下文。每一步都要把消息历史、工具结果、文件片段、系统指令、工具 schema、运行状态发给模型。看上去是一个任务,账单上可能是十几次甚至几十次模型调用。

这就是 Agent 成本最容易被低估的地方。

成本不是只发生在模型回答那一刻

一个 Agent run 里,成本至少有五类。

第一类是模型 input token。系统指令、工具 schema、用户目标、历史消息、文件片段、工具结果,全都算。

第二类是模型 output token。它可能是最终回答,也可能是中间推理后的 tool call 参数、计划、摘要。

第三类是工具成本。外部 API 查询、浏览器任务、数据库请求、容器运行、代码执行,都可能有资源账单。

第四类是重试成本。模型调用重试、工具调用重试、失败后重新规划,都会放大账单。

第五类是恢复和评测成本。checkpoint 之后继续执行、trace replay、真实模型 smoke eval,也要花钱。

所以我更愿意把 Agent 成本写成:

Run Cost =
  Σ(step input token + step output token)
  + Σ(tool cost)
  + retry cost
  + recovery cost
  + eval cost

这不是会计洁癖。你不这么算,线上成本一定会'突然'冒出来。

Agent 为什么比 Chatbot 更容易爆 token

普通 Chatbot 至少有一个优点:用户问一句,模型答一句。历史会变长,但每次通常只有一个回答。

Agent 有三个额外放大器。

第一个放大器是 step。

maxSteps=20 不代表最多调用 20 次模型这么简单。每一步都可能带上工具列表、上下文摘要、最近 observation 和运行状态。前面几步留下的结果,还会变成后面几步的输入。

第二个放大器是工具输出。

一次 npm test 失败可能吐几万字符。一次 rg 搜索可能返回几百行。一次读取日志可能直接把上下文塞满。如果 runtime 不做降级,模型每一轮都会拖着这些日志跑。

第三个放大器是工具 schema。

工具多了以后,schema 本身也很贵。一个 MCP 环境里可能有几十个 server、几百个 tools。你把所有工具都塞给模型,不只是浪费 token,还会增加误调用概率。

这三个放大器叠在一起,成本就不再线性。

长上下文不是免费午餐

现在模型上下文窗口越来越大,很多人第一反应是:那就全塞进去。

我理解这个冲动。早期上下文太小,大家被截断折磨过。可长上下文不是免费的。

OpenAI 的产品页面在解释上下文窗口时也提到,可用空间会被系统指令、工具、记忆、内部处理等占用。Anthropic 和 OpenAI 都提供 prompt caching,说明长前缀、重复上下文确实值得被缓存和优化。换句话说,厂商也知道重复发送大段上下文是成本问题。

更大的窗口解决的是'放得下',不是'放得对'。

Agent 真正需要的是当前目标、关键约束、最近行动、相关事实、失败证据和下一步可用工具。把半小时前的旧日志、已经废弃的计划、全量搜索结果和无关文件都塞进去,模型不会变成资深工程师。它只会更慢、更贵,还可能被旧信息带偏。

上下文工程不是'尽量多给',而是'知道什么不能丢,什么必须降级'。

Context Builder 要有预算报告

我建议把 Context Builder 当成一个正式模块,而不是 controller 里的字符串拼接。

它的输入大概是这样:

type ContextBuildInput = {
  systemPrompt: string;
  developerPolicy: string;
  userMessage: string;
  recentMessages: RuntimeMessage[];
  runState: RunState;
  repoMap?: RepoMap;
  pinnedFiles: FileSnippet[];
  toolResults: ToolResult[];
  tokenBudget: number;
};

输出不能只有 messages。还要有 report:

type ContextBuildResult = {
  messages: RuntimeMessage[];
  report: {
    budget: number;
    used: number;
    mustKeep: string[];
    included: string[];
    summarized: string[];
    dropped: string[];
    reasons: Record<string, string>;
  };
};

没有这个 report,你根本不知道钱花在哪。

更糟的是,你不知道模型为什么没看见某个关键约束。最后排查时只会说:'模型又忘了。'有了 report,你至少能看到:用户要求是不是被保留了,错误日志是不是被摘要了,哪个文件被丢掉了,工具结果有没有被截断。

这份 report 应该进 trace,也应该进 eval 报告。

工具结果要分档,不要全量塞回去

工具输出进入上下文前,先问五个问题:

这是事实,还是噪声?
后续是否需要逐字引用?
有没有结构化字段可提取?
是否超过预算?
是否包含 secret 或隐私数据?

测试日志通常不需要全量。模型需要的是失败用例、断言信息、文件路径、行号、栈顶和命令退出码。

搜索结果也不需要全量。模型需要文件路径、匹配行和少量上下文。

安装日志更不用全塞。模型需要包名、版本冲突、失败原因和 lockfile 是否变化。

我会把工具结果分成四档:

全量:短配置、少量搜索结果
片段:测试栈、类型错误上下文
摘要:长日志、批量搜索结果
引用:超大 artifact,只给 ref

关键是:降级后必须标记。

{
  "content": "测试失败摘要:...",
  "truncated": true,
  "artifactRef": "artifact:test-log:run_123_step_7"
}

模型必须知道自己看到的是摘要,不是完整事实。否则它会把摘要当成全量证据。

Max steps 也是成本开关

maxSteps 不只是防死循环,也是成本开关。

最小 runtime 里常见停止条件包括:

type StopReason =
  | "final"
  | "max_steps"
  | "repeated_error"
  | "budget_exhausted"
  | "user_cancelled"
  | "permission_denied";

这里的 budget_exhausted 应该是一等公民。

很多系统只在请求发出后才知道花了多少 token。更好的做法是发送前估算,发送后校正:

type BudgetState = {
  maxInputTokens: number;
  maxOutputTokens: number;
  maxRunTokens: number;
  usedInputTokens: number;
  usedOutputTokens: number;
  remainingRunTokens: number;
};

当剩余预算不足时,runtime 先降级上下文,再缩小工具暴露范围,再请求用户确认是否继续。最差的做法是默默丢掉关键约束,然后让模型继续'自信地完成任务'。

Prompt caching 不是免死金牌

OpenAI 和 Anthropic 都支持 prompt caching。对于 Agent 来说,这很有价值。

系统指令、工具说明、稳定的项目背景、长文档前缀,都可能成为可缓存内容。缓存命中后,重复前缀的成本和延迟会下降。

但 prompt caching 不能替代 Context Builder。

原因很简单:Agent 每一步都有动态内容。用户目标、当前 step、工具 observation、文件片段、错误日志、权限决策都在变。缓存能帮你优化稳定前缀,但不会自动告诉你哪些动态内容该保留,哪些该摘要。

所以更实用的策略是:

  • 把稳定 system/developer 指令放在前面。
  • 工具 schema 保持稳定顺序。
  • 动态 observation 放在后面。
  • 不要每轮重写整段系统提示。
  • 对大型工具列表做按任务筛选。

缓存是加速器,不是预算系统。

成本要进入 eval

很多 Agent eval 只看通过率。

这很危险。

一个策略可能让通过率从 78% 提到 82%,但平均 token 增加 90%,危险工具审批增加 3 倍,延迟翻倍。你不能只看'变好了'。

Eval 报告至少要有三组指标:

能力:pass rate、测试通过、文件正确性
效率:step、tool call、latency、token、cost
边界:approval、must-not-call、secret、rollback、resume

对 Agent Runtime 来说,成本治理不是财务部门月底才看的表。它应该出现在 PR、A/B 测试和发布门禁里。

比如一次 runtime 策略对比:

{
  "experiment": "tool-selection-all-vs-task-scoped",
  "baseline": "all_tools",
  "candidate": "task_scoped_tools",
  "tasks": 60,
  "passRateDelta": -0.01,
  "tokenDeltaPct": -34.7,
  "latencyDeltaPct": -18.2,
  "safetyRegressions": 0,
  "decision": "ship"
}

这比一句'新版更聪明'可信多了。

一个最小成本治理清单

如果你的 Agent 已经能跑任务了,下一步可以先补这 10 件事:

1. 每个 run 记录 input/output token。
2. 每个 step 记录 token、latency、tool calls。
3. Context Builder 输出 budget report。
4. 工具结果支持全量、片段、摘要、artifact 引用四档。
5. 长日志默认摘要,不直接塞回模型。
6. 工具 schema 按任务筛选,不全量暴露。
7. maxSteps 和 maxRunTokens 同时生效。
8. budget_exhausted 是明确 stop reason。
9. eval 报告加入 token/cost/latency。
10. PR 里要求说明成本变化。

这 10 件事不需要你换模型,也不需要一上来接复杂平台。先用 JSON trace 和 Markdown 报告都行。

重要的是,先让成本可见。

最后

Agent 的账单不是'贵模型导致的'。很多时候,是 runtime 没有预算意识。

模型一次调用多少钱,当然要看供应商定价。可一个 run 为什么调用 18 次模型,为什么每次都带着三万 token,为什么重复读同一个文件,为什么长日志每轮都回灌,为什么工具 schema 全量暴露,这些是你自己的系统问题。

我更喜欢把 token budget 当成产品预算。

预算不是为了抠门。预算是为了让系统知道:什么必须保留,什么可以降级,什么时候应该停下来问用户。

参考资料

  • OpenAI: Business pricing
  • OpenAI API Docs: Prompt caching
  • Anthropic Docs: Prompt caching
  • LangGraph Docs: Persistence
  • LangChain issue: "Agent stopped due to max iterations."

推荐阅读

  • 一个 Production Agent Runtime 到底需要什么?
  • Agent Memory 越做越乱,本质上是 Runtime 问题
  • 我为什么写《Agent Runtime 工程化》

目录

  1. 一次 Agent 任务为什么能烧掉几十次 LLM 调用?
  2. 成本不是只发生在模型回答那一刻
  3. Agent 为什么比 Chatbot 更容易爆 token
  4. 长上下文不是免费午餐
  5. Context Builder 要有预算报告
  6. 工具结果要分档,不要全量塞回去
  7. Max steps 也是成本开关
  8. Prompt caching 不是免死金牌
  9. 成本要进入 eval
  10. 一个最小成本治理清单
  11. 最后
  12. 参考资料
  13. 推荐阅读
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 在 Linux 桌面里跑 Windows 应用:Winboat 实战笔记
  • AI 编程工具深度对比:Trae、Cursor、Copilot 与 Windsurf
  • 论文阅读--Agent AI 探索多模态交互的前沿领域(一)
  • OpenCode 开源 AI 编程助手使用教程
  • Linux diff 与 patch 命令实战指南
  • 网络安全工程师职业定义、核心技能与认证体系详解
  • Python 为何如此流行?深度解析其核心优势与应用场景
  • 大疆无人机如何导出日志并解析
  • 前端 WebSocket 通信实战与最佳实践
  • OpenClaw 进阶教程:记忆系统、定时任务、多模型与子代理解析
  • Python 爬虫实战指南:从基础请求到分布式框架
  • Kubernetes Python 客户端实战教程
  • Java IO 核心:BufferedReader、BufferedWriter、PrintStream 与 PrintWriter 详解
  • AI 辅助编程工具:GitHub Copilot 安装与使用指南
  • 基于 Rokid AR 眼镜的聚会游戏助手开发实践
  • 百瑞互联 BR8654A02 蓝牙 6.0 SOC 芯片规格介绍
  • Windows 7 安装 Python 3.9+ 配置指南
  • 前端加密:常用方式与使用示例
  • GitHub Copilot 学生认证教程(2026 版)
  • openclaw-termux:在 Android 上部署 OpenClaw AI Gateway

相关免费在线工具

  • 数学计算器

    计算数学表达式的计算器。您可以使用sqrt、cos、sin、abs等函数。 在线工具,数学计算器在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online