欢迎光临
我们一直在努力

【Hermes:进阶调优与性能优化】43、减少 Token 消耗的 10 个实战技巧 —— 把 AI 调用成本从“烧钱”变成“省心”

在这里插入图片描述

减少 Token 消耗的 10 个实战技巧 —— 把 AI 调用成本从“烧钱”变成“省心”

每次 API 调用都在燃烧 token,而 token 就是真金白银。本文将分享 10 个经过验证的实战技巧,从精简 Toolset 到控制召回数量,从 Skill 瘦身到子 Agent 隔离,让你在不牺牲智能体能力的前提下,把月度账单直接砍半。

前言:为什么你的 Token 消耗总在失控?

你部署了一个智能体,功能很酷,用户很喜欢。月底看到账单时,笑容突然凝固——token 消耗量远超预期。

这是许多从开发阶段进入生产阶段的团队都会遇到的“惊喜”。问题出在哪里?大多数情况下,不是模型太贵,而是你无意中浪费了大量 token。

常见的浪费场景:

  • 每个请求都携带了 10 个工具的完整描述(即使这次只用 1 个)
  • 每次都从知识库召回 10 条历史记忆(其中 8 条完全不相关)
  • Skill 里塞满了复杂的示例和注释(模型每一轮都要读一遍)
  • 主 Agent 的上下文里堆积了子 Agent 的中间输出
  • 会话记忆保存了 3 个月前的对话(每次加载占用大量 token)

好消息是,这些问题都可以通过一系列简单的配置和设计技巧来解决。本文将为你梳理 10 个最有效的手段,每一个都经过了实际生产环境的验证。你不需要修改模型,不需要重写代码,只需调整配置和流程,就能显著降低 token 消耗。

全文包含 5 张 mermaid 流程图,帮助你直观理解优化点。让我们从最容易被忽视的“工具描述”开始。


1. 精简 Toolset:每多一个工具,system prompt 就多一段描述

1.1 问题本质

当你为 Agent 配置工具时,框架会把每个工具的名称、描述、参数 schema 全部塞进 system prompt。每次 API 调用,这些内容都会原封不动地传给模型。

假设一个工具有 200 字符的描述,10 个工具就是 2000 字符(约 500 token)。对于一个简单问答,这些内容占用了 30%~50% 的上下文,而模型可能根本不需要它们。

真实案例:某团队为客服 Agent 配置了 15 个工具(查订单、退换货、优惠券、物流跟踪等)。实际上,80% 的对话只用到其中 3 个。他们按照“按需加载”的思路重构了 Toolset,月度 token 消耗下降了 42%。

1.2 解决方案:动态 Toolset

Honcho 支持为不同的场景定义不同的 Toolset(参考第 9 篇)。核心思想:只给 Agent 当前任务可能用到的工具。

# config.yaml
toolsets:
– name: basic
includes: [web_get, memory_recall, reply]
– name: devops
includes: [terminal, file_read, code_execution]
– name: data
includes: [sql_query, file_write]

# 根据任务类型动态选择
default_toolset: basic

更细粒度地,可以在对话中临时启用工具:

/enable_tools weather skill_search

1.3 按需加载 vs 全量加载对比

模式每次请求携带工具数平均 token 开销适用场景
全量加载 15~30 1500~3000 开发测试
按需 Toolset 3~5 300~500 生产环境

1.4 更激进的优化:工具描述压缩

如果必须保留较多工具,可以压缩工具描述:

原描述(长):

“weather: 查询指定城市的实时天气信息,包括温度、湿度、风速、天气状况。参数 city 为城市名称,例如’北京’。返回 JSON 格式。”

压缩后(短):

“weather: 查询城市天气,返回温度/湿度/风速。参数: city。”

模型同样能理解,token 从约 50 降到 20。

1.5 工具加载策略流程图

