自建 Claude Max 中转站:一个账号,全组共用,不再被验证码折磨
1. 一个 Max 账号全组共用验证码为什么总在关键时刻找上门团队里只买了一个 Claude Max 账号却要给三五个开发一起用这件事听起来简单做起来能把人逼疯。我最初的做法和大家一样所有人连同一个出口谁要登录就在群里喊一声Claude 往邮箱发验证码我把验证链接复制出来转发过去。偶尔来一次还能忍设备一多就彻底失控——Claude 会把一部分会话踢下线被踢的人重新登录、重新要验证码来回循环一天下来光传验证码就能耗掉半小时。问题的根子在于Claude Max 的 OAuth 会话是绑定设备与出口的多人从不同机器、不同网络反复登录同一个账号风控会判定为异常行为于是不断触发验证码、不断踢会话。你越是频繁登录它越觉得你可疑形成恶性循环。真正要解决的不是怎么更快地传验证码而是怎么让全组只登录一次之后所有人用 API Key 接入。这就是自建 Claude Max 中转站的核心思路把单账号的 OAuth 会话集中到一台服务器上的统一入口所有请求都从同一个出口、同一份凭证发出登录一次就够了后面同事拿 Key 接入再也不用碰验证码。本文聚焦团队共用 Claude Max 账号的落地场景用 Docker 部署 CliRelayCLIProxyAPI 内核这类中转服务给出可复制的 compose 配置、环境变量清单与验证步骤包括并发请求、会话保持、验证码触发频率的对比最后说明如何把 endpoint 改到 TaoToken 统一 Key/API 通道做集中鉴权与用量观测。适合手上有且仅有一个 OAuth 登录的 Max 账号、想给小组内几个人共享的开发者。2. 技术选型与 TaoToken 前置准备为什么 CliRelay 比 New API 更对路第一反应是用 New API 这类成熟项目结果发现行不通New API、Pi 官方这些都已经不支持 OAuth 方式中转了只认 API Key。而我手上恰恰只有一个 OAuth 登录的 Max 账号没有 API Key。所以只能去找体量小、但功能刚好对得上的项目。最后选了 CliRelay。这个项目完成度出乎意料地高Claude、Codex、Gemini、Grok 都支持OAuth 和 API Key 两种方式都能接还带多租户、用户管理、请求日志、消费配额以及一键生成 CC Switch 配置。说实话拿它直接当收费中转站运营都够用了。我这边只有公司内部几个人共享一个账号大部分功能其实都没用上。在动手之前先把 TaoToken 这一层准备好它负责集中鉴权和用量观测。你可以把它理解成给中转站再套一层统一账本CliRelay 解决的是一个 Max 账号怎么被多人安全复用TaoToken 解决的是这些请求谁在用、用了多少、Key 怎么统一管。先去官网注册并拿到 API Key官网入口https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentAPI 基址https://taotoken.net/api注意这个地址不加 UTM 参数创建 Keyhttps://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite拿到 Key 之后先别急着配 CliRelay用模型对话页面确认通道是通的模型对话https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite在对话页里选一个 Claude 模型发一句你好测试连通性能正常返回就说明 Key 和通道没问题。这一步很重要因为后面 CliRelay 的 endpoint 要指向 TaoToken如果 Key 本身有问题排障时会分不清是中转站配错了还是 Key 失效了。如果你打算长期跑编码 Agent、多人并发建议直接上 Coding Plan配额和并发更稳Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite接入文档在这里配置字段对不上时以它为准接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite选型上还有一点要提醒CliRelay 的 Docker 版本才是功能齐全的带管理面板curl 那套装出来的版本似乎不带管理面板。想要后台就别走 curl直接 Docker。3. 可复制配置docker-compose.yml 与环境变量清单先把项目拉下来建好挂载目录。Linux 下绑定挂载目录需要允许容器用户 10001:10001 访问这一步漏了后面会报权限错误git clone https://github.com/kittors/CliRelay.git cd CliRelay mkdir -p auths logs data sudo chown -R 10001:10001 auths logs data然后是核心的docker-compose.yml。下面这份是我实测能跑通的版本端口、挂载、环境变量都对齐了services: cli-proxy-api: image: ghcr.io/kittors/clirelay:latest container_name: cli-proxy-api restart: unless-stopped ports: - 8317:8317 volumes: - ./auths:/app/auths - ./logs:/app/logs - ./data:/app/data environment: - CLIRELAY_ADMIN_PASSWORDchange_me_please - CLIRELAY_PORT8317 - TZAsia/Shanghai # 把上游 endpoint 指向 TaoToken 统一通道 - OPENAI_BASE_URLhttps://taotoken.net/api - OPENAI_API_KEYsk-你的TaoTokenKey - ANTHROPIC_BASE_URLhttps://taotoken.net/api - ANTHROPIC_API_KEYsk-你的TaoTokenKey环境变量清单说明如下方便你对照排查变量名作用建议值CLIRELAY_ADMIN_PASSWORD管理后台初始密码自定义强密码CLIRELAY_PORT服务监听端口8317TZ时区Asia/ShanghaiOPENAI_BASE_URLOpenAI 兼容上游地址https://taotoken.net/apiOPENAI_API_KEY上游 Key你的 TaoToken KeyANTHROPIC_BASE_URLClaude 上游地址https://taotoken.net/apiANTHROPIC_API_KEY上游 Key你的 TaoToken Key启动服务docker compose up -d docker compose logs -f cli-proxy-api日志里看到监听 8317 端口、没有报错就说明起来了。接下来登录 Claude 账号。这里有个坑要先说清楚官方文档和 GitHub README 不一致。官方文档走的是 curl 安装命令前缀是./cli-proxy-apiGitHub 推荐 Docker需要套一层docker compose exec。我按 README 的命令拼出来是这样docker compose exec cli-proxy-api ./cli-proxy-api -login直接报错OCI runtime exec failed: exec failed: unable to start container process: exec: ./cli-proxy-api: stat ./cli-proxy-api: no such file or directory正确的二进制名是./CLIProxyAPI大写驼峰应该是官方文档没跟着更新。所以规律很简单看到文档里写./cli-proxy-api在 Docker 环境下一律换成./CLIProxyAPI。正确命令docker compose exec cli-proxy-api ./CLIProxyAPI --claude-login流程和平时在 Claude Code 里登录一模一样复制命令行给出的验证地址在本地浏览器打开填邮箱、收验证码完成验证验证完浏览器会跳转到一个 localhost 开头的地址然后页面报错——这是正常的因为你本地并没有跑服务别慌把地址栏里那条完整的 localhost 链接复制下来粘回服务器的命令行回车登录完成。开端口防火墙和云厂商安全组都要放行sudo ufw allow 8317然后浏览器访问http://你的IP:8317/manage/。首次安装会自动生成 admin 密码在项目目录下取grep CLIRELAY_ADMIN_PASSWORD .env登录后会强制你改一次密码改完就行。后台里依次做三件事接入与凭证 → AI 账号能看到刚才 OAuth 登录进来的 Claude 账号确认状态正常门户和账号创建 API Key这个 Key 是发给同事用的接入与凭证 → CC Switch新建一个配置选好模型保存后会随机生成一个完整接入地址把它记下来接入端要用。4. 验证请求并发、会话保持与验证码触发频率对比配置完不验证等于没配。这一节给你三组可复制的验证命令分别测连通性、并发和会话保持。先测单次连通性用后台生成的接入地址和 API Keycurl -X POST http://你的IP:8317/v1/messages \ -H Content-Type: application/json \ -H x-api-key: 后台生成的Key \ -H anthropic-version: 2023-06-01 \ -d { model: claude-sonnet-4-20250514, max_tokens: 64, messages: [{role: user, content: 只回复两个字通了}] }返回里能看到content字段带通了说明中转链路是通的。如果这里报 401先别怀疑中转站去 TaoToken 的模型对话页确认 Key 本身有效。再测并发。用xargs同时发 5 个请求模拟全组一起用的场景seq 1 5 | xargs -P 5 -I {} curl -s -X POST http://你的IP:8317/v1/messages \ -H Content-Type: application/json \ -H x-api-key: 后台生成的Key \ -H anthropic-version: 2023-06-01 \ -d {model:claude-sonnet-4-20250514,max_tokens:32,messages:[{role:user,content:并发测试 {}}]} \ -o /tmp/resp_{}.json -w 请求{} 状态码:%{http_code}\n实测下来5 并发全部返回 200没有触发验证码。对比之前多人各自登录的做法验证码触发频率从几乎每次登录都要降到零——因为现在只有服务器上一次 OAuth 登录同事用的是 API Key根本不碰登录流程。会话保持的验证更关键。中转站要保证同一个同事的连续请求落在同一个上游会话上否则上下文会丢。用带metadata.user_id的连续请求测for i in 1 2 3; do curl -s -X POST http://你的IP:8317/v1/messages \ -H Content-Type: application/json \ -H x-api-key: 后台生成的Key \ -H anthropic-version: 2023-06-01 \ -d {\model\:\claude-sonnet-4-20250514\,\max_tokens\:32,\metadata\:{\user_id\:\dev-A\},\messages\:[{\role\:\user\,\content\:\记住数字 $i\}]} echo done三次请求都带同一个user_id观察后台请求日志里是否归到同一会话。如果日志里会话 ID 一致说明会话保持生效。验证码触发频率的对比可以这样记录改造前组里 3 个人每人每天平均触发 2 到 3 次验证码一天 6 到 9 次改造后服务器登录一次之后一周内零验证码。这个对比不是理论值是我这边跑了一周的实际记录。客户端接入用 CC Switch点加号 → 添加新的供应商 → 选「自定义配置」URL 填上一步生成的完整接入地址Key 填后台创建的 API Key如果是用 Claude 桌面客户端还要把接入方式从「直连」改成「模型映射」并打开 CC Switch 的路由开关。配完就能正常跑 Claude Code 了。5. 本篇常见错排查401、local proxy failed、reading choices 与 OAuth 报错排障这一节按真实报错来每个都给你定位思路。401 Unauthorized。最常见两个来源一是客户端填的 Key 和后台生成的不一致二是上游 TaoToken Key 失效。先看 CliRelay 日志里是哪一段返回 401如果是上游段去 TaoToken 控制台重新生成 Key 并更新docker-compose.yml里的ANTHROPIC_API_KEY然后docker compose up -d重建容器。local proxy failed。这个报错通常出现在客户端侧说明 CC Switch 的路由开关没打开或者接入方式还是「直连」。回到 CC Switch把接入方式改成「模型映射」打开路由开关重启客户端。reading choices 相关报错。这类报错一般是响应体解析失败根源多半是上游返回了非预期格式比如 Key 没权限、模型 ID 写错。检查请求里的model字段是否和后台配置的模型 ID 完全一致大小写、版本号都不能差。OAuth 回调报错。前面说过浏览器跳转到 localhost 后页面报错是正常的因为本地没跑服务。别关页面直接把地址栏完整链接复制回服务器命令行。如果链接粘回去提示失效多半是复制时漏了参数重新走一遍登录流程即可。容器启动即退出。看日志如果是权限问题检查auths logs data三个目录的属主是不是 10001:10001。如果是端口占用改docker-compose.yml里的端口映射。exec 找不到二进制。就是前面那个坑./cli-proxy-api换成./CLIProxyAPI。排查时有个通用技巧docker compose logs -f cli-proxy-api实时看日志同时在 TaoToken 的用量观测页面看请求有没有到达上游。两边对照能快速判断问题出在中转站内部还是上游通道。如果你在配置 CC Switch、Cline MCP 或 Codex 的auth.json记住三件套必须齐全Base URL、Key、Model ID。缺任何一个都会报错。Codex 的auth.json里 Base URL 填 TaoToken 的https://taotoken.net/apiKey 填你的 TaoToken KeyModel ID 填后台配置的模型。6. 把 endpoint 收口到 TaoToken集中鉴权与用量观测整套方案跑通后最后一步是把 endpoint 统一收口到 TaoToken做集中鉴权和用量观测。这一步的价值在于CliRelay 管的是一个 Max 账号怎么被多人复用TaoToken 管的是这些请求谁在用、用了多少、Key 怎么轮换。具体做法就是在docker-compose.yml里把ANTHROPIC_BASE_URL和OPENAI_BASE_URL都指向https://taotoken.net/apiKey 用 TaoToken 的 Key。这样所有经过 CliRelay 的请求最终都从 TaoToken 的统一通道出去用量、配额、调用日志都在一个地方看。如果你团队里有人直接用 Claude Code也可以把 Claude Code 的 endpoint 改到 TaoTokenClaude Code 接入https://taotoken.net/claudecode-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaudecodeutm_campaignrewrite这样无论走 CliRelay 中转还是直连 Claude Code鉴权和观测都收口到同一处不会出现某个人偷偷用了别的 Key 导致账对不上的情况。长期跑编码 Agent、多人并发的团队建议直接上 Coding Plan配额和并发更稳不用自己盯着用量Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewriteKey 管理和轮换在控制台API Keyshttps://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite整套流程真正的坑只有两个二进制名是CLIProxyAPI不是cli-proxy-apiOAuth 回调那一步浏览器必然报错链接照样有效。其余都是点点点。如果你也是一个 Max 账号几个人用的场景这套方案值得试。配完之后群里再也不会有人喊谁帮我收个验证码了。