慕雪的小助手正在绞尽脑汁···
慕雪小助手的总结
DeepSeek & LongCat

本文将告诉你如何配置claude-code-router转发Claude Code请求至OpenAI API格式,兼容所有OpenAI格式的平台。

1. 前情提要

上文提到过,Claude Code必须要使用Anthropic API格式才能正常调用,但是绝大部分平台还没有跟进这一兼容性API,只提供了OpenAI这个老大哥格式的API接口。所以,我们需要借助工具,把Claude Code的Anthropic API格式请求转成OpenAI的格式,就可以正常使用了。

这个工具,便是开源的claude-code-router。注意,claude-code-router是一个额外的工具,和claude-code本体没有任何关联。

开源仓库:https://github.com/musistudio/claude-code-router/

image.png

2. 配置Claude Code Router

2.1. 安装Claude Code Router

首先,你需要安装好大于18版本的node和npm(最好是安装20.x版本以上的),并且安装了Claude Code[1]

1
npm install -g @anthropic-ai/claude-code

然后,安装 Claude Code Router:

1
npm install -g @musistudio/claude-code-router

安装好了之后,可以使用ccr start命令启动claude-code-router的服务端,这便是我们需要设置到Claude Code的ANTHROPIC_BASE_URL环境变量中的值了,默认端口是localhost:3456。

本文测试使用的版本,这俩工具版本更新比较快,不保证所有版本都可用:

1
2
3
4
5
❯ claude --version
1.0.127 (Claude Code)

❯ ccr version
claude-code-router version: 1.0.50

2.2. 配置Claude Code

在终端中修改Claude Code环境变量如下,就可以让Claude Code使用Claude Code Router的转发能力了。

1
2
3
export ANTHROPIC_BASE_URL=http://127.0.0.1:3456
# 这里必须设置AUTH_TOKEN,随便弄一个值就行,不然claude code会进行检查,没有AUTH_TOKEN是不合法的,会提示让你/login登录
export ANTHROPIC_AUTH_TOKEN=12356

2.3. 配置Claude Code Router

上面我们只是下载了Claude Code Router,还需要在Claude Code Router里面进行配置,才能转发到我们想要使用的OpenAI格式端点上。

需要修改配置文件~/.claude-code-router/config.json,写入如下内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
{
"PORT": 3456,
"LOG": true,
"LOG_LEVEL": "debug",
"API_TIMEOUT_MS": 600000,
"NON_INTERACTIVE_MODE": false,
"Providers": [
{
"name": "siliconflow",
"api_base_url": "https://api.siliconflow.cn/v1/chat/completions",
"api_key": "硅基流动API KEY",
"models": [
"Qwen/Qwen3-8B"
],
"transformer": {
"use": [
[
"maxtoken",
{
"max_tokens": 8192
}
]
]
}
}
],
"Router": {
"default": "siliconflow,Qwen/Qwen3-8B",
"background": "siliconflow,Qwen/Qwen3-8B",
"think": "siliconflow,Qwen/Qwen3-8B",
"longContext": "siliconflow,Qwen/Qwen3-8B",
"longContextThreshold": 60000,
"webSearch": "siliconflow,Qwen/Qwen3-8B"
}
}

在这个配置中,Router是我们最终想要使用的模型服务,格式为提供商,模型名

提供商就是在Providers里面写好的供应商列表,其中第一个的name我设置成了siliconflow,base_url是硅基流动的OpenAI API,Claude Code Router会自动判断URL类型(OpenAI格式URL后缀都是/chat/completions),并使用内置的OpenAI格式转发器,将Anthropic API格式转换成OpenAI格式。

其他OpenAI API服务提供商也是一样的操作,你只需要修改本配置中的api_base_urlapi_key就可以了,其他什么都不用改。max_tokens的数字也可以根据你的需要修改,会直接设置到OpenAI的API中。

注意,使用Claude Code Router之后,Claude Code的环境变量ANTHROPIC_MODEL里面配置的模型已经没有任何作用了,我们的模型由Claude Code Router的Router配置决定使用哪一个模型。

2.4. 后台持久运行ccr

如果是mac和Linux设备,你可以使用两种方式后台持久运行ccr,第一种方式是nohup,系统一般都自带了。

1
nohup ccr start >> /dev/null 2>&1 &

第二种方式是我更加推荐的,用tmux在后台运行[2]

1
2
3
4
5
6
7
# 安装tmux
brew install tmux
# 开一个终端
tmux new-sesstion -s ccr
# 开始运行
ccr start
# 然后用ctrl+b d的快捷键退出tmux,或直接关闭当前终端(tmux不会终止)

windows设备我不太清楚如何让一个命令行程序后台运行,建议自己百度一下或者问AI。