#mermaid-svg-v0j1WHYTQLvoO1J6{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-v0j1WHYTQLvoO1J6 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-v0j1WHYTQLvoO1J6 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-v0j1WHYTQLvoO1J6 .error-icon{fill:#552222;}#mermaid-svg-v0j1WHYTQLvoO1J6 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-v0j1WHYTQLvoO1J6 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-v0j1WHYTQLvoO1J6 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-v0j1WHYTQLvoO1J6 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-v0j1WHYTQLvoO1J6 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-v0j1WHYTQLvoO1J6 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-v0j1WHYTQLvoO1J6 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-v0j1WHYTQLvoO1J6 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-v0j1WHYTQLvoO1J6 .marker.cross{stroke:#333333;}#mermaid-svg-v0j1WHYTQLvoO1J6 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-v0j1WHYTQLvoO1J6 p{margin:0;}#mermaid-svg-v0j1WHYTQLvoO1J6 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-v0j1WHYTQLvoO1J6 .cluster-label text{fill:#333;}#mermaid-svg-v0j1WHYTQLvoO1J6 .cluster-label span{color:#333;}#mermaid-svg-v0j1WHYTQLvoO1J6 .cluster-label span p{background-color:transparent;}#mermaid-svg-v0j1WHYTQLvoO1J6 .label text,#mermaid-svg-v0j1WHYTQLvoO1J6 span{fill:#333;color:#333;}#mermaid-svg-v0j1WHYTQLvoO1J6 .node rect,#mermaid-svg-v0j1WHYTQLvoO1J6 .node circle,#mermaid-svg-v0j1WHYTQLvoO1J6 .node ellipse,#mermaid-svg-v0j1WHYTQLvoO1J6 .node polygon,#mermaid-svg-v0j1WHYTQLvoO1J6 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-v0j1WHYTQLvoO1J6 .rough-node .label text,#mermaid-svg-v0j1WHYTQLvoO1J6 .node .label text,#mermaid-svg-v0j1WHYTQLvoO1J6 .image-shape .label,#mermaid-svg-v0j1WHYTQLvoO1J6 .icon-shape .label{text-anchor:middle;}#mermaid-svg-v0j1WHYTQLvoO1J6 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-v0j1WHYTQLvoO1J6 .rough-node .label,#mermaid-svg-v0j1WHYTQLvoO1J6 .node .label,#mermaid-svg-v0j1WHYTQLvoO1J6 .image-shape .label,#mermaid-svg-v0j1WHYTQLvoO1J6 .icon-shape .label{text-align:center;}#mermaid-svg-v0j1WHYTQLvoO1J6 .node.clickable{cursor:pointer;}#mermaid-svg-v0j1WHYTQLvoO1J6 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-v0j1WHYTQLvoO1J6 .arrowheadPath{fill:#333333;}#mermaid-svg-v0j1WHYTQLvoO1J6 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-v0j1WHYTQLvoO1J6 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-v0j1WHYTQLvoO1J6 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-v0j1WHYTQLvoO1J6 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-v0j1WHYTQLvoO1J6 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-v0j1WHYTQLvoO1J6 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-v0j1WHYTQLvoO1J6 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-v0j1WHYTQLvoO1J6 .cluster text{fill:#333;}#mermaid-svg-v0j1WHYTQLvoO1J6 .cluster span{color:#333;}#mermaid-svg-v0j1WHYTQLvoO1J6 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-v0j1WHYTQLvoO1J6 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-v0j1WHYTQLvoO1J6 rect.text{fill:none;stroke-width:0;}#mermaid-svg-v0j1WHYTQLvoO1J6 .icon-shape,#mermaid-svg-v0j1WHYTQLvoO1J6 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-v0j1WHYTQLvoO1J6 .icon-shape p,#mermaid-svg-v0j1WHYTQLvoO1J6 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-v0j1WHYTQLvoO1J6 .icon-shape .label rect,#mermaid-svg-v0j1WHYTQLvoO1J6 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-v0j1WHYTQLvoO1J6 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-v0j1WHYTQLvoO1J6 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-v0j1WHYTQLvoO1J6 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

简单问答

代码调试

数据分析

用户请求

识别任务类型

加载 basic Toolset3 tools ≈ 400 token

加载 devops Toolset4 tools ≈ 600 token

加载 data Toolset3 tools ≈ 450 token

执行请求

响应


