#!/usr/bin/env bash # 验证 zenmux 两个端点 + prompt cache 是否可用 # 用法:bash scripts/verify-zenmux.sh set -euo pipefail # 加载密钥 if [[ -f secrets.env ]]; then set -a; source secrets.env; set +a fi if [[ -z "${ZENMUX_API_KEY:-}" ]]; then echo "❌ ZENMUX_API_KEY 未设置。请 cp secrets.env.example secrets.env 并填入 key" exit 1 fi echo "============================================" echo " zenmux 端点与 prompt cache 自检" echo "============================================" # -------- 测试 1:OpenAI 兼容端点(Gemini) -------- echo "" echo "[1/3] 测试 OpenAI 兼容端点(google/gemini-2.5-pro,隐式缓存)..." RESP1=$(curl -sS -w "\n---HTTP:%{http_code}---\n" -X POST "https://zenmux.ai/api/v1/chat/completions" \ -H "Authorization: Bearer $ZENMUX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "google/gemini-2.5-pro", "messages": [{"role": "user", "content": "用一句话回答:PubMed 是什么?"}], "max_tokens": 100 }') echo "$RESP1" | tail -5 echo "" # -------- 测试 2:Anthropic 兼容端点(Claude Haiku) -------- echo "[2/3] 测试 Anthropic 兼容端点(claude-haiku-4.5)..." RESP2=$(curl -sS -w "\n---HTTP:%{http_code}---\n" -X POST "https://zenmux.ai/api/anthropic/v1/messages" \ -H "x-api-key: $ZENMUX_API_KEY" \ -H "anthropic-version: 2023-06-01" \ -H "Content-Type: application/json" \ -d '{ "model": "claude-haiku-4.5", "max_tokens": 100, "messages": [{"role": "user", "content": "用一句话回答:PubMed 是什么?"}] }') echo "$RESP2" | tail -5 echo "" # -------- 测试 3:Claude + prompt cache(Sonnet) -------- echo "[3/3] 测试 Claude prompt cache(连续 2 次请求,第 2 次应命中 cache)..." # 构造一个至少 1024 tokens 的 system prompt(约 3000 字符中文足够) LONG_PROMPT=$(printf 'You are a biomedical research assistant. ' && \ for i in $(seq 1 80); do printf 'This is test content line %d to build cacheable prefix context. ' "$i" done) PAYLOAD=$(cat </dev/null || echo "?") echo " cache_creation_input_tokens = $CACHE_CREATE" sleep 2 echo " 第 2 次调用(应命中 cache)..." R2=$(curl -sS -X POST "https://zenmux.ai/api/anthropic/v1/messages" \ -H "x-api-key: $ZENMUX_API_KEY" \ -H "anthropic-version: 2023-06-01" \ -H "Content-Type: application/json" \ -d "$PAYLOAD") CACHE_READ=$(echo "$R2" | python3 -c "import sys, json; d=json.load(sys.stdin); print(d.get('usage',{}).get('cache_read_input_tokens', 0))" 2>/dev/null || echo "?") echo " cache_read_input_tokens = $CACHE_READ" echo "" echo "============================================" echo " 结果" echo "============================================" if [[ "$CACHE_CREATE" != "0" && "$CACHE_CREATE" != "?" ]]; then echo "✅ Cache 写入成功($CACHE_CREATE tokens)" else echo "⚠️ Cache 未写入(可能是 prompt 太短或端点不支持)" fi if [[ "$CACHE_READ" != "0" && "$CACHE_READ" != "?" ]]; then echo "✅ Cache 命中成功($CACHE_READ tokens)— 成本大幅降低" else echo "⚠️ Cache 未命中(检查 AGENTS.md §6.5 诊断步骤)" fi echo "" echo "完整 usage 字段(第 2 次):" echo "$R2" | python3 -m json.tool 2>/dev/null | grep -A 10 '"usage"' || echo "$R2"