03 多协议支持:一个模型同时讲 OpenAI、Responses 和 Anthropic 三种“方言“
文章目录
03 多协议支持:一个模型同时讲 OpenAI、Responses 和 Anthropic 三种"方言"
《DeepSeek-V4-Flash 本地部署与公网服务化》系列 · 第 ③ 篇 / 共 5 篇
① 硬件选型与 llama.cpp 部署 | ② API 鉴权与腾讯云公网桥接 | ③ 多协议支持:Anthropic 与 Responses API(本篇) | ④ 稳定性与性能调优实录 | ⑤ 客户端接入:pi 与各类 SDK
llama-server 原生只说 OpenAI Chat Completions。本篇用 LiteLLM 加一层协议翻译,让同一个模型同时支持 Anthropic Messages(Claude Code 等)和 OpenAI Responses(Codex CLI 等)。
1. 架构与落点选择
OpenAI 客户端 → /v1/* → 直连 llama-server:8081(无损)
Responses 客户端 → /v1/responses → LiteLLM:8090 → llama-server:8081
Anthropic 客户端 → /anthropic/v1/* → LiteLLM:8090 → llama-server:8081
shim 放在模型机(local-server,503GB 内存)而不是跳板机——跳板机只有 945MB 内存,LiteLLM 依赖树(fastapi/uvicorn/openai/pydantic/tiktoken…)跑起来就要几百 MB。为此把 02 篇的隧道扩成双端口(8081 模型 + 8090 shim),跳板机侧 permitlisten 和 iptables 同步加 8090。
2. 安装(含两个坑)
模型机没有 python3-venv 且不想动 sudo,用 --without-pip + get-pip 引导:
python3 -m venv --without-pip ~/deepseek-v4-flash/shim-venv
curl -sSL https://bootstrap.pypa.io/get-pip.py -o /tmp/get-pip.py
~/deepseek-v4-flash/shim-venv/bin/python /tmp/get-pip.py -i https://pypi.tuna.tsinghua.edu.cn/simple
~/deepseek-v4-flash/shim-venv/bin/pip install -i https://pypi.tuna.tsinghua.edu.cn/simple \
"litellm[proxy]" "fastapi==0.115.12" "sse-starlette==2.2.1"
坑 1:litellm 1.96.2 与最新 fastapi(0.141.x)不兼容——litellm/proxy/management_endpoints/.../common.py 引用了 fastapi 0.12x 移除的内部函数 get_flat_dependant,启动即 ImportError。锁 fastapi==0.115.12 解决。
坑 2:锁了旧 fastapi 后 starlette 被拉到 0.46,而 sse-starlette 3.4.8 要求 starlette≥0.49——SSE 流式会埋雷。再锁 sse-starlette==2.2.1 对齐。
3. LiteLLM 配置
~/deepseek-v4-flash/litellm_config.yaml:
model_list:
- model_name: deepseek-v4-flash # 主名
litellm_params:
model: openai/deepseek-v4-flash # openai/ 前缀 = OpenAI 兼容端点
api_base: http://127.0.0.1:8081/v1
api_key: os.environ/DS_API_KEY # 从环境变量读, 不写死
- model_name: claude-sonnet-4-5 # 别名: Claude 系客户端不改模型名也能用
litellm_params:
model: openai/deepseek-v4-flash
api_base: http://127.0.0.1:8081/v1
api_key: os.environ/DS_API_KEY
# claude-opus-4-5 / claude-haiku-4-5 同理...
general_settings:
master_key: os.environ/DS_API_KEY # 与 llama-server 同一把 key
litellm_settings:
drop_params: true # 丢弃后端不认识的参数, 而不是报错
启动(tmux 会话 ds-shim):
cd ~/deepseek-v4-flash
DS_API_KEY=$(cat .api-key) ./shim-venv/bin/litellm \
--config litellm_config.yaml --host 127.0.0.1 --port 8090
鉴权复用同一把 API key,Authorization: Bearer 和 Anthropic 风格的 x-api-key 都接受。
4. nginx 路由细节
两个新 location(80/443 两个 server block 都加):
# Anthropic: 剥前缀 /anthropic/v1/messages -> shim /v1/messages
location ^~ /anthropic/ {
include /etc/nginx/snippets/ds-anthropic-proxy.conf; # proxy_pass http://127.0.0.1:8090/;
}
# Responses: 比 ^~ /v1/ 前缀更长所以优先, 路径原样透传
location ^~ /v1/responses {
include /etc/nginx/snippets/ds-responses-proxy.conf; # proxy_pass http://127.0.0.1:8090;
}
两个技巧:/anthropic/ 用带尾斜杠的 proxy_pass http://127.0.0.1:8090/ 做前缀剥离;/v1/responses 用无 URI 的 proxy_pass http://127.0.0.1:8090 保持原路径。nginx 前缀匹配取最长者,所以 /v1/responses 会精确切到 shim,其余 /v1/* 仍直连 llama-server。
5. 三种协议保真度实测
同一把 key、同一个模型,三条路径全部验证通过(非流式 + SSE 流式 + 无 key 拒绝):
| 能力 | Chat Completions(直连) | Responses(shim) | Anthropic(shim) |
|---|---|---|---|
| 基础对话 | ✅ | ✅ | ✅ |
| 流式 | ✅ SSE | ✅ response.created→reasoning_text.delta→… 事件完整 |
✅ message_start→content_block_delta→message_stop 完整 |
| 工具调用 | ✅ | ✅ | ✅(tool_use 块 + stop_reason: tool_use,实测让模型"查北京天气"返回标准 tool_use) |
| 思考内容 | ✅ reasoning_content 原样 |
✅ 映射为 reasoning output item |
⚠️ 丢弃(不显示,但仍消耗 max_tokens) |
| 无 key | 401 | 500(litellm 癖性,同样拒绝) | 500 |
Anthropic 路由的注意事项:思考被吞意味着 max_tokens 别给太小(<64 时可能整段输出都是隐藏思考,content 为空数组);客户端给 1024+ 就正常。
6. 客户端用法
Claude Code(Anthropic 协议):
ANTHROPIC_BASE_URL=https://api.example.com/anthropic \
ANTHROPIC_AUTH_TOKEN=<API_KEY> \
ANTHROPIC_MODEL=deepseek-v4-flash \
claude
Codex CLI(Responses 协议):
OPENAI_BASE_URL=https://api.example.com/v1 \
OPENAI_API_KEY=<API_KEY> \
codex -m deepseek-v4-flash
原生 Anthropic SDK:
import anthropic
client = anthropic.Anthropic(base_url="https://api.example.com/anthropic", api_key="<API_KEY>")
client.messages.create(model="deepseek-v4-flash", max_tokens=1024,
messages=[{"role": "user", "content": "hi"}])
建议:支持多种协议的客户端(如 pi)优先走原生 Chat Completions——少一层翻译,reasoning_content 无损。Anthropic/Responses 入口是给"只认那一种协议"的客户端准备的。
上一篇:02 API 鉴权与公网桥接 · 下一篇:04 稳定性与性能调优实录
更多推荐

所有评论(0)