2. 控制 FTS5 召回数量:限制注入上下文的历史片段长度

2.1 问题:过度召回

长期记忆(知识层)是 Honcho 的强大功能,但如果不加限制,每次调用 recall 可能会返回 10 条、20 条甚至更多的历史片段。每个片段 300~500 token,加起来就是数千 token,其中很多可能并不相关。

2.2 解决方案:设置合理的召回参数

在 config.yaml 中配置:

memory:
recall:
top_k: 3 # 只召回最相关的 3 条
max_tokens_per_doc: 300 # 每条最多 300 token
min_similarity: 0.65 # 相似度低于 0.65 的丢弃

经验值:

  • 简单场景(FAQ 问答):top_k = 2,每条 200 token
  • 复杂调研:top_k = 5,每条 500 token
  • 代码助手:top_k = 4,每条 400 token

2.3 动态调整

还可以根据请求类型动态调整:

# 在 Skill 中根据情况指定召回数量
– tool: memory_recall
params:
query: "用户偏好"
top_k: 2 # 短期记忆少召回

2.4 向量检索效果 vs token 成本

#mermaid-svg-WRIBVtKzUI5psNtV{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-WRIBVtKzUI5psNtV .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-WRIBVtKzUI5psNtV .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-WRIBVtKzUI5psNtV .error-icon{fill:#552222;}#mermaid-svg-WRIBVtKzUI5psNtV .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-WRIBVtKzUI5psNtV .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-WRIBVtKzUI5psNtV .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-WRIBVtKzUI5psNtV .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-WRIBVtKzUI5psNtV .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-WRIBVtKzUI5psNtV .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-WRIBVtKzUI5psNtV .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-WRIBVtKzUI5psNtV .marker{fill:#333333;stroke:#333333;}#mermaid-svg-WRIBVtKzUI5psNtV .marker.cross{stroke:#333333;}#mermaid-svg-WRIBVtKzUI5psNtV svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-WRIBVtKzUI5psNtV p{margin:0;}#mermaid-svg-WRIBVtKzUI5psNtV .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-WRIBVtKzUI5psNtV .cluster-label text{fill:#333;}#mermaid-svg-WRIBVtKzUI5psNtV .cluster-label span{color:#333;}#mermaid-svg-WRIBVtKzUI5psNtV .cluster-label span p{background-color:transparent;}#mermaid-svg-WRIBVtKzUI5psNtV .label text,#mermaid-svg-WRIBVtKzUI5psNtV span{fill:#333;color:#333;}#mermaid-svg-WRIBVtKzUI5psNtV .node rect,#mermaid-svg-WRIBVtKzUI5psNtV .node circle,#mermaid-svg-WRIBVtKzUI5psNtV .node ellipse,#mermaid-svg-WRIBVtKzUI5psNtV .node polygon,#mermaid-svg-WRIBVtKzUI5psNtV .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-WRIBVtKzUI5psNtV .rough-node .label text,#mermaid-svg-WRIBVtKzUI5psNtV .node .label text,#mermaid-svg-WRIBVtKzUI5psNtV .image-shape .label,#mermaid-svg-WRIBVtKzUI5psNtV .icon-shape .label{text-anchor:middle;}#mermaid-svg-WRIBVtKzUI5psNtV .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-WRIBVtKzUI5psNtV .rough-node .label,#mermaid-svg-WRIBVtKzUI5psNtV .node .label,#mermaid-svg-WRIBVtKzUI5psNtV .image-shape .label,#mermaid-svg-WRIBVtKzUI5psNtV .icon-shape .label{text-align:center;}#mermaid-svg-WRIBVtKzUI5psNtV .node.clickable{cursor:pointer;}#mermaid-svg-WRIBVtKzUI5psNtV .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-WRIBVtKzUI5psNtV .arrowheadPath{fill:#333333;}#mermaid-svg-WRIBVtKzUI5psNtV .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-WRIBVtKzUI5psNtV .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-WRIBVtKzUI5psNtV .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-WRIBVtKzUI5psNtV .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-WRIBVtKzUI5psNtV .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-WRIBVtKzUI5psNtV .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-WRIBVtKzUI5psNtV .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-WRIBVtKzUI5psNtV .cluster text{fill:#333;}#mermaid-svg-WRIBVtKzUI5psNtV .cluster span{color:#333;}#mermaid-svg-WRIBVtKzUI5psNtV div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-WRIBVtKzUI5psNtV .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-WRIBVtKzUI5psNtV rect.text{fill:none;stroke-width:0;}#mermaid-svg-WRIBVtKzUI5psNtV .icon-shape,#mermaid-svg-WRIBVtKzUI5psNtV .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-WRIBVtKzUI5psNtV .icon-shape p,#mermaid-svg-WRIBVtKzUI5psNtV .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-WRIBVtKzUI5psNtV .icon-shape .label rect,#mermaid-svg-WRIBVtKzUI5psNtV .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-WRIBVtKzUI5psNtV .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-WRIBVtKzUI5psNtV .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-WRIBVtKzUI5psNtV :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

