Hacker News 上一条评论引发了广泛关注:

另一位用户补充:

为什么一个"AI 助手"会如此昂贵?

成本拆解:每一分钱都花在哪里

初始化阶段:14,000 tokens

当你首次启动 Moltbot(原 Clawdbot) 并发送第一条消息时:

clawdbot gateway start
# T@elegrimm: "你好"

实际发送给 Claude API 的内容:

=== System Prompt (约 3,000 tokens) ===
You are Moltbot, a personal AI assistant...
[完整的系统提示词,包含:]
- 角色定义 (500 tokens)
- 可用工具列表 (1,500 tokens)
- 操作指南 (1,000 tokens)

=== Memory/Context (约 2,000 tokens) ===
[如果有历史记忆]
- 用户偏好 (500 tokens)
- 历史对话摘要 (1,000 tokens)
- Skills 定义 (500 tokens)

=== Tool Definitions (约 8,000 tokens) ===
{
  "tools": [
    {
      "name": "bash",
      "description": "Execute shell commands...",
      "input_schema": {...}  // 详细的 JSON Schema
    },
    {
      "name": "browser",
      "description": "Navigate web pages...",
      "input_schema": {...}
    },
    // ... 20+ 个工具,每个 300-500 tokens
  ]
}

=== 用户消息 (约 10 tokens) ===
"你好"

=== 总计:约 13,010 tokens ===

Claude API 计费:

输入: 13,010 tokens × $3/M = $0.039
输出: 50 tokens × $15/M = $0.00075
单次交互: $0.04

看起来不多,但这只是"你好"的成本。

复杂任务的 Token 爆炸

场景:让 Moltbot(原 Clawdbot) 查天气

用户: "查一下北京明天的天气"

Moltbot(原 Clawdbot) 的执行流程:

Step 1: 理解意图 (13k+ tokens 输入)

上下文: 13,000 tokens (System + Tools)
用户消息: 20 tokens
总输入: 13,020 tokens
输出 (工具调用): 100 tokens

Step 2: 执行 browser tool (30k+ tokens 输入)

// Clawdbot 决定使用 browser 访问天气网站
browser_navigate("https://weather.com/weather/tomorrow/l/Beijing")

// 网页内容返回 (HTML → Markdown)15,000 tokens 的网页内容

下一轮 API 调用:

上下文: 13,000 tokens
历史消息:
  - User: "查一下北京明天的天气" (20 tokens)
  - Assistant: tool_use(browser_navigate...) (100 tokens)
  - Tool Result: [15,000 tokens 的网页内容]
总输入: 28,120 tokens
输出: 200 tokens (解析天气信息)

Step 3: 格式化回复 (30k+ tokens 输入)

上下文: 13,000 tokens
完整历史:
  - 所有之前的消息和工具调用 (15,220 tokens)
总输入: 28,220 tokens
输出: 150 tokens (用户友好的回复)

总计

输入 Token:
  13,020 + 28,120 + 28,220 = 69,360 tokens

输出 Token:
  100 + 200 + 150 = 450 tokens

成本:
  输入: 69,360 × $3/M = $0.208
  输出: 450 × $15/M = $0.0068
  总计: $0.215

一个"查天气"的请求,成本是"你好"的 5倍以上

多任务并行的成本爆炸

用户在一天内执行的任务:

1. 查天气 (3次交互)
2. 整理文件 (10次交互,Agent loop)
3. 发送邮件 (5次交互)
4. 浏览网页总结 (8次交互)
5. 创建提醒 (3次交互)
...
总计: 100+ 次交互

每次交互都包含完整上下文,Token 线性累积:

交互1: 13k tokens
交互2: 13k + 15k (上一轮历史) = 28k tokens
交互3: 13k + 15k + 15k = 43k tokens
...
交互100: 13k + 87k (99轮历史) = 100k tokens

如果历史记录没有及时清理,后期每次交互都是巨额消耗

技术根源分析

原因1:完整上下文重发

Claude API 是无状态的,每次调用都需要重新发送所有上下文:

// Clawdbot 的调用逻辑
async function sendMessage(userMessage: string) {
  const history = await db.getAllMessages();  // 获取所有历史
  
  const response = await claude.messages.create({
    model: 'claude-opus-4.5',
    system: SYSTEM_PROMPT,  // 3,000 tokens
    tools: ALL_TOOLS,        // 8,000 tokens
    messages: [
      ...history,            // 可能有几万到几十万 tokens
      {role: 'user', content: userMessage}
    ]
  });
  
  return response;
}

