You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

5.6 KiB

allowed-tools description name
Bash(wsl -- *) Command: claude-stats (imported from Claude Code) cmd-claude-stats

Claude 模型统计

查询 Claude 模型的错误率缓存率,自动排除 relay-pulse 检测令牌。

参数 $ARGUMENTS

根据 $ARGUMENTS 确定日期范围:

传入格式 含义
(空) 今天
2026-05-09 指定某一天
2026-05-01 2026-05-09 指定日期范围(含首尾两天)
7d 最近 7 天

执行步骤

第一步:根据参数计算日期过滤条件

  • created_at 字段是秒级 Unix 时间戳(bigint),用 UNIX_TIMESTAMP('YYYY-MM-DD') 转换
  • 今天:created_at >= UNIX_TIMESTAMP(CURDATE())
  • 某一天 Dcreated_at >= UNIX_TIMESTAMP('D') AND created_at < UNIX_TIMESTAMP('D') + 86400
  • 范围 D1D2created_at >= UNIX_TIMESTAMP('D1') AND created_at < UNIX_TIMESTAMP('D2') + 86400
  • 最近 N 天:created_at >= UNIX_TIMESTAMP(DATE_SUB(CURDATE(), INTERVAL N-1 DAY))

将计算好的条件替换到下面 SQL 中的 {DATE_FILTER} 占位符。

第二步:上传 SQL 文件到服务器

