精选案例 · Agent / 实践案例
a2o - Anthropic to OpenAI API Proxy
这个案例围绕「a2o - Anthropic to OpenAI API Proxy」记录了一条真实 AI 实践线索,正文重点集中在「项目动机」「功能」,适合先按任务意图阅读再判断复用。
案例速读
README 标题「a2o - Anthropic to OpenAI API Proxy」下已经出现运行/配置路径、脚本或接口线索、结果证据,正文重点集中在「项目动机」「功能」,比纯概念介绍更适合进入精选阅读流。 这篇案例的阅读价值在于,它把真实任务、模型辅助过程和可迁移做法放在同一个上下文里,读者可以从 「a2o - Anthropic to OpenAI API Proxy」、「项目动机」、「功能」、「兼容性」 进入正文。
- 建议重点看 可参考其中的运行与配置路径、包含可迁移的命令、脚本或接口线索、已有结果或观测证据可用于判断复用价值。结合 Agent / 实践案例 和「任务驱动用户、AI 实践者」这一受众定位,它更适合作为任务检索后的精读材料,而不是只看一句短摘要后快速跳过。
- 正文目录和原始材料仍然是判断依据;导读只帮助你更快定位阅读重点。
- 看点
- a2o - Anthropic to OpenAI API Proxy
- 读者
- 任务驱动用户、AI 实践者
- 复用
- 可参考其中的运行与配置路径
- 结构
- 10 个目录入口
原文内容
a2o - Anthropic to OpenAI API Proxy
本人是地空学院博后,日常重度使用 Claude Code 辅助编程。Claude Code 的消息协议基于 Anthropic 格式,市面上类似 cc-switch 的工具过于臃肿,于是利用 DeepSeek V4 Pro 写了这个极轻量的 Anthropic → OpenAI 协议转换代理。USTC DeepSeek 现已同时支持 Anthropic 和 OpenAI 接口,因此本项目的目的转向深入了解 Agent 与大模型之间的工作流。
单文件、零依赖,通过协议转换观察 Claude Code 与 LLM 之间的完整交互过程。
项目动机
Claude Code 作为 AI 编程 Agent,通过 Anthropic Messages API 与 LLM 交互,涉及流式响应、tool calling、thinking/reasoning 等复杂协议细节。通过实现协议转换层,可以:
- 透明地观察 Agent 与模型之间的每一轮请求和响应
- 理解 tool call 的完整生命周期:定义 → 调用 → 执行 → 结果回传
- 观察流式响应中 content block 的切换逻辑(text / thinking / tool_use)
- 分析 system prompt 的组织方式和多轮对话的消息结构
功能
- 将 Anthropic
/v1/messages请求转换为 OpenAI/v1/chat/completions格式 - 支持流式/非流式响应、tool calling、thinking/reasoning blocks
- 支持多服务负载均衡、上游代理
- 请求级日志,便于调试和观察协议细节
兼容性
| 特性 | 状态 |
|---|---|
| 流式/非流式响应 | ✅ |
| Tool calling (tools + tool_use + tool_result) | ✅ |
| Thinking / reasoning blocks | ✅ |
| 多模态 (图片) | ✅ |
| 前缀缓存透传 | ✅ |
工作流
Claude Code ──Anthropic──▶ a2o ──OpenAI──▶ 上游 API (LiteLLM / 任意兼容服务)
(Agent) 格式 (协议转换) 格式
通过 a2o 的 debug 日志,可以观察到 Claude Code 发送的完整 system prompt 结构、tool 定义、以及每一轮对话中模型返回的 tool_use 和 thinking 内容。
快速开始
# 1. 编译
go build -o a2o main.go
# 2. 配置
cp config.example.json config.json
vim config.json
# 3. 运行
./a2o -config config.json
# 4. 测试
curl -s http://localhost:9999/v1/messages \
-H "x-api-key: your-client-auth-key-here" \
-H "anthropic-version: 2023-06-01" \
-d '{"model":"deepseek-chat","max_tokens":50,"messages":[{"role":"user","content":"hi"}]}'
配置说明
{
"debug_level": "info",
"auth_token": "client-auth-key",
"services": [
{
"comment": "ustc_deepseek",
"listen_address": "9999",
"openai_base_url": "https://api.llm.ustc.edu.cn/v1/chat/completions",
"openai_api_key": "sk-xxx",
"force_model": "",
"upstream_proxy": ""
}
],
"round_robin_address": "",
"timeout_seconds": 300
}
| 字段 | 说明 |
|---|---|
debug_level |
"info" 或 "debug"(输出请求/响应详情) |
auth_token |
a2o 自身的鉴权密钥,客户端需在 x-api-key 或 Authorization: Bearer 头中提供。注意:这是 Claude Code → a2o 之间的密钥,不是发往上游的 API key |
services[].listen_address |
a2o 监听端口(如 9999) |
services[].openai_base_url |
上游 API 地址,需以 /v1/chat/completions 结尾 |
services[].openai_api_key |
上游 API 密钥,a2o 发往上游时使用 |
services[].force_model |
可选,强制覆盖客户端请求的 model 名称 |
round_robin_address |
可选,多服务负载均衡端口 |
timeout_seconds |
上游请求超时时间,默认 300 |
对接 Claude Code
设置 Claude Code 的环境变量指向 a2o:
export ANTHROPIC_AUTH_TOKEN=client-auth-key
export ANTHROPIC_BASE_URL=http://localhost:9999
注意:ANTHROPIC_AUTH_TOKEN 需与 config.json 中的 auth_token 一致,ANTHROPIC_BASE_URL 不需要 /v1 后缀。
端点
| 路径 | 说明 |
|---|---|
POST /v1/messages |
主代理端点 |
GET /health |
健康检查 |
POST /v1/messages/count_tokens |
Token 估算 |
调试
config.json 中设置 "debug_level": "debug" 即可观察完整的请求/响应流:
[deepseek-chat] 📥 Request: model=deepseek-chat, messages=3, tools=12
[deepseek-chat] 📤 Response: 50432 prompt tokens, 512 completion tokens
[deepseek-chat] 💾 Prefix Cache Hit: 50432 cached tokens (vLLM)
[deepseek-chat] 🔗 Cache Header: HIT
通过日志可以观察:
- Claude Code 发送的 system prompt 规模和 tool 定义数量
- 模型返回的 thinking 内容和 tool call 参数
- 缓存命中情况和 token 消耗分布