乐于分享
好东西不私藏

【Claude Code源码杂谈(1)】使用轻量模型节约agent成本

【Claude Code源码杂谈(1)】使用轻量模型节约agent成本

- 2026年4月4日

【Claude Code源码杂谈(1)】使用轻量模型节约agent成本

📌 :本文所有成本数据基于代码中硬编码的标准定价(来自 src/utils/modelCost.ts),源自官方定价文档。实际定价可能会随时间变化,最新定价请参考

platform.claude.com/docs/en/about-claude/pricing

Claude Code 采用 多层级模型架构,根据不同的计算场景使用不同性能的模型。

Haiku 4.5 作为轻量级模型,在以下关键场景中被系统性地使用:

  • 成本驱动 的边缘任务

    Web Search、Token Counting

  • 低延迟 的实时反馈任务

    Away Summary、Session Search

  • 高吞吐 的后台工作

    Rate Limit Processing

Haiku适配情况

Claude Code中Haiku 4.5 的核心使用场景

1️⃣:Web Search Tool 的快速执行

触发条件:Feature Flag tengu_plum_vx3 启用时

tengu_plum_vx3 是一个功能开关,用于控制 WebSearchTool 是否使用 Haiku。

tengu_plum_vx3开关
  • useHaiku = true 时:使用 getSmallFastModel() 进行网络搜索,禁用思考配置 (thinkingConfig: disabled)
  • useHaiku = false 时:使用常规主模型 (context.options.mainLoopModel)

Web 搜索不需要复杂推理,这个标志可让网络搜索操作更轻量、更快速/低成本 。

2️⃣:Token Counting Fallback

api provider

目前支持的api provider:

PROVIDER
启用方式
认证方式
firstParty
默认
ANTHROPIC_API_KEY/ OAuth
bedrock
CLAUDE_CODE_USE_BEDROCK=1
AWS 凭证 / Bearer Token
vertex
CLAUDE_CODE_USE_VERTEX=1
GCP 凭证
foundry
CLAUDE_CODE_USE_FOUNDRY=1
Azure AD / API Key

而较为准确的token使用情况有以下作用:

  1. 上下文使用量 > 阈值 → 自动压缩对话历史
自动压缩
  1. 用户可以在UI上直观查看上下文使用状态

  2. 防止超过 Context Window

    如果 token 计数不准确,可能:

    • 发送超过 200k tokens 的请求 → API 报错
    • 或者压缩时机不对 →不知道用了多少,就没法决定什么时候该压缩。导致 上下文被意外截断

为什么此处需要haiku:

  • Anthropic 直连 API 有 countTokens() 支持

  • AWS Bedrock 的 CountTokensCommand 支持

  • Google Vertex 有 beta 支持

    但 Bedrock 有些情况下 countTokens 不可用,可能返回 null

countTokensWithFallback (analyzeContext.ts:77)
  ├─ countMessagesTokensWithAPI (tokenEstimation.ts:140)
  │    ├─ Bedrock → countTokensWithBedrock (可能返回 null)
  │    └─ 其他 → anthropic.beta.messages.countTokens
  │
  └─ (如果上面返回 null) → countTokensViaHaikuFallback (tokenEstimation.ts:251)
       └─ 实际调用 Haiku 模型 + 统计 usage.input_tokens
