CCX:多上游AI API代理与协议转换网关
CCX 是一个高性能的 AI API 代理与协议转换网关,支持 Claude、OpenAI Chat、OpenAI Images、Codex Responses 与 Gemini。它提供统一入口、内置 Web 管理界面、渠道编排、故障转移、多密钥管理和模型路由能力。
功能特性
- 一体化架构 - 后端与前端一体化,单端口部署,前端构建产物嵌入 Go 二进制文件
- 双密钥认证 -
PROXY_ACCESS_KEY用于代理访问,可选ADMIN_ACCESS_KEY用于管理接口 - 内置管理面板 - Web 管理控制台,支持渠道管理、测试、日志和监控
- 多协议支持 - 同时支持 Claude Messages、OpenAI Chat Completions、OpenAI Images、Codex Responses、Gemini API
- 智能调度 - 优先级排序、促销期、健康检查、故障转移与熔断恢复
- 渠道级配置 - 每个渠道支持多 API Key 轮换、代理、自定义请求头、模型白名单和路由前缀
- 会话跟踪 - Responses API 支持多轮会话跟踪与 Trace 亲和性
- 协议转换 - 支持 Claude ↔ OpenAI Chat ↔ Responses ↔ Gemini 之间的双向协议转换
架构概览
CCX 对外提供一个统一后端入口:
客户端 -> backend :3000 ->
|- / -> Web 管理界面
|- /api/* -> 管理 API
|- /v1/messages -> Claude Messages 代理
|- /v1/chat/completions -> OpenAI Chat 代理
|- /v1/responses -> Codex Responses 代理
|- /v1/images/generations -> OpenAI Images 生成
|- /v1/images/edits -> OpenAI Images 编辑
|- /v1/images/variations -> OpenAI Images 变体
|- /v1/models -> Models API
`- /v1beta/models/* -> Gemini 代理
安装指南
方式一:直接运行二进制
- 从 Releases 下载最新可执行文件
- 在可执行文件同目录创建
.env:
PROXY_ACCESS_KEY=your-proxy-access-key
PORT=3000
ENABLE_WEB_UI=true
APP_UI_LANGUAGE=zh-CN
- 启动后访问
http://localhost:3000
方式二:Docker
docker run -d \
--name ccx \
-p 3000:3000 \
-e PROXY_ACCESS_KEY=your-proxy-access-key \
-e APP_UI_LANGUAGE=zh-CN \
-v $(pwd)/.config:/app/.config \
crpi-i19l8zl0ugidq97v.cn-hangzhou.personal.cr.aliyuncs.com/bene/ccx:latest
使用 Docker Compose 后台运行:
docker compose up -d
方式三:源码构建
git clone https://github.com/BenedictKing/ccx
cd ccx
cp backend-go/.env.example backend-go/.env
make run
常用命令:
make dev # 同时启动前端开发服务器和后端热重载
make run # 构建前端并运行 Go 后端
make build # 构建前端并编译 Go 后端
使用说明
环境变量配置
| 变量 | 默认值 | 说明 |
|---|---|---|
PORT | 3000 | 服务器端口 |
ENV | production | 运行环境 |
ENABLE_WEB_UI | true | 启用 Web 管理界面 |
PROXY_ACCESS_KEY | - | 代理访问密钥(必填) |
ADMIN_ACCESS_KEY | - | 可选管理密钥 |
APP_UI_LANGUAGE | en-US | 界面语言(zh-CN/en-US) |
LOG_LEVEL | info | 日志级别 |
REQUEST_TIMEOUT | 300000 | 请求超时(毫秒) |
QUIET_POLLING_LOGS | true | 静默轮询日志 |
API 端点
代理入口
# Claude Messages
POST /v1/messages
POST /v1/messages/count_tokens
# OpenAI Chat Completions
POST /v1/chat/completions
# Codex Responses
POST /v1/responses
POST /v1/responses/compact
# OpenAI Images
POST /v1/images/generations
POST /v1/images/edits
POST /v1/images/variations
# Gemini
POST /v1beta/models/{model}:generateContent
# 模型列表
GET /v1/models
GET /v1/models/:model
# 健康检查
GET /health
管理 API
/api/messages/channels/*
/api/chat/channels/*
/api/responses/channels/*
/api/gemini/channels/*
/api/images/channels/*
使用示例
# 通过代理调用 Claude API
curl -X POST http://localhost:3000/v1/messages \
-H "x-api-key: your-proxy-access-key" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-3-5-sonnet-20241022",
"messages": [{"role": "user", "content": "Hello"}],
"max_tokens": 1024
}'
# 通过代理调用 OpenAI Chat API
curl -X POST http://localhost:3000/v1/chat/completions \
-H "x-api-key: your-proxy-access-key" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4",
"messages": [{"role": "user", "content": "Hello"}]
}'
核心代码
调度器核心逻辑
// scheduler.go - 多渠道调度器
type ChannelScheduler struct {
mu sync.RWMutex
configManager *config.ConfigManager
messagesMetricsManager *metrics.MetricsManager
responsesMetricsManager *metrics.MetricsManager
geminiMetricsManager *metrics.MetricsManager
chatMetricsManager *metrics.MetricsManager
imagesMetricsManager *metrics.MetricsManager
traceAffinity *session.TraceAffinityManager
conversationTracker *conversation.ConversationTracker
overrideManager *conversation.OverrideManager
}
// 选择渠道的核心方法
func (s *ChannelScheduler) SelectChannel(...) (*config.UpstreamConfig, error) {
// 1. 检查渠道覆盖
// 2. 检查促销期渠道
// 3. 检查 Trace 亲和性
// 4. 按优先级排序
// 5. 健康检查和熔断过滤
}
Provider 接口定义
// provider.go - 上游提供商接口
type Provider interface {
// 将请求转换为目标上游格式
ConvertToProviderRequest(c *gin.Context, upstream *config.UpstreamConfig, apiKey string) (*http.Request, []byte, error)
// 将提供商响应转换为 Claude 格式
ConvertToClaudeResponse(providerResp *types.ProviderResponse) (*types.ClaudeResponse, error)
// 处理流式响应
HandleStreamResponse(body io.ReadCloser) (<-chan string, <-chan error, error)
}
// 支持的提供商:OpenAI、Gemini、Claude、Responses
func GetProvider(serviceType string) Provider {
switch serviceType {
case "openai": return &OpenAIProvider{}
case "gemini": return &GeminiProvider{}
case "claude": return &ClaudeProvider{}
case "responses": return &ResponsesProvider{}
default: return nil
}
}
熔断器状态管理
// metrics.go - 熔断器状态
type CircuitState uint8
const (
CircuitStateClosed CircuitState = iota // 正常状态
CircuitStateOpen // 熔断打开
CircuitStateHalfOpen // 半开状态
)
// Key 级别指标管理
type KeyMetrics struct {
MetricsKey string
BaseURL string
KeyMask string
CircuitState CircuitState
CircuitOpenedAt *time.Time
ConsecutiveFailures int64
}
协议转换核心
// converters.go - Responses 协议转换器接口
type ResponsesConverter interface {
ToProviderRequest(sess *session.Session, req *types.ResponsesRequest) (interface{}, error)
FromProviderResponse(resp map[string]interface{}, sessionID string) (*types.ResponsesResponse, error)
GetProviderName() string
}
// 转换器工厂
func NewConverter(serviceType string) ResponsesConverter {
switch serviceType {
case "openai": return &OpenAIChatConverter{}
case "claude": return &ClaudeConverter{}
case "gemini": return &GeminiResponsesConverter{}
case "responses": return &ResponsesPassthroughConverter{}
default: return &OpenAIChatConverter{}
}
}
1Z5R1dkCK4RKCL7aKVd+uA==