yym68686 commited on
Commit
fc8f1ee
·
1 Parent(s): b812da1

📖 Docs: Update the documentation, add an English README.

Browse files
Files changed (4) hide show
  1. README.md +53 -52
  2. README_CN.md +190 -0
  3. test/parse_markdown.py +159 -0
  4. test/translate_md.py +50 -0
README.md CHANGED
@@ -1,71 +1,72 @@
1
  # uni-api
2
 
3
  <p align="center">
4
- <a href="https://t.me/uni_api">
5
  <img src="https://img.shields.io/badge/Join Telegram Group-blue?&logo=telegram">
6
  </a>
7
- <a href="https://hub.docker.com/repository/docker/yym68686/uni-api">
8
  <img src="https://img.shields.io/docker/pulls/yym68686/uni-api?color=blue" alt="docker pull">
9
  </a>
10
  </p>
11
 
 
12
 
13
  ## Introduction
14
 
15
- 如果个人使用的话,one/new-api 过于复杂,有很多个人不需要使用的商用功能,如果你不想要复杂的前端界面,有想要支持的模型多一点,可以试试 uni-api。这是一个统一管理大模型API的项目,可以通过一个统一的API接口调用多个后端服务,统一转换为 OpenAI 格式,支持负载均衡。目前支持的后端服务有:OpenAIAnthropicGeminiVertexDeepBricksOpenRouter 等。
16
 
17
  ## Features
18
 
19
- - 无前端,纯配置文件配置 API 渠道。只要写一个文件就能运行起一个属于自己的 API 站,文档有详细的配置指南,小白友好。
20
- - 统一管理多个后端服务,支持 OpenAIDeepseekDeepBricksOpenRouter 等其他API OpenAI 格式的提供商。支持 OpenAI Dalle-3 图像生成。
21
- - 同时支持 AnthropicGeminiVertex APIVertex 同时支持 Claude Gemini API
22
- - 支持 OpenAI AnthropicGeminiVertex 原生 tool use 函数调用。
23
- - 支持 OpenAIAnthropicGeminiVertex 原生识图 API
24
- - 支持四种负载均衡。
25
- 1. 支持渠道级加权负载均衡,可以根据不同的渠道权重分配请求。默认不开启,需要配置渠道权重。
26
- 2. 支持 Vertex 区域级负载均衡,支持 Vertex 高并发,最高可将 GeminiClaude 并发提高 (API数量 * 区域数量) 倍。自动开启不需要额外配置。
27
- 3. 除了 Vertex 区域级负载均衡,所有 API 均支持渠道级顺序负载均衡,提高沉浸式翻译体验。自动开启不需要额外配置。
28
- 4. 支持单个渠道多个 API Key 自动开启 API key 级别的轮训负载均衡。
29
- - 支持自动重试,当一个 API 渠道响应失败时,自动重试下一个 API 渠道。
30
- - 支持细粒度的权限控制。支持使用通配符设置 API key 可用渠道的特定模型。
31
- - 支持限流,可以设置每分钟最多请求次数,可以设置为整数,如 2/min2 次每分钟、5/hour5 次每小时、10/day10 次每天,10/month10 次每月,10/year10 次每年。默认60/min
32
 
33
  ## Configuration
34
 
35
- 使用 api.yaml 配置文件,可以配置多个模型,每个模型可以配置多个后端服务,支持负载均衡。下面是 api.yaml 配置文件的示例:
36
 