准确性提升

召回数量与 token 消耗

+15% recall

+20%

+22%

top_k=1

~500 token

top_k=3

~1500 token

top_k=5

~2500 token

top_k=10

~5000 token

Acc2

Acc3

Acc4

可以看到,从 top_k=3 到 top_k=5,token 增加了 67%,但准确性提升很小(约 5%)。因此推荐 top_k 不超过 5。


3. Skill 的“瘦身”:删除冗余示例,保留核心规则

3.1 Skill 的 token 成本

每个 Skill 文件中包含的 description、examples、instructions 等字段,在 Agent 初始化或 Skill 被触发时会被加载到上下文中。如果你有 20 个 Skill,每个 800 token,那就是 16000 token——可能比一次对话的 token 还多。

3.2 瘦身策略

  • 删除冗余示例:每个 Skill 保留 1~2 个最典型的示例即可,不需要 5 个。
  • 压缩描述:像工具描述一样,用最精炼的语言说明 Skill 用途。
  • 使用引用而非内联:将大段的指令存入知识层,Skill 中只存引用 ID。
  • 优化前(weather_skill.yaml):

    description: "这个 Skill 用于查询天气。用户可以问'北京天气怎么样'、'上海气温多少度'、'广州会下雨吗'等多种方式。它会调用天气 API,返回温度、湿度、风速、天气状况、紫外线指数等信息。"
    examples:
    – input: "北京天气"
    output: "北京今天晴,25℃,湿度40%"
    – input: "上海会下雨吗"
    output: "上海今天有雨,记得带伞"
    – input: "广州气温"
    output: "广州今天28℃"

    优化后:

    description: "查询天气。支持城市名+天气/气温/下雨等表达。"
    examples: # 只保留一个示例
    – input: "北京天气"
    output: "北京今天晴,25℃"

    token 从约 350 降到 100,减少了 70%。

    3.3 自动压缩工具

    Honcho 提供了 skill_compress 命令,可以分析 Skill 文件并给出精简建议:

    honcho skill compress weather_skill.yaml –dry-run

    输出:

    weather_skill.yaml 当前 450 token,建议精简至 150 token。
    可删除:
    – examples[1] (相似度 0.95)
    – description 中的冗余同义词

    3.4 Skill 瘦身流程图

    #mermaid-svg-rvxahTtMkcb5ADcD{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-rvxahTtMkcb5ADcD .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-rvxahTtMkcb5ADcD .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-rvxahTtMkcb5ADcD .error-icon{fill:#552222;}#mermaid-svg-rvxahTtMkcb5ADcD .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-rvxahTtMkcb5ADcD .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-rvxahTtMkcb5ADcD .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-rvxahTtMkcb5ADcD .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-rvxahTtMkcb5ADcD .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-rvxahTtMkcb5ADcD .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-rvxahTtMkcb5ADcD .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-rvxahTtMkcb5ADcD .marker{fill:#333333;stroke:#333333;}#mermaid-svg-rvxahTtMkcb5ADcD .marker.cross{stroke:#333333;}#mermaid-svg-rvxahTtMkcb5ADcD svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-rvxahTtMkcb5ADcD p{margin:0;}#mermaid-svg-rvxahTtMkcb5ADcD .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-rvxahTtMkcb5ADcD .cluster-label text{fill:#333;}#mermaid-svg-rvxahTtMkcb5ADcD .cluster-label span{color:#333;}#mermaid-svg-rvxahTtMkcb5ADcD .cluster-label span p{background-color:transparent;}#mermaid-svg-rvxahTtMkcb5ADcD .label text,#mermaid-svg-rvxahTtMkcb5ADcD span{fill:#333;color:#333;}#mermaid-svg-rvxahTtMkcb5ADcD .node rect,#mermaid-svg-rvxahTtMkcb5ADcD .node circle,#mermaid-svg-rvxahTtMkcb5ADcD .node ellipse,#mermaid-svg-rvxahTtMkcb5ADcD .node polygon,#mermaid-svg-rvxahTtMkcb5ADcD .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-rvxahTtMkcb5ADcD .rough-node .label text,#mermaid-svg-rvxahTtMkcb5ADcD .node .label text,#mermaid-svg-rvxahTtMkcb5ADcD .image-shape .label,#mermaid-svg-rvxahTtMkcb5ADcD .icon-shape .label{text-anchor:middle;}#mermaid-svg-rvxahTtMkcb5ADcD .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-rvxahTtMkcb5ADcD .rough-node .label,#mermaid-svg-rvxahTtMkcb5ADcD .node .label,#mermaid-svg-rvxahTtMkcb5ADcD .image-shape .label,#mermaid-svg-rvxahTtMkcb5ADcD .icon-shape .label{text-align:center;}#mermaid-svg-rvxahTtMkcb5ADcD .node.clickable{cursor:pointer;}#mermaid-svg-rvxahTtMkcb5ADcD .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-rvxahTtMkcb5ADcD .arrowheadPath{fill:#333333;}#mermaid-svg-rvxahTtMkcb5ADcD .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-rvxahTtMkcb5ADcD .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-rvxahTtMkcb5ADcD .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rvxahTtMkcb5ADcD .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-rvxahTtMkcb5ADcD .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rvxahTtMkcb5ADcD .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-rvxahTtMkcb5ADcD .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-rvxahTtMkcb5ADcD .cluster text{fill:#333;}#mermaid-svg-rvxahTtMkcb5ADcD .cluster span{color:#333;}#mermaid-svg-rvxahTtMkcb5ADcD div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-rvxahTtMkcb5ADcD .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-rvxahTtMkcb5ADcD rect.text{fill:none;stroke-width:0;}#mermaid-svg-rvxahTtMkcb5ADcD .icon-shape,#mermaid-svg-rvxahTtMkcb5ADcD .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rvxahTtMkcb5ADcD .icon-shape p,#mermaid-svg-rvxahTtMkcb5ADcD .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-rvxahTtMkcb5ADcD .icon-shape .label rect,#mermaid-svg-rvxahTtMkcb5ADcD .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rvxahTtMkcb5ADcD .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-rvxahTtMkcb5ADcD .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-rvxahTtMkcb5ADcD :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    examples

    long description

    instructions

    是

    否

    原始 Skill

    分析 token 分布

    哪些部分最重?

    保留 1-2 个典型示例

    压缩为 1 句话

    引用知识层大段文本

    验证功能不变

    效果 OK?

    部署精简版

    恢复部分内容


    4. 子 Agent 的上下文隔离:避免主 Agent 重复加载背景

    4.1 问题:主 Agent 的上下文堆积

    当你使用 delegate_task 创建子 Agent 并行执行任务时,主 Agent 会把子 Agent 的完整执行过程、中间结果、最终输出都保留在自己的上下文中。如果频繁使用子 Agent,主 Agent 的上下文会迅速膨胀。

    4.2 解决方案:只传递必要的结果

    在调用 delegate_task 时,指定只返回摘要或最终结果,而不是完整日志。

    – tool: delegate_task
    params:
    task: "分析这份 PDF"
    return_full_log: false # 只返回最终输出,不返回中间步骤
    max_output_tokens: 500 # 限制返回内容长度

    4.3 使用独立会话

    另一种思路:为子 Agent 分配完全独立的会话 ID,它的输出直接写入知识层,主 Agent 只通过 recall 检索结果,而不是将其加载到上下文:

    – tool: delegate_task
    params:
    task: "长期调研任务"
    session_id: "independent_research" # 独立会话
    store_to_memory: true # 结果存知识层

    然后主 Agent 需要时再召回:

    – tool: memory_recall
    params:
    query: "调研结论"
    session_filter: "independent_research"

    4.4 效果对比

    模式主 Agent 上下文增量是否可并行适用场景
    默认(返回完整日志) +2000 token/任务 是 调试、小任务
    只返回结果 +500 token/任务 是 生产环境
    独立会话 + 检索 +0 token(检索额外) 是 超大任务

    5. 使用更小的模型处理预处理任务

    5.1 核心思想

    不是所有任务都需要最强大的模型。例如:

    • 提取用户意图(分类任务)
    • 判断是否触发某个 Skill(意图路由)
    • 简单文本清洗、格式化
    • 判断对话是否结束

    这些任务可以用 小模型(如 GPT-3.5 Turbo、Claude Haiku、Gemini Flash)完成,精度要求不高,但能节省大量成本。

    5.2 架构设计

    #mermaid-svg-y51CBJT34HSSXt7M{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-y51CBJT34HSSXt7M .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-y51CBJT34HSSXt7M .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-y51CBJT34HSSXt7M .error-icon{fill:#552222;}#mermaid-svg-y51CBJT34HSSXt7M .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-y51CBJT34HSSXt7M .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-y51CBJT34HSSXt7M .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-y51CBJT34HSSXt7M .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-y51CBJT34HSSXt7M .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-y51CBJT34HSSXt7M .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-y51CBJT34HSSXt7M .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-y51CBJT34HSSXt7M .marker{fill:#333333;stroke:#333333;}#mermaid-svg-y51CBJT34HSSXt7M .marker.cross{stroke:#333333;}#mermaid-svg-y51CBJT34HSSXt7M svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-y51CBJT34HSSXt7M p{margin:0;}#mermaid-svg-y51CBJT34HSSXt7M .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-y51CBJT34HSSXt7M .cluster-label text{fill:#333;}#mermaid-svg-y51CBJT34HSSXt7M .cluster-label span{color:#333;}#mermaid-svg-y51CBJT34HSSXt7M .cluster-label span p{background-color:transparent;}#mermaid-svg-y51CBJT34HSSXt7M .label text,#mermaid-svg-y51CBJT34HSSXt7M span{fill:#333;color:#333;}#mermaid-svg-y51CBJT34HSSXt7M .node rect,#mermaid-svg-y51CBJT34HSSXt7M .node circle,#mermaid-svg-y51CBJT34HSSXt7M .node ellipse,#mermaid-svg-y51CBJT34HSSXt7M .node polygon,#mermaid-svg-y51CBJT34HSSXt7M .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-y51CBJT34HSSXt7M .rough-node .label text,#mermaid-svg-y51CBJT34HSSXt7M .node .label text,#mermaid-svg-y51CBJT34HSSXt7M .image-shape .label,#mermaid-svg-y51CBJT34HSSXt7M .icon-shape .label{text-anchor:middle;}#mermaid-svg-y51CBJT34HSSXt7M .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-y51CBJT34HSSXt7M .rough-node .label,#mermaid-svg-y51CBJT34HSSXt7M .node .label,#mermaid-svg-y51CBJT34HSSXt7M .image-shape .label,#mermaid-svg-y51CBJT34HSSXt7M .icon-shape .label{text-align:center;}#mermaid-svg-y51CBJT34HSSXt7M .node.clickable{cursor:pointer;}#mermaid-svg-y51CBJT34HSSXt7M .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-y51CBJT34HSSXt7M .arrowheadPath{fill:#333333;}#mermaid-svg-y51CBJT34HSSXt7M .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-y51CBJT34HSSXt7M .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-y51CBJT34HSSXt7M .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-y51CBJT34HSSXt7M .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-y51CBJT34HSSXt7M .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-y51CBJT34HSSXt7M .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-y51CBJT34HSSXt7M .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-y51CBJT34HSSXt7M .cluster text{fill:#333;}#mermaid-svg-y51CBJT34HSSXt7M .cluster span{color:#333;}#mermaid-svg-y51CBJT34HSSXt7M div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-y51CBJT34HSSXt7M .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-y51CBJT34HSSXt7M rect.text{fill:none;stroke-width:0;}#mermaid-svg-y51CBJT34HSSXt7M .icon-shape,#mermaid-svg-y51CBJT34HSSXt7M .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-y51CBJT34HSSXt7M .icon-shape p,#mermaid-svg-y51CBJT34HSSXt7M .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-y51CBJT34HSSXt7M .icon-shape .label rect,#mermaid-svg-y51CBJT34HSSXt7M .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-y51CBJT34HSSXt7M .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-y51CBJT34HSSXt7M .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-y51CBJT34HSSXt7M :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    简单问答

    需要推理

    代码任务

    用户输入

    小模型路由GPT-3.5 / Haiku

    小模型回答

    大模型Sonnet / GPT-4o

    代码模型GPT-4.1

    输出

    5.3 Honcho 中的配置

    在 config.yaml 中定义多个模型端点:

    models:
    – name: router
    provider: openai
    model: gpt–3.5–turbo
    – name: main
    provider: anthropic
    model: claude–3.5–sonnet
    – name: code
    provider: openai
    model: gpt–4.1

    然后在 Skill 或路由逻辑中按需选择。

    5.4 成本节省估算

    假设每天 10,000 次请求,其中 6000 次是简单问答(可用小模型),4000 次需要大模型。

    方案小模型单价大模型单价日成本月成本
    全部用大模型 – $5/1M token $50 $1500
    60% 用小模型($1/1M) $6 $20 $26 $780

    节省约 48%。


    6. 开启 moa 工具的缓存模式

    6.1 MoA 的 token 浪费

    MoA(多模型编排)会同时调用多个模型,每个模型独立处理完整的输入。如果输入很长(例如长文档分析),token 消耗会成倍增加。

    6.2 缓存模式

    MoA 工具支持缓存模式:将公共的 prompt 部分(如系统指令、长文档)预先计算 embedding 或缓存结果,每个模型只处理差异部分。

    在 config.yaml 中启用:

    moa:
    cache_enabled: true
    cache_ttl: 3600 # 缓存 1 小时
    cache_backend: redis # 可选 redis 或 memory

    6.3 效果

    对于 10k token 的输入,使用 3 个模型并行,无缓存时每轮消耗 30k token;启用缓存后,首个请求消耗 30k,后续相同或相似请求只消耗差异部分(例如 1k token),节省最高 90%。

    6.4 适用场景

    • 重复性的长文档审核(如合同、财报)
    • 批量处理类似格式的数据
    • 定时任务(如每日报告)

    7. 限制会话记忆保留天数

    7.1 问题:会话历史无限增长

    默认情况下,Honcho 会保留完整的会话历史,用于维持上下文连贯性。但会话越长,token 越多。一周的密集对话可能积累 100k+ token,每次请求都携带这些历史,成本高昂。

    7.2 解决方案:自动过期

    在 config.yaml 中设置会话历史保留策略:

    session:
    max_history_tokens: 8000 # 最多保留 8k token 的历史
    max_age_days: 3 # 超过 3 天的消息自动清除
    summary_keep: true # 清除前生成摘要保留核心信息

    7.3 摘要机制

    当会话历史超过阈值时,Honcho 会自动调用模型生成摘要,用摘要替换原始对话,大幅压缩 token。例如:

    • 原始对话:15000 token
    • 生成的摘要:1000 token
    • 压缩率 93%

    摘要本身也会被定期更新,确保信息不丢失。

    7.4 效果对比

    会话活跃天数无限制模式 token/请求限制+摘要模式 token/请求节省
    1 天 5000 5000 0%
    3 天 15000 5000(摘要) 67%
    7 天 35000 5000 86%
    30 天 150000+ 5000 >96%

    结论:对于长期项目,会话记忆优化是 token 节省最显著的手段之一。


    8. 总结:长期使用者的成本控制

    8.1 10 个技巧速查表

    #技巧节省潜力实施难度推荐指数
    1 精简 Toolset ⭐⭐⭐⭐ 低 ⭐⭐⭐⭐⭐
    2 控制 FTS5 召回数量 ⭐⭐⭐ 低 ⭐⭐⭐⭐⭐
    3 Skill 瘦身 ⭐⭐ 中 ⭐⭐⭐⭐
    4 子 Agent 上下文隔离 ⭐⭐⭐ 中 ⭐⭐⭐⭐
    5 小模型预处理 ⭐⭐⭐⭐⭐ 中 ⭐⭐⭐⭐⭐
    6 MoA 缓存模式 ⭐⭐⭐⭐ 高 ⭐⭐⭐
    7 限制会话记忆 ⭐⭐⭐⭐⭐ 低 ⭐⭐⭐⭐⭐

    8.2 实施路线图

    对于初次进行成本优化的团队,建议按以下顺序实施:

    第一阶段(立即执行,收益最高):

    • 限制会话记忆保留天数(#7)
    • 控制 FTS5 召回数量(#2)
    • 精简 Toolset(#1)

    这三项改动无需复杂配置,能迅速减少 30%~50% 的 token 消耗。

    第二阶段(一周内):

    • 使用小模型处理预处理任务(#5)
    • 子 Agent 上下文隔离(#4)

    第三阶段(持续优化):

    • Skill 瘦身(#3)
    • MoA 缓存(#6)

    8.3 监控与迭代

    成本优化不是一次性工作。建议设置定期审查:

    • 每日:查看 token 消耗趋势图,识别异常高峰
    • 每周:检查 top 10 最耗 token 的会话和 Skill
    • 每月:回顾整体节省比例,调整阈值参数

    Honcho 提供了内置的统计命令:

    honcho stats token –period week

    输出:

    日期 总 token 输入 token 输出 token 节省比例
    2025-04-18 1,234,567 800,000 434,567 baseline
    2025-04-25 650,000 400,000 250,000 47% ↓

    8.4 一句话总结

    Token 消耗的控制不是“抠门”,而是资源效率工程——通过精简 Toolset、优化召回、瘦身 Skill、小模型分层、会话摘要等 10 个技巧,你可以在保持智能体能力不变的情况下,将月度 API 成本压缩到原来的四分之一甚至更低。

    下一步:登录你的 Honcho 实例,检查当前配置中的 Toolset 数量、FTS5 的 top_k 值、会话历史保留时长。从第一阶段的 3 个优化点入手,下周此时再对比账单,你会惊讶于变化。


    附录:配置模板(可直接复制)

    # ============================================
    # Token 优化配置模板
    # ============================================

    # 1. 精简 Toolset
    toolsets:
    – name: minimal
    includes: [reply, memory_recall]
    – name: standard
    includes: [web_get, memory_recall, memory_save, reply]

    default_toolset: minimal

    # 2. 控制召回数量
    memory:
    recall:
    top_k: 3
    max_tokens_per_doc: 300
    min_similarity: 0.65

    # 3. 会话记忆限制
    session:
    max_history_tokens: 8000
    max_age_days: 3
    summary_keep: true

    # 4. MoA 缓存
    moa:
    cache_enabled: true
    cache_ttl: 3600
    cache_backend: memory

    # 5. 小模型优先路由
    routing:
    simple_intent_models: ["claude-3-haiku", "gpt-3.5-turbo"]
    complex_model: "claude-3.5-sonnet"


    版权声明:本文为原创技术博客,采用 CC BY-NC-SA 4.0 许可。欢迎转载,请保留出处。如有 token 优化实践心得,欢迎评论区交流。

    赞(0)
    未经允许不得转载:171主机测评 » 【Hermes:进阶调优与性能优化】43、减少 Token 消耗的 10 个实战技巧 —— 把 AI 调用成本从“烧钱”变成“省心”
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址