3. 测试效果

写好上述配置之后,ccr restart重新启动ccr的服务,然后打开claude code,就可以看到效果了,注意图中的API Base URL必须是本地的3456端口,才能确定使用的是Claude Code Router,一定要检查一下。

image.png

可以看到,发送的hello有了正常的回答。此时我们的请求已经通过Claude Code Router,打到了硅基流动OpenAI API的服务器上,成功使用上了OpenAI API的能力。

梅开二度的解释:如果你发现在Claude Code里面使用非Claude模型咨询“你是谁”时返回了一个Claude模型的结果,不要惊讶,这也是正常情况。因为Claude Code的System Prompt里面写了让AI工具返回他自己是Claude 4 Sonet模型,所以即便你用的不是Claude模型,AI因为遵循了SP依旧返回了Claude模型的答案。不过目前看Claude Code新版本好像已经修复了这个问题了。

可以试试让AI读一个文件,测试工具调用也是OK的

image.png

至此,大功告成!

4. 额外transformer配置:合并Content数组

4.1. 啥时候需要这个transformer?

如果你在执行了上文前三点的配置之后就可以用了(发送请求和工具调用都没问题),那就不需要这个自定义的transformer。如果不能,考虑是不是你使用的OpenAI API content不支持数组的问题,尝试一下添加第四点的这个transformer插件。


下面讲一下转发OpenAI接口时,可能会遇到的情况。

相关issue:

我们最常见的OpenAI API的请求body格式如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"model": "gpt-3.5-turbo",
"messages": [
{
"role": "system",
"content": "You are a helpful, respectful and honest assistant. Always answer as helpfully as possible, while being safe. Your answers should not include any harmful, unethical, racist, sexist, toxic, dangerous, or illegal content. Please ensure that your responses are socially unbiased and positive in nature. If a question does not make sense or is not factually coherent, explain why instead of answering something not correct. If you don't know the answer to a question, please don't share false information."
},
{
"role": "user",
"content": "{{用户输入的问题或指令}}"
}
],
"temperature": 0.7,
"max_tokens": 1000,
"stream": false
}

新版本的OpenAI API格式中,content不仅可以是字符串,还可以是一个数组,如下所示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
"model": "gpt-3.5-turbo",
"messages": [
{
"role": "system",
"content": [
{
"type": "text",
"text": "You are a helpful, respectful and honest assistant. Always answer as helpfully as possible, while being safe. Your answers should not include any harmful, unethical, racist, sexist, toxic, dangerous, or illegal content. Please ensure that your responses are socially unbiased and positive in nature. If a question does not make sense or is not factually coherent, explain why instead of answering something not correct. If you don't know the answer to a question, please don't share false information."
},
{
"type": "text",
"text": "其他内容"
}
]
},
{
"role": "user",
"content": "{{用户输入的问题或指令}}"
}
],
"temperature": 0.7,
"max_tokens": 1000,
"stream": false
}

Claude Code Router正是使用这种数组的方式发送的OpenAI API请求。问题在于,并非所有OpenAI API服务提供商都兼容了content为数组的格式,这就导致可能有部分OpenAI API服务商没办法正常通过Claude Code Router转发使用。

此时,我们就需要加上Claude Code Router的自定义transformer插件能力了,自定义transformer允许我们对Claude Code Router发出的请求进行二次修改。通过一个js脚本,我们就可以把上述content为数组的情况,改成content为字符串的情况(强行合并content的数组)

4.2. 添加合并content数组的transformer

js脚本内容如下,写入~/.claude-code-router/plugins/content_array_to_text.js文件即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class ContentArrayToTextTransformer {
constructor(options = {}) {
this.name = "content-array-to-text";
}

async transformRequestIn(request) {
if (!request || !request.messages || !Array.isArray(request.messages)) {
return request;
}

// 深拷贝整个请求对象
const transformedRequest = JSON.parse(JSON.stringify(request));

for (const message of transformedRequest.messages) {
if (typeof message.content !== 'string' && Array.isArray(message.content)) {
const textParts = [];

for (const item of message.content) {
if (item.type === "text" || item.type === undefined) {
if (typeof item.text === 'string') {
textParts.push(item.text);
} else if (typeof item === 'string') {
textParts.push(item);
}
}
// 忽略非 text 类型
}

if (textParts.length > 0) {
message.content = textParts.join('\n');
}
// 如果没有 text 内容,保留原数组(或你可以设为空字符串)
}
}

return transformedRequest;
}

async transformResponseOut(response) {
return response;
}
}
// 必须要有这一行
module.exports = ContentArrayToTextTransformer;

对应修改ccr的~/.claude-code-router/config.json,用上这个transformer。

