AIClient-2-API:开源AI网关实现多模型统一调用与协议转换 1. 项目概述一个为开发者而生的AI API统一网关如果你和我一样是个喜欢折腾各种AI模型但又对官方API的调用限制、高昂成本或者复杂的客户端绑定感到头疼的开发者那么今天分享的这个项目绝对能让你眼前一亮。我最近深度体验并部署了AIClient-2-API简称A2它本质上是一个功能强大的API代理网关。它的核心价值在于能够将那些原本只能在特定客户端比如Gemini CLI、Kiro、Antigravity等里使用的免费或受限大模型服务通过技术手段“解放”出来封装成标准的、兼容OpenAI API格式的本地接口。这意味着什么意味着你手头那些基于OpenAI API开发的工具比如NextChat、Cherry-Studio、Cline或者你自己写的脚本现在可以无缝、免费地调用Claude 4.5 Opus、Gemini 3.0 Pro、Grok 4这些顶级模型了。你不用再为每个模型单独写适配代码也不用担心客户端的配额限制。A2就像一个万能翻译官和调度中心帮你统一管理智能调度。我之所以花时间研究它是因为在实际开发中多模型切换和成本控制是刚需。官方API固然稳定但成本不菲而一些客户端提供的免费额度或内部接口又往往有诸多限制。A2的出现巧妙地找到了一个平衡点。它基于Node.js构建采用策略和适配器模式架构清晰扩展性强。内置的账户池管理、智能轮询、健康检查和故障转移机制更是将服务的可用性提升到了生产级别。接下来我就结合自己的部署和踩坑经验为你详细拆解这个项目的核心设计、实操要点以及那些官方文档里不会写的“坑”。2. 核心架构与设计思路拆解2.1 为什么需要这样一个“统一网关”在深入代码之前我们先聊聊需求。当前AI模型市场百花齐放但接入方式却五花八门官方API标准但贵且有速率限制。客户端绑定如Gemini CLI、Kiro客户端提供免费或低成本访问但必须通过特定客户端软件无法集成到自己的应用流水线中。内部接口如Google的Antigravity性能强大但通常不对外开放访问方式隐蔽且不稳定。对于开发者而言理想状态是用一个统一的、标准的接口最好是OpenAI格式去调用所有我感兴趣的模型并且成本可控稳定性高。A2正是瞄准了这个痛点。它的设计哲学不是创造新的API标准而是做“向下兼容”的桥梁将非标准的、客户端的、内部的API“翻译”成业界事实标准——OpenAI API。2.2 核心模块策略模式与适配器模式的精妙结合翻看A2的源码你会发现它的核心架构非常清晰主要围绕两个设计模式展开1. 策略模式 (Strategy Pattern) - 管理“怎么调用”这是处理不同提供商Provider的核心。每个提供商如gemini-cli-oauth,claude-kiro-oauth都是一个独立的策略类。这些类都实现了一套相同的接口比如sendMessage,handleStream等。当请求进来时路由层会根据配置或路径选择对应的策略来执行实际的API调用。这样做的好处是新增一个提供商只需要新增一个策略类对原有系统入侵极小。我在阅读代码时注意到每个策略类内部都封装了针对该提供商特有的认证逻辑OAuth、Cookie、请求构造和响应解析隔离做得非常好。2. 适配器模式 (Adapter Pattern) - 解决“格式不同”不同模型的原始API返回的数据结构天差地别。适配器的任务就是把千奇百怪的响应转换成统一的OpenAI兼容格式。例如Claude API返回的可能是content块数组而Gemini返回的是candidates。A2中为每个提供商策略配套了相应的适配器确保最终输出给客户端的数据结构是一致的如choices[0].message.content。这保证了上游应用无需做任何修改。3. 账户池管理 (Provider Pool Manager) - 实现高可用这是A2的另一个亮点。对于支持多账户的提供商比如你可以配置多个Gemini OAuth账户A2引入了池化管理器。它不仅仅是一个简单的列表而是包含了健康检查定期探测账户是否可用网络、配额、Token有效性。智能轮询默认采用加权轮询可以根据账户的健康状态、历史成功率动态调整权重将请求优先发给更稳定的账户。故障转移当某个账户连续失败或返回429速率限制时自动将其标记为“不健康”并从可用池中暂时移除等待恢复。缓冲队列与去重在高并发场景下对刷新Token等操作进行排队和去重避免重复请求导致账户被风控。这种设计使得单个服务点的故障不会导致整个服务不可用极大地提升了服务的鲁棒性。我在压力测试时模拟一个账户被限速请求几乎无感地切换到了池中的另一个账户。2.3 协议转换OpenAI、Claude、Gemini的三方会谈A2支持三种主流协议间的智能转换OpenAI、ClaudeAnthropic格式、Gemini。这不仅仅是格式转换还涉及到底层HTTP请求头和路由的映射。请求路由通过请求路径来区分。例如发送到/v1/chat/completions的请求会被当作OpenAI格式处理发送到/claude-kiro-oauth/v1/messages的则被当作Claude格式处理。路由层会解析后交给对应的提供商策略。参数映射不同协议的参数名不同。比如OpenAI的max_tokens对应Claude的max_tokens对应Gemini的maxOutputTokens。适配器需要完成这些字段的映射和转换。流式响应三种协议都支持Server-Sent Events (SSE) 流式输出但数据块格式不同。A2的流式处理器需要实时转换并保持流式传输的完整性这对代码的健壮性要求很高。我在测试流式对话时发现它的转换非常平滑没有出现断流或格式错乱。3. 从零到一的完整部署与配置实战理论讲完了我们上手实操。我会以最推荐的Docker部署方式为例带你走通全流程并穿插讲解每个步骤背后的原理和注意事项。3.1 环境准备与Docker部署首先确保你的机器上已经安装了Docker和Docker Compose。这是最干净、依赖问题最少的部署方式。步骤一拉取镜像并启动容器官方提供了预构建的Docker镜像我们直接运行即可。下面这个命令是一个“全能”启动命令映射了所有可能用到的端口docker run -d \ -p 3000:3000 \ -p 8085:8085 -p 8086:8086 \ -p 1455:1455 \ -p 19876:19880 \ --restartalways \ -v /path/to/your/configs:/app/configs \ --name aiclient2api \ justlikemaki/aiclient-2-api:latest参数逐行解析-d: 后台运行容器。-p 3000:3000: 将容器的3000端口Web管理界面映射到宿主机的3000端口。-p 8085:8085 -p 8086:8086:这是关键8085和8086端口分别用于Gemini和Antigravity的OAuth回调。OAuth授权完成后Google服务器会回调到这些端口。如果没映射授权会失败。-p 1455:1455: Codex OAuth的回调端口。-p 19876:19880: Kiro OAuth的回调端口范围。--restartalways: 设置容器随Docker守护进程启动而启动保证服务长期运行。-v /path/to/your/configs:/app/configs:极其重要将宿主机的一个目录挂载到容器的/app/configs。所有配置文件、授权凭证都会保存在这里。即使容器销毁你的配置也不会丢失。请将/path/to/your/configs替换为你本地真实的、有读写权限的目录路径例如~/aiclient-configs。--name aiclient2api: 给容器起个名字方便管理。步骤二访问Web管理界面容器启动后在浏览器中访问http://你的服务器IP:3000。默认登录密码是admin123。强烈建议首次登录后立即在管理界面修改密码或者按照提示在宿主机挂载目录下的pwd文件中修改。实操心得端口冲突排查如果启动失败最常见的原因是端口被占用。可以用netstat -tulpn | grep :3000(Linux) 或lsof -i :3000(macOS) 查看哪个进程占用了端口。解决冲突后修改命令中的宿主机端口号如-p 3001:3000即可。3.2 核心配置详解以Gemini和Kiro为例登录Web UI后左侧导航栏找到“配置”页面。这里可以可视化地配置所有提供商。我们以配置Gemini CLI OAuth和Kiro为例。1. 配置Gemini CLI OAuth原理Gemini CLI是Google官方命令行工具通过OAuth 2.0授权。A2模拟了这个过程获取到访问令牌后就能以程序化方式调用Gemini API。操作在“配置”页面找到“Gemini CLI OAuth”板块。点击右上角的“生成授权”按钮。系统会弹出一个对话框并尝试在浏览器打开一个Google OAuth授权页面。你需要确保运行A2的服务器或本地机器其8085端口能被公网访问或至少能被你的浏览器访问否则回调会失败。对于本地部署这通常没问题对于服务器部署你可能需要设置反向代理或使用ngrok等工具进行内网穿透。使用你的Google账号登录并授权。成功后页面会提示授权完成A2后端会自动将凭证文件保存到挂载的configs目录下的~/.gemini/oauth_creds.json容器内路径实际文件在宿主机挂载点内。注意事项项目ID有些Gemini API调用需要有效的Google Cloud项目ID。你可以在Web UI的配置项中填写也可以通过启动参数--project-id传入。这个ID需要和你授权时使用的Google Cloud项目一致。凭证过期OAuth令牌会过期。A2的账户池管理器内置了令牌刷新逻辑会在令牌快过期时自动刷新无需手动干预。2. 配置Kiro API原理Kiro是一个第三方客户端提供了访问Claude等模型的通道。A2通过读取Kiro客户端生成的本地认证令牌文件来模拟其请求。操作你需要在你的设备上可以是另一台电脑安装并登录Kiro客户端。登录成功后它会在本地生成一个认证令牌文件。在A2的Web UI“配置文件”页面你可以直接上传这个令牌文件通常位于~/.aws/sso/cache/kiro-auth-token.json。系统会自动将其放入正确的位置。或者你也可以手动将该文件复制到宿主机挂载目录的对应路径下例如你的挂载目录/.aws/sso/cache/kiro-auth-token.json。在“配置”页面启用Kiro提供商并确保其Base URL等配置正确。最佳实践Kiro与Claude Code搭配使用体验最佳。在A2中你可以将请求路由到claude-kiro-oauth这个提供商来使用Claude模型。重要Kiro的服务条款和可用性可能变化使用时请关注其官方公告。不建议用于核心生产业务。3.3 账户池与故障转移高级配置单个账户容易遇到限速。A2的账户池功能让你可以配置多个同类型账户实现负载均衡和故障转移。1. 创建账户池配置文件在宿主机挂载的configs目录下参考provider_pools.json.example创建一个provider_pools.json文件。{ gemini-cli-oauth: [ { uuid: gemini-account-1, credentialsPath: /app/configs/.gemini/oauth_creds_account1.json, checkHealth: true, weight: 10 }, { uuid: gemini-account-2, credentialsPath: /app/configs/.gemini/oauth_creds_account2.json, checkHealth: true, weight: 10 } ], claude-kiro-oauth: [ { uuid: kiro-account-1, credentialsPath: /app/configs/.aws/sso/cache/kiro-auth-token-1.json, checkHealth: true } ] }2. 在主配置中启用在Web UI的“配置”页面找到“高级设置”或直接修改configs/config.json设置PROVIDER_POOLS_FILE_PATH为./configs/provider_pools.json。3. 跨类型故障转移 (Fallback)这是更高级的用法。当某个类型如gemini-cli-oauth的所有账户都不可用时可以自动回退到另一个兼容的类型如gemini-antigravity。 在configs/config.json中配置{ providerFallbackChain: { gemini-cli-oauth: [gemini-antigravity], claude-kiro-oauth: [claude-custom] } }这个配置意味着当所有Gemini CLI账户都挂了请求会自动尝试用Antigravity账户处理Kiro挂了就回退到自定义的Claude端点。3.4 TLS Sidecar攻克Cloudflare 403封锁像Grok这类服务会对TLS指纹JA3/JA4进行严格校验直接使用编程语言的HTTP库访问会返回403。A2集成了一个基于Go uTLS的Sidecar代理来解决这个问题。对于Docker用户最简单 官方镜像已经内置了编译好的tls-sidecar二进制文件。你只需要在Web UI“配置”页面中找到“TLS Sidecar”选项并启用它即可。系统会自动在后台启动这个代理进程并将Grok等需要绕过检测的请求路由过去。对于本地运行用户 你需要手动编译这个组件。确保安装了Go (1.20)。在项目根目录下执行cd tls-sidecar go build -o tls-sidecar确保生成的tls-sidecarWindows下为tls-sidecar.exe文件位于项目根目录或tls-sidecar目录下。在配置中启用TLS_SIDECAR_ENABLED。它的原理是使用Go的uTLS库模拟最新版Chrome浏览器的TLS握手特征从而骗过Cloudflare的检测。启用后对于配置了使用Sidecar的提供商请求会先发往本地的Sidecar代理默认端口9090由它完成“伪装”后的请求再将结果返回给A2主服务。4. 集成使用与客户端配置配置好A2之后如何用它呢非常简单因为它提供的是OpenAI兼容接口。4.1 直接通过cURL测试假设你的A2运行在http://localhost:3000并且配置好了Gemini提供商。curl http://localhost:3000/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer any-string-here \ # A2默认不验证此字段可任意填写 -d { model: gemini-2.0-flash-exp, # 指定你想用的模型 messages: [ {role: system, content: You are a helpful assistant.}, {role: user, content: Hello, how are you?} ], stream: false }你会收到一个标准的OpenAI格式的响应。注意model字段你需要填写A2所支持的具体模型标识符可以在Web UI的提供商配置里看到。4.2 在NextChat、Cherry-Studio等客户端中使用以NextChat为例打开NextChat设置找到“模型提供商”或“自定义接口”设置。将“接口地址”设置为http://你的A2服务器地址:3000/v1。API Key可以任意填写如果A2未启用密钥验证或者填写你在A2中配置的全局API密钥。在模型列表中手动添加模型名称填写A2支持的模型名如gemini-2.0-flash-exp,claude-3-5-sonnet-20241022等。保存后就可以在聊天界面选择这些模型进行对话了。路径路由的妙用A2支持通过路径来指定提供商。例如如果你想强制使用Kiro提供的Claude模型可以在接口地址中填写http://localhost:3000/claude-kiro-oauth/v1。这样所有请求都会走Kiro通道实现了更精细的控制。4.3 支持Claude的“深度思考”模式A2的一个高级特性是支持Kiro的扩展思考功能。这需要你在请求体中添加特定的参数。对于Claude原生格式 (/v1/messages){ model: claude-3-5-sonnet-20241022, max_tokens: 1024, thinking: { type: enabled, budget_tokens: 10000 }, messages: [...] }对于OpenAI兼容格式 (/v1/chat/completions){ model: claude-3-5-sonnet-20241022, messages: [...], extra_body: { anthropic: { thinking: { type: enabled, budget_tokens: 10000 } } } }budget_tokens参数控制思考的深度范围在1024到24576之间。这个功能对于需要复杂推理的任务非常有用。5. 运维监控与问题排查实录即使配置再完美在实际运行中也难免遇到问题。A2提供了强大的工具来帮助你监控和排查。5.1 利用Web UI进行实时监控仪表盘总览系统状态查看活跃连接数和请求示例。提供商池这里可以直观看到每个账户的健康状态绿色/红色、近期成功率、已用配额等。如果某个账户变红可以点击查看具体错误信息。实时日志这是排查问题的利器。你可以在这里看到所有进出的请求和响应详情包括转换前后的数据。当某个请求失败时通过日志可以清晰看到是哪个环节出了问题是认证失败、网络超时还是模型不支持。5.2 常见问题与解决方案速查表我在长期使用中遇到了不少典型问题这里总结一下问题现象可能原因排查步骤与解决方案OAuth授权页面打不开或授权失败1. 回调端口未映射或未开放。2. 本地网络无法访问Google。3. 浏览器缓存或Cookie冲突。1.检查Docker命令确保-p 8085:8085等端口映射存在且宿主机器端口未被占用。2.测试网络在服务器上curl https://accounts.google.com看是否通。3.使用无痕模式进行授权。请求返回429 Too Many Requests单个提供商如Gemini的速率限制RPD达到上限。1.查看日志确认是哪个提供商返回429。2.配置账户池为该提供商添加多个账户分散请求。3.启用Fallback配置providerFallbackChain在A账户限速时自动切到B提供商。请求Grok返回403 ForbiddenTLS指纹被识别为机器人。1.确认TLS Sidecar已启用在Web UI配置页面检查。2.检查Sidecar进程在服务器上 ps auxDocker容器启动后立刻退出1. 配置文件错误。2. 挂载目录权限不足。3. 端口冲突。1.查看容器日志docker logs aiclient2api。2.检查挂载目录确保宿主机目录存在且有读写权限chmod 755。3.检查端口占用。Web UI可以打开但API请求超时或无响应1. 提供商配置错误或凭证失效。2. 网络代理问题。3. 账户池中所有账户都不健康。1.检查提供商状态在Web UI“提供商池”页面查看是否为绿色。2.检查代理配置如果你配置了统一代理确认代理服务是否可用。3.检查实时日志看请求是否被正确路由和处理。流式输出中断或格式错误1. 网络不稳定。2. 模型提供商端中断了流。3. 适配器在流式转换时出错。1.检查网络。2.查看非流式请求是否正常以排除凭证问题。3.查看日志中流式响应的原始数据判断问题是来自上游还是转换过程。5.3 性能调优与安全建议连接池与超时设置在configs/config.json中可以调整REQUEST_TIMEOUT默认30000毫秒和HTTP代理的连接池参数以适应不同的网络环境。日志级别生产环境建议将日志级别调整为WARN或ERROR避免过多的INFO日志影响性能。可以在配置文件中修改LOG_LEVEL。安全加固修改默认密码第一时间修改Web UI的默认密码。启用API密钥验证在配置中设置API_KEYS这样客户端调用时必须提供有效的密钥。使用HTTPS如果服务暴露在公网务必在A2前面配置Nginx等反向代理启用HTTPS。限制访问IP通过防火墙或反向代理配置只允许可信的IP地址访问3000管理端口。定期维护定期检查凭证文件是否过期虽然A2有自动刷新但偶尔会失败关注各模型提供商的官方政策变化尤其是Kiro、Antigravity这类非官方渠道。6. 扩展开发与自定义提供商A2的模块化设计使得添加新的模型提供商变得相对简单。如果你有新的“客户端API”想要集成可以遵循以下步骤1. 创建新的策略类在src/providers/目录下新建一个文件例如my-new-provider.js。这个类需要继承基础Provider类并实现sendMessage,refreshToken等核心方法。你需要在这里处理与新提供商API的所有交互细节。2. 创建对应的适配器在src/adapters/目录下创建适配器类负责将新提供商的原始响应转换为OpenAI格式。3. 注册提供商在src/providers/index.js中导入并注册你新建的提供商给它分配一个唯一的类型标识符如my-new-provider。4. 更新路由和配置在路由逻辑中确保请求能正确路由到你的新提供商。同时更新Web UI的配置界面允许用户配置这个新提供商的参数。5. 编写测试为你的新提供商编写单元测试和集成测试确保功能稳定。这个过程需要对JavaScript/Node.js和A2的代码结构有一定了解。官方文档和现有提供商如Gemini、Kiro的代码是最好的参考。通过这种扩展理论上你可以将任何有API的AI服务接入到这个统一的网关中来。经过数周的深度使用AIClient-2-API已经成为了我本地开发和小型项目中的AI模型调度中枢。它极大地降低了多模型实验和集成的成本。虽然依赖第三方客户端接口存在一定的不确定性但其优秀的架构设计、丰富的功能和活跃的社区使得它成为目前解决“免费/低成本多模型统一调用”需求的最佳开源方案之一。如果你也受困于模型API的碎片化不妨亲手部署试试相信它会给你带来惊喜。