即使 Anthropic 有服务端缓存(Prompt Caching),也只缓存"完全相同"的前缀。

如果历史消息哪怕改变一个字符,缓存失效,全部重新计费。

原因2:工具定义过于详细

Moltbot(原 Clawdbot) 支持 20+ 个工具,每个工具的 input_schema 非常详细:

{
  "name": "browser",
  "description": "Navigate and interact with web pages...",
  "input_schema": {
    "type": "object",
    "properties": {
      "action": {
        "type": "string",
        "enum": ["navigate", "click", "type", "scroll", "screenshot", ...],
        "description": "详细描述每个 action..."
      },
      "url": {
        "type": "string",
        "format": "uri",
        "description": "完整的 URL 规则..."
      },
      "selector": {
        "type": "string",
        "description": "CSS selector 或 XPath..."
      },
      // ... 还有十几个参数
    },
    "required": ["action"],
    "additionalProperties": false
  }
}

每个工具 300-500 tokens,20 个工具就是 6,000-10,000 tokens。

而且每次调用都要重新发送这些定义,因为 API 无状态。

原因3:网页内容未压缩

Browser Tool 返回的内容是完整的网页(转成 Markdown):

原始 HTML: 150 KB
转换后 Markdown: 50 KB
Token 数:  15,000

如果网页内容很长(比如新闻网站、文档页面),可能超过 50,000 tokens。

Moltbot(原 Clawdbot) 没有做"智能截断"或"摘要",直接把全部内容喂给 AI。

原因4:Agent Loop 失控

有时 Agent 会进入"无限循环":

User: "帮我找一下最新的 AI 新闻"

Agent 执行:
1. browser_navigate(hackernews.com)
   → 发现需要点击"More"
2. browser_click("More")
   → 发现还有"More"
3. browser_click("More")
   → 又有"More"
4. browser_click("More")
   ...
   [循环 20 次]

每次循环都是一轮完整的 API 调用,上下文不断增长。

最终可能消耗 几百万 tokens,用户才意识到出问题了。

与 Claude Code 的对比

为什么 Claude Code 不会"烧钱",但 Moltbot(原 Clawdbot) 会?

Claude Code 的成本控制

1. 使用订阅 Token

Claude Code 使用 Claude Pro/Max 订阅的配额,不按 token 计费:

Claude Pro: $20/月,"无限"对话(有速率限制)
Claude Code: 使用同一配额

用户不会看到具体的 token 消耗,只会遇到速率限制("请稍后再试")。

2. 上下文窗口限制

Claude Code 主动限制上下文:

// 伪代码
const MAX_CONTEXT_TOKENS = 100000;

function trimContext(messages) {
  let tokens = 0;
  let result = [];
  
  // 从最近的消息开始往回取
  for (let i = messages.length - 1; i >= 0; i--) {
    const msgTokens = estimateTokens(messages[i]);
    if (tokens + msgTokens > MAX_CONTEXT_TOKENS) break;
    tokens += msgTokens;
    result.unshift(messages[i]);
  }
  
  return result;
}

如果历史超过 10 万 tokens,只保留最近的部分。

3. 工具动态加载

Claude Code 不是一次性发送所有工具,而是根据任务动态选择:

用户: "读取 README.md"
  → 只发送 filesystem 工具定义

用户: "访问 example.com"
  → 只发送 browser 工具定义

这样每次调用的 tools 定义只有 500-1000 tokens,而不是 8000 tokens。

Moltbot(原 Clawdbot) 为什么不这样做?

设计哲学差异

Claude Code:
  - 专注单一任务(coding)
  - 明确的任务边界
  - Anthropic 控制成本

Moltbot(原 Clawdbot):
  - 通用助手(什么都能做)
  - 模糊的任务边界
  - 用户自己承担成本

Moltbot(原 Clawdbot) 追求"全能",代价是无法精细优化。

缓解方案

方案1:启用 Prompt Caching

Anthropic 提供了 Prompt Caching 功能(2025年底推出):

