精选案例 · 工程接入与部署 / Agent 自动化
a2o - Anthropic to OpenAI API Proxy
a2o 是一个单文件、零依赖的 Go 语言工具,可将 Anthropic Messages API 请求转换为 OpenAI Chat Completions 格式。支持流式/非流式响应、tool calling、thinking/reasoning blocks、多模态及前缀缓存透传。…
案例速读
该项目由 USTC 地空学院博后基于日常使用 Claude Code 的需求开发,解决了 Anthropic 到 OpenAI 协议转换的痛点。代码为单文件、零依赖,支持流式、tool calling、thinking 等高阶特性,并内置详细 debug 日志用于观察 Agent-LLM 完整交互。文档完整(含配置说明、快速开始、端点列表等),适合 USTC 用户快速部署并结合校内 DeepSeek 服务使用,也对协议理解和教学有实际价值。 建议从 「a2o - Anthropic to OpenAI API Proxy」、「项目动机」、「功能」、「兼容性」 进入正文,先确认真实任务和模型辅助过程。
- 重点看 单文件架构,易于集成和二次开发、完整协议转换逻辑(Anthropic ↔ OpenAI)可复用、debug 日志设计可直接用于其他代理调试。结合 工程接入与部署 / Agent 自动化 / API代理 / 协议转换 和「USTC 师生及研究人员、AI Agent 开发者、LLM 协议研究者」,它更适合作为任务检索后的精读材料。
- 正文目录和原始材料仍然是判断依据;导读只帮助你更快定位阅读重点。
- 首读入口
- 项目动机
- 读者
- USTC 师生及研究人员、AI Agent 开发者、LLM 协议研究者
- 复用
- 单文件架构,易于集成和二次开发
- 结构
- 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 消耗分布