37
  ```yaml
38
  providers:
39
- - provider: provider_name # 服务提供商名称, openaianthropicgeminiopenrouterdeepbricks,随便取名字,必填
40
- base_url: https://api.your.com/v1/chat/completions # 后端服务的API地址,必填
41
- api: sk-YgS6GTi0b4bEabc4C # 提供商的API Key,必填
42
- model: # 至少填一个模型
43
- - gpt-4o # 可以使用的模型名称,必填
44
- - claude-3-5-sonnet-20240620: claude-3-5-sonnet # 重命名模型,claude-3-5-sonnet-20240620 是服务商的模型名称,claude-3-5-sonnet 是重命名后的名字,可以使用简洁的名字代替原来复杂的名称,选填
45
  - dall-e-3
46
 
47
  - provider: anthropic
48
  base_url: https://api.anthropic.com/v1/messages
49
- api: # 支持多个 API Key,多个 key 自动开启轮训负载均衡,至少一个 key,必填
50
  - sk-ant-api03-bNnAOJyA-xQw_twAA
51
  - sk-ant-api02-bNnxxxx
52
  model:
53
- - claude-3-5-sonnet-20240620: claude-3-5-sonnet # 重命名模型,claude-3-5-sonnet-20240620 是服务商的模型名称,claude-3-5-sonnet 是重命名后的名字,可以使用简洁的名字代替原来复杂的名称,选填
54
- tools: true # 是否支持工具,如生成代码、生成文档等,默认是 true,选填
55
 
56
  - provider: gemini
57
- base_url: https://generativelanguage.googleapis.com/v1beta # base_url 支持 v1beta/v1, 仅供 Gemini 模型使用,必填
58
  api: AIzaSyAN2k6IRdgw
59
  model:
60
  - gemini-1.5-pro
61
- - gemini-1.5-flash-exp-0827: gemini-1.5-flash # 重命名后,原来的模型名字 gemini-1.5-flash-exp-0827 无法使用,如果要使用原来的名字,可以在 model 中添加原来的名字,只要加上下面一行就可以使用原来的名字了
62
- - gemini-1.5-flash-exp-0827 # 加上这一行,gemini-1.5-flash-exp-0827 gemini-1.5-flash 都可以被请求
63
  tools: true
64
 
65
  - provider: vertex
66
- project_id: gen-lang-client-xxxxxxxxxxxxxx # 描述: 您的Google Cloud项目ID。格式: 字符串,通常由小写字母、数字和连字符组成。获取方式: Google Cloud Console的项目选择器中可以找到您的项目ID。
67
- private_key: "-----BEGIN PRIVATE KEY-----\nxxxxx\n-----END PRIVATE" # 描述: Google Cloud Vertex AI服务账号的私钥。格式: 一个JSON格式的字符串,包含服务账号的私钥信息。获取方式: Google Cloud Console中创建服务账号,生成JSON格式的密钥文件,然后将其内容设置为此环境变量的值。
68
- client_email: [email protected] # 描述: Google Cloud Vertex AI服务账号的电子邮件地址。格式: 通常是形如 "[email protected]" 的字符串。获取方式: 在创建服务账号时生成,也可以在Google Cloud Console的"IAM与管理"部分查看服务账号详情获得。
69
  model:
70
  - gemini-1.5-pro
71
  - gemini-1.5-flash
@@ -74,7 +75,7 @@ providers:
74
  - claude-3-sonnet@20240229: claude-3-sonnet
75
  - claude-3-haiku@20240307: claude-3-haiku
76
  tools: true
77
- notes: https://xxxxx.com/ # 可以放服务商的网址,备注信息,官方文档,选填
78
 
79
  - provider: other-provider
80
  base_url: https://api.xxx.com/v1/messages
@@ -82,40 +83,40 @@ providers:
82
  model:
83
  - causallm-35b-beta2ep-q6k: causallm-35b
84
  tools: false
85
- engine: openrouter # 强制使用某个消息格式,目前支持 gptclaudegeminiopenrouter 原生格式,选填
86
 
87
  api_keys:
88
- - api: sk-KjjI60Yf0JFWtfgRmXqFWyGtWUd9GZnmi3KlvowmRWpWpQRo # API Key,用户使用本服务需要 API key,必填
89
- model: # API Key 可以使用的模型,必填
90
- - gpt-4o # 可以使用的模型名称,可以使用所有提供商提供的 gpt-4o 模型
91
- - claude-3-5-sonnet # 可以使用的模型名称,可以使用所有提供商提供的 claude-3-5-sonnet 模型
92
- - gemini/* # 可以使用的模型名称,仅可以使用名为 gemini 提供商提供的所有模型,其中 gemini provider 名称,* 代表所有模型
93
  role: admin
94
 
95
  - api: sk-pkhf60Yf0JGyJygRmXqFQyTgWUd9GZnmi3KlvowmRWpWqrhy
96
  model:
97
- - anthropic/claude-3-5-sonnet # 可以使用的模型名称,仅可以使用名为 anthropic 提供商提供的 claude-3-5-sonnet 模型。其他提供商的 claude-3-5-sonnet 模型不可以使用。
98
  preferences:
99
- USE_ROUND_ROBIN: true # 是否使用轮询负载均衡,true 为使用,false 为不使用,默认为 true。开启轮训后每次请求模型按照 model 配置的顺序依次请求。与 providers 里面原始的渠道顺序无关。因此你可以设置每个 API key 请求顺序不一样。
100
- AUTO_RETRY: true # 是否自动重试,自动重试下一个提供商,true 为自动重试,false 为不自动重试,默认为 true
101
- RATE_LIMIT: 2/min # 支持限流,每分钟最多请求次数,可以设置为整数,如 2/min2 次每分钟、5/hour5 次每小时、10/day10 次每天,10/month10 次每月,10/year10 次每年。默认60/min,选填
102
 
103
- # 渠道级加权负载均衡配置示例
104
  - api: sk-KjjI60Yf0JFWtxxxxxxxxxxxxxxwmRWpWpQRo
105
  model:
106
- - gcp1/*: 5 # 冒号后面就是权重,权���仅支持正整数。
107
- - gcp2/*: 3 # 数字的大小代表权重,数字越大,请求的概率越大。
108
- - gcp3/*: 2 # 在该示例中,所有渠道加起来一共有 10 个权重,及 10 个请求里面有 5 个请求会请求 gcp1/* 模型,2 个请求会请求 gcp2/* 模型,3 个请求会请求 gcp3/* 模型。
109
 
110
  preferences:
111
- USE_ROUND_ROBIN: true # USE_ROUND_ROBIN 必须为 true 并且上面的渠道后面没有权重时,会按照原始的渠道顺序请求,如果有权重,会按照加权后的顺序请求。
112
  AUTO_RETRY: true
113
  ```
114
 
115
- ## 环境变量
116
 
117
- - CONFIG_URL: 配置文件的下载地址,可以是本地文件,也可以是远程文件,选填
118
- - TIMEOUT: 请求超时时间,默认为 20 秒,超时时间可以控制当一个渠道没有响应时,切换下一个渠道需要的时间。选填
119
 
120
  ## Docker Local Deployment
121
 
@@ -142,7 +143,7 @@ services:
142
  - ./api.yaml:/home/api.yaml
