Skip to content
Back to skills

770 Readme Cn De79e993

BSecurity

<p align="center"> <a href="https://t.me/uni_api"> <img src="https://img.shields.io/badge/Join Telegram Group-blue?&logo=telegram"> </a> <a href="https://hub.docker.com/repository/docker/yym68686/uni-api"> <img src="https://img.shields.io/docker/pulls/yym68686/uni-api?color=blue" alt="docker pull"> </a> </p> [英文](./README.md) | [中文](./README_CN.md)

  • 9 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added June 1, 2026
devopspythongoshellbashsqlnodeexpressdockerawsgcp

Works with

  • cli
  • api

Security analysis

B85/100
  • mediumUses curl or wget to download content
  • highContains patterns that look like hardcoded API keys
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 2 files and shows the line behind each finding

Scanned June 1, 2026

npx -y skills add tools-only/X-Skills --skill 770-readme_cn_de79e993 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 770 Readme Cn De79e993?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 770 Readme Cn De79e993
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-770-readme-cn-de79e993/badge)](https://www.skillsdirectory.com/skills/tools-only-770-readme-cn-de79e993)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
# uni-api

<p align="center">
  <a href="https://t.me/uni_api">
    <img src="https://img.shields.io/badge/Join Telegram Group-blue?&logo=telegram">
  </a>
   <a href="https://hub.docker.com/repository/docker/yym68686/uni-api">
    <img src="https://img.shields.io/docker/pulls/yym68686/uni-api?color=blue" alt="docker pull">
  </a>
</p>

[英文](./README.md) | [中文](./README_CN.md)

## 介绍

如果个人使用的话,one/new-api 过于复杂,有很多个人不需要使用的商用功能,如果你不想要复杂的前端界面,又想要支持的模型多一点,可以试试 uni-api。这是一个统一管理大模型 API 的项目,可以通过一个统一的API 接口调用多种不同提供商的服务,统一转换为 OpenAI 格式,支持负载均衡。目前支持的后端服务有:OpenAI、Anthropic、Gemini、Vertex、Azure、AWS、xai、Cohere、Groq、Cloudflare、OpenRouter、[0-0.pro](https://0-0.pro) 等。

## ✨ 特性

- 无前端,纯配置文件配置 API 渠道。只要写一个文件就能运行起一个属于自己的 API 站,文档有详细的配置指南,小白友好。
- 统一管理多个后端服务,支持 OpenAI、Deepseek、OpenRouter 等其他 API 是 OpenAI 格式的提供商。支持 OpenAI Dalle-3 图像生成。
- 同时支持 Anthropic、Gemini、Vertex AI、Azure、AWS、xai、Cohere、Groq、Cloudflare、[0-0.pro](https://0-0.pro)。Vertex 同时支持 Claude 和 Gemini API。
- 支持 OpenAI、 Anthropic、Gemini、Vertex、Azure、AWS、xai 原生 tool use 函数调用。
- 支持 OpenAI、Anthropic、Gemini、Vertex、Azure、AWS、xai 原生识图 API。
- 支持四种负载均衡。
  1. 支持渠道级加权负载均衡,可以根据不同的渠道权重分配请求。默认不开启,需要配置渠道权重。
  2. 支持 Vertex 区域级负载均衡,支持 Vertex 高并发,最高可将 Gemini,Claude 并发提高 (API数量 * 区域数量) 倍。自动开启不需要额外配置。
  3. 除了 Vertex 区域级负载均衡,所有 API 均支持渠道级顺序负载均衡,提高沉浸式翻译体验。默认不开启,需要配置 `SCHEDULING_ALGORITHM` 为 `round_robin`。
  4. 支持单个渠道多个 API Key 自动开启 API key 级别的轮训负载均衡。
- 支持自动重试,当一个 API 渠道响应失败时,自动重试下一个 API 渠道。
- 支持渠道冷却,当一个 API 渠道响应失败时,会自动将该渠道排除冷却一段时间,不再请求该渠道,冷却时间结束后,会自动将该模型恢复,直到再次请求失败,会重新冷却。
- 支持细粒度的模型超时时间设置,可以为每个模型设置不同的超时时间。
- 支持细粒度的权限控制。支持使用通配符设置 API key 可用渠道的特定模型。
- 支持限流,可以设置每分钟最多请求次数,可以设置为整数,如 2/min,2 次每分钟、5/hour,5 次每小时、10/day,10 次每天,10/month,10 次每月,10/year,10 次每年。默认60/min。
- 支持多个标准 OpenAI 格式的接口:`/v1/chat/completions`,`/v1/responses`,`/v1/images/generations`,`/v1/embeddings`,`/v1/audio/transcriptions`,`/v1/audio/speech`,`/v1/moderations`,`/v1/models`。
- 支持 OpenAI moderation 道德审查,可以对用户的消息进行道德审查,如果发现不当的消息,会返回错误信息。降低后台 API 被提供商封禁的风险。

## 使用方法

启动 uni-api 必须使用配置文件,有两种方式可以启动配置文件:

1. 第一种是使用 `CONFIG_URL` 环境变量填写配置文件 URL,uni-api启动时会自动下载。
2. 第二种就是挂载名为 `api.yaml` 的配置文件到容器内。

### 方法一:挂载 `api.yaml` 配置文件启动 uni-api

必须事先填写完成配置文件才能启动 `uni-api`,必须使用名为 `api.yaml` 的配置文件才能启动 `uni-api`,可以配置多个模型,每个模型可以配置多个后端服务,支持负载均衡。下面是最小可运行的 `api.yaml` 配置文件的示例:

```yaml
providers:
  - provider: provider_name # 服务提供商名称, 如 openai、anthropic、gemini、openrouter,随便取名字,必填
    base_url: https://api.your.com/v1/chat/completions # 后端服务的API地址,必填
    api: sk-YgS6GTi0b4bEabc4C # 提供商的API Key,必填,自动使用 base_url 和 api 通过 /v1/models 端点获取可用的所有模型。
  # 这里可以配置多个提供商,每个提供商可以配置多个 API Key,每个提供商可以配置多个模型。
api_keys:
  - api: sk-[REDACTED] # API Key,用户请求 uni-api 需要 API key,必填
  # 该 API Key 可以使用所有模型,即可以使用 providers 下面设置的所有渠道里面的所有模型,不需要一个个添加可用渠道。
```

`api.yaml` 详细的高级配置:

```yaml
providers:
  - provider: provider_name # 服务提供商名称, 如 openai、anthropic、gemini、openrouter,随便取名字,必填
    base_url: https://api.your.com/v1/chat/completions # 后端服务的API地址,必填
    api: sk-YgS6GTi0b4bEabc4C # 提供商的API Key,必填
    model: # 选填,如果不配置 model,会自动通过 base_url 和 api 通过 /v1/models 端点获取可用的所有模型。
      - gpt-5.2 # 可以使用的模型名称,必填
      - claude-sonnet-4-5-20250929: claude-sonnet-4-5 # 重命名模型,claude-sonnet-4-5-20250929 是服务商的模型名称,claude-3-5-sonnet 是重命名后的名字,可以使用简洁的名字代替原来复杂的名称,选填
      - dall-e-3

  - provider: anthropic
    base_url: https://api.anthropic.com/v1/messages
    api: # 支持多个 API Key,多个 key 自动开启轮训负载均衡,至少一个 key,必填
      - sk-[REDACTED]
      - sk-ant-api02-bNnxxxx
    model:
      - claude-sonnet-4-5-20250929: claude-sonnet-4-5 # 重命名模型,claude-sonnet-4-5-20250929 是服务商的模型名称,claude-sonnet-4-5 是重命名后的名字,可以使用简洁的名字代替原来复杂的名称,选填
      - claude-sonnet-4-5-20250929: claude-sonnet-4-5-think # 重命名模型,claude-sonnet-4-5-20250929 是服务商的模型名称,claude-sonnet-4-5-think 是重命名后的名字,可以使用简洁的名字代替原来复杂的名称,如果重命名后的名字里面有think,则自动转换为 claude 思考模型,默认思考 token 限制为 4096。选填
    tools: true # 是否支持工具,如生成代码、生成文档等,默认是 true,选填
    preferences:
      post_body_parameter_overrides: # 支持自定义请求体参数
        claude-sonnet-4-5-think: # 给模型 claude-sonnet-4-5-think 添加自定义请求体参数
          tools:
            - type: code_execution_20250522 # 给模型 claude-sonnet-4-5-think 添加 code_execution 工具
              name: code_execution
            - type: web_search_20250305 # 给模型 claude-sonnet-4-5-think 添加 web_search 工具,max_uses 表示最多使用 5 次
              name: web_search
              max_uses: 5

  - provider: gemini
    base_url: https://generativelanguage.googleapis.com/v1beta # base_url 支持 v1beta/v1, 仅供 Gemini 模型使用,必填
    api: # 支持多个 API Key,多个 key 自动开启轮训负载均衡,至少一个 key,必填
      - AIzaSyAN2k6IRdgw123
      - AIzaSyAN2k6IRdgw456
      - AIzaSyAN2k6IRdgw789
    model:
      - gemini-3-pro-preview: gemini-3-pro
      - gemini-2.5-flash: gemini-2.5-flash # 重命名后,原来的模型名字 gemini-2.5-flash 无法使用,如果要使用原来的名字,可以在 model 中添加原来的名字,只要加上下面一行就可以使用原来的名字了
      - gemini-2.5-flash
      - gemini-pro-latest: gemini-2.5-pro-search # 可以以 -search 后缀重命名模型,同时在 post_body_parameter_overrides 设置针对此模型的自定义请求体参数即可启用搜索。
      - gemini-2.5-flash: gemini-2.5-flash-think-24576-search # 可以以 -search 后缀重命名模型,同时在 post_body_parameter_overrides 设置针对此模型的自定义请求体参数即可启用搜索,同时支持使用 `-think-数字` 自定义推理预算,可以同时开启也可以单独开启。
      - gemini-2.5-flash: gemini-2.5-flash-think-0 # 支持以 -think-数字 自定义推理预算,当数字为 0 时,表示关闭推理。
      - gemini-embedding-001
      - text-embedding-004
    tools: true
    preferences:
      api_key_rate_limit: 15/min # 每个 API Key 每分钟最多请求次数,选填。默认为 999999/min。支持多个频率约束条件:15/min,10/day
      # api_key_rate_limit: # 可以为每个模型设置不同的频率限制
      #   gemini-2.5-flash: 10/min,500/day
      #   gemini-2.5-pro: 5/min,25/day,1048576/tpr # 1048576/tpr 表示每次请求的 tokens 数量限制为 1048576 个 tokens
      #   default: 4/min # 如果模型没有设置频率限制,使用 default 的频率限制
      api_key_cooldown_period: 60 # 每个 API Key 遭遇 429 错误后的冷却时间,单位为秒,选填。默认为 0 秒, 当设置为 0 秒时,不启用冷却机制。当存在多个 API key 时才会生效。
      api_key_schedule_algorithm: round_robin # 设置多个 API Key 的请求顺序,选填。默认为 round_robin,可选值有:round_robin,random,fixed_priority,smart_round_robin。当存在多个 API key 时才会生效。round_robin 是轮询负载均衡,random 是随机负载均衡,fixed_priority 是固定优先级调度,永远使用第一个可用的 API key。smart_round_robin 是一个基于历史成功率的智能调度算法,详见 FAQ 部分。
      model_timeout: # 模型超时时间,单位为秒,默认 100 秒,选填
        gemini-2.5-pro: 500 # 模型 gemini-2.5-pro 的超时时间为 500 秒
        gemini-2.5-flash: 500 # 模型 gemini-2.5-flash 的超时时间为 500 秒
        default: 10 # 模型没有设置超时时间,使用默认的超时时间 10 秒,当请求的不在 model_timeout 里面的模型时,超时时间默认是 10 秒,不设置 default,uni-api 会使用全局配置的模型超时时间。
      keepalive_interval: # 心跳间隔,单位为秒,默认 99999 秒,选填。适合当 uni-api 域名托管在 cloudflare 并使用推理模型时使用。优先级高于全局配置的 keepalive_interval。
        gemini-2.5-pro: 50 # 模型 gemini-2.5-pro 的心跳间隔为 50 秒,此数值必须小于 model_timeout 设置的超时时间,否则忽略此设置。
      proxy: socks5://[用户名]:[密码]@[IP地址]:[端口] # 代理地址,选填。支持 socks5 和 http 代理,默认不使用代理。
      headers:  # 额外附加自定义HTTP请求头,选填。
        Custom-Header-1: Value-1
        Custom-Header-2: Value-2
      post_body_parameter_overrides: # 支持自定义请求体参数
        gemini-2.5-pro-search: # 给模型 gemini-2.5-pro-search 添加自定义请求体参数
          tools:
            - google_search: {} # 给模型 gemini-2.5-pro-search 添加 google_search 工具
            - url_context: {} # 给模型 gemini-2.5-pro-search 添加 url_context 工具

  - provider: vertex
    project_id: gen-lang-client-xxxxxxxxxxxxxx #    描述: 您的Google Cloud项目ID。格式: 字符串,通常由小写字母、数字和连字符组成。获取方式: 在Google Cloud Console的项目选择器中可以找到您的项目ID。
    private_key: "-----BEGIN PRIVATE KEY-----\nxxxxx\n-----END PRIVATE" # 描述: Google Cloud Vertex AI服务账号的私钥。格式: 一个 JSON 格式的字符串,包含服务账号的私钥信息。获取方式: 在 Google Cloud Console 中创建服务账号,生成JSON格式的密钥文件,然后将其内容设置为此环境变量的值。
    client_email: xxxxxxxxxx@xxxxxxx.gserviceaccount.com # 描述: Google Cloud Vertex AI 服务账号的电子邮件地址。格式: 通常是形如 "service-account-name@project-id.iam.gserviceaccount.com" 的字符串。获取方式: 在创建服务账号时生成,也可以在 Google Cloud Console 的"IAM与管理"部分查看服务账号详情获得。
    model:
      - gemini-2.5-flash
      - gemini-3-pro-preview: gemini-3-pro
      - gemini-pro-latest: gemini-2.5-pro-search # 可以以 -search 后缀重命名模型,同时在 post_body_parameter_overrides 设置针对此模型的自定义请求体参数即可启用搜索。不设置 post_body_parameter_overrides 参数,则无法启用搜索。
      - claude-sonnet-4-5@20250929: claude-sonnet-4-5
      - claude-opus-4-5@20251101: claude-opus-4-5
      - claude-haiku-4-5@20251001: claude-haiku-4-5
      - gemini-embedding-001
      - text-embedding-004
    tools: true
    notes: https://xxxxx.com/ # 可以放服务商的网址,备注信息,官方文档,选填
    preferences:
      post_body_parameter_overrides: # 支持自定义请求体参数
        gemini-2.5-pro-search: # 给模型 gemini-2.5-pro-search 添加自定义请求体参数
          tools:
            - google_search: {} # 给模型 gemini-2.5-pro-search 添加 google_search 工具
        gemini-2.5-flash:
          generationConfig:
            thinkingConfig:
              includeThoughts: True
              thinkingBudget: 24576
            maxOutputTokens: 65535
        gemini-2.5-flash-search:
          tools:
            - google_search: {}
            - url_context: {}

  - provider: cloudflare
    api: f42b3xxxxxxxxxxq4aoGAh # Cloudflare API Key,必填
    cf_account_id: 8ec0xxxxxxxxxxxxe721 # Cloudflare Account ID,必填
    model:
      - '@cf/meta/llama-3.1-8b-instruct': llama-3.1-8b # 重命名模型,@cf/meta/llama-3.1-8b-instruct 是服务商的原始的模型名称,必须使用引号包裹模型名,否则yaml语法错误,llama-3.1-8b 是重命名后的名字,可以使用简洁的名字代替原来复杂的名称,选填
      - '@cf/meta/llama-3.1-8b-instruct' # 必须使用引号包裹模型名,否则yaml语法错误

  - provider: azure
    base_url: https://your-endpoint.openai.azure.com
    api: your-api-key
    model:
      - gpt-5.2
    preferences:
      post_body_parameter_overrides: # 支持自定义请求体参数
        key1: value1 # 强制在请求中添加 "key1": "value1" 参数
        key2: value2 # 强制在请求中添加 "key2": "value2" 参数
        stream_options:
          include_usage: true # 强制在请求中添加 "stream_options": {"include_usage": true} 参数
      cooldown_period: 0 # 当 cooldown_period 设置为 0 时,表示该渠道不启用冷却机制,优先级高于全局配置的 cooldown_period。

  - provider: databricks
    base_url: https://xxx.azuredatabricks.net
    api:
      - xxx
    model:
      - databricks-claude-sonnet-4: claude-sonnet-4
      - databricks-claude-opus-4: claude-opus-4
      - databricks-claude-sonnet-4-5: claude-sonnet-4-5

  - provider: aws
    base_url: https://bedrock-runtime.us-east-1.amazonaws.com
    aws_access_key: xxxxxxxx
    aws_secret_key: xxxxxxxx
    model:
      - anthropic.claude-sonnet-4-5-20250929-v1:0: claude-sonnet-4-5

  - provider: vertex-express
    base_url: https://aiplatform.googleapis.com/
    project_id:
      - xxx # key1 的 project_id
      - xxx # key2 的 project_id
    api:
      - xx.xxx # key1 的 api
      - xx.xxx # key2 的 api
    model:
      - gemini-3-pro-preview

  - provider: other-provider
    base_url: https://api.xxx.com/v1/messages
    api: sk-bNnAOJyA-xQw_twAA
    model:
      - causallm-35b-beta2ep-q6k: causallm-35b
      - anthropic/claude-sonnet-4-5
    tools: false
    engine: openrouter # 强制使用某个消息格式,目前支持 gpt,claude,gemini,openrouter 原生格式,选填

  # 豆包火山引擎翻译(Ark /api/v3/responses)
  - provider: doubao-translate
    base_url: https://ark.cn-beijing.volces.com/api/v3/responses
    api: xxxxxxxxxxxxxxxxxxxxxxxx
    model:
      - doubao-seed-translation
    preferences:
      post_body_parameter_overrides:
        doubao-seed-translation:
          translation_options:
            target_language: zh # 默认目标语言,可选
            # source_language: en # 可选

api_keys:
  - api: sk-[REDACTED] # API Key,用户使用本服务需要 API key,必填
    model: # 该 API Key 可以使用的模型,选填。默认开启渠道级轮询负载均衡,每次请求模型按照 model 配置的顺序依次请求。与 providers 里面原始的渠道顺序无关。因此你可以设置每个 API key 请求顺序不一样。
      - gpt-5.2 # 可以使用的模型名称,可以使用所有提供商提供的 gpt-5.2 模型
      - claude-sonnet-4-5 # 可以使用的模型名称,可以使用所有提供商提供的 claude-sonnet-4-5 模型
      - gemini/* # 可以使用的模型名称,仅可以使用名为 gemini 提供商提供的所有模型,其中 gemini 是 provider 名称,* 代表所有模型
    role: admin # 设置 API key 的别名,选填。请求日志会显示该 API key 的别名。如果 role 为 admin,则仅有此 API key 可以请求 v1/stats,/v1/generate-api-key 端点。如果所有 API key 都没有设置 role 为 admin,则默认第一个 API key 为 admin 拥有请求 v1/stats,/v1/generate-api-key 端点的权限。

  - api: sk-[REDACTED]
    model:
      - anthropic/claude-sonnet-4-5 # 可以使用的模型名称,仅可以使用名为 anthropic 提供商提供的 claude-sonnet-4-5 模型。其他提供商的 claude-sonnet-4-5 模型不可以使用。这种写法不会匹配到other-provider提供的名为anthropic/claude-3-5-sonnet的模型。
      - <anthropic/claude-sonnet-4-5> # 通过在模型名两侧加上尖括号,这样就不会去名为anthropic的渠道下去寻找claude-3-5-sonnet模型,而是将整个 anthropic/claude-sonnet-4-5 作为模型名称。这种写法可以匹配到other-provider提供的名为 anthropic/claude-sonnet-4-5 的模型。但不会匹配到anthropic下面的claude-3-5-sonnet模型。
      - openai-test/omni-moderation-latest # 当开启消息道德审查后,可以使用名为 openai-test 渠道下的 omni-moderation-latest 模型进行道德审查。
      - sk-KjjI60Yd0JFWtxxxxxxxxxxxxxxwmRWpWpQRo/* # 支持将其他 api key 当作渠道
    preferences:
      SCHEDULING_ALGORITHM: fixed_priority # 当 SCHEDULING_ALGORITHM 为 fixed_priority 时,使用固定优先级调度,永远执行第一个拥有请求的模型的渠道。默认开启,SCHEDULING_ALGORITHM 缺省值为 fixed_priority。SCHEDULING_ALGORITHM 可选值有:fixed_priority,round_robin,weighted_round_robin, lottery, random。
      # 当 SCHEDULING_ALGORITHM 为 random 时,使用随机轮训负载均衡,随机请求拥有请求的模型的渠道。
      # 当 SCHEDULING_ALGORITHM 为 round_robin 时,使用轮训负载均衡,按照顺序请求用户使用的模型的渠道。
      AUTO_RETRY: true # 是否自动重试,自动重试下一个提供商,true 为自动重试,false 为不自动重试,默认为 true。也可以设置为数字,表示重试次数。
      rate_limit: 15/min # 支持限流,每分钟最多请求次数,可以设置为整数,如 2/min,2 次每分钟、5/hour,5 次每小时、10/day,10 次每天,10/month,10 次每月,10/year,10 次每年。默认999999/min,选填。支持多个频率约束条件:15/min,10/day
      # rate_limit: # 可以为每个模型设置不同的频率限制
      #   gemini-2.5-flash: 10/min,500/day
      #   gemini-2.5-pro: 5/min,25/day
      #   default: 4/min # 如果模型没有设置频率限制,使用 default 的频率限制
      ENABLE_MODERATION: true # 是否开启消息道德审查,true 为开启,false 为不开启,默认为 false,当开启后,会对用户的消息进行道德审查,如果发现不当的消息,会返回错误信息。

  # 渠道级加权负载均衡配置示例
  - api: sk-KjjI60Yd0JFWtxxxxxxxxxxxxxxwmRWpWpQRo
    model:
      - gcp1/*: 5 # 冒号后面就是权重,权重仅支持正整数。
      - gcp2/*: 3 # 数字的大小代表权重,数字越大,请求的概率越大。
      - gcp3/*: 2 # 在该示例中,所有渠道加起来一共有 10 个权重,及 10 个请求里面有 5 个请求会请求 gcp1/* 模型,2 个请求会请求 gcp2/* 模型,3 个请求会请求 gcp3/* 模型。

    preferences:
      SCHEDULING_ALGORITHM: weighted_round_robin # 仅当 SCHEDULING_ALGORITHM 为 weighted_round_robin 并且上面的渠道如果有权重,会按照加权后的顺序请求。使用加权轮训负载均衡,按照权重顺序请求拥有请求的模型的渠道。当 SCHEDULING_ALGORITHM 为 lottery 时,使用抽奖轮训负载均衡,按照权重随机请求拥有请求的模型的渠道。没设置权重的渠道自动回退到 round_robin 轮训负载均衡。
      AUTO_RETRY: true
      credits: 10 # 支持设置余额,此时设置的数字表示该 API Key 的可以用 10 美元,选填。默认为无限余额,当设置为 0 时,该 key 不可使用。当用户使用完余额后,后续请求将会被阻止。
      created_at: 2024-01-01T00:00:00+08:00 # 当设置好余额后,必须设置 created_at 参数,表示使用费用从 created_at 设定的时间开始计算。选填。默认从当前时间的第 30 天前开始计算。

preferences: # 全局配置
  model_timeout: # 模型超时时间,单位为秒,默认 100 秒,选填
    gpt-5.2: 10 # 模型 gpt-5.2 的超时时间为 10 秒,gpt-5.2 是模型名称,当请求 gpt-5.2-2025-12-11 等模型时,超时时间也是 10 秒
    claude-sonnet-4-5: 10 # 模型 claude-sonnet-4-5 的超时时间为 10 秒,当请求 claude-sonnet-4-5-20250929 等模型时,超时时间也是 10 秒
    default: 10 # 模型没有设置超时时间,使用默认的超时时间 10 秒,当请求的不在 model_timeout 里面的模型时,超时时间默认是 10 秒,不设置 default,uni-api 会使用 环境变量 TIMEOUT 设置的默认超时时间,默认超时时间是 100 秒
    gemini-3-pro: 30 # 模型 gemini-3-pro 的超时时间为 30 秒,当请求名字是 gemini-3-pro 开头的模型时,超时时间是 30 秒
    gemini-3-pro-image: 100 # 模型 gemini-3-pro-image 的超时时间为 100 秒,当请求名字是 gemini-3-pro-image 开头的模型时,超时时间是 100 秒
  cooldown_period: 300 # 渠道冷却时间,单位为秒,默认 300 秒,选填。当模型请求失败时,会自动将该渠道排除冷却一段时间,不再请求该渠道,冷却时间结束后,会自动将该模型恢复,直到再次请求失败,会重新冷却。当 cooldown_period 设置为 0 时,不启用冷却机制。
  rate_limit: 999999/min # uni-api 全局速率限制,单位为次数/分钟,支持多个频率约束条件,例如:15/min,10/day。默认 999999/min,选填。
  keepalive_interval: # 心跳间隔,单位为秒,默认 99999 秒,选填。适合当 uni-api 域名托管在 cloudflare 并使用推理模型时使用。
    gemini-2.5-pro: 50 # 模型 gemini-2.5-pro 的心跳间隔为 50 秒,此数值必须小于 model_timeout 设置的超时时间,否则忽略此设置。
  error_triggers: # 错误触发器,当模型返回的消息包含错误触发器中的任意一个字符串时,该渠道会自动返回报错。选填
    - The bot's usage is covered by the developer
    - process this request due to overload or policy
  proxy: socks5://[username]:[password]@[ip]:[port] # 全局代理地址,选填。
  model_price: # 模型价格,单位为美元/M tokens,选填。默认价格为 1,2,表示输入 1 美元/100 万 tokens,输出 2 美元/100 万 tokens。
    gpt-5.2: 1,2
    claude-sonnet-4-5: 0.12,0.48
    default: 1,2
```

挂载配置文件并启动 uni-api docker 容器:

```bash
docker run --user root -p 8001:8000 --name uni-api -dit \
-v ./api.yaml:/home/api.yaml \
yym68686/uni-api:latest
```

### 方法二:使用 `CONFIG_URL` 环境变量启动 uni-api

按照方法一写完配置文件后,上传到云端硬盘,获取文件的直链,然后使用 `CONFIG_URL` 环境变量启动 uni-api docker 容器:

```bash
docker run --user root -p 8001:8000 --name uni-api -dit \
-e CONFIG_URL=http://file_url/api.yaml \
yym68686/uni-api:latest
```

### Codex(`/v1/responses` + `engine: codex`)

如果你希望使用 Codex CLI / OpenAI Responses API 客户端直接请求 uni-api,请:

1. 客户端将 `base_url` 指向 uni-api,并携带 uni-api 的 `api_keys[].api`。
2. 在 uni-api 的 `providers` 中新增一个 `engine: codex` 的渠道,配置多个账号凭据(`api` 支持列表;使用 `account_id,refresh_token` 逗号格式,uni-api 会自动换取/刷新 `access_token`)。
3. 当某个账号额度耗尽时,uni-api 会对该 token 进行冷却并自动切换到下一个账号(默认冷却 6 小时,可用 `api_key_quota_cooldown_period` 覆盖)。

示例配置:

```yaml
providers:
  - provider: codex
    engine: codex
    # 支持填写为 https://chatgpt.com/backend-api/codex 或 https://chatgpt.com/backend-api/codex/responses
    base_url: https://chatgpt.com/backend-api/codex
    api:
      # 每个条目为 "account_id,refresh_token"(用于自动设置 Chatgpt-Account-Id,并自动换取 access_token 作为 Bearer)
      - <chatgpt_account_id_1>,<refresh_token_1>
      - <chatgpt_account_id_2>,<refresh_token_2>
    model:
      - gpt-5.2-codex
      - gpt-5.2-codex-mini
    preferences:
      api_key_schedule_algorithm: round_robin
      api_key_quota_cooldown_period: 21600 # 额度耗尽冷却时间(秒),可选

api_keys:
  - api: sk-xxx
    model:
      - codex/*
```

> 提示:如果你的客户端只支持 `/v1/chat/completions`,也可以直接用同样的模型名走 `/v1/chat/completions`,uni-api 会按需对上游 Responses 流进行转换。
>
> 注意:Codex 上游会拒绝部分 Chat Completions 参数(如 `temperature`/`top_p`/`max_tokens` 等),uni-api 会在转发时自动过滤;如果你看到 `403 Forbidden`,也请先确认客户端携带的是 uni-api 的 `api_keys[].api`。

### 搜索渠道(`/v1/search`)

要启用 `/v1/search`,需要在 `providers` 中配置包含 `search` 模型的渠道,并在 `api_keys[].model` 中显式授权 `provider/search`。

示例(Jina + Tavily):

```yaml
providers:
  - provider: jina
    base_url: https://api.jina.ai/v1/chat/completions
    api:
      - jina_xxx1
      - jina_xxx2
    model:
      - jina-embeddings-v3
      - search
    preferences:
      api_key_rate_limit:
        search: 100/min

  - provider: tavily
    base_url: https://api.tavily.com/search
    api:
      - tvly-dev-xxx
    model:
      - search
    preferences:
      api_key_rate_limit:
        search: 100/min

api_keys:
  - api: sk-xxx
    model:
      - jina/search
      - tavily/search
```

请求示例:

```bash
curl -X GET 'https://xxx.xxx/v1/search?q=Jina%2BAI' \
  --header 'Authorization: Bearer sk-xxx'
```

## 环境变量

- CONFIG_URL: 配置文件的下载地址,可以是本地文件,也可以是远程文件,选填。
- DEBUG: 是否开启调试模式,默认为 false,选填,开启后会打印更多日志,用于提交 issue 时使用。
- TIMEOUT: 请求超时时间,默认为 100 秒,超时时间可以控制当一个渠道没有响应时,切换下一个渠道需要的时间,选填。
- DISABLE_DATABASE: 是否禁用数据库,默认为 false,选填。
- DB_TYPE: 数据库类型,默认为 sqlite,选填。支持 sqlite 和 postgres。

当 DB_TYPE 为 postgres 时,需要设置以下环境变量:

- DB_USER: 数据库用户名,默认为 postgres,选填。
- DB_PASSWORD: 数据库密码,默认为 mysecretpassword,选填。
- DB_HOST: 数据库主机,默认为 localhost,选填。
- DB_PORT: 数据库端口,默认为 5432,选填。
- DB_NAME: 数据库名称,默为 postgres,选填。

## Koyeb 远程部署

点击下面的按钮可以自动使用构建好的 uni-api docker 镜像一键部署:

[![Deploy to Koyeb](https://www.koyeb.com/static/images/deploy/button.svg)](https://app.koyeb.com/deploy?name=uni-api&type=docker&image=docker.io%2Fyym68686%2Funi-api%3Alatest&instance_type=free&regions=was&instances_min=0&env%5BCONFIG_URL%5D=)

让 Koyeb 读取配置文件有两种方法,选一种即可:

1. 填写环境变量 `CONFIG_URL` 为配置文件的直链

2. 直接粘贴 api.yaml 文件内容,如果直接把 api.yaml 文件内容粘贴到 Koyeb 环境变量设置的 file 里面,其中粘贴到文本框后,在下方 path 输入 api.yaml 路径为 `/home/api.yaml`。

最后点击 Deploy 部署按钮。

## Ubuntu 部署

在仓库 Releases 找到对应的二进制文件最新版本,例如名为 uni-api-linux-x86_64-0.0.99.pex 的文件。在服务器下载二进制文件并运行:

```bash
wget https://github.com/yym68686/uni-api/releases/download/v0.0.99/uni-api-linux-x86_64-0.0.99.pex
chmod +x uni-api-linux-x86_64-0.0.99.pex
./uni-api-linux-x86_64-0.0.99.pex
```

## serv00 远程部署(FreeBSD 14.0)

首先登录面板,Additional services 里面点击选项卡 Run your own applications 开启允许运行自己的程序,然后到面板 Port reservation 去随便开一个端口。

如果没有自己的域名,去面板 WWW websites 删掉默认给的域名,再新建一个域名 Domain 为刚才删掉的域名,点击 Advanced settings 后设置 Website type 为 Proxy 域名,Proxy port 指向你刚才开的端口,不要选中 Use HTTPS。

ssh 登陆到 serv00 服务器,执行下面的命令:

```bash
git clone --depth 1 -b main --quiet https://github.com/yym68686/uni-api.git
cd uni-api
python -m venv uni-api
source uni-api/bin/activate
pip install --upgrade pip
cpuset -l 0 pip install -vv -r pyproject.toml
```

从开始安装到安装完成需要等待10分钟,安装完成后执行下面的命令:

```bash
tmux new -A -s uni-api
source uni-api/bin/activate
export CONFIG_URL=http://file_url/api.yaml
export DISABLE_DATABASE=true
# 修改端口,xxx 为端口,自行修改,对应刚刚在面板 Port reservation 开的端口
sed -i '' 's/port=8000/port=xxx/' main.py
sed -i '' 's/reload=True/reload=False/' main.py
python main.py
```

使用 ctrl+b d 退出 tmux,即可让程序后台运行。此时就可以在其他聊天客户端使用 uni-api 了。curl 测试脚本:

```bash
curl -X POST https://xxx.serv00.net/v1/chat/completions \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer sk-xxx' \
-d '{"model": "gpt-5.2","messages": [{"role": "user","content": "你好"}]}'
```

参考文档:

https://docs.serv00.com/Python/

https://linux.do/t/topic/201181

https://linux.do/t/topic/218738

## Docker 本地部署

Start the container

```bash
docker run --user root -p 8001:8000 --name uni-api -dit \
-e CONFIG_URL=http://file_url/api.yaml \ # 如果已经挂载了本地配置文件,不需要设置 CONFIG_URL
-v ./api.yaml:/home/api.yaml \ # 如果已经设置 CONFIG_URL,不需要挂载配置文件
-v ./uniapi_db:/home/data \ # 如果不想保存统计数据,不需要挂载该文件夹
yym68686/uni-api:latest
```

Or if you want to use Docker Compose, here is a docker-compose.yml example:

```yaml
services:
  uni-api:
    container_name: uni-api
    image: yym68686/uni-api:latest
    environment:
      - CONFIG_URL=http://file_url/api.yaml # 如果已经挂载了本地配置文件,不需要设置 CONFIG_URL
    ports:
      - 8001:8000
    volumes:
      - ./api.yaml:/home/api.yaml # 如果已经设置 CONFIG_URL,不需要挂载配置文件
      - ./uniapi_db:/home/data # 如果不想保存统计数据,不需要挂载该文件夹
```

CONFIG_URL 就是可以自动下载远程的配置文件。比如你在某个平台不方便修改配置文件,可以把配置文件传到某个托管服务,可以提供直链给 uni-api 下载,CONFIG_URL 就是这个直链。如果使用本地挂载的配置文件,不需要设置 CONFIG_URL。CONFIG_URL 是在不方便挂载配置文件的情况下使用。

### api.yaml 热重启(最小修改)+ 前端同步读取

`uni-api` 默认启动时读取一次 `api.yaml`。如果你希望“在前端修改 api.yaml 后,uni-api 立即生效”,最小修改的做法是:

- `api.yaml` 同时挂载给后端 `uni-api` 和前端(`uni-api-status`)
- 额外加一个 `config-watcher` 监听 `api.yaml` 变更,并自动 `docker restart uni-api`

下面是一个可直接使用的 `docker-compose.yml` 示例(把 `./api.yaml` 放在同目录):

```yaml
services:
  uni-api:
    image: yym68686/uni-api:latest
    container_name: uni-api
    restart: unless-stopped
    ports:
      - "8001:8000"
    environment:
      - WATCHFILES_FORCE_POLLING=true
    volumes:
      - ./api.yaml:/home/api.yaml
      - ./uniapi_db:/home/data

  uniapi-frontend:
    image: ghcr.io/melosbot/uni-api-status:latest
    container_name: uni-api-frontend
    restart: unless-stopped
    ports:
      - "3700:3000"
    environment:
      - NODE_ENV=production
      - PORT=3000
      - API_YAML_PATH=/app/config/api.yaml
      - STATS_DB_PATH=/app/data/stats.db
    volumes:
      - ./api.yaml:/app/config/api.yaml
      - ./uniapi_db:/app/data:ro
    depends_on:
      - uni-api

  config-watcher:
    image: alpine:latest
    container_name: uni-api-config-watcher
    restart: unless-stopped
    volumes:
      - ./api.yaml:/watch/api.yaml:ro
      - /var/run/docker.sock:/var/run/docker.sock
    command: >
      sh -c "
      apk add --no-cache inotify-tools docker-cli &&
      while true; do
        inotifywait -e modify,close_write /watch/api.yaml &&
        echo 'api.yaml changed, restarting uni-api...' &&
        docker restart uni-api
      done
      "
```

注意:`config-watcher` 通过挂载 `/var/run/docker.sock` 来重启容器,仅建议在可信机器/环境中使用。

如需用域名同时访问前端和 API,可用 Caddy 反代(`Caddyfile` 示例):

```caddyfile
yourdomain.com {
  encode gzip
  tls a@bc.com

  route /v1* {
    reverse_proxy localhost:8001 {
      header_up Host {host}
      header_up X-Real-IP {remote}
    }
  }

  route * {
    reverse_proxy localhost:3700 {
      header_up Host {host}
      header_up X-Real-IP {remote}
    }
  }
}
```

这样就可以通过 `yourdomain.com` 在前端修改 `api.yaml`,保存后会触发重启 `uni-api`,随后 `uni-api` 会读取最新配置。

Run Docker Compose container in the background

```bash
docker-compose pull
docker-compose up -d
```

Docker build

```bash
docker buildx build --platform linux/amd64,linux/arm64 -t yym68686/uni-api:latest --push .
docker pull yym68686/uni-api:latest

# test image
docker buildx build --platform linux/amd64,linux/arm64 -t yym68686/uni-api:test -f Dockerfile.debug --push .
docker pull yym68686/uni-api:test
```

One-Click Restart Docker Image

```bash
set -eu
docker pull yym68686/uni-api:latest
docker rm -f uni-api
docker run --user root -p 8001:8000 -dit --name uni-api \
-e CONFIG_URL=http://file_url/api.yaml \
-v ./api.yaml:/home/api.yaml \
-v ./uniapi_db:/home/data \
yym68686/uni-api:latest
docker logs -f uni-api
```

RESTful curl test

```bash
curl -X POST http://127.0.0.1:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${API}" \
-d '{"model": "gpt-5.2","messages": [{"role": "user", "content": "Hello"}],"stream": true}'
```

音频输入(/v1/chat/completions)示例:

```bash
curl -X POST 'https://xxx.xxx/v1/chat/completions' \
  --header 'Content-Type: application/json' \
  --header "Authorization: Bearer ${API}" \
  --data '{
  "model": "gemini-2.5-flash",
  "messages": [
    {
      "role": "user",
      "content": [
        {
          "type": "text",
          "text": "Generate a transcript of the speech."
        },
        {
          "type": "input_audio",
          "input_audio": {
            "data": "<base64 bytes here>",
            "format": "wav"
          }
        }
      ]
    }
  ]
}'
```

使用 URL 作为音频输入:

```bash
curl -X POST 'https://xxx.xxx/v1/chat/completions' \
  --header 'Content-Type: application/json' \
  --header "Authorization: Bearer ${API}" \
  --data '{
  "model": "gemini-2.5-flash",
  "messages": [
    {
      "role": "user",
      "content": [
        {
          "type": "text",
          "text": "Generate a transcript of the speech."
        },
        {
          "type": "input_audio",
          "input_audio": {
            "data": "https://www.youtube.com/watch?v=ku-N-eS1lgM",
            "format": "mp4"
          }
        }
      ]
    }
  ]
}'
```

pex linux 打包:

```bash
VERSION=$(cat VERSION)
pex -D . -r pyproject.toml \
    -c uvicorn \
    --inject-args 'main:app --host 0.0.0.0 --port 8000' \
    --platform linux_x86_64-cp-3.10.12-cp310 \
    --interpreter-constraint '==3.10.*' \
    --no-strip-pex-env \
    -o uni-api-linux-x86_64-${VERSION}.pex
```

macos 打包:

```bash
VERSION=$(cat VERSION)
pex -r pyproject.toml \
    -c uvicorn \
    --inject-args 'main:app --host 0.0.0.0 --port 8000' \
    -o uni-api-macos-arm64-${VERSION}.pex
```

## HuggingFace Space 远程部署

WARN: 请注意远程部署的密钥泄露风险,请勿滥用服务以避免封号
Space 仓库需要提供三个文件  `Dockerfile`、`README.md`、`entrypoint.sh`
运行程序还需要 api.yaml(我以全量放在机密中为例,也可以HTTP下载的方式实现),访问匹配、模型和渠道配置等均在配置文件中
操作步骤
1. 访问 https://huggingface.co/new-space 新建一个sapce,要public库,开源协议/名字/描述等随便
2. 访问你的space的file,URL是 https://huggingface.co/spaces/your-name/your-space-name/tree/main,把下面三个文件上传(`Dockerfile`、`README.md`、`entrypoint.sh`)
3. 访问你的space的setting,URL是 https://huggingface.co/spaces/your-name/your-space-name/settings 找到 Secrets 新建机密 `API_YAML_CONTENT`(注意大写),把你的api.yaml在本地写好后直接复制进去,UTF-8编码
4. 继续在设置中,找到 Factory rebuild 让它重新构建,如果你修改机密或者文件或者手动重启Sapce等情况均有可能导致卡住无log,此时就用这个方法解决
5. 在设置最右上角有三个点的按钮,找到 Embed this Space 获取Space的公网链接,格式 https://(your-name)-(your-space-name).hf.space 去掉括号

相关的文件代码如下
```Dockerfile
# Dockerfile,记得删除本行
# 使用uni-api官方镜像
FROM yym68686/uni-api:latest

# 创建数据目录并设置权限
RUN mkdir -p /data && chown -R 1000:1000 /data

# 设置用户和工作目录
RUN useradd -m -u 1000 user
USER user
ENV HOME=/home/user \
    PATH=/home/user/.local/bin:$PATH \
    DISABLE_DATABASE=true

# 复制入口点脚本
COPY --chown=user entrypoint.sh /home/user/entrypoint.sh
RUN chmod +x /home/user/entrypoint.sh

# 确保/home目录可写(这很重要!)
USER root
RUN chmod 777 /home
USER user

# 设置工作目录
WORKDIR /home/user

# 入口点
ENTRYPOINT ["/home/user/entrypoint.sh"]
```

```markdown
# README.md,覆盖掉默认的,记得删除本行
---
title: Uni API
emoji: 🌍
colorFrom: gray
colorTo: yellow
sdk: docker
app_port: 8000
pinned: false
license: gpl-3.0
---
```
```shell
# entrypoint.sh,记得删除本行
#!/bin/sh
set -e
CONFIG_FILE_PATH="/home/api.yaml"  # 注意这里改成/home/api.yaml

echo "DEBUG: Entrypoint script started."

# 检查Secret是否存在
if [ -z "$API_YAML_CONTENT" ]; then
  echo "ERROR: Secret 'API_YAML_CONTENT' is不存在或为空。退出。"
  exit 1
else
  echo "DEBUG: API_YAML_CONTENT secret found. Preparing to write..."
  printf '%s\n' "$API_YAML_CONTENT" > "$CONFIG_FILE_PATH"
  echo "DEBUG: Attempted to write to $CONFIG_FILE_PATH."

  if [ -f "$CONFIG_FILE_PATH" ]; then
    echo "DEBUG: File $CONFIG_FILE_PATH created successfully. Size: $(wc -c < "$CONFIG_FILE_PATH") bytes."
    # 显示文件的前几行进行调试(注意不要显示敏感信息)
    echo "DEBUG: First few lines (without sensitive info):"
    head -n 3 "$CONFIG_FILE_PATH" | grep -v "api:" | grep -v "password"
  else
    echo "ERROR: File $CONFIG_FILE_PATH was NOT created."
    exit 1
  fi
fi

echo "DEBUG: About to execute python main.py..."
# 不需要使用--config参数,因为程序有默认路径
cd /home
exec python main.py "$@"
```

## uni-api 前端部署

uni-api 的 web 前端可以自行部署,地址:https://github.com/yym68686/uni-api-web

也可以使用我提前部署好的前端,地址:https://uni-api-web.pages.dev/

说明:`uni-api-web` 是独立的前后端项目,而 `uni-api` 目前仅提供后端能力。`uni-api-web` 不负责自动重试/故障转移等能力,这些能力仍由 `uni-api` 负责;你只需要在 `uni-api-web` 配置 `uni-api` 的 base url 即可(同时 `uni-api-web` 也可以对接其他兼容的 API)。`uni-api-web` 主要提供用户管理、计费、日志、权限控制等功能;`uni-api` 会一直保持“仅后端”的设计。

前端相关环境变量的解释请参考 `uni-api-web` 的 README:https://github.com/yym68686/uni-api-web

下面是一个 `docker-compose.yml` 示例:

```yaml
services:
  web:
    image: yym68686/uni-api-frontend:main
    container_name: uni-api-frontend
    restart: unless-stopped
    depends_on:
      - api
    environment:
      # Inside Docker, use service-to-service networking (NOT localhost).
      API_BASE_URL: ${API_BASE_URL:-http://api:8000/v1}
      NEXT_TELEMETRY_DISABLED: ${NEXT_TELEMETRY_DISABLED:-1}
      NODE_ENV: ${NODE_ENV:-production}
      APP_NAME: ${APP_NAME:-UniAPI}
      GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID:-}
      GOOGLE_REDIRECT_URI: ${GOOGLE_REDIRECT_URI:-}
    ports:
      - "8003:3000"

  db:
    image: postgres:17.6-alpine
    container_name: uni-api-db
    restart: unless-stopped
    environment:
      POSTGRES_USER: ${DB_POSTGRES_USER:-uniapi}
      POSTGRES_PASSWORD: ${DB_POSTGRES_PASSWORD:-}
      POSTGRES_DB: ${DB_POSTGRES_DB:-uniapi}
    ports:
      - "5433:5432"
    volumes:
      - uniapi_pg_data:/var/lib/postgresql/data

  api:
    image: yym68686/uni-api-backend:main
    container_name: uni-api-backend
    restart: unless-stopped
    depends_on:
      - db
    environment:
      DATABASE_URL: ${DATABASE_URL:-}
      APP_ENV: ${APP_ENV:-dev}
      APP_NAME: ${BACKEND_APP_NAME:-Uni API Backend}
      API_PREFIX: ${API_PREFIX:-/v1}
      SESSION_TTL_DAYS: ${SESSION_TTL_DAYS:-7}
      GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID:-}
      GOOGLE_CLIENT_SECRET: ${GOOGLE_CLIENT_SECRET:-}
      GOOGLE_REDIRECT_URI: ${GOOGLE_REDIRECT_URI:-}
      ADMIN_BOOTSTRAP_TOKEN: ${ADMIN_BOOTSTRAP_TOKEN:-}
      RESEND_API_KEY: ${RESEND_API_KEY:-}
      RESEND_FROM_EMAIL: ${RESEND_FROM_EMAIL:-}
      EMAIL_VERIFICATION_REQUIRED: ${EMAIL_VERIFICATION_REQUIRED:-true}
    ports:
      - "8002:8000"

  postgres:
    container_name: postgres
    image: postgres:17.6
    restart: always
    environment:
      POSTGRES_USER: ${UNIAPI_POSTGRES_USER:-root}
      POSTGRES_PASSWORD: ${UNIAPI_POSTGRES_PASSWORD:-}
      POSTGRES_DB: ${UNIAPI_POSTGRES_DB:-uniapi}
    ports:
      - "5432:5432"
    volumes:
      - ./postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${UNIAPI_POSTGRES_USER:-root} -d ${UNIAPI_POSTGRES_DB:-uniapi}"]
      interval: 5s
      timeout: 5s
      retries: 5

  uni-api:
    container_name: uni-api
    image: yym68686/uni-api:latest
    environment:
      # CONFIG_URL: ${CONFIG_URL:-}
      TIMEOUT: ${TIMEOUT:-200}
      DB_TYPE: ${DB_TYPE:-postgres}
      DB_HOST: ${DB_HOST:-postgres}
      DB_PORT: ${DB_PORT:-5432}
      DB_USER: ${DB_USER:-root}
      DB_PASSWORD: ${DB_PASSWORD:-}
      DB_NAME: ${DB_NAME:-uniapi}
    depends_on:
      postgres:
        condition: service_healthy
    ports:
      - "8001:8000"
    volumes:
      - ./api-copy.yaml:/home/api.yaml
      - ./uniapi_db:/home/data
      - /etc/localtime:/etc/localtime:ro
    restart: unless-stopped

volumes:
  uniapi_pg_data:
```

## 赞助商

我们感谢以下赞助商的支持:
<!-- ¥2050 -->
- @PowerHunter:¥2000
- @IM4O4: ¥100
- @ioi:¥50

## 如何赞助我们

如果您想支持我们的项目,您可以通过以下方式赞助我们:

1. [PayPal](https://www.paypal.me/yym68686)

2. [USDT-TRC20](https://pb.yym68686.top/~USDT-TRC20),USDT-TRC20 钱包地址:`TLFbqSv5pDu5he43mVmK1dNx7yBMFeN7d8`

3. [微信](https://pb.yym68686.top/~wechat)

4. [支付宝](https://pb.yym68686.top/~alipay)

感谢您的支持!

## 常见问题

- 为什么总是出现 `Error processing request or performing moral check: 404: No matching model found` 错误?

将 ENABLE_MODERATION 设置为 false 将修复这个问题。当 ENABLE_MODERATION 为 true 时,API 必须能够使用 omni-moderation-latest 模型,如果你没有在提供商模型设置里面提供 omni-moderation-latest,将会报错找不到模型。

- 怎么优先请求某个渠道,怎么设置渠道的优先级?

直接在api_keys里面通过设置渠道顺序即可。不需要做其他设置,示例配置文件:

```yaml
providers:
  - provider: ai1
    base_url: https://xxx/v1/chat/completions
    api: sk-xxx

  - provider: ai2
    base_url: https://xxx/v1/chat/completions
    api: sk-xxx

api_keys:
  - api: sk-1234
    model:
      - ai2/*
      - ai1/*
```

这样设置则先请求 ai2,失败后请求 ai1。

- 各种调度算法背后的行为是怎样的?比如 fixed_priority,weighted_round_robin,lottery,random,round_robin, smart_round_robin?

所有调度算法需要通过在配置文件的 api_keys.(api).preferences.SCHEDULING_ALGORITHM 设置为 fixed_priority,weighted_round_robin,lottery,random,round_robin, smart_round_robin 中的任意值来开启。

1. fixed_priority:固定优先级调度。所有请求永远执行第一个拥有用户请求的模型的渠道。报错时,会切换下一个渠道。这是默认的调度算法。

2. weighted_round_robin:加权轮训负载均衡,按照配置文件 api_keys.(api).model 设定的权重顺序请求拥有用户请求的模型的渠道。

3. lottery:抽奖轮训负载均衡,按照配置文件 api_keys.(api).model 设置的权重随机请求拥有用户请求的模型的渠道。

4. round_robin:轮训负载均衡,按照配置文件 api_keys.(api).model 的配置顺序请求拥有用户请求的模型的渠道。可以查看上一个问题,如何设置渠道的优先级。

5. smart_round_robin: 智能成功率调度。这是一个专为拥有大量 API Key(成百上千甚至数万个)的渠道设计的先进调度算法。它的核心机制是:
    - **基于历史成功率排序**:算法会根据过去72小时内每个 API Key 的实际请求成功率进行动态排序。
    - **智能分组与负载均衡**:为了避免流量永远只集中在少数几个“最优” Key 上,该算法会将所有 Key(包括从未用过的 Key)智能地分成若干组。它会将成功率最高的 Key 分布到每个组的开头,次高的分布到第二位,以此类推。这确保了负载能被均匀地分配给不同梯队的 Key,同时也保证了新 Key 或历史表现不佳的 Key 也有机会被尝试(探索)。
    - **周期性自动更新**:当一个渠道的所有 Key 都被轮询过一遍之后,系统会自动触发一次重排序,从数据库中拉取最新的成功率数据,生成一个全新的、更优的 Key 序列。这个更新频率是自适应的:Key 池越大、请求量越小,更新周期就越长;反之则越短。
    - **适用场景**:强烈建议拥有大量 API Key 的用户启用此算法,以最大化 Key 池的利用率和请求成功率。

- 应该怎么正确填写 base_url?

除了高级配置里面所展示的一些特殊的渠道,所有 OpenAI 格式的提供商需要把 base_url 填完整,也就是说 base_url 必须以 /v1/chat/completions 结尾或者 /v1/responses 结尾。如果你使用的 GitHub models,base_url 应该填写为 https://models.inference.ai.azure.com/chat/completions,而不是 Azure 的 URL。

对于 Azure 渠道,base_url 兼容以下几种写法:https://your-endpoint.services.ai.azure.com/models/chat/completions?api-version=2024-05-01-preview 和 https://your-endpoint.services.ai.azure.com/models/chat/completions,https://your-endpoint.openai.azure.com,推荐使用第一种写法。如果不显式指定 api-version,默认使用 2024-10-21 版本。

- 模型超时时间是如何确认的?渠道级别的超时设置和全局模型超时设置的优先级是什么?

渠道级别的超时设置优先级高于全局模型超时设置。优先级顺序:渠道级别模型超时设置 > 渠道级别默认超时设置 > 全局模型超时设置 > 全局默认超时设置 > 环境变量 TIMEOUT。

更细一点,`model_timeout` 和 `keepalive_interval` 的匹配规则是一样的(同时适用于全局 `preferences.model_timeout` / `preferences.keepalive_interval` 和单个渠道 `providers.(provider).preferences.model_timeout` / `providers.(provider).preferences.keepalive_interval`):

1. 先定义两个名字:
   - 「请求模型名」:你在请求体 `model` 字段里写的,例如 `gpt-5.2`、`claude-sonnet-4-5`。
   - 「真实上游模型名」:在 `providers.(provider).model` 左边配置的原始 ID,例如:
     ```yaml
     providers:
       - provider: openai
         model:
           - gpt-5.2-2025-12-11: gpt-5.2   # 左边是真实上游模型名,右边是请求里使用的别名
     ```
     在这个例子里,请求模型名是 `gpt-5.2`,真实上游模型名是 `gpt-5.2-2025-12-11`。

2. 在某个具体渠道下(单个 provider 的 `preferences.model_timeout`)确定超时时间时,会按下面 6 层回退顺序依次尝试(前一步命中就不会再往后走):

   1) 使用「请求模型名」在该渠道的 `model_timeout` 中做精确匹配(大小写不敏感)。

   2) 如果没有精确命中,再用「请求模型名」做模糊匹配:检查 `model_timeout` 下面是否有某个 key 是请求模型名的一部分。
      比如你只配置了:
      ```yaml
      model_timeout:
        gpt-5.2: 20
      ```
      那么 `gpt-5.2-2025-12-11`、`gpt-5-mini` 等模型都会命中 20 秒。

   3) 如果请求模型名在这个渠道里完全匹配不到任何 key,再换成「真实上游模型名」在该渠道的 `model_timeout` 中做精确匹配。
      例如只给上游 ID `gpt-5.2-2025-12-11` 配了超时,也能在这一步被命中。

   4) 如果真实上游模型名的精确匹配失败,再用「真实上游模型名」做模糊匹配:检查 `model_timeout` 下面的某个 key 是否是真实上游模型名的一部分。

   5) 如果前四步都没有命中,并且该渠道的 `model_timeout` 里配置了 `default`,则使用该渠道的 `default` 超时时间。

   6) 如果这个渠道完全没有命中(包括没有渠道级 `default`),则回退到全局 `preferences.model_timeout`:
      - 先用「请求模型名」按「精确匹配 → 模糊匹配 → 全局 `default`」的顺序尝试一遍;
      - 如果没有命中,再用「真实上游模型名」按「精确匹配 → 模糊匹配 → 全局 `default`」的顺序尝试一遍;
      - 如果全局也没有任何匹配,最后才会退回到环境变量 `TIMEOUT` 的值(默认 100 秒)。

实际配置时,`model_timeout` 下面的模型名可以这样写:

- 写成你请求时用的别名(例如 `gpt-5.2`、`claude-sonnet-4-5`),方便按「请求模型名」直接命中;
- 写成真实上游模型名(例如 `gpt-5.2-2025-12-11`),适合只想精确控制某个供应商的某个版本;
- 或者写一段稳定的公共前缀 / 关键子串(例如只写 `gpt-5.2`),用来同时覆盖一批以该前缀开头的模型。

通过合理配置 `model_timeout`,可以避免出现某些渠道请求超时报错的情况。如果你遇到 `{'error': '500', 'details': 'fetch_response_stream Read Response Timeout'}` 错误,请尝试增加对应模型的超时时间。

- api_key_rate_limit 是怎么工作的?我如何给多个模型设置相同的频率限制?

如果你想同时给 gemini-1.5-pro-latest,gemini-1.5-pro,gemini-1.5-pro-001,gemini-1.5-pro-002 这四个模型设置相同的频率限制,可以这样设置:

```yaml
api_key_rate_limit:
  gemini-1.5-pro: 1000/min
```

这会匹配所有含有 gemini-1.5-pro 字符串的模型。gemini-1.5-pro-latest,gemini-1.5-pro,gemini-1.5-pro-001,gemini-1.5-pro-002 这四个模型频率限制都会设置为 1000/min。api_key_rate_limit 字段配置的逻辑如下,这是一个示例配置文件:

```yaml
api_key_rate_limit:
  gemini-1.5-pro: 1000/min
  gemini-1.5-pro-002: 500/min
```

此时如果有一个使用模型 gemini-1.5-pro-002 的请求。

首先,uni-api 会尝试精确匹配 api_key_rate_limit 的模型。如果刚好设置了 gemini-1.5-pro-002 的频率限制,则 gemini-1.5-pro-002 的频率限制则为 500/min,如果此时请求的模型不是 gemini-1.5-pro-002,而是 gemini-1.5-pro-latest,由于 api_key_rate_limit 没有设置 gemini-1.5-pro-latest 的频率限制,因此会寻找有没有前缀和 gemini-1.5-pro-latest 相同的模型被设置了,因此 gemini-1.5-pro-latest 的频率限制会被设置为 1000/min。

- 我想设置渠道1和渠道2为随机轮训,uni-api 在渠道1和渠道2请求失败后才自动重试渠道3,怎么设置?

uni-api 支持将 api key 本身作为渠道,可以通过这一特性对渠道进行分组管理。

```yaml
api_keys:
  - api: sk-xxx1
    model:
      - sk-xxx2/* # 渠道 1 2 采用随机轮训,失败后请求渠道3
      - aws/* # 渠道3
    preferences:
      SCHEDULING_ALGORITHM: fixed_priority # 表示始终优先请求 api key:sk-xxx2 里面的渠道 1 2,失败后自动请求渠道 3

  - api: sk-xxx2
    model:
      - anthropic/claude-sonnet-4-5 # 渠道1
      - openrouter/claude-sonnet-4-5 # 渠道2
    preferences:
      SCHEDULING_ALGORITHM: random # 渠道 1 2 采用随机轮训
```

- 我想使用 Cloudflare AI Gateway,怎么填写 base_url?

对于 gemini 渠道,Cloudflare AI Gateway 的 base_url 需要填写为 https://gateway.ai.cloudflare.com/v1/{account_id}/{gateway_name}/google-ai-studio/v1beta/openai/chat/completions ,{account_id} 和 {gateway_name} 需要替换为你的 Cloudflare 账户 ID 和 Gateway 名称。

对于 Vertex 渠道,Cloudflare AI Gateway 的 base_url 需要填写为 https://gateway.ai.cloudflare.com/v1/{account_id}/{gateway_name}/google-vertex-ai ,{account_id} 和 {gateway_name} 需要替换为你的 Cloudflare 账户 ID 和 Gateway 名称。

- 什么时候 api key 的具有管理权限?

1. 当只有一个 key 时,说明是自用,唯一的 key 获得管理权限,可以通过前端看到所有渠道敏感信息。
2. 当存在两个以上的 key 时,必须指定其中一个或多个 key 的 role 字段为 admin,只有 role 为 admin 的 key 才有权限访问敏感信息。这样设计的原因是为了防止另外一个 key 的用户也能访问敏感信息。因此添加了 强制给 key 设置 role 为 admin 的设计。

- 配置文件使用 koyeb 文件方式部署后,如果配置文件渠道没有写 model 字段,启动会报错,怎么解决?

koyeb 部署 uni-api 的 api.yaml 默认是 0644 权限,uni-api 没有写权限。当 uni-api 尝试获取 model 字段时,会修改配置文件,此时会报错。控制台输入 chmod 0777 api.yaml 赋予 uni-api 写权限即可。

- nginx代理后无法获取用户真实IP?

nginx添加
```xml
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;

```

## 压测

压测工具:[locust](https://locust.io/)

压测脚本:[test/locustfile.py](test/locustfile.py)

mock_server:[test/mock_server.go](test/mock_server.go)

启动压测:

```bash
go run test/mock_server.go
# 100 10 120s
locust -f test/locustfile.py
python main.py
```

压测结果:

| Type | Name | 50% | 66% | 75% | 80% | 90% | 95% | 98% | 99% | 99.9% | 99.99% | 100% | # reqs |
|------|------|-----|-----|-----|-----|-----|-----|-----|-----|--------|---------|------|--------|
| POST | /v1/chat/completions (stream) | 18 | 23 | 29 | 35 | 83 | 120 | 140 | 160 | 220 | 270 | 270 | 6948 |
| | Aggregated | 18 | 23 | 29 | 35 | 83 | 120 | 140 | 160 | 220 | 270 | 270 | 6948 |

## 安全

我们非常重视项目的安全性。如果您发现任何安全漏洞,请通过 [yym68686@outlook.com](mailto:yym68686@outlook.com) 与我们联系。

**致谢 (Acknowledgments):**

*   我们特别感谢 **@ryougishiki214** 报告了一个安全问题,该问题已在 [v1.5.1](https://github.com/yym68686/uni-api/releases/tag/v1.5.1) 版本中得到解决。

## ⭐ Star 历史

<a href="https://github.com/yym68686/uni-api/stargazers">
        <img width="500" alt="Star History Chart" src="https://api.star-history.com/svg?repos=yym68686/uni-api&type=Date">
</a>

Files in this skill

  • README.md706 B
  • skill.md56.2 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.