1
0
Files
nex/docs/analysis_reference/analysis_one_api.md

31 KiB
Raw Permalink Blame History

One-API 项目转换层深度分析报告

一、项目概览

One-API 是一个基于 Go 语言Gin 框架)开发的大模型 API 网关代理项目。其核心功能是:将用户发来的统一 OpenAI 格式请求,转换为各家大模型厂商的原生 API 格式,转发请求后,再将厂商的响应统一转换回 OpenAI 格式返回给用户

对外暴露的接口完全兼容 OpenAI API 规范,用户只需更改 base_urlapi_key 即可使用。

与同类项目的核心差异

One-API 是此类项目的鼻祖和基线,采用最简单的架构模式——仅支持 OpenAI 格式作为唯一输入/输出协议,所有转换都是 OpenAI ↔ 厂商原生格式 的双向转换。New-API 在其基础上增加了 Claude/Gemini 输入支持和 Hub-and-Spoke 架构。One-API 的设计追求简洁实用56 种渠道类型通过三层映射归并为 19 种 API 类型,其中 18 种 OpenAI 兼容渠道直接复用同一适配器,实现零开销透传。


二、项目目录结构

one-api/
├── main.go                    # 程序入口
├── router/
│   └── relay.go               # 路由定义(/v1/chat/completions 等)
├── middleware/
│   ├── auth.go                # Token 认证
│   ├── distributor.go         # 渠道分发(负载均衡)
│   └── rate-limit.go          # 限流
├── controller/
│   └── relay.go               # 入口控制器(含重试逻辑)
├── relay/                     # ★ 转换层核心目录
│   ├── adaptor.go             # Adaptor 工厂函数 (69行)
│   ├── adaptor/               # 各厂商 Adaptor 实现
│   │   ├── interface.go       # Adaptor 接口定义 (9方法)
│   │   ├── common.go          # 公共辅助函数
│   │   ├── openai/            # OpenAI 适配器(基座)
│   │   ├── anthropic/         # Anthropic Claude 适配器
│   │   ├── gemini/            # Google Gemini 适配器
│   │   ├── geminiv2/          # Gemini V2 模型适配器
│   │   ├── ali/               # 阿里通义千问适配器
│   │   ├── baidu/             # 百度文心适配器
│   │   ├── zhipu/             # 智谱 ChatGLM 适配器
│   │   ├── tencent/           # 腾讯混元适配器
│   │   ├── xunfei/            # 讯飞星火适配器
│   │   ├── aws/               # AWS Bedrock Claude 适配器 (含子适配器)
│   │   │   ├── claude/        #   Claude on Bedrock
│   │   │   └── llama3/        #   Llama3 on Bedrock
│   │   ├── vertexai/          # Google Vertex AI (含子适配器)
│   │   │   ├── claude/        #   Claude on Vertex AI
│   │   │   └── gemini/        #   Gemini on Vertex AI
│   │   ├── ollama/            # Ollama 适配器
│   │   ├── coze/              # Coze 适配器
│   │   ├── cohere/            # Cohere 适配器
│   │   ├── cloudflare/        # Cloudflare Workers AI 适配器
│   │   ├── deepl/             # DeepL 翻译适配器
│   │   ├── replicate/         # Replicate 适配器
│   │   ├── palm/              # Google PaLM 适配器
│   │   ├── proxy/             # 通用代理适配器
│   │   ├── aiproxy/           # AIProxy 适配器
│   │   └── ... (38个子目录)
│   ├── controller/            # 中转控制器(按功能分类)
│   │   ├── text.go            # 文本类请求处理 (115行)
│   │   ├── image.go           # 图片生成请求处理 (238行)
│   │   ├── audio.go           # 音频请求处理 (281行)
│   │   ├── proxy.go           # 通用代理请求处理
│   │   ├── helper.go          # 辅助函数(配额、计费等)
│   │   └── error.go           # 统一错误处理
│   ├── meta/
│   │   └── relay_meta.go      # 请求元数据结构 (66行)
│   ├── model/                 # 内部数据模型
│   │   ├── general.go         # 统一 OpenAI 请求结构 (88行)
│   │   ├── message.go         # 消息结构(支持多模态) (91行)
│   │   ├── misc.go            # Usage、Error 等通用结构 (27行)
│   │   ├── tool.go            # Tool/Function Calling 结构
│   │   └── image.go           # 图片请求结构
│   ├── apitype/
│   │   └── define.go          # API 类型枚举 (19种)
│   ├── channeltype/
│   │   ├── define.go          # 渠道类型枚举 (56种)
│   │   ├── helper.go          # ChannelType → APIType 映射
│   │   └── url.go             # 各渠道默认 BaseURL (52条)
│   ├── relaymode/
│   │   ├── define.go          # 中转模式枚举 (11种)
│   │   └── helper.go          # URL 路径 → 中转模式映射
│   └── billing/               # 计费相关
└── model/                     # 数据库模型
    ├── channel.go             # 渠道配置
    └── ...