const response = await claude.messages.create({
  model: 'claude-opus-4.5',
  system: [
    {
      type: 'text',
      text: SYSTEM_PROMPT,
      cache_control: {type: 'ephemeral'}  // 缓存这部分
    }
  ],
  tools: ALL_TOOLS.map(tool => ({
    ...tool,
    cache_control: {type: 'ephemeral'}  // 缓存工具定义
  })),
  messages: history
});

效果:

第1次调用:
  输入: 13,000 tokens (全部计费)
  缓存: 11,000 tokens (System + Tools)

第2次调用:
  输入: 2,000 tokens (只计费新增的历史)
  缓存命中: 11,000 tokens (减免计费)
  
节省: 约 85% 的 token 成本

但需要注意:

  • 缓存只保留 5 分钟
  • 缓存命中率取决于 prompt 是否完全一致
  • 如果用户修改了 System Prompt 或 Tools,缓存失效

方案2:分层上下文管理

将历史消息分成三层:

class ContextManager {
  async getContext(sessionId: string) {
    // 短期记忆:最近 10 轮,完整保留
    const recentMessages = await db.getMessages(sessionId, 10);
    
    // 中期记忆:最近 100 轮,只保留摘要
    const midTermSummary = await this.summarize(
      await db.getMessages(sessionId, 100, 10)
    );
    
    // 长期记忆:所有历史,提取关键事实
    const longTermFacts = await db.getKeyFacts(sessionId);
    
    return {
      recent: recentMessages,        // 完整对话
      summary: midTermSummary,       // "用户询问了天气、日程、邮件"
      facts: longTermFacts           // "用户是素食者、住在北京"
    };
  }
  
  async summarize(messages) {
    // 使用便宜的模型(Haiku)生成摘要
    const summary = await claude.messages.create({
      model: 'claude-haiku-4.5',  // $0.25/M 输出 token
      messages: [{
        role: 'user',
        content: `总结以下对话的关键信息,忽略闲聊:n${messages.join('n')}`
      }]
    });
    return summary.content[0].text;
  }
}

效果:

之前:
  上下文: 10 万 tokens (所有历史)
  
现在:
  最近 10 轮: 5,000 tokens
  中期摘要: 500 tokens
  长期事实: 200 tokens
  总计: 5,700 tokens
  
节省: 94% 的 token

方案3:智能工具选择

不要一次性发送所有工具定义,根据任务类型动态选择:

function selectTools(userMessage: string): Tool[] {
  const intent = classifyIntent(userMessage);
  
  const toolGroups = {
    filesystem: ['read_file', 'write_file', 'list_dir'],
    web: ['browser', 'web_fetch'],
    communication: ['gmail', 'telegram', 'slack'],
    system: ['bash', 'cron'],
    // ...
  };
  
  // 根据意图选择相关工具
  let selectedTools = [];
  if (intent.includes('file')) {
    selectedTools.push(...toolGroups.filesystem);
  }
  if (intent.includes('web')) {
    selectedTools.push(...toolGroups.web);
  }
  
  return selectedTools;
}

效果:

之前:
  工具定义: 8,000 tokens (20+ 工具)

现在:
  工具定义: 1,500 tokens (3-5 工具)

节省: 81% 的工具 token

方案4:网页内容压缩

对 Browser Tool 返回的内容进行智能截断:

async function fetchWebContent(url: string) {
  const html = await browser.navigate(url);
  const markdown = htmlToMarkdown(html);
  
  // 如果内容过长,进行摘要
  if (estimateTokens(markdown) > 10000) {
    const summary = await claude.messages.create({
      model: 'claude-haiku-4.5',  // 使用便宜的模型
      messages: [{
        role: 'user',
        content: `总结以下网页的核心内容,保留关键信息:n${markdown}`
      }]
    });
    return summary.content[0].text;  // 约 500-1000 tokens
  }
  
  return markdown;
}

效果:

之前:
  网页内容: 15,000 tokens

现在:
  摘要: 800 tokens

节省: 95% 的内容 token

方案5:成本熔断机制

设置硬性上限,防止失控:

class CostGuard {
  private dailySpent = 0;
  private sessionSpent = new Map<string, number>();
  
