JetBrains AI (Grazie) 网关代理,把 Grazie 封装成 Anthropic / OpenAI / Google / xAI 四套官方协议端点。任何官方 SDK 只改 base_url 即可使用 Claude、GPT、Gemini、Grok。
docker run -d -p 8080:8080 \
-e PORT=8080 \
-e LOG_LEVEL=info \
-v ./data:/app/data \
ghcr.io/kao0312/air-proxy:latestToken 缓存持久化在 data/tokens.db (SQLite, WAL mode),务必挂载 ./data 保证重启不丢已刷新的 JWT。
| 变量 | 默认值 | 说明 |
|---|---|---|
PORT |
8080 |
监听端口 |
LOG_LEVEL |
info |
日志等级: debug / info / warn / error |
UPSTREAM_HOST |
https://api.app.prod.grazie.aws.intellij.net |
Grazie 上游地址 |
UPSTREAM_PROXY |
(空) | 上游 HTTP / SOCKS5 代理。中国大陆等被墙地区必填,否则上游返回 451。例: http://127.0.0.1:10808、socks5h://127.0.0.1:1080 |
REFRESH_INTERVAL_SECONDS |
3600 |
后台扫描续期间隔 |
REFRESH_THRESHOLD_SECONDS |
86400 |
距离过期 < 此值时触发续期 |
MAX_REFRESH_FAILURES |
3 |
连续刷新失败 N 次后标记 DEAD |
MAX_REQUEST_BODY_MB |
32 |
请求体上限 |
STORE_ENABLED |
true |
设为 false 关闭 SQLite 持久化 |
认证方式: 把 Grazie JWT 当成 API Key,放到 Authorization: Bearer ... 头里即可。JWT 怎么拿见 docs/13-jwt-bootstrap.md。
from anthropic import Anthropic
client = Anthropic(base_url="http://localhost:8080", api_key="<grazie-jwt>")
client.messages.create(
model="claude-opus-4-7",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello"}],
)from openai import OpenAI
client = OpenAI(base_url="http://localhost:8080/v1", api_key="<grazie-jwt>")
client.chat.completions.create(
model="gpt-5.5",
messages=[{"role": "user", "content": "Hello"}],
)import google.generativeai as genai
genai.configure(
api_key="<grazie-jwt>",
transport="rest",
client_options={"api_endpoint": "http://localhost:8080"},
)
genai.GenerativeModel("gemini-3.1-pro-preview").generate_content("Hello")curl http://localhost:8080/v1/chat/completions \
-H "Authorization: Bearer <grazie-jwt>" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-opus-4-7",
"stream": true,
"messages": [{"role": "user", "content": "Hello"}]
}'curl http://localhost:8080/v1/models| 路径 | 协议 | 上游 vendor |
|---|---|---|
POST /v1/messages |
Anthropic Messages | Anthropic |
POST /v1/messages/count_tokens |
Anthropic Messages | Anthropic |
POST /v1/chat/completions |
OpenAI Chat Completions | OpenAI |
POST /v1/responses |
OpenAI Responses | OpenAI |
POST /v1beta/models/{model}:generateContent |
Vertex AI generateContent | |
POST /v1beta/models/{model}:streamGenerateContent |
Vertex AI streaming | |
POST /xai/v1/responses |
xAI Responses | xAI |
GET /v1/models |
OpenAI 兼容模型列表 | — |
GET /health |
健康检查 | — |
每个端点只接受自己 vendor 的模型,纯 1:1 字节级透传,不做协议翻译。
| 厂商 | 代表型号 |
|---|---|
| Anthropic | claude-opus-4-7 / claude-sonnet-4-6 / claude-haiku-4-5-20251001 等 8 款 Claude 4 系列 |
| OpenAI Chat | gpt-4o / gpt-4.1 / gpt-5 / gpt-5.5 全系列含日期快照 |
| OpenAI Responses | o1 / o3 / o4-mini / gpt-5*-pro / gpt-5*-codex 系列 |
gemini-2.5-pro / gemini-3-flash-preview / gemini-3.1-pro-preview 等 9 款 |
|
| xAI | grok-4-0709 / grok-4-1-fast-reasoning / grok-4.3 等 6 款 |
完整清单访问 GET /v1/models,或查看 src/models.go。
- JWT 自动续期:用户首次提交的 JWT 进入 SQLite + 内存缓存,后台 worker 每
REFRESH_INTERVAL_SECONDS扫一次,剩余 <REFRESH_THRESHOLD_SECONDS即续期。客户端 SDK 永远拿同一个 key,过期了也照用。 - Singleflight 启动:同一 token 并发首次请求合并为一次 bootstrap,避免重复打到上游
/auth/jwt/refresh。 - DEAD 状态隔离:连续刷新失败超阈值或上游对最新 JWT 仍返回 401,整条 entry 直接 DEAD,后续请求快速失败而非反复打爆上游。
- 字节级透传:请求 / 响应体不解析、不重写,SSE 按 chunk 即时 flush,vendor 协议特性(Anthropic
tool_useblocks、Googleparts、OpenAIreasoning块)完整保留。 - 多 header 兼容:
Authorization: Bearer/x-api-key/Grazie-Authenticate-JWT/x-goog-api-key/?key=任一都能识别,匹配各家 SDK 默认行为。 - OAuth / 上游专用代理:
UPSTREAM_PROXY支持http、https、socks5、socks5h,被墙地区一行解决 451。 - Vendor 风格错误:对 Anthropic 返回
{"type":"error",...}、对 OpenAI 返回{"error":{"message",...}}、对 Google 返回{"error":{"code","status",...}},SDK 异常解析无缝。