143
  ```
144
 
145
- CONFIG_URL 就是可以自动下载远程的配置文件。比如你在某个平台不方便修改配置文件,可以把配置文件传到某个托管服务,可以提供直链给 uni-api 下载,CONFIG_URL 就是这个直链。
146
 
147
  Run Docker Compose container in the background
148
 
 
1
  # uni-api
2
 
3
  <p align="center">
4
+ <a href="https://t.me/uni_api">
5
  <img src="https://img.shields.io/badge/Join Telegram Group-blue?&logo=telegram">
6
  </a>
7
+ <a href="https://hub.docker.com/repository/docker/yym68686/uni-api">
8
  <img src="https://img.shields.io/docker/pulls/yym68686/uni-api?color=blue" alt="docker pull">
9
  </a>
10
  </p>
11
 
12
+ [English](./README.md) | [Chinese](./README_CN.md)
13
 
14
  ## Introduction
15
 
16
+ If used personally, one/new-api is too complex and has many commercial features that individuals do not need. If you don't want a complicated frontend interface and want to support more models, you can try uni-api. This is a project that manages large model APIs uniformly. It allows you to call multiple backend services through a unified API interface, converting them uniformly to OpenAI format and supporting load balancing. The currently supported backend services include: OpenAI, Anthropic, Gemini, Vertex, DeepBricks, OpenRouter, etc.
17
 
18
  ## Features
19
 
20
+ - No front-end, purely configuration file to set up API channels. You can run your own API site just by writing a file. The documentation has detailed configuration guidelines, friendly for beginners.
21
+ - Unified management of multiple backend services, supporting OpenAI, Deepseek, DeepBricks, OpenRouter, and other API providers in the OpenAI format. Supports OpenAI Dalle-3 image generation.
22
+ - Supports Anthropic, Gemini, Vertex API simultaneously. Vertex supports both Claude and Gemini API.
23
+ - Support native tool use function calls for OpenAI, Anthropic, Gemini, Vertex.
24
+ - Supports OpenAI, Anthropic, Gemini, Vertex native image recognition API.
25
+ - Supports four types of load balancing.
26
+ 1. Supports channel-level weighted load balancing, which can allocate requests based on different channel weights. By default, it is not enabled and requires channel weight configuration.
27
+ 2. Supports Vertex region-level load balancing, supports Vertex high concurrency, and can increase Gemini and Claude concurrency by up to (number of APIs * number of regions) times. Automatically enabled without additional configuration.
28
+ 3. Except for Vertex region-level load balancing, all APIs support channel-level sequential load balancing, enhancing the immersive translation experience. Automatically enabled without additional configuration.
29
+ 4. Support automatic API key-level polling load balancing for multiple API Keys in a single channel.
30
+ - Supports automatic retry. When an API channel response fails, automatically retry the next API channel.
31
+ - Supports fine-grained access control. Supports using wildcards to set specific models available for API key channels.
32
+ - Supports rate limiting, can set the maximum number of requests per minute, can be set as an integer, such as 2/min, 2 times per minute, 5/hour, 5 times per hour, 10/day, 10 times per day, 10/month, 10 times per month, 10/year, 10 times per year. Default is 60/min.
33
 
34
  ## Configuration
35
 
36
+ Using the api.yaml configuration file, you can configure multiple models, and each model can configure multiple backend services, supporting load balancing. Below is an example of the api.yaml configuration file:
37
 
38
  ```yaml
39
  providers:
40
+ - provider: provider_name # Service provider name, such as openai, anthropic, gemini, openrouter, deepbricks, arbitrary name, required
41
+ base_url: https://api.your.com/v1/chat/completions # Backend service API address, required
42
+ api: sk-YgS6GTi0b4bEabc4C # Provider's API Key, required
43
+ model: # At least one model
44
+ - gpt-4o # Usable model name, required
45
+ - claude-3-5-sonnet-20240620: claude-3-5-sonnet # Rename model, claude-3-5-sonnet-20240620 is the provider's model name, claude-3-5-sonnet is the renamed name, can use a short name instead of the original complex name, optional
46
  - dall-e-3
47
 
48
  - provider: anthropic
49
  base_url: https://api.anthropic.com/v1/messages
50
+ api: # Supports multiple API Keys, multiple keys automatically enable polling load balancing, at least one key, required
51
  - sk-ant-api03-bNnAOJyA-xQw_twAA
52
  - sk-ant-api02-bNnxxxx
53
  model:
54
+ - claude-3-5-sonnet-20240620: claude-3-5-sonnet # Rename model, claude-3-5-sonnet-20240620 is the provider's model name, claude-3-5-sonnet is the renamed name, can use a short name instead of the original complex name, optional
55
+ tools: true # Whether to support tools, such as generating code, generating documents, etc., default is true, optional
56
 
57
  - provider: gemini
58
+ base_url: https://generativelanguage.googleapis.com/v1beta # base_url supports v1beta/v1, only for Gemini models, required
59
  api: AIzaSyAN2k6IRdgw
60
  model:
61
  - gemini-1.5-pro
62
+ - gemini-1.5-flash-exp-0827: gemini-1.5-flash # After renaming, the original model name gemini-1.5-flash-exp-0827 cannot be used, if you want to use the original name, you can add the original name in the model, just add the following line to use the original name
63
+ - gemini-1.5-flash-exp-0827 # Add this line, both gemini-1.5-flash-exp-0827 and gemini-1.5-flash can be requested
64
  tools: true
65
 