  async checkBudget(sessionId: string, estimatedCost: number) {
    const config = {
      dailyLimit: 10.0,      // $10/天
      sessionLimit: 2.0,     // $2/会话
      alertThreshold: 0.8
    };
    
    // 检查日总量
    if (this.dailySpent + estimatedCost > config.dailyLimit) {
      throw new Error(
        `日预算已用尽 ($${this.dailySpent.toFixed(2)}/${config.dailyLimit})`
      );
    }
    
    // 检查会话总量
    const spent = this.sessionSpent.get(sessionId) || 0;
    if (spent + estimatedCost > config.sessionLimit) {
      throw new Error(
        `会话预算已用尽 ($${spent.toFixed(2)}/${config.sessionLimit})n` +
        `建议运行 'session clear' 清理历史`
      );
    }
    
    // 预警
    if (spent + estimatedCost > config.sessionLimit * config.alertThreshold) {
      console.warn(`️  会话成本接近上限:$${(spent + estimatedCost).toFixed(2)}`);
    }
  }
  
  recordCost(sessionId: string, cost: number) {
    this.dailySpent += cost;
    this.sessionSpent.set(
      sessionId,
      (this.sessionSpent.get(sessionId) || 0) + cost
    );
  }
}

方案6:使用更便宜的模型

不是所有任务都需要 Opus-4.5:

function selectModel(task: Task): string {
  // 简单任务:Haiku (便宜 60 倍)
  if (task.type === 'simple_qa' || task.type === 'summarize') {
    return 'claude-haiku-4.5';
  }
  
  // 中等任务:Sonnet (便宜 5 倍)
  if (task.type === 'code_review' || task.type === 'analysis') {
    return 'claude-sonnet-4.5';
  }
  
  // 复杂任务:Opus
  if (task.type === 'complex_reasoning') {
    return 'claude-opus-4.5';
  }
}

成本对比:

Haiku:  输入 $0.25/M, 输出 $1.25/M
Sonnet: 输入 $3/M,   输出 $15/M
Opus:   输入 $15/M,  输出 $75/M

如果 50% 的任务可以用 Haiku,成本降低 40%+

实际成本估算

按照上述优化方案,重新计算"查天气"的成本:

优化前

3 次交互,每次 28k tokens
总输入: 84,000 tokens → $0.252
总输出: 450 tokens → $0.007
总计: $0.259

优化后

启用 Prompt Caching:
  第1次: 13,000 tokens (全部计费)
  第2次: 2,000 tokens (缓存命中)
  第3次: 2,000 tokens (缓存命中)
  总输入: 17,000 tokens → $0.051

网页摘要:
  原 15,000 tokens → 800 tokens
  节省 14,200 tokens → $0.043

使用 Haiku 生成摘要:
  原 Opus $0.007 → Haiku $0.001
  节省: $0.006

总计: $0.259 → $0.051
节省: 80%

如果用户一天执行 100 个类似任务:

优化前: $0.259 × 100 = $25.9/天
优化后: $0.051 × 100 = $5.1/天

月成本:
  优化前: $777
  优化后: $153

最终建议

对于用户

  1. 定期清理会话历史
# 查看当前会话的 token 消耗
clawdbot session info telegram:@your_username

# 如果消耗过大,清理历史
clawdbot session clear telegram:@your_username
  1. 坚控每日成本
# 查看今日消耗
clawdbot cost today

# 设置预算上限
clawdbot config set cost.dailyLimit 10.0
  1. 避免长时间 Agent Loop

如果任务执行超过 5 分钟还没完成,手动中断:

Ctrl+C
# 或在 T@elegrimm 发送 "/stop"
  1. 使用便宜的模型
# 修改配置
clawdbot config set agent.model claude-sonnet-4.5

# 或根据任务手动指定
clawdbot agent --model haiku "总结这篇文章"

对于开发者

  1. 实现 Prompt Caching
  2. 引入分层上下文管理
  3. 动态选择工具定义
  4. 智能压缩网页内容
  5. 添加成本熔断机制
  6. 支持多模型切换

这些优化可以将成本降低 70-90%,让 Moltbot(原 Clawdbot) 真正可用。

目前的状态:能用,但太贵。

优化后的状态:能用,且可承受。

本站提供的所有下载资源均来自互联网,仅提供学习交流使用,版权归原作者所有。如需商业使用,请联系原作者获得授权。 如您发现有涉嫌侵权的内容,请联系我们 邮箱:alixiixcom@163.com