wsl -- bash -c "
cat > /tmp/claude_stats_error.sql << 'ENDSQL'
SELECT
  model_name,
  SUM(CASE WHEN type = 2 THEN 1 ELSE 0 END) as success,
  SUM(CASE WHEN type = 5 THEN 1 ELSE 0 END) as errors,
  COUNT(*) as total,
  ROUND(SUM(CASE WHEN type = 5 THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 2) as error_rate_pct
FROM logs
WHERE {DATE_FILTER}
  AND model_name LIKE '%claude%'
  AND type IN (2, 5)
  AND token_name != 'relay-pulse'
GROUP BY model_name
ORDER BY total DESC;
ENDSQL

cat > /tmp/claude_stats_cache.sql << 'ENDSQL'
SELECT
  model_name,
  COUNT(*) as total_requests,
  SUM(prompt_tokens) as prompt_tokens,
  SUM(completion_tokens) as completion_tokens,
  SUM(CAST(IFNULL(JSON_UNQUOTE(JSON_EXTRACT(other, '$.cache_tokens')), 0) AS UNSIGNED)) as cache_read_tokens,
  SUM(CAST(IFNULL(JSON_UNQUOTE(JSON_EXTRACT(other, '$.cache_creation_tokens')), 0) AS UNSIGNED)) as cache_creation_tokens,
  SUM(CASE WHEN CAST(IFNULL(JSON_UNQUOTE(JSON_EXTRACT(other, '$.cache_tokens')), 0) AS UNSIGNED) > 0 THEN 1 ELSE 0 END) as cache_hit_requests,
  ROUND(
    SUM(CASE WHEN CAST(IFNULL(JSON_UNQUOTE(JSON_EXTRACT(other, '$.cache_tokens')), 0) AS UNSIGNED) > 0 THEN 1 ELSE 0 END) * 100.0 / COUNT(*),
    2
  ) as cache_hit_rate_pct,
  ROUND(
    (SUM(prompt_tokens) * 1.0
     + SUM(CAST(IFNULL(JSON_UNQUOTE(JSON_EXTRACT(other, '$.cache_tokens')), 0) AS UNSIGNED)) * 0.1
     + SUM(CAST(IFNULL(JSON_UNQUOTE(JSON_EXTRACT(other, '$.cache_creation_tokens')), 0) AS UNSIGNED)) * 1.25)
    * 100.0
    / NULLIF(
        SUM(prompt_tokens)
        + SUM(CAST(IFNULL(JSON_UNQUOTE(JSON_EXTRACT(other, '$.cache_tokens')), 0) AS UNSIGNED))
        + SUM(CAST(IFNULL(JSON_UNQUOTE(JSON_EXTRACT(other, '$.cache_creation_tokens')), 0) AS UNSIGNED)),
        0),
    2
  ) as cost_pct_of_full,
  ROUND(
    SUM(CAST(IFNULL(JSON_UNQUOTE(JSON_EXTRACT(other, '$.cache_creation_tokens')), 0) AS UNSIGNED)) * 1.0
    / NULLIF(SUM(CAST(IFNULL(JSON_UNQUOTE(JSON_EXTRACT(other, '$.cache_tokens')), 0) AS UNSIGNED)), 0),
    3
  ) as creation_to_read_ratio
FROM logs
WHERE {DATE_FILTER}
  AND type = 2
  AND model_name LIKE '%claude%'
  AND other IS NOT NULL
  AND token_name != 'relay-pulse'
GROUP BY model_name
ORDER BY total_requests DESC;
ENDSQL

cat > /tmp/claude_stats_errcode.sql << 'ENDSQL'
SELECT
  model_name,
  CAST(JSON_UNQUOTE(JSON_EXTRACT(other, '$.status_code')) AS UNSIGNED) as status_code,
  COUNT(*) as cnt,
  ROUND(COUNT(*) * 100.0 / SUM(COUNT(*)) OVER (PARTITION BY model_name), 1) as pct
FROM logs
WHERE {DATE_FILTER}
  AND type = 5
  AND model_name LIKE '%claude%'
  AND token_name != 'relay-pulse'
  AND other IS NOT NULL
GROUP BY model_name, status_code
ORDER BY model_name, cnt DESC;
ENDSQL

scp /tmp/claude_stats_error.sql root@139.180.189.205:/tmp/claude_stats_error.sql
scp /tmp/claude_stats_cache.sql root@139.180.189.205:/tmp/claude_stats_cache.sql
scp /tmp/claude_stats_errcode.sql root@139.180.189.205:/tmp/claude_stats_errcode.sql
"

第三步:执行查询并展示结果

wsl -- bash -c "ssh -o ConnectTimeout=20 -o ServerAliveInterval=10 root@139.180.189.205 'echo \"=== 错误率 ===\"; docker exec -i mysql mysql -uroot -pLanqi123456 new-api < /tmp/claude_stats_error.sql; echo; echo \"=== 缓存 ===\"; docker exec -i mysql mysql -uroot -pLanqi123456 new-api < /tmp/claude_stats_cache.sql; echo; echo \"=== 错误状态码分布 ===\"; docker exec -i mysql mysql -uroot -pLanqi123456 new-api < /tmp/claude_stats_errcode.sql' 2>&1 | grep -v 'Warning'"

字段说明

错误率表:

  • success — 正常请求数(type=2)
  • errors — 错误请求数(type=5)
  • error_rate_pct — 错误率 %

缓存率表:

  • cache_hit_rate_pct次数缓存率 = 有缓存命中的请求数 / 总请求数(最能反映缓存策略是否生效)
  • cost_pct_of_full实际成本占比 = (prompt × 1 + cache_read × 0.1 + cache_creation × 1.25) / (全量按原价计费),越低越省钱(Anthropic 标准定价:cache_read 是原价 10%,cache_creation 是原价 125%)
  • creation_to_read_ratio缓存创建/读取比 = cache_creation_tokens / cache_read_tokens,比值高说明缓存频繁失效再重建,命中复用差

错误状态码分布表:

  • status_code — HTTP 状态码(504=上游超时,429=限流,400=请求参数错误)
  • cnt — 该状态码的错误次数
  • pct — 占该模型全部错误的百分比

注意事项

  • 日期以 OV 服务器(UTC+0)的时区为准,北京时间当天 08:00 后才对应同一自然日
  • relay-pulse 是自动探活令牌,已从统计中排除