注意,配置中最后的transformers里面的path必须写死一个绝对路径,不能使用相对路径,用户家目录也不能用~替代,必须用绝对路径!你需要改成你自己的绝对路径,别直接抄我的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
{
"PORT": 3456,
"LOG": true,
"LOG_LEVEL": "debug",
"API_TIMEOUT_MS": 600000,
"NON_INTERACTIVE_MODE": false,
"Providers": [
{
"name": "openai",
"api_base_url": "https://api.siliconflow.cn/v1/chat/completions",
"api_key": "sk-xxxx",
"models": [
"Qwen/Qwen3-8B"
],
"transformer": {
"use": [
[
"maxtoken",
{
"max_tokens": 8192
}
],
"content-array-to-text"
]
}
}
],
"Router": {
"default": "openai,Qwen/Qwen3-8B",
"background": "openai,Qwen/Qwen3-8B",
"think": "openai,Qwen/Qwen3-8B",
"longContext": "openai,Qwen/Qwen3-8B",
"longContextThreshold": 60000,
"webSearch": "openai,Qwen/Qwen3-8B"
},
"transformers": [
{
"path": "/Users/mothra/.claude-code-router/plugins/content_array_to_text.js"
}
]
}

修改配置之后,ccr start重新启动ccr服务,注意检查日志中必须出现这一行,才是ok的

1
{"level":30,"time":1758979607079,"pid":58358,"hostname":"MACBOOKAIR-MOTHRA","msg":"register transformer: content-array-to-text (no endpoint)"}

如果出现了下面这种错误,说明你的transformers写的不对,需要修改!

1
{"level":50,"time":1758979551770,"pid":58108,"hostname":"MACBOOKAIR-MOTHRA","msg":"load transformer (/Users/mothra/.claude-code-router/plugins/content_array_to_text.js) \nerror: t is not a constructor\nstack: TypeError: t is not a constructor\n    at ia.registerTransformerFromConfig (/usr/local/lib/node_modules/@musistudio/claude-code-router/dist/cli.js:79015:19)\n    at ia.loadFromConfig (/usr/local/lib/node_modules/@musistudio/claude-code-router/dist/cli.js:79050:33)\n    at ia.initialize (/usr/local/lib/node_modules/@musistudio/claude-code-router/dist/cli.js:79029:68)"}

注意,transformers写的不对时,不会让ccr拒绝启动,只是ccr不会加载这个transformers!别以为终端没有出现报错就是没啥问题,一定要检查日志哦。

4.3. 测试修改后的效果

测试一下,依旧可以正常请求硅基流动,搞定了!

image.png

在日志中可以看到,我们的请求已经正常合并成一个字符串了(这里system prompt的内容很长,我只截取了开头部分)

1
2
3
4
"request": {
"method": "POST",
"headers": {},
"body": "{\"messages\":[{\"role\":\"system\",\"content\":\"You are Claude Code, Anthropic's official CLI for Claude.\\n\\nYou are an interactive CLI tool that helps users with software engineering tasks. Use the instructions below and the tools available to you to assist the user.\\n\\nIMPORTANT: Assist with defensive security tasks only. Refuse to create, modify, or improve code that may be used maliciously. Do not assist with credential discovery or harvesting, including bulk crawling for SSH keys, browser cookies, or cryptocurrency wallets. Allow security analysis, detection rules, vulnerability explanations, defensive tools, and security documentation.\\n

而添加transformer修改之前的system content部分是个数组,如下所示

1
2
3
4
"request": {
"method": "POST",
"headers": {},
"body": "{\"messages\":[{\"role\":\"system\",\"content\":[{\"type\":\"text\",\"text\":\"You are Claude Code, Anthropic's official CLI for Claude.\",\"cache_control\":{\"type\":\"ephemeral\"}},{\"type\":\"text\",\"text\":\"\\nYou are an interactive CLI tool that helps users with software engineering tasks. Use the instructions below and the tools available to you to assist the user.\\n\\nIMPORTANT: Assist with defensive security tasks only. Refuse to create, modify, or improve code that may be used maliciously. Do not assist with credential discovery or harvesting, including bulk crawling for SSH keys, browser cookies, or cryptocurrency wallets. Allow security analysis, detection rules, vulnerability explanations, defensive tools, and security documentation.\\n

5. 更多

更多Claude Code Router的配置,可以参考官方Github的文档:https://github.com/musistudio/claude-code-router/blob/main/README_zh.md


  1. claude-code安装参考:https://blog.musnow.top/posts/5046572767 ↩︎

  2. tmux的使用参考之前写过的博客:https://blog.musnow.top/posts/2203891398/ ↩︎