async function countTokensWithFallback(
messagesAnthropic.Beta.Messages.BetaMessageParam[],
toolsAnthropic.Beta.Messages.BetaToolUnion[],
): Promise<number | null> {
try {
// 第一优先级:用 native API 计数
const result = await countMessagesTokensWithAPI(messages, tools)
if (result !== nullreturn result
  } catch (err) { /* ... */ }

try {
// 第二优先级:Haiku fallback(成本最低)
const fallbackResult = await countTokensViaHaikuFallback(messages, tools)
return fallbackResult
  } catch (err) { /* ... */ }

// 最后手段:粗略估算(不调用 API)
return roughTokenCountEstimation(content)
}

Haiku Fallback 通过发送 max_tokens=1 的虚假请求,最小化成本,来从response.usage.input_tokens 读取实际 token 数

export async function countTokensViaHaikuFallback(
messagesAnthropic.Beta.Messages.BetaMessageParam[],
toolsAnthropic.Beta.Messages.BetaToolUnion[],
): Promise<number | null> {
const model = 
getVertexRegionForModel(getSmallFastModel()) === 'global'
      ? getDefaultSonnetModel()  // Vertex global 不支持 Haiku
      : hasThinkingBlocks(messages) && getAPIProvider() === 'bedrock'
      ? getDefaultSonnetModel()  // Bedrock 的 Haiku 3.5 不支持 thinking
      : getSmallFastModel()      // 其他情况用 Haiku 4.5

// 关键技巧:发送 max_tokens=1 的虚假请求
const response = await queryModel({
    model,
    messages,
    tools,
max_tokens1,  // 最小化成本:不会实际输出任何 tokens
  })

// 从 response.usage.input_tokens 读取实际 token 数
return response.usage.input_tokens
}
场景
成本
用途
主循环 Token Count
✅ 免费(原生 API)
上下文管理
Haiku Fallback
$0.000001-0.00001
Bedrock 与第三方服务
粗略估算
$0
热路径快速检查

3️⃣:离线会话摘要

用户长时间离开后,生成”用户回来时”的快速摘要卡片

export async function generateAwaySummary(
messagesreadonly Message[],
signalAbortSignal,
): Promise<string | null> {
const memory = await getSessionMemoryContent()

// 只取最近 30 条消息(≈15 轮对话)
const recent = messages.slice(-30)

const response = await queryModelWithoutStreaming({
modelgetSmallFastModel(),  // ← Haiku 4.5
thinkingConfig: { type'disabled' },
systemPrompt: [],
messages: [
      ...recent,
createUserMessage({
content`用户离开了。写 1-3 句话总结:
          1) 高层任务(他们在构建/调试什么)
          2) 下一个具体步骤
          忽略实现细节和 commit 摘要。`
,
      }),
    ],
// ...
  })

return extractMessageText(response)
}
需要考虑的方面
说明
延迟
用户打开应用后立即显示,不能等待
质量需求
只需 “足够好” 的摘要,不需最高质量
成本压力
每个用户回话可能触发 → 需降低单次成本

而Haiku 推理快速,成本低,足以生成短文本摘要

4️⃣:会话历史搜索

帮助用户快速找到相关的历史对话

export async function agenticSessionSearch(
querystring,
logsLogOption[],
signal?: AbortSignal,
): Promise<LogOption[]> {
// 第一轮:快速 grep 过滤
const matchingLogs = logs.filter(log =>
logContainsQuery(log, query.toLowerCase())
  )

// 第二轮:用 AI 进行语义重排序
const userMessage = `Sessions:
${sessionList}

Search query: "${query}"

Find the sessions most relevant to this query.`


const response = await queryModel({
modelgetSmallFastModel(),  // ← Haiku 4.5
messages: [{ role'user'content: userMessage }],
max_tokens256,
  })

// 解析 AI 返回的排序结果
return parseRelevantSessions(response)
}

5️⃣:Rate Limit 降级处理

Claude.ai 用户有强制 rate limits(5 hour / 7 day)

export async function checkClaudeAIRateLimits(): Promise<ClaudeAILimits> {
try {
// 发送最小化请求以获取 rate limit 头信息
const model = getSmallFastModel()  // Haiku 4.5

const response = await queryModel({
      model,
messages: [{ role'user'content'.' }],
max_tokens1,
    })

// 从响应头读取 rate limit 信息
const utilization = parseHeaders(response.headers)

return {
status: utilization > 0.9 ? 'limited' : 'allowed',
      utilization,
    }
  } catch (error) {
// ...处理错误
  }
}

6️⃣:权限决策中的安全分类(Bash 权限检查)

文件位置:docs/safety/why-safety-matters.mdx

Bash 命令执行前需通过 5 层权限检查

Layer 1: AST 解析(tree-sitter) ← 不用 AI
Layer 2: 精确规则匹配 ← 不用 AI
Layer 3: 分类器检查
        ↓
        用 Haiku 对 deny/ask 规则进行语义匹配

Layer 4: 沙箱虚拟化 ← 不用 AI
Layer 5: Hooks & 预算 ← 不用 AI

Haiku 在权限中的角色:

// 用户定义规则(来自配置):
const denyRules = [
"避免访问 /etc/passwd",
"阻止向 AWS 发送 sensitive 数据"
]

// Bash 命令:bash("grep admin /var/log/auth.log")

// 步骤 1-2 失败(不是字面上的 /etc/passwd,有文件读权限)
//
// 步骤 3:用 Haiku 做语义检查
const semanticMatch = await queryModel({
modelgetSmallFastModel(),  // Haiku 4.5
messages: [{
role'user',
content`规则:"${denyRules[0]}"
              命令:"grep admin /var/log/auth.log"
              命令是否违反规则?(yes/no)`

  }],
max_tokens10,
})

// 返回:"no" - 因为 /var/log/auth.log ≠ /etc/passwd
// 命令被允许

为什么这里用 Haiku:

  • 关键时刻:安全决策,必须准确
  • Haiku 能力足够:规则匹配是 LLM 的强项
  • 成本极低:每次检查 < $0.000001
  • 延迟包容:安全检查可接受 100-200ms 延迟

附录:模型定价对比

定价来源src/utils/modelCost.ts 中的硬编码标准定价配置

模型
INPUT(输入)
OUTPUT(输出)
使用场景
Haiku 4.5
$1/1M
$5/1M
边缘计算、轻量级任务
Sonnet 4.6
$3/1M
$15/1M
记忆筛选、一般任务
Opus 4.6
$15/1M(fast)
$75/1M(fast)
复杂推理、最高质量

成本对比(1M input + 100K output):

Haiku 4.5: $1 + $0.5 = $1.5

Sonnet 4.6: $3 + $1.5 = $4.5

Opus 4.6: $15 + $7.5 = $22.5

相关资料:

  • 基于 Claude Code npm 发布包 source map 还原版本

  • Caylent — Claude Haiku 4.5 Deep Dive: Cost, Capabilities, and the Multi-Agent Opportunity

    https://caylent.com/blog/claude-haiku-4-5-deep-dive-cost-capabilities-and-the-multi-agent-opportunity