66
  - provider: vertex
67
+ project_id: gen-lang-client-xxxxxxxxxxxxxx # Description: Your Google Cloud project ID. Format: String, usually composed of lowercase letters, numbers, and hyphens. How to obtain: You can find your project ID in the project selector of the Google Cloud Console.
68
+ private_key: "-----BEGIN PRIVATE KEY-----\nxxxxx\n-----END PRIVATE" # Description: The private key of the Google Cloud Vertex AI service account. Format: A JSON formatted string containing the private key information of the service account. How to obtain: Create a service account in the Google Cloud Console, generate a JSON formatted key file, and then set its content as the value of this environment variable.
69
+ client_email: [email protected] # Description: The email address of the Google Cloud Vertex AI service account. Format: Usually a string like "[email protected]". How to obtain: Generated when creating the service account, you can also view the service account details in the "IAM & Admin" section of the Google Cloud Console.
70
  model:
71
  - gemini-1.5-pro
72
  - gemini-1.5-flash
 
75
  - claude-3-sonnet@20240229: claude-3-sonnet
76
  - claude-3-haiku@20240307: claude-3-haiku
77
  tools: true
78
+ notes: https://xxxxx.com/ # Can put the provider's website, notes, official documentation, optional
79
 
80
  - provider: other-provider
81
  base_url: https://api.xxx.com/v1/messages
 
83
  model:
84
  - causallm-35b-beta2ep-q6k: causallm-35b
85
  tools: false
86
+ engine: openrouter # Force the use of a specific message format, currently supports gpt, claude, gemini, openrouter native format, optional
87
 
88
  api_keys:
89
+ - api: sk-KjjI60Yf0JFWtfgRmXqFWyGtWUd9GZnmi3KlvowmRWpWpQRo # API Key, required for users to use this service
90
+ model: # Models that this API Key can use, required
91
+ - gpt-4o # Usable model name, can use all gpt-4o models provided by providers
92
+ - claude-3-5-sonnet # Usable model name, can use all claude-3-5-sonnet models provided by providers
93
+ - gemini/* # Usable model name, can only use all models provided by the provider named gemini, where gemini is the provider name, * represents all models
94
  role: admin
95
 
96
  - api: sk-pkhf60Yf0JGyJygRmXqFQyTgWUd9GZnmi3KlvowmRWpWqrhy
97
  model:
98
+ - anthropic/claude-3-5-sonnet # Usable model name, can only use the claude-3-5-sonnet model provided by the provider named anthropic. Models of other providers' claude-3-5-sonnet cannot be used.
99
  preferences:
100
+ USE_ROUND_ROBIN: true # Whether to use polling load balancing, true to use, false to not use, default is true. When polling is enabled, each request model is requested in the order configured in the model. It is not related to the original channel order in providers. Therefore, you can set different request sequences for each API key.
101
+ AUTO_RETRY: true # Whether to automatically retry, automatically retry the next provider, true to automatically retry, false to not automatically retry, default is true
102
+ RATE_LIMIT: 2/min # Supports rate limiting, maximum number of requests per minute, can be set to an integer, such as 2/min, 2 times per minute, 5/hour, 5 times per hour, 10/day, 10 times per day, 10/month, 10 times per month, 10/year, 10 times per year. Default is 60/min, optional
103
 
104
+ # Channel-level weighted load balancing configuration example
105
  - api: sk-KjjI60Yf0JFWtxxxxxxxxxxxxxxwmRWpWpQRo
106
  model:
107
+ - gcp1/*: 5 # The number after the colon is the weight, weights only support positive integers.
108
+ - gcp2/*: 3 # The larger the number, the greater the probability of being requested.
109
+ - gcp3/*: 2 # In this example, there are a total of 10 weights for all channels, and 5 out of 10 requests will request the gcp1/* model, 2 requests will request the gcp2/* model, and 3 requests will request the gcp3/* model.
110
 
111
  preferences:
112
+ USE_ROUND_ROBIN: true # When USE_ROUND_ROBIN must be true and there is no weight after the channels above, it will request in the original channel order, if there is weight, it will request in the weighted order.
113
  AUTO_RETRY: true
114
  ```
115
 
116
+ ## Environment variables
117
 
118
+ - CONFIG_URL: The download address of the configuration file, it can be a local file or a remote file, optional
119
+ - TIMEOUT: Request timeout, default is 20 seconds. The timeout can control the time needed to switch to the next channel when a channel does not respond. Optional
120
 
121
  ## Docker Local Deployment
122
 
 
143
  - ./api.yaml:/home/api.yaml
144
  ```
145
 
146
+ CONFIG_URL is a direct link that can automatically download remote configuration files. For example, if you find it inconvenient to modify configuration files on a certain platform, you can upload the configuration file to a hosting service and provide a direct link for uni-api to download. CONFIG_URL is this direct link.
147
 
148
  Run Docker Compose container in the background
149
 
README_CN.md ADDED
@@ -0,0 +1,190 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # uni-api
2
+
3
+ <p align="center">
4
+ <a href="https://t.me/uni_api">
5
+ <img src="https://img.shields.io/badge/Join Telegram Group-blue?&logo=telegram">
6
+ </a>
7
+ <a href="https://hub.docker.com/repository/docker/yym68686/uni-api">
8
+ <img src="https://img.shields.io/docker/pulls/yym68686/uni-api?color=blue" alt="docker pull">
9
+ </a>
10
+ </p>
11
+
12
+ [英文](./README.md) | [中文](./README_CN.md)
13
+
14
+ ## Introduction
15
+
16
+ 如果个人使用的话,one/new-api 过于复杂,有很多个人不需要使用的商用功能,如果你不想要复杂的前端界面,有想要支持的模型多一点,可以试试 uni-api。这是一个统一管理大模型API的项目,可以通过一个统一的API接口调用多个后端服务,统一转换为 OpenAI 格式,支持负载均衡。目前支持的后端服务有:OpenAI、Anthropic、Gemini、Vertex、DeepBricks、OpenRouter 等。
17
+
18
+ ## Features
19
+
20
+ - 无前端,纯配置文件配置 API 渠道。只要写一个文件就能运行起一个属于自己的 API 站,文档有详细的配置指南,小白友好。
21
+ - 统一管理多个后端服务,支持 OpenAI、Deepseek、DeepBricks、OpenRouter 等其他API 是 OpenAI 格式的提供商。支持 OpenAI Dalle-3 图像生成。
22
+ - 同时支持 Anthropic、Gemini、Vertex API。Vertex 同时支持 Claude 和 Gemini API。
23
+ - 支持 OpenAI、 Anthropic、Gemini、Vertex 原生 tool use 函数调用。
24
+ - 支持 OpenAI、Anthropic、Gemini、Vertex 原生识图 API。
25
+ - 支持四种负载均衡。
26
+ 1. 支持渠道级加权负载均衡,可以根据不同的渠道权重分配请求。默认不开启,需要配置渠道权重。
27
+ 2. 支持 Vertex 区域级负载均衡,支持 Vertex 高并发,最高可将 Gemini,Claude 并发提高 (API数量 * 区域数量) 倍。自动开启不需要额外配置。
28
+ 3. 除了 Vertex 区域级负载均衡,所有 API 均支持渠道级顺序负载均衡,提高沉浸式翻译体验。自动开启不需要额外配置。
29
+ 4. 支持单个渠道多个 API Key 自动开启 API key 级别的轮训负载均衡。
30
+ - 支持自动重试,当一个 API 渠道响应失败时,自动重试下一个 API 渠道。
31
+ - 支持细粒度的权限控制。支持使用通配符设置 API key 可用渠道的特定模型。
32
+ - 支持限流,可以设置每分钟最多请求次数,可以设置为整数,如 2/min,2 次每分钟、5/hour,5 次每小时、10/day,10 次每天,10/month,10 次每月,10/year,10 次每年。默认60/min。
33
+
34
+ ## Configuration
35
+
36
+ 使用 api.yaml 配置文件,可以配置多个模型,每个模型可以配置多个后端服务,支持负载均衡。下面是 api.yaml 配置文件的示例:
37
+
38
+ ```yaml
39
+ providers:
40
+ - provider: provider_name # 服务提供商名称, 如 openai、anthropic、gemini、openrouter、deepbricks,随便取名字,必填
41
+ base_url: https://api.your.com/v1/chat/completions # 后端服务的API地址,必填
42
+ api: sk-YgS6GTi0b4bEabc4C # 提供商的API Key,必填
43
+ model: # 至少填一个模型
44
+ - gpt-4o # 可以使用的模型名称,必填
45
+ - claude-3-5-sonnet-20240620: claude-3-5-sonnet # 重命名模型,claude-3-5-sonnet-20240620 是服务商的模型名称,claude-3-5-sonnet 是重命名后的名字,可以使用简洁的名字代替原来复杂的名称,选填
46
+ - dall-e-3
47
+
48
+ - provider: anthropic
49
+ base_url: https://api.anthropic.com/v1/messages
50
+ api: # 支持多个 API Key,多个 key 自动开启轮训负载均衡,至少一个 key,必填
51
+ - sk-ant-api03-bNnAOJyA-xQw_twAA
52
+ - sk-ant-api02-bNnxxxx
53
+ model:
54
+ - claude-3-5-sonnet-20240620: claude-3-5-sonnet # 重命名模型,claude-3-5-sonnet-20240620 是服务商的模型名称,claude-3-5-sonnet 是重命名后的名字,可以使用简洁的名字代替原来复杂的名称,选填
55
+ tools: true # 是否支持工具,如生成代码、生成文档等,默认是 true,选填
56
+
57
+ - provider: gemini
58
+ base_url: https://generativelanguage.googleapis.com/v1beta # base_url 支持 v1beta/v1, 仅供 Gemini 模型使用,必填
59
+ api: AIzaSyAN2k6IRdgw
60
+ model:
61
+ - gemini-1.5-pro
62
+ - gemini-1.5-flash-exp-0827: gemini-1.5-flash # 重命名后,原来的模型名字 gemini-1.5-flash-exp-0827 无法使用,如果要使用原来的名字,可以在 model 中添加原来的名字,只要加上下面一行就可以使用原来的名字了
63
+ - gemini-1.5-flash-exp-0827 # 加上这一行,gemini-1.5-flash-exp-0827 和 gemini-1.5-flash 都可以被请求
64
+ tools: true
65
+
66
+ - provider: vertex
67
+ project_id: gen-lang-client-xxxxxxxxxxxxxx # 描述: 您的Google Cloud项目ID。格式: 字符串,通常由小写字母、数字和连字符组成。获取方式: 在Google Cloud Console的项目选择器中可以找到您的项目ID。
68
+ private_key: "-----BEGIN PRIVATE KEY-----\nxxxxx\n-----END PRIVATE" # 描述: Google Cloud Vertex AI服务账号的私钥。格式: 一个JSON格式的字符串,包含服务账号的私钥信息。获��方式: 在Google Cloud Console中创建服务账号,生成JSON格式的密钥文件,然后将其内容设置为此环境变量的值。
69
+ client_email: [email protected] # 描述: Google Cloud Vertex AI服务账号的电子邮件地址。格式: 通常是形如 "[email protected]" 的字符串。获取方式: 在创建服务账号时生成,也可以在Google Cloud Console的"IAM与管理"部分查看服务账号详情获得。
70
+ model:
71
+ - gemini-1.5-pro
72
+ - gemini-1.5-flash
73
+ - claude-3-5-sonnet@20240620: claude-3-5-sonnet
74
+ - claude-3-opus@20240229: claude-3-opus
75
+ - claude-3-sonnet@20240229: claude-3-sonnet
76
+ - claude-3-haiku@20240307: claude-3-haiku
77
+ tools: true
78
+ notes: https://xxxxx.com/ # 可以放服务商的网址,备注信息,官方文档,选填
79
+
80
+ - provider: other-provider
81
+ base_url: https://api.xxx.com/v1/messages
82
+ api: sk-bNnAOJyA-xQw_twAA
83
+ model:
84
+ - causallm-35b-beta2ep-q6k: causallm-35b
85
+ tools: false
86
+ engine: openrouter # 强制使用某个消息格式,目前支持 gpt,claude,gemini,openrouter 原生格式,选填
87
+
88
+ api_keys:
89
+ - api: sk-KjjI60Yf0JFWtfgRmXqFWyGtWUd9GZnmi3KlvowmRWpWpQRo # API Key,用户使用本服务需要 API key,必填
90
+ model: # 该 API Key 可以使用的模型,必填
91
+ - gpt-4o # 可以使用的模型名称,可以使用所有提供商提供的 gpt-4o 模型
92
+ - claude-3-5-sonnet # 可以使用的模型名称,可以使用所有提供商提供的 claude-3-5-sonnet 模型
93
+ - gemini/* # 可以使用的模型名称,仅可以使用名为 gemini 提供商提供的所有模型,其中 gemini 是 provider 名称,* 代表所有模型
94
+ role: admin
95
+
96
+ - api: sk-pkhf60Yf0JGyJygRmXqFQyTgWUd9GZnmi3KlvowmRWpWqrhy
97
+ model:
98
+ - anthropic/claude-3-5-sonnet # 可以使用的模型名称,仅可以使用名为 anthropic 提供商提供的 claude-3-5-sonnet 模型。其他提供商的 claude-3-5-sonnet 模型不可以使用。
99
+ preferences:
100
+ USE_ROUND_ROBIN: true # 是否使用轮询负载均衡,true 为使用,false 为不使用,默认为 true。开启轮训后每次请求模型按照 model 配置的顺序依次请求。与 providers 里面原始的渠道顺序无关。因此你可以设置每个 API key 请求顺序不一样。
101
+ AUTO_RETRY: true # 是否自动重试,自动重试下一个提供商,true 为自动重试,false 为不自动重试,默认为 true
102
+ RATE_LIMIT: 2/min # 支持限流,每分钟最多请求次数,可以设置为整数,如 2/min,2 次每分钟、5/hour,5 次每小时、10/day,10 次每天,10/month,10 次每月,10/year,10 次每年。默认60/min,选填
103
+
104
+ # 渠道级加权负载均衡配置示例
105
+ - api: sk-KjjI60Yf0JFWtxxxxxxxxxxxxxxwmRWpWpQRo
106
+ model:
107
+ - gcp1/*: 5 # 冒号后面就是权重,权重仅支持正整数。
108
+ - gcp2/*: 3 # 数字的大小代表权重,数字越大,请求的概率越大。
109
+ - gcp3/*: 2 # 在该示例中,所有渠道加起来一共有 10 个权重,及 10 个请求里面有 5 个请求会请求 gcp1/* 模型,2 个请求会请求 gcp2/* 模型,3 个请求会请求 gcp3/* 模型。
110
+
111
+ preferences:
112
+ USE_ROUND_ROBIN: true # 当 USE_ROUND_ROBIN 必须为 true 并且上面的渠道后面没有权重时,会按照原始的渠道顺序请求,如果有权重,会按照加权后的顺序请求。
113
+ AUTO_RETRY: true
114
+ ```
115
+
116
+ ## 环境变量
117
+
118
+ - CONFIG_URL: 配置文件的下载地址,可以是本地文件,也可以是远程文件,选填
119
+ - TIMEOUT: 请求超时时间,默认为 20 秒,超时时间可以控制当一个渠道没有响应时,切换下一个渠道需要的时间。选填
120
+
121
+ ## Docker Local Deployment
122
+
123
+ Start the container
124
+
125
+ ```bash
126
+ docker run --user root -p 8001:8000 --name uni-api -dit \
127
+ -v ./api.yaml:/home/api.yaml \
128
+ yym68686/uni-api:latest
129
+ ```
130
+
131
+ Or if you want to use Docker Compose, here is a docker-compose.yml example:
132
+
133
+ ```yaml
134
+ services:
135
+ uni-api:
136
+ container_name: uni-api
137
+ image: yym68686/uni-api:latest
138
+ environment:
139
+ - CONFIG_URL=http://file_url/api.yaml
140
+ ports:
141
+ - 8001:8000
142
+ volumes:
143
+ - ./api.yaml:/home/api.yaml
144
+ ```
145
+
146
+ CONFIG_URL 就是可以自动下载远程的配置文件。比如你在某个平台不方便修改配置文件,可以把配置文件传到某个托管服务,可以提供直链给 uni-api 下载,CONFIG_URL 就是这个直链。
147
+
148
+ Run Docker Compose container in the background
149
+
150
+ ```bash
151
+ docker-compose pull
152
+ docker-compose up -d
153
+ ```
154
+
155
+ Docker build
156
+
157
+ ```bash
158
+ docker build --no-cache -t uni-api:latest -f Dockerfile --platform linux/amd64 .
159
+ docker tag uni-api:latest yym68686/uni-api:latest
160
+ docker push yym68686/uni-api:latest
161
+ ```
162
+
163
+ One-Click Restart Docker Image
164
+
165
+ ```bash
166
+ set -eu
167
+ docker pull yym68686/uni-api:latest
168
+ docker rm -f uni-api
169
+ docker run --user root -p 8001:8000 -dit --name uni-api \
170
+ -e CONFIG_URL=http://file_url/api.yaml \
171
+ -v ./api.yaml:/home/api.yaml \
172
+ yym68686/uni-api:latest
173
+ docker logs -f uni-api
174
+ ```
175
+
176
+ RESTful curl test
177
+
178
+ ```bash
179
+ curl -X POST http://127.0.0.1:8000/v1/chat/completions \
180
+ -H "Content-Type: application/json" \
181
+ -H "Authorization: Bearer ${API}" \
182
+ -d '{"model": "gpt-4o","messages": [{"role": "user", "content": "Hello"}],"stream": true}'
183
+ ```
184
+
185
+
186
+ ## Star History
187
+
188
+ <a href="https://github.com/yym68686/uni-api/stargazers">
189
+ <img width="500" alt="Star History Chart" src="https://api.star-history.com/svg?repos=yym68686/uni-api&type=Date">
190
+ </a>
test/parse_markdown.py ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class MarkdownEntity:
2
+ def __init__(self, content: str, entity_type: str):
3
+ self.content = content
4
+ self.entity_type = entity_type
5
+
6
+ def __repr__(self):
7
+ return f'<{self.entity_type}: {self.content}>'
8
+
9
+ class Title(MarkdownEntity):
10
+ def __init__(self, content: str, level: int):
11
+ super().__init__(content, 'Title')
12
+ self.level = level
13
+
14
+ class CodeBlock(MarkdownEntity):
15
+ def __init__(self, content: str, language: str = 'python'):
16
+ super().__init__(content, 'CodeBlock')
17
+ self.language = language
18
+
19
+ class ListItem(MarkdownEntity):
20
+ def __init__(self, content: str):
21
+ super().__init__(content, 'ListItem')
22
+
23
+ class Link(MarkdownEntity):
24
+ def __init__(self, content: str, url: str):
25
+ super().__init__(content, 'Link')
26
+ self.url = url
27
+
28
+ class EmptyLine(MarkdownEntity):
29
+ def __init__(self, content: str):
30
+ super().__init__(content, 'EmptyLine')
31
+
32
+ class Paragraph(MarkdownEntity):
33
+ def __init__(self, content: str):
34
+ super().__init__(content, 'Paragraph')
35
+
36
+ def parse_markdown(lines, delimiter='\n\n'):
37
+ entities = []
38
+ current_code_block = []
39
+ in_code_block = False
40
+ language = None
41
+
42
+ for line in lines:
43
+ # line = line.strip()
44
+
45
+ if line.startswith('#'):
46
+ level = line.count('#')
47
+ title_content = line[level:].strip()
48
+ entities.append(Title(title_content, level))
49
+
50
+ elif line.startswith('```'):
51
+ if in_code_block and language:
52
+ entities.append(CodeBlock(''.join(current_code_block), language))
53
+ current_code_block = []
54
+ in_code_block = False
55
+ language = None
56
+ else:
57
+ in_code_block = True
58
+ language = line.lstrip('`').strip()
59
+
60
+ elif in_code_block:
61
+ current_code_block.append(line)
62
+
63
+ elif '[' in line and ']' in line and '(' in line and ')' in line and line.count('[') == 1:
64
+ start = line.index('[') + 1
65
+ end = line.index(']')
66
+ url_start = line.index('(') + 1
67
+ url_end = line.index(')')
68
+ link_text = line[start:end].strip()
69
+ link_url = line[url_start:url_end].strip()
70
+ entities.append(Link(link_text, link_url))
71
+
72
+ elif line == delimiter:
73
+ entities.append(EmptyLine(line))
74
+
75
+ elif line:
76
+ entities.append(Paragraph(line))
77
+
78
+ return entities
79
+
80
+ def convert_entities_to_text(entities):
81
+ result = []
82
+ for entity in entities:
83
+ if isinstance(entity, Title):
84
+ result.append(f"{'#' * entity.level} {entity.content}")
85
+ elif isinstance(entity, CodeBlock):
86
+ code = entity.content.lstrip('\n').rstrip('\n')
87
+ result.append(f"```{entity.language}\n{code}\n```")
88
+ elif isinstance(entity, ListItem):
89
+ result.append(f"- {entity.content}")
90
+ elif isinstance(entity, Link):
91
+ result.append(f"[{entity.content}]({entity.url})")
92
+ elif isinstance(entity, EmptyLine):
93
+ result.append(f"{entity.content}")
94
+ elif isinstance(entity, Paragraph):
95
+ result.append(f"{entity.content}")
96
+ return ''.join(result)
97
+
98
+ def save_text_to_file(text: str, file_path: str):
99
+ with open(file_path, 'w', encoding='utf-8') as file:
100
+ file.write(text)
101
+
102
+ def process_markdown_entities_and_save(entities, file_path, raw_text=None):
103
+ # Step 1: Convert entities to text
104
+ text_output = convert_entities_to_text(entities)
105
+ if raw_text and raw_text != text_output:
106
+ raise ValueError("The text output does not match the raw text input.")
107
+ # Step 2: Save to file
108
+ save_text_to_file(text_output, file_path)
109
+
110
+ def read_markdown_file(file_path):
111
+ with open(file_path, 'r', encoding='utf-8') as file:
112
+ return file.read()
113
+
114
+ def split_markdown(text, delimiter='\n\n'):
115
+ # 使用两个换行符作为分割标记,分割段落
116
+ # 创建一个新的列表来存储结果
117
+ paragraphs = text.split(delimiter)
118
+ result = []
119
+
120
+ # 遍历分割后的段落,在它们之间插入空行实体
121
+ for i, paragraph in enumerate(paragraphs):
122
+ if i > 0:
123
+ # 在非第一段之前插入空行实体
124
+ result.append(delimiter)
125
+
126
+ # 添加当前段落
127
+ result.append(paragraph)
128
+
129
+ return result
130
+
131
+ def get_entities_from_markdown_file(file_path, delimiter='\n\n'):
132
+ # 读取 Markdown 文件
133
+ markdown_text = read_markdown_file(file_path)
134
+
135
+ # 分割 Markdown 文档
136
+ paragraphs = split_markdown(markdown_text, delimiter=delimiter)
137
+
138
+ # 解析 Markdown 文档
139
+ return parse_markdown(paragraphs, delimiter=delimiter)
140
+
141
+ if __name__ == '__main__':
142
+ markdown_file_path = "README_CN.md" # 替换为你的 Markdown 文件路径
143
+
144
+ # 读取 Markdown 文件
145
+ delimiter = '\n'
146
+ markdown_text = read_markdown_file(markdown_file_path)
147
+ paragraphs = split_markdown(markdown_text, delimiter=delimiter)
148
+ parsed_entities = parse_markdown(paragraphs, delimiter=delimiter)
149
+
150
+ # # 显示解析结果
151
+ # result = [str(entity) for entity in parsed_entities]
152
+ # for idx, entity in enumerate(result):
153
+ # print(f"段落 {idx + 1} 解析:{entity}\n")
154
+
155
+ # 保存到文件
156
+ output_file_path = "output.md"
157
+ process_markdown_entities_and_save(parsed_entities, output_file_path, raw_text=markdown_text)
158
+
159
+ print(f"Markdown 文档已保存到 {output_file_path}")
test/translate_md.py ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from ModelMerge import chatgpt
3
+ from parse_markdown import get_entities_from_markdown_file, process_markdown_entities_and_save
4
+
5
+ def translate_text(text, agent):
6
+ result = agent.ask(text)
7
+ return result
8
+
9
+ def translate(input_file_path, output_file_path="output.md", language="English", api_key=None, api_url="https://api.openai.com/v1/chat/completions", engine="gpt-4o"):
10
+ if not api_key:
11
+ raise ValueError("API key is required for translation.")
12
+ translator_prompt = (
13
+ "You are a translation engine, you can only translate text and cannot interpret it, and do not explain. "
14
+ "Translate the text to {}, please do not explain any sentences, just translate or leave them as they are. "
15
+ "Retain all spaces and line breaks in the original text. "
16
+ "Please do not wrap the code in code blocks, I will handle it myself. "
17
+ "If the code has comments, you should translate the comments as well. "
18
+ "This is the content you need to translate: "
19
+ ).format(language)
20
+
21
+ agent = chatgpt(
22
+ api_key=api_key,
23
+ api_url=api_url,
24
+ engine=engine,
25
+ system_prompt=translator_prompt,
26
+ use_plugins=False
27
+ )
28
+
29
+ # 读取 Markdown 文件
30
+ raw_paragraphs = get_entities_from_markdown_file(input_file_path, delimiter='\n')
31
+ target_paragraphs = raw_paragraphs
32
+
33
+ # 逐段翻译
34
+ for index, paragraph in enumerate(raw_paragraphs):
35
+ if paragraph.content and paragraph.content.strip() != "":
36
+ translated_text = translate_text(paragraph.content, agent)
37
+ if translated_text:
38
+ target_paragraphs[index].content = translated_text
39
+
40
+ # 输出翻译结果
41
+ process_markdown_entities_and_save(target_paragraphs, output_file_path)
42
+
43
+ if __name__ == "__main__":
44
+ input_file_path = "README_CN.md"
45
+ output_file_path = "README.md"
46
+ language = "English"
47
+ api_key = os.getenv("API")
48
+ api_url = os.getenv("API_URL")
49
+ engine = "gpt-4o"
50
+ translate(input_file_path, output_file_path, language, api_key, api_url, engine)