三、转换层技术架构

3.1 整体架构图

                    ┌─────────────────────────────────────────┐
                    │         用户请求 (OpenAI 格式)            │
                    │   POST /v1/chat/completions              │
                    └──────────────────┬──────────────────────┘
                                       │
                    ┌──────────────────▼──────────────────────┐
                    │           router/relay.go                │
                    │   路由: /v1/* → controller.Relay         │
                    └──────────────────┬──────────────────────┘
                                       │
                    ┌──────────────────▼──────────────────────┐
                    │          middleware (中间件链)             │
                    │  CORS → GzipDecode → PanicRecover        │
                    │  → TokenAuth → Distribute                │
                    │  1. 解析 Token, 验证身份                   │
                    │  2. 根据模型名选择渠道(随机负载均衡)         │
                    │  3. 将渠道信息注入 gin.Context             │
                    └──────────────────┬──────────────────────┘
                                       │
                    ┌──────────────────▼──────────────────────┐
                    │         controller/relay.go              │
                    │  1. 根据 URL 判断 relayMode               │
                    │  2. 调用 relayHelper 分发                  │
                    │  3. 失败时自动重试(切换渠道)                │
                    └──────────────────┬──────────────────────┘
                                       │
              ┌────────────────────────┼────────────────────────┐
              │                        │                        │
    ┌─────────▼──────────┐  ┌─────────▼──────────┐  ┌─────────▼──────────┐
    │ RelayTextHelper    │  │ RelayImageHelper   │  │ RelayAudioHelper   │
    │ text.go (115行)    │  │ image.go (238行)   │  │ audio.go (281行)   │
    └─────────┬──────────┘  └─────────┬──────────┘  └─────────┬──────────┘
              │                        │                        │
              └────────────────────────┼────────────────────────┘
                                       │
                    ┌──────────────────▼──────────────────────┐
                    │        relay/adaptor.go                  │
                    │  GetAdaptor(apiType) → 具体Adaptor实例     │
                    └──────────────────┬──────────────────────┘
                                       │
              ┌────────────────────────┼────────────────────────┐
              │                        │                        │
    ┌─────────▼──────────┐  ┌─────────▼──────────┐  ┌─────────▼──────────┐
    │ openai.Adaptor     │  │ anthropic.Adaptor  │  │ gemini.Adaptor     │
    │ ConvertRequest()   │  │ ConvertRequest()   │  │ ConvertRequest()   │
    │ DoRequest()        │  │ DoRequest()        │  │ DoRequest()        │
    │ DoResponse()       │  │ DoResponse()       │  │ DoResponse()       │
    └─────────┬──────────┘  └─────────┬──────────┘  └─────────┬──────────┘
              │                        │                        │
              └────────────────────────┼────────────────────────┘
                                       │
                    ┌──────────────────▼──────────────────────┐
                    │         上游大模型厂商 API                 │
                    └─────────────────────────────────────────┘

3.2 核心设计模式:适配器模式

Adaptor 接口 (relay/adaptor/interface.go, 21 行):

type Adaptor interface {
    Init(meta *meta.Meta)                                    // 初始化元数据
    GetRequestURL(meta *meta.Meta) (string, error)           // 构建请求 URL
    SetupRequestHeader(c, req, meta) error                   // 设置认证请求头
    ConvertRequest(c, mode, request) (any, error)            // 请求体转换 (OpenAI → 厂商)
    ConvertImageRequest(request) (any, error)                // 图片请求转换
    DoRequest(c, meta, requestBody) (*http.Response, error)  // 发送 HTTP 请求
    DoResponse(c, resp, meta) (usage, err)                   // 响应体转换 (厂商 → OpenAI)
    GetModelList() []string                                  // 返回支持的模型列表
    GetChannelName() string                                  // 返回渠道名称
}

9 个方法构成最精简的适配器接口,相比 New-API 的 15+ 方法接口更聚焦。

3.3 三层映射关系

项目通过三层映射将"渠道"与"转换逻辑"关联:

ChannelType (渠道类型)  →  APIType (API 类型)  →  Adaptor (适配器实例)
     (56 种)                  (19 种)                 (18 个实现)
  • ChannelType: 具体的厂商/服务商标识56 种)
  • APIType: 共享同一套转换逻辑的分组19 种,定义在 relay/apitype/define.go
  • Adaptor: 负责具体转换逻辑的实例

映射代码: relay/channeltype/helper.goToAPIType() 函数。

关键设计: 18 种 OpenAI 兼容渠道的 APIType 被映射为 apitype.OpenAI,直接复用 openai.Adaptor,无需编写独立转换逻辑。兼容渠道列表 (relay/adaptor/openai/compatible.go):

var CompatibleChannels = []int{
    Azure, AI360, Moonshot, Baichuan, Minimax, Doubao,
    Mistral, Groq, LingYiWanWu, StepFun, DeepSeek, TogetherAI,
    Novita, SiliconFlow, XAI, BaiduV2, XunfeiV2,
}

另有 OpenRouter、AliBailian、GeminiOpenAICompatible 也有特殊映射处理。

3.4 Adaptor 工厂

文件: relay/adaptor.go (69 行)

GetAdaptor(apiType int) 映射 18 种 API 类型到具体适配器实例Proxy 类型额外处理)。


四、请求处理完整流程

4.1 路由阶段

文件: router/relay.go (74 行)

所有 /v1/ 下的请求都经过中间件链:CORS() → GzipDecodeMiddleware() → RelayPanicRecover → TokenAuth → Distribute

4.2 中间件阶段

Token 认证 (middleware/auth.go, 167 行)

  • Authorization 头提取 Bearer <token>
  • 管理员可通过 sk-<token>-<channelId> 指定特定渠道
  • 验证 Token 有效性,提取 userId、tokenId
  • 从请求体解析 model 字段,验证模型可用性
  • 支持 IP 子网限制

渠道分发 (middleware/distributor.go, 102 行)

  • 获取用户分组 (group)
  • 根据 group + model 随机选择一个可用渠道
  • 将渠道信息注入 gin.Context渠道类型、API Key、BaseURL、ModelMapping 等
  • 渠道类型转换为 APIType存入 meta

4.3 控制器阶段

文件: controller/relay.go (156 行)

func Relay(c *gin.Context) {
    relayMode := relaymode.GetByPath(c.Request.URL.Path)
    bizErr := relayHelper(c, relayMode)
    // 失败时自动重试:切换到其他渠道
    for i := retryTimes; i > 0; i-- {
        channel := CacheGetRandomSatisfiedChannel(group, model)
        SetupContextForSelectedChannel(c, channel, model)
        bizErr = relayHelper(c, relayMode)
    }
}

relayHelper 根据 relayMode 分发:

  • ChatCompletions / Completions / Embeddings / ModerationsRelayTextHelper
  • ImagesGenerationsRelayImageHelper
  • AudioSpeech / AudioTranscription / AudioTranslationRelayAudioHelper
  • ProxyRelayProxyHelper

重试策略: 429 和 5xx 触发重试400 和 2xx 不重试。管理员指定渠道时不重试。

4.4 转换处理阶段 — RelayTextHelper

文件: relay/controller/text.go (115 行)

func RelayTextHelper(c *gin.Context) *model.ErrorWithStatusCode {
    // 1. 解析请求(统一按 OpenAI 格式解析)
    meta := meta.GetByContext(c)
    textRequest := getAndValidateTextRequest(c, meta.Mode)

    // 2. 模型名称映射
    textRequest.Model = getMappedModelName(textRequest.Model, meta.ModelMapping)

    // 3. 强制系统提示词注入
    setSystemPrompt(textRequest, meta)

    // 4. 计算配额、预扣费
    promptTokens := getPromptTokens(textRequest, meta.Mode)
    preConsumedQuota := preConsumeQuota(...)  // 用户配额 > 100x预扣时跳过

    // 5. 获取对应 Adaptor
    adaptor := relay.GetAdaptor(meta.APIType)
    adaptor.Init(meta)

    // 6. 请求转换OpenAI 格式 → 厂商格式)
    requestBody := getRequestBody(c, meta, textRequest, adaptor)

    // 7. 发送请求到上游
    resp := adaptor.DoRequest(c, meta, requestBody)

    // 8. 响应转换(厂商格式 → OpenAI 格式)
    usage := adaptor.DoResponse(c, resp, meta)

    // 9. 后扣费
    postConsumeQuota(usage, ...)
}

请求体透传优化

文件: relay/controller/text.gogetRequestBody() 函数

当满足以下所有条件时,跳过请求转换,直接透传原始请求体:

  • API 类型为 OpenAI
  • 模型名未被映射
  • 渠道不是百川(百川有特殊处理)
  • 无强制系统提示词
  • 未启用 include_usage 强制选项
if meta.APIType == apitype.OpenAI &&
    meta.OriginModelName == meta.ActualModelName &&
    meta.ChannelType != channeltype.Baichuan &&
    meta.ForcedSystemPrompt == "" {
    return c.Request.Body, nil  // 直接透传,零开销
}

五、各厂商转换逻辑详解

5.1 OpenAI 适配器(基座)

文件: relay/adaptor/openai/ (9 文件)

作为项目的"基座适配器",不仅处理 OpenAI 自身,还被 18 种 OpenAI 兼容渠道复用。

请求转换: 基本不需要格式转换,直接透传 GeneralOpenAIRequest。唯一处理:流式模式下自动注入 stream_options.include_usage = true

URL 构建: 根据渠道类型有不同逻辑:

  • 标准 OpenAI 兼容: BaseURL + RequestURLPath
  • Azure: /openai/deployments/{model}/{task}?api-version=xxx
  • Minimax/Doubao/Novita/BaiduV2/AliBailian/GeminiOpenAICompatible: 各有独立 URL 逻辑

认证方式:

  • 标准渠道: Authorization: Bearer <api_key>
  • Azure: api-key: <api_key>
  • OpenRouter: 额外 HTTP-RefererX-Title

流式处理: 逐行解析 SSE (data: {...}),提取 usage 信息,支持 Cloudflare AI Gateway URL。

5.2 Anthropic Claude 适配器

文件: relay/adaptor/anthropic/ (4 文件, main.go 379 行)

Claude 使用完全不同的 API 格式,需要大量转换工作。

请求转换 (main.go ConvertRequest()):

OpenAI 字段 Claude 字段 转换说明
messages[].role = "system" system (顶层字段) 系统提示词提取到顶层
messages[].content (string) messages[].content (Content 数组) 包装为 [{type:"text", text:"..."}]
messages[].role = "tool" messages[].role = "user" + type = "tool_result" 工具结果转为用户消息
messages[].tool_calls content.type = "tool_use" 工具调用转为 content 块
tools[].function.parameters tools[].input_schema 字段名转换
tool_choice tool_choice.type + name auto/tool/any 格式映射
max_tokens max_tokens 直接映射,默认 4096

认证: x-api-key: <api_key> + anthropic-version: 2023-06-01。Claude 3.5 Sonnet 额外添加 anthropic-beta: max-tokens-3-5-sonnet-2024-07-15

URL: {base_url}/v1/messages

响应转换:

Claude 字段 OpenAI 字段
content[].text choices[].message.content
content[].type = "tool_use" choices[].message.tool_calls[]
stop_reason: "end_turn"/"stop_sequence" finish_reason: "stop"
stop_reason: "max_tokens" finish_reason: "length"
stop_reason: "tool_use" finish_reason: "tool_calls"
usage.input_tokens/output_tokens usage.prompt_tokens/completion_tokens

流式处理: Claude 的 SSE 事件类型(message_startcontent_block_startcontent_block_deltamessage_delta)逐事件转换为 OpenAI 的 chat.completion.chunk 格式。

5.3 Google Gemini 适配器

文件: relay/adaptor/gemini/ (4 文件, main.go 437 行)

请求转换:

OpenAI 字段 Gemini 字段 转换说明
messages[] contents[] 数组结构转换
role = "assistant" role = "model" 角色名映射
role = "system" systemInstructionrole = "user" 新模型用 systemInstruction旧模型转 user
tools[].function tools[].functionDeclarations[] 字段名转换
temperature/top_p/max_tokens generationConfig.{temperature, topP, maxOutputTokens} 包装到 generationConfig
response_format.type = "json_object" responseMimeType = "application/json" MIME 类型映射

特殊处理:

  • system 消息后自动插入 model: "Okay" 虚拟消息Gemini API 要求角色交替)
  • 安全设置设为最低 (GeminiSafetySetting5 个类别)
  • 图片数量限制最多 16 张,转为 base64 inlineData
  • 支持 system instruction 的模型列表硬编码: gemini-2.0-flash, gemini-2.0-flash-exp, gemini-2.0-flash-thinking-exp-01-21

URL: {base_url}/{version}/models/{model}:{action}

  • 版本选择: gemini-2.0gemini-1.5v1beta;其他用 config.GeminiVersion
  • 非流式: generateContent
  • 流式: streamGenerateContent?alt=sse
  • Embedding: batchEmbedContents

认证: x-goog-api-key: <api_key>

5.4 阿里通义千问适配器

文件: relay/adaptor/ali/ (5 文件, main.go 267 行)

使用阿里 DashScope API 格式。

请求转换:

  • Messages 包装到 Input.Messages,参数包装到 Parameters(含 ResultFormat: "message", IncrementalOutput, EnableSearch
  • 模型名后缀 -internet 启用联网搜索 (EnableSearch: true)
  • top_p 上限为 0.9999
  • 图片生成使用异步模式 (X-DashScope-Async: enable),轮询等待(最多 20 步2 秒间隔)

URL:

  • 文本: /api/v1/services/aigc/text-generation/generation
  • Embedding: /api/v1/services/embeddings/text-embedding/text-embedding
  • 图片: /api/v1/services/aigc/text2image/image-synthesis

特殊头: X-DashScope-SSE: enable (流式), X-DashScope-Async: enable (异步)

5.5 百度文心一言适配器

文件: relay/adaptor/baidu/ (4 文件, main.go 312 行)

认证方式: 百度不使用 API Key 直接认证,而是先通过 client_id|client_secret 获取 access_token,然后在 URL 中传递。

access_token 缓存机制:

  • baiduTokenStore 使用 sync.Map 存储
  • 缓存的 token 在过期前 1 小时触发异步刷新
  • API Key 格式: client_id|client_secret,通过 OAuth2 端点获取 token

请求转换: 系统消息提取到 System 字段,FrequencyPenaltyPenaltyScore

URL: {base_url}/rpc/2.0/ai_custom/v1/wenxinworkshop/{suffix}?access_token={token}

  • URL 中包含模型端点名称(如 chat/completions_pro),通过大量 switch-case 映射模型名到端点

5.6 智谱 ChatGLM 适配器

文件: relay/adaptor/zhipu/ (4 文件)

双版本支持:

  • v4 (glm-* 模型): /api/paas/v4/chat/completionsOpenAI 兼容,直接复用 OpenAI 的 StreamHandler/Handler
  • v3: /api/paas/v3/model-api/{model}/{method} — 自有格式

认证: JWT tokenAPI Key 格式 id.secretHMAC-SHA256 签名)

5.7 腾讯混元适配器

文件: relay/adaptor/tencent/ (4 文件, main.go 307 行)

  • URL: {baseURL}/ (单一端点)
  • 认证: TC3-HMAC-SHA256 签名算法(完整实现在 main.go 中)
  • API Key 格式: appId|secretId|secretKey

5.8 讯飞星火适配器

文件: relay/adaptor/xunfei/ (5 文件, main.go 273 行)

  • 协议: WebSocket唯一非 HTTP 适配器)
  • GetRequestURL() 返回空字符串,DoRequest() 返回 dummy 200
  • DoResponse() 处理实际 WebSocket 通信
  • 认证: HMAC-SHA256 签名的 WebSocket URL
  • API Key 格式: appId|apiSecret|apiKey (pipe 分隔三部分)
  • 流式: 使用 c.Stream() + SSE 格式
  • 非流式: 累积所有 WebSocket chunk 后返回单次响应

5.9 AWS Bedrock Claude 适配器

文件: relay/adaptor/aws/ (5 文件)

  • 使用 AWS SDK v2 bedrockruntime.Client,不走 HTTP
  • 子适配器模式: registry.go 根据模型名分派到 aws/claude/aws/llama3/
  • aws/claude/: 复用 anthropic.ConvertRequest() 转换请求,使用 Bedrock InvokeModel/InvokeModelWithResponseStream 通信
  • aws/llama3/: Llama3 专用转换

5.10 Google Vertex AI 适配器

文件: relay/adaptor/vertexai/ (5 文件)

  • URL: {baseURL}/v1/projects/{project}/locations/{region}/publishers/google/models/{model}:{action}
  • Claude: rawPredict/streamRawPredict?alt=sse
  • Gemini: generateContent/streamGenerateContent?alt=sse
  • 子适配器模式: registry.go 分派到 vertexai/claude/vertexai/gemini/
  • vertexai/claude/: 复用 anthropic.ConvertRequest(),设置 anthropic_version: "vertex-2023-10-16"
  • vertexai/gemini/: 复用 gemini.ConvertRequest()
  • 认证: Google Cloud IAM GenerateAccessToken (ADC)Token 缓存 50 分钟 TTL

5.11 其他适配器简述

适配器 文件 关键特征
Ollama adaptor/ollama/ 类 OpenAI 格式,/api/chat/api/generate
Coze adaptor/coze/ 字节跳动 Coze 平台
Cohere adaptor/cohere/ Cohere 自有 API 格式
Cloudflare adaptor/cloudflare/ Workers AIURL 支持 Cloudflare AI Gateway
DeepL adaptor/deepl/ 翻译 API非 LLM
Replicate adaptor/replicate/ 异步任务模式
PaLM adaptor/palm/ Google PaLM (旧版)
Proxy adaptor/proxy/ 通用透传代理,无转换

六、统一数据模型

6.1 统一请求模型 (relay/model/general.go, 88 行)

type GeneralOpenAIRequest struct {
    Messages            []Message       // 聊天消息
    Model               string          // 模型名
    MaxTokens           int             // 最大生成 token
    MaxCompletionTokens int             // 最大完成 token (o-series)
    Temperature         *float64        // 温度
    TopP                *float64        // Top-P
    TopK                int             // Top-K
    Stream              bool            // 流式
    StreamOptions       *StreamOptions  // 流式选项
    Tools               []Tool          // 工具调用
    ToolChoice          any             // 工具选择
    Stop                any             // 停止词
    ResponseFormat      *ResponseFormat // 响应格式
    ReasoningEffort     string          // 推理强度
    Store               *bool           // 存储标记
    // ... 更多字段
}

这是整个项目的"通用语言"——所有厂商的请求都先解析为此格式,再由各 Adaptor 转换为厂商格式。

6.2 统一消息模型 (relay/model/message.go, 91 行)

type Message struct {
    Role             string  // system / user / assistant / tool / developer
    Content          any     // 字符串 或 多模态内容数组
    ReasoningContent any     // 推理内容 (o1 等模型)
    Name             *string // 消息发送者名称
    ToolCalls        []Tool  // 工具调用结果
    ToolCallId       string  // 工具调用 ID
}

Content 支持字符串纯文本和数组多模态text + image_url通过 ParseContent() 解析。

6.3 统一 Usage 模型

type Usage struct {
    PromptTokens     int
    CompletionTokens int
    TotalTokens      int
}

6.4 统一错误模型

所有上游错误统一转换为 OpenAI 错误格式:

{"error": {"message": "...", "type": "...", "param": "...", "code": "..."}}

GeneralErrorResponse 兼容多种厂商的错误格式OpenAI 的 error.message、通用的 message、百度的 error_msg 等)。


七、中转模式 (RelayMode)

文件: relay/relaymode/ (2 文件)

11 种中转模式,根据 URL 路径自动判断:

模式 URL 路径 说明
ChatCompletions /v1/chat/completions Chat 聊天补全
Completions /v1/completions 文本补全
Embeddings /v1/embeddings, /v1/engines/:model/embeddings 文本嵌入
Moderations /v1/moderations 内容审核
ImagesGenerations /v1/images/generations 图片生成
Edits /v1/edits 文本编辑
AudioSpeech /v1/audio/speech 语音合成
AudioTranscription /v1/audio/transcriptions 语音识别
AudioTranslation /v1/audio/translations 语音翻译
Proxy /v1/oneapi/proxy/:channelid/*target 通用代理

判断逻辑通过 strings.HasPrefix 匹配。


八、关键业务逻辑

8.1 配额管理

"预扣费 + 后结算"机制:

  1. 预扣费: 根据 prompt tokens 和模型倍率预先扣除估算配额
  2. 后结算: 根据 usage 的实际 token 数计算费用并调整
  3. 信任优化: 用户配额超过预扣费 100 倍时跳过预扣

8.2 自动重试

请求失败时 (429/5xx)

  1. 选择另一个不同的渠道(随机负载均衡)
  2. 重新设置上下文
  3. 从缓存的原始 body 重放请求
  4. 最多重试 RetryTimes
  5. 429 返回特殊消息"当前分组上游负载已饱和,请稍后再试"

8.3 错误监控

processChannelRelayError() 异步记录错误,并通过 monitor.ShouldDisableChannel() 自动禁用频繁出错的渠道。


九、流式 (SSE) 处理架构

9.1 统一处理流程

上游 SSE 流 → Scanner 逐行扫描 → 解析厂商 JSON → 转换为 OpenAI 格式 → SSE 写回客户端

9.2 各厂商 SSE 格式对比

厂商 SSE 前缀 数据格式 结束标记
OpenAI data: ChatCompletionsStreamResponse data: [DONE]
Anthropic data: StreamResponse (type 字段区分事件) 无显式标记
Gemini data: ChatResponse 无显式标记
阿里 data: ChatResponse (\n 分隔) 无显式标记
百度 data: ChatStreamResponse is_end = true

9.3 OpenAI 兼容渠道的 SSE 优化

OpenAI 兼容渠道的流式数据直接透传给客户端,仅需解析统计 usage 信息,不需要格式转换。


十、架构总结

10.1 核心设计原则

  1. 统一入口,适配器分发: 所有请求通过同一入口,由工厂模式创建对应适配器
  2. OpenAI 格式为"通用语言": 内部所有流转使用 OpenAI 格式,仅在"进出"时转换
  3. 接口抽象: 通过 Adaptor 接口 (9 方法) 隔离各厂商差异,新增厂商只需实现接口
  4. 零拷贝优化: OpenAI 兼容渠道无特殊处理时直接透传请求体
  5. 关注点分离: 认证、分发、转换、计费、重试各自独立

10.2 新增厂商适配步骤

  1. relay/channeltype/define.go 添加 ChannelType 常量
  2. relay/apitype/define.go 添加 APIType(或复用已有)
  3. relay/channeltype/helper.go 添加 ToAPIType() 映射
  4. relay/channeltype/url.go 添加默认 BaseURL
  5. 创建 relay/adaptor/<vendor>/ 目录实现 Adaptor 接口
  6. 如果复用 OpenAI 格式,只需在 compatible.goCompatibleChannels 列表中添加

10.3 架构特点

优点:

  • 接口精简9 方法),扩展性强
  • 18 种 OpenAI 兼容渠道零开销透传
  • 自动重试 + 渠道切换 + 错误监控自动禁用
  • 统一的计费和错误处理
  • 子适配器模式支持 Bedrock/Vertex AI 的多云厂商模型

局限:

  • 仅支持 OpenAI 格式输入/输出New-API 已在此基础上扩展了 Claude/Gemini 输入)
  • 音频处理未完全走 Adaptor 接口
  • 部分适配器 SSE 解析逻辑有重复模式,可抽取公共基类
  • 缺少请求/响应中间件钩子的统一注入点