Claude Code 成本优化深度指南 — max-turns、max-budget-usd、fallback-model 与 Token 监控
简介
AI 编程助手的能力令人惊叹,但随之而来的成本问题也不容忽视。Claude Code 按 Token 计费,一个复杂的代码重构任务可能消耗数十万 Token,折算下来费用不菲。如果不加控制,一个团队每天的花费可能轻松突破数百美元。
好消息是,Claude Code 提供了丰富的成本控制机制:max-turns 限制最大对话轮数、max-budget-usd 设置硬性预算上限、fallback-model 实现自动模型降级、effort 级别调节输出深度,以及完整的 Token 监控体系。这些功能让你可以在"性能"和"成本"之间找到最佳平衡点。
本文将深入讲解每一项成本控制策略的原理、配置方法和实战场景,帮助你构建经济高效的 AI 编程工作流。无论你是个人开发者精打细算,还是企业 IT 管理员需要管理百人的 AI 使用预算,都能在这里找到实用的解决方案。
目录
- 一、成本模型与 Token 计费
- 二、max-turns: 限制对话轮数
- 三、max-budget-usd: 硬性预算上限
- 四、fallback-model: 自动模型降级
- 五、effort 级别: 调节输出深度
- 六、Token 监控与分析
- 七、成本优化实战策略
- 八、团队预算管理
- 九、总结
- 十、下篇预告
一、成本模型与 Token 计费
1.1 Token 是什么?
Token 是大语言模型处理文本的基本单位。一个英文单词大约对应 1.3 个 Token,一个中文字符通常对应 1-2 个 Token。Claude Code 的每次交互都会产生两类 Token:
- Input Tokens(输入 Token):你发送给模型的提示词、代码上下文、历史对话等
- Output Tokens(生成 Token):模型生成的回复、代码、分析结果等
计费公式:
总费用 = (Input Tokens × Input 单价) + (Output Tokens × Output 单价)不同模型的单价差异显著:
| 模型 | Input 价格 ($/M tokens) | Output 价格 ($/M tokens) |
|---|---|---|
| Claude Sonnet 4 | $3.00 | $15.00 |
| Claude Opus 4 | $15.00 | $75.00 |
| Claude Haiku | $0.80 | $4.00 |
Output Token 的价格通常是 Input Token 的 5 倍,这意味着模型"说得越多"成本越高。
1.2 典型任务 Token 消耗
理解典型任务的 Token 消耗是制定成本策略的前提:
┌─────────────────────────────────┬──────────────┬──────────────┬─────────┐
│ 任务类型 │ Input Tokens │ Output Tokens│ 预估费用│
├─────────────────────────────────┼──────────────┼──────────────┼─────────┤
│ 解释一段 50 行代码 │ 2,000 │ 1,500 │ $0.03 │
│ 重构 500 行模块 │ 15,000 │ 10,000 │ $0.20 │
│ 生成单元测试套件 │ 8,000 │ 20,000 │ $0.32 │
│ 完整 PR 审查(10 文件) │ 50,000 │ 15,000 │ $0.38 │
│ 多轮架构讨论 + 代码生成 │ 200,000 │ 50,000 │ $1.35 │
│ 大型代码库迁移(多轮迭代) │ 500,000 │ 200,000 │ $4.50 │
└─────────────────────────────────┴──────────────┴──────────────┴─────────┘二、max-turns: 限制对话轮数
2.1 为什么需要限制轮数?
在 --print 模式和 --bare 模式中,Claude Code 会自主进行多轮"思考-行动"循环。每轮循环 Claude 可以读取文件、执行命令、修改代码、运行测试……这个能力很强,但如果没有上限,一个简单的任务可能演变成无止境的循环:
# 危险!没有轮数限制
claude --print "修复所有测试用例"
# Claude 可能进入:改代码 → 跑测试 → 发现新问题 → 改代码 → 跑测试 → ...
# 持续 50+ 轮,消耗数十万 Token2.2 配置 max-turns
--max-turns 参数限制 Claude Code 在一个任务中的最大循环轮数:
# 限制最多 10 轮交互
claude --print --max-turns 10 "修复所有失败的测试"
# bare 模式下同样适用
claude --bare --max-turns 5 "检查 src/auth/ 下的代码规范"
# 通过环境变量设置全局默认值
export CLAUDE_CODE_MAX_TURNS=20
claude --print "重构 UserService 类"2.3 不同场景的推荐轮数
# 快速查询 / 解释代码:3-5 轮足够
claude --print --max-turns 3 "解释这个正则表达式的含义"
# 单文件编辑 / Bug 修复:5-10 轮
claude --print --max-turns 10 "修复 getUser 函数中的空指针异常"
# 多文件重构:15-25 轮
claude --print --max-turns 20 "将 callback 风格改为 async/await"
# PR 审查:10-15 轮
claude --bare --max-turns 15 --from-pr 42 "进行代码审查"
# 复杂功能开发:25-40 轮(需谨慎监控预算)
claude --print --max-turns 30 "实现 OAuth2 登录流程,包括前端和后端"2.4 轮数耗尽的处理
当达到 max-turns 限制时,Claude Code 会停止执行并输出当前状态:
⚠️ Maximum turns (10) reached. Stopping.
Last action: Running test suite (3 of 47 tests still failing)在脚本中可以捕获退出码进行后续处理:
#!/bin/bash
# 带轮数限制的成本保护脚本
claude --bare --max-turns 15 "实现用户注册功能"
exit_code=$?
if [ $exit_code -eq 3 ]; then
echo "⚠️ 达到最大轮数限制,任务未完成"
echo "📋 建议:增加 max-turns 或将任务拆分为更小的子任务"
# 可选:用更便宜的模型继续
claude --bare --max-turns 10 --model haiku "基于之前的进度继续完成剩余工作"
elif [ $exit_code -eq 0 ]; then
echo "✅ 任务在预算内完成"
fi三、max-budget-usd: 硬性预算上限
3.1 安全熔断机制
--max-budget-usd 是 Claude Code 最强大的成本控制功能——它提供了一个硬性美元上限,一旦累计花费达到这个金额,Claude Code 会立即停止所有操作。这是防止意外高额账单的最后一道防线。
# 设置 5 美元硬性上限
claude --print --max-budget-usd 5 "重构整个认证模块"
# 裸模式下同样有效
claude --bare --max-budget-usd 2 "审查 PR #42"
# 极低成本模式(适合快速查询)
claude --print --max-budget-usd 0.50 "解释这段代码的逻辑"3.2 预算耗尽的行为
当花费接近上限时,Claude Code 会发出警告:
⚠️ Budget warning: $4.50 of $5.00 used (90%)
Consider simplifying your request or increasing the budget.当达到上限时:
🛑 Budget limit reached ($5.00). Stopping immediately.
Total tokens consumed: 1,250,000 (Input: 800,000, Output: 450,000)退出码为 4,便于脚本识别:
claude --bare --max-budget-usd 3 "大规模代码重构"
case $? in
0) echo "✅ 任务完成" ;;
3) echo "⚠️ 轮数耗尽" ;;
4) echo "💰 预算耗尽" ;;
*) echo "❌ 其他错误" ;;
esac3.3 环境变量配置
通过环境变量设置全局默认预算,适合团队统一策略:
# ~/.bashrc 或 CI 环境变量
export CLAUDE_CODE_MAX_BUDGET_USD=10 # 全局默认 10 美元
# 特定项目覆盖
cd /path/to/small-project
export CLAUDE_CODE_MAX_BUDGET_USD=2 # 小项目限制 2 美元
# CI 环境中严格限制
export CLAUDE_CODE_MAX_BUDGET_USD=1 # CI 流水线每次最多 1 美元3.4 预算监控脚本
#!/usr/bin/env python3
"""Claude Code 预算监控与预警脚本"""
import json
import subprocess
import sys
from datetime import datetime
class BudgetMonitor:
def __init__(self, daily_limit=50.0, warn_threshold=0.8):
self.daily_limit = daily_limit
self.warn_threshold = warn_threshold
self.log_file = "~/.claude-code/usage-log.jsonl"
def parse_usage_log(self):
"""解析使用日志,计算当日花费"""
total_cost = 0.0
today = datetime.now().strftime("%Y-%m-%d")
try:
with open(self.log_file) as f:
for line in f:
entry = json.loads(line)
if entry.get("date", "").startswith(today):
total_cost += entry.get("cost", 0.0)
except FileNotFoundError:
pass
return total_cost
def check_and_warn(self):
"""检查预算并发出预警"""
current_cost = self.parse_usage_log()
usage_ratio = current_cost / self.daily_limit
if usage_ratio >= 1.0:
print(f"🛑 今日预算已耗尽 (${current_cost:.2f}/${self.daily_limit:.2f})")
return False
elif usage_ratio >= self.warn_threshold:
print(f"⚠️ 预算预警: ${current_cost:.2f}/${self.daily_limit:.2f} "
f"({usage_ratio*100:.0f}%)")
# 发送通知
self.send_notification(current_cost, usage_ratio)
return True
def send_notification(self, cost, ratio):
"""发送预算预警通知"""
# 可以集成 Slack、钉钉、企业微信等
message = (
f"🔔 Claude Code 预算预警\n"
f"今日花费: ${cost:.2f}\n"
f"预算上限: ${self.daily_limit:.2f}\n"
f"使用比例: {ratio*100:.0f}%"
)
print(f"📧 发送通知: {message}")
if __name__ == "__main__":
monitor = BudgetMonitor(daily_limit=50.0)
monitor.check_and_warn()四、fallback-model: 自动模型降级
4.1 模型降级策略
fallback-model 允许你在主模型不可用或预算不足时自动切换到更便宜的模型。这是一个多级降级策略:
# 主模型用 Sonnet,降级到 Haiku
claude --print \
--model sonnet \
--fallback-model haiku \
"审查代码并生成文档"4.2 多级降级配置
通过配置文件实现多级降级策略:
# .claude-code/config.yaml
models:
primary: sonnet # 主要使用 Claude Sonnet 4
fallbacks:
- haiku # 第一降级:Claude Haiku(成本最低)
- sonnet-lite # 第二降级:轻量版 Sonnet(如果有)
budget:
max_per_task: 5.00 # 每个任务最大 5 美元
daily_limit: 50.00 # 每日总预算
routing:
# 根据任务类型自动选择模型
rules:
- pattern: "解释.*|说明.*|什么是.*"
model: haiku # 解释类用 Haiku
- pattern: "审查.*|review.*"
model: sonnet # 审查类用 Sonnet
- pattern: "重构.*|架构.*|设计.*"
model: opus # 复杂重构用 Opus
- default: sonnet4.3 成本对比:模型降级节省
任务: 批量代码审查 (50 个 PR)
全用 Opus:
50 PR × $4.50/PR = $225.00
Sonnet 为主 + Haiku 降级:
35 PR × $0.38 (Sonnet) + 15 PR × $0.10 (Haiku) = $14.80
节省: $210.20 (93.4%)4.4 智能降级脚本
#!/bin/bash
# smart-model-select.sh - 根据任务复杂度选择模型
select_model() {
local task="$1"
local file_count="$2"
local line_count="$3"
# 简单任务:Haiku
if [ "$file_count" -le 1 ] && [ "$line_count" -le 100 ]; then
echo "haiku"
return
fi
# 中等任务:Sonnet
if [ "$file_count" -le 10 ] && [ "$line_count" -le 1000 ]; then
echo "sonnet"
return
fi
# 复杂任务:Opus
echo "opus"
}
# 使用示例
FILES_CHANGED=$(git diff --name-only HEAD~1 | wc -l)
LINES_CHANGED=$(git diff --stat HEAD~1 | tail -1 | grep -oP '\d+ insertion' | grep -oP '\d+')
MODEL=$(select_model "code-review" "$FILES_CHANGED" "${LINES_CHANGED:-0}")
echo "🤖 使用模型: $MODEL (文件: $FILES_CHANGED, 行数: ${LINES_CHANGED:-0})"
claude --bare \
--model "$MODEL" \
--fallback-model haiku \
--max-budget-usd 2 \
"审查最近的代码变更"五、effort 级别: 调节输出深度
5.1 什么是 effort 级别?
effort 参数控制 Claude Code 在完成任务时的"努力程度"。更高的 effort 级别意味着 Claude 会进行更深入的分析、更全面的搜索、更详尽的回复——但也会消耗更多 Token 和时间。
# 低 effort:快速、简要的回复
claude --print --effort low "这个函数有什么问题?"
# 中等 effort(默认):平衡质量和成本
claude --print --effort medium "重构这个模块"
# 高 effort:全面、深入的分析
claude --print --effort high "全面审查这个项目的架构"5.2 三级 effort 对比
| 维度 | low | medium (默认) | high |
|---|---|---|---|
| 文件搜索深度 | 当前文件 | 相关目录 | 全项目 |
| 代码分析粒度 | 表面检查 | 逻辑分析 | 深度推理 |
| 测试覆盖 | 基本 | 完整 | 边界 + 异常 |
| 文档详尽度 | 简要 | 适中 | 详尽 |
| Token 消耗 | ~30% | 100% | ~200%+ |
| 适用场景 | 快速查询 | 日常开发 | 关键审查 |
5.3 effort 与成本的关系
# 同一个任务,不同 effort 级别的 Token 消耗对比
# low effort: 快速回答
claude --print --effort low "找出这段代码的 bug"
# → Input: 3,200 tokens, Output: 800 tokens, 费用: ~$0.02
# medium effort: 标准分析
claude --print --effort medium "找出这段代码的 bug"
# → Input: 5,500 tokens, Output: 2,200 tokens, 费用: ~$0.05
# high effort: 全面审查
claude --print --effort high "找出这段代码的 bug"
# → Input: 12,000 tokens, Output: 4,500 tokens, 费用: ~$0.105.4 场景化配置
# .claude-code/effort-rules.yaml
effort_profiles:
quick_answer:
effort: low
max_turns: 3
description: "快速问答"
daily_coding:
effort: medium
max_turns: 15
description: "日常编码"
code_review:
effort: high
max_turns: 20
description: "代码审查"
pr_merge_check:
effort: high
max_turns: 25
max_budget_usd: 5.00
description: "PR 合并前检查"在脚本中引用配置:
#!/bin/bash
# 根据场景自动设置 effort
case "$1" in
explain)
EFFORT_FLAGS="--effort low --max-turns 3 --max-budget-usd 0.50"
;;
fix)
EFFORT_FLAGS="--effort medium --max-turns 10 --max-budget-usd 2.00"
;;
review)
EFFORT_FLAGS="--effort high --max-turns 20 --max-budget-usd 5.00"
;;
refactor)
EFFORT_FLAGS="--effort high --max-turns 30 --max-budget-usd 10.00"
;;
*)
EFFORT_FLAGS="--effort medium --max-turns 15"
;;
esac
shift
claude --bare $EFFORT_FLAGS "$@"六、Token 监控与分析
6.1 内置 Token 统计
Claude Code 在每次任务完成时会输出 Token 使用统计:
✅ Task completed
📊 Token Usage:
Input tokens: 45,230
Output tokens: 12,800
Total tokens: 58,030
Estimated cost: $0.33
Duration: 2m 34s在 --output-format stream-json 模式下,Token 信息包含在 result 事件中:
{
"type": "result",
"subtype": "success",
"usage": {
"input_tokens": 45230,
"output_tokens": 12800,
"total_tokens": 58030
},
"cost_usd": 0.33,
"duration_ms": 154000
}6.2 Token 监控仪表板脚本
#!/bin/bash
# token-dashboard.sh - Claude Code Token 使用仪表板
USAGE_LOG="${CLAUDE_CODE_HOME:-~/.claude-code}/usage-log.jsonl"
show_daily_summary() {
local date="${1:-$(date +%Y-%m-%d)}"
echo "📊 Claude Code 每日使用报告 — $date"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
# 从 stream-json 日志中聚合数据
total_input=0
total_output=0
total_cost=0
task_count=0
while IFS= read -r line; do
input=$(echo "$line" | jq -r '.usage.input_tokens // 0')
output=$(echo "$line" | jq -r '.usage.output_tokens // 0')
cost=$(echo "$line" | jq -r '.cost_usd // 0')
total_input=$((total_input + input))
total_output=$((total_output + output))
total_cost=$(echo "$total_cost + $cost" | bc)
task_count=$((task_count + 1))
done < <(grep "\"type\":\"result\"" "$USAGE_LOG" | grep "$date")
echo ""
echo "任务数量: $task_count"
echo "Input Token: $(numfmt --to=si $total_input)"
echo "Output Token: $(numfmt --to=si $total_output)"
echo "Total Token: $(numfmt --to=si $((total_input + total_output)))"
printf "总费用: \$%.2f\n" "$total_cost"
echo ""
# Token 效率分析
if [ $total_output -gt 0 ]; then
ratio=$(echo "scale=2; $total_input / $total_output" | bc)
echo "Input/Output 比率: $ratio"
if (( $(echo "$ratio > 5" | bc -l) )); then
echo "⚠️ Input Token 偏高,考虑精简提示词或减少上下文"
fi
fi
}
show_top_tasks() {
echo ""
echo "🔥 Top 10 最昂贵的任务:"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
grep "\"type\":\"result\"" "$USAGE_LOG" | \
jq -r '[.cost_usd, .prompt[0:60]] | @tsv' | \
sort -rn | \
head -10 | \
while IFS=$'\t' read -r cost prompt; do
printf " $%.2f %s\n" "$cost" "$prompt..."
done
}
# 执行报告
show_daily_summary "$1"
show_top_tasks6.3 长期趋势分析
#!/usr/bin/env python3
"""Claude Code Token 趋势分析"""
import json
import matplotlib.pyplot as plt
from datetime import datetime, timedelta
from collections import defaultdict
def analyze_trends(log_file, days=30):
"""分析最近 N 天的 Token 使用趋势"""
daily_stats = defaultdict(lambda: {
"input": 0, "output": 0, "cost": 0.0, "tasks": 0
})
cutoff = datetime.now() - timedelta(days=days)
with open(log_file) as f:
for line in f:
entry = json.loads(line)
date_str = entry.get("date", "")
try:
date = datetime.strptime(date_str, "%Y-%m-%d")
except ValueError:
continue
if date >= cutoff:
stats = daily_stats[date_str]
usage = entry.get("usage", {})
stats["input"] += usage.get("input_tokens", 0)
stats["output"] += usage.get("output_tokens", 0)
stats["cost"] += entry.get("cost_usd", 0.0)
stats["tasks"] += 1
# 生成趋势图
dates = sorted(daily_stats.keys())
costs = [daily_stats[d]["cost"] for d in dates]
tokens_in = [daily_stats[d]["input"] for d in dates]
tokens_out = [daily_stats[d]["output"] for d in dates]
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 8))
ax1.plot(dates, costs, "b-", marker="o")
ax1.set_title("每日费用趋势")
ax1.set_ylabel("费用 ($)")
ax1.grid(True)
ax2.plot(dates, tokens_in, "g-", label="Input", marker=".")
ax2.plot(dates, tokens_out, "r-", label="Output", marker=".")
ax2.set_title("每日 Token 消耗")
ax2.set_ylabel("Token 数量")
ax2.legend()
ax2.grid(True)
plt.tight_layout()
plt.savefig("./usage-trend.png")
print("📈 趋势图已保存到 ./usage-trend.png")
if __name__ == "__main__":
analyze_trends("~/.claude-code/usage-log.jsonl")七、成本优化实战策略
7.1 策略 1: 提示词优化减少 Input Token
Input Token 占据大部分成本。优化提示词是最直接的省钱方式:
# ❌ 浪费 Input Token
claude --print "
请仔细阅读以下代码,这段代码实现了一个用户认证系统,
包含了登录、注册、密码重置、Token 验证等多个功能模块。
我需要你帮我找出其中可能存在的问题,包括但不限于安全漏洞、
性能问题、代码风格问题等等。请尽可能详细地分析每一个函数。
$(cat src/auth/*.py src/auth/**/*.py) # 加载所有文件,很多是不相关的
"
# ✅ 精准提示,减少上下文
claude --print "
检查 src/auth/login.py 中的 authenticate() 函数是否有 SQL 注入漏洞。
只关注这个函数,不需要分析其他文件。
"优化效果对比:
| 方式 | Input Tokens | Output Tokens | 费用 |
|---|---|---|---|
| 模糊大提示 | 120,000 | 8,000 | $0.48 |
| 精准小提示 | 8,000 | 2,000 | $0.05 |
| 节省 | 93.3% | 75.0% | 89.6% |
7.2 策略 2: 分层审查降低成本
#!/bin/bash
# 两阶段审查:先用 Haiku 做快速扫描,再用 Sonnet 深入分析
# 第一阶段:Haiku 快速扫描(便宜)
echo "🔍 第一阶段:快速扫描..."
scan_result=$(claude --bare --model haiku --max-turns 5 --effort low \
"快速扫描以下文件,列出可能需要深入审查的文件路径:$(git diff --name-only)")
# 解析需要深入审查的文件
files_to_review=$(echo "$scan_result" | grep -oP 'src/\S+\.py')
# 第二阶段:Sonnet 深入审查(只针对重点文件)
echo "🔍 第二阶段:深入审查..."
for file in $files_to_review; do
echo " 审查 $file..."
claude --bare --model sonnet --max-turns 10 --max-budget-usd 1 \
"深入审查 $file 中的代码变更"
done7.3 策略 3: 利用缓存避免重复消耗
#!/bin/bash
# cache-review.sh - 带缓存的 PR 审查
CACHE_DIR=".claude-cache/reviews"
mkdir -p "$CACHE_DIR"
get_pr_hash() {
local pr_num="$1"
# 用 PR 的 diff hash 作为缓存 key
gh pr diff "$pr_num" | sha256sum | cut -d' ' -f1
}
cached_review() {
local pr_num="$1"
local cache_key=$(get_pr_hash "$pr_num")
local cache_file="$CACHE_DIR/${cache_key}.json"
if [ -f "$cache_file" ]; then
echo "📦 使用缓存结果 (PR #$pr_num)"
cat "$cache_file"
return 0
fi
echo "🔍 执行新审查 (PR #$pr_num)"
claude --bare --from-pr "$pr_num" --output-format stream-json \
"进行代码审查" > "$cache_file"
echo "$cache_file"
}
# 批量审查时使用缓存
for pr in $(gh pr list --state open --json number -q '.[].number'); do
cached_review "$pr"
done7.4 策略 4: 非工作时间使用低价模型
#!/usr/bin/env python3
"""根据时间段自动选择模型"""
from datetime import datetime
def select_model_by_time():
now = datetime.now()
hour = now.hour
# 工作时间 (9:00-18:00):用 Sonnet 保证质量
if 9 <= hour < 18:
return "sonnet", 15, 5.00
# 非工作时间:用 Haiku 省钱
else:
return "haiku", 10, 1.00
# 周末:更激进的省钱策略
if now.weekday() >= 5:
return "haiku", 8, 0.50
model, max_turns, max_budget = select_model_by_time()
print(f"🤖 当前模型: {model}, 最大轮数: {max_turns}, 预算: ${max_budget}")
# claude --bare --model $model --max-turns $max_turns --max-budget-usd $max_budget "..."八、团队预算管理
8.1 团队预算分配
#!/bin/bash
# team-budget-manager.sh - 团队预算分配与追踪
TEAM_BUDGET_FILE=".claude-team-budget.json"
# 初始化团队预算
init_team_budget() {
cat > "$TEAM_BUDGET_FILE" << 'EOF'
{
"monthly_budget": 500.00,
"members": {
"alice": { "daily_limit": 10.00, "spent_today": 0.00 },
"bob": { "daily_limit": 8.00, "spent_today": 0.00 },
"charlie": { "daily_limit": 12.00, "spent_today": 0.00 }
},
"projects": {
"core-api": { "budget": 200.00, "spent": 0.00 },
"frontend": { "budget": 150.00, "spent": 0.00 },
"infra": { "budget": 150.00, "spent": 0.00 }
}
}
EOF
}
# 检查个人预算
check_personal_budget() {
local user="$1"
local spent_today
spent_today=$(jq -r ".members.$user.spent_today" "$TEAM_BUDGET_FILE")
local daily_limit
daily_limit=$(jq -r ".members.$user.daily_limit" "$TEAM_BUDGET_FILE")
echo "scale=2; $spent_today / $daily_limit" | bc | {
read ratio
if (( $(echo "$ratio >= 1.0" | bc -l) )); then
echo "🛑 $user 今日预算已用完 ($spent_today/$daily_limit)"
return 1
elif (( $(echo "$ratio >= 0.8" | bc -l) )); then
echo "⚠️ $user 今日预算即将用完 ($spent_today/$daily_limit)"
fi
return 0
}
}8.2 CI 成本限制最佳实践
# .github/workflows/claude-review.yml
name: Claude Code PR Review (Cost-Optimized)
on: pull_request
jobs:
claude-review:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- name: Calculate PR size
id: size
run: |
FILES=$(git diff --name-only HEAD~1 HEAD | wc -l)
LINES=$(git diff --stat HEAD~1 HEAD | tail -1 | grep -oP '\d+ changes' | grep -oP '\d+')
echo "files=$FILES" >> $GITHUB_OUTPUT
echo "lines=${LINES:-0}" >> $GITHUB_OUTPUT
- name: Select model based on PR size
id: model
run: |
if [ ${{ steps.size.outputs.files }} -le 3 ]; then
echo "model=haiku" >> $GITHUB_OUTPUT
echo "budget=0.50" >> $GITHUB_OUTPUT
echo "turns=8" >> $GITHUB_OUTPUT
elif [ ${{ steps.size.outputs.files }} -le 10 ]; then
echo "model=sonnet" >> $GITHUB_OUTPUT
echo "budget=2.00" >> $GITHUB_OUTPUT
echo "turns=15" >> $GITHUB_OUTPUT
else
echo "model=sonnet" >> $GITHUB_OUTPUT
echo "budget=5.00" >> $GITHUB_OUTPUT
echo "turns=20" >> $GITHUB_OUTPUT
fi
- name: Claude Code Review
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
claude --bare \
--model ${{ steps.model.outputs.model }} \
--max-turns ${{ steps.model.outputs.turns }} \
--max-budget-usd ${{ steps.model.outputs.budget }} \
--output-format stream-json \
"审查此 PR 的代码质量和安全性" \
> review-output.json
- name: Parse and Comment
# ... 解析结果并评论8.3 成本优化检查清单
## Claude Code 成本优化检查清单
### 基础配置
- [ ] 设置 --max-budget-usd 硬性上限
- [ ] 配置 --max-turns 防止无限循环
- [ ] 配置 fallback-model 降级策略
### 日常使用
- [ ] 使用 --effort low 处理简单查询
- [ ] 精确指定文件范围,避免加载无关上下文
- [ ] 合并相关请求,减少单独调用次数
### 批量任务
- [ ] 优先使用 Haiku 进行初筛
- [ ] 启用结果缓存避免重复审查
- [ ] 并行处理时设置合理的并发数
### 团队管理
- [ ] 建立个人和项目的预算配额
- [ ] 定期审查 Token 使用报告
- [ ] 对高消耗任务进行事后分析
### CI/CD 集成
- [ ] 根据 PR 规模动态选择模型
- [ ] 设置 CI 单次调用预算上限
- [ ] 缓存已审查的 PR diff九、总结
Claude Code 的成本优化是一个系统工程,需要从多个维度入手:
核心控制手段:
--max-turns防止任务无限循环,从源头上控制 Token 消耗--max-budget-usd提供硬性熔断,确保不会超出预期花费--fallback-model实现自动降级,在性能和成本之间灵活切换--effort级别精细调节 Claude 的"努力程度",匹配任务复杂度
关键优化策略:
- 精准提示 — 减少无关上下文,Input Token 可节省 80%+
- 分层处理 — Haiku 初筛 + Sonnet 深挖,整体成本降低 50%+
- 缓存复用 — 相同 PR diff 不重复审查
- 动态选型 — 根据任务复杂度自动选择模型
- 预算监控 — 实时追踪 + 预警通知
团队级最佳实践:
- 为每个成员和项目设置预算配额
- 在 CI 中根据 PR 规模动态调整模型和预算
- 定期生成 Token 使用报告,识别优化空间
掌握这些技巧后,Claude Code 不再是一个"成本黑洞",而是一个可控、可预测、高效能的编程助手。
十、下篇预告
Claude Code 企业级部署全攻略 — 从团队配置共享到安全策略管控,从集中式 rules 管理到合规审查流程,再到 SSO 单点登录集成,手把手教你将 Claude Code 打造成符合企业规范的开发工具。