diff --git a/README.md b/README.md index 03f6933..1a72325 100644 --- a/README.md +++ b/README.md @@ -5,14 +5,23 @@ > 大多数 OpenAI 客户端不支持 Azure OpenAI Service,但Azure OpenAI Service的申请和绑卡都非常简单,并且还提供了免费的额度。此脚本使用免费的 Cloudflare Worker 作为代理,使得支持 OpenAI 的客户端可以直接使用 Azure OpenAI Service。 +### 项目说明: +- 我没有服务器可以使用吗? + - 这段脚本跑在Cloudflare Worker, 不需要服务器, 不需要绑卡, 每天10W次请求 免费 +- 我没有自己的域名可以使用吗? + - 也可以, 参考: https://github.com/haibbo/cf-openai-azure-proxy/issues/3 +- 实现打印机模式: + - Azure OpenAI Service's 回复是一段一段回复的(当前仅GPT-4有此问题, GPT-3的问题Azure已经解决) + - 返回给客户端的时候, 本项目拆出一条条的消息, 依次给, 达到打印机模式 +- 项目也支持 Docker 部署(基于 wrangler) - +### 部署 代理 OpenAI 的请求到 Azure OpenAI Serivce,代码部署步骤: 1. 注册并登录到 Cloudflare 账户 2. 创建一个新的 Cloudflare Worker 3. 将 [cf-openai-azure-proxy.js](./cf-openai-azure-proxy.js) 复制并粘贴到 Cloudflare Worker 编辑器中 -4. 通过修改或环境变量调整 resourceName 和 deployName 的值 +4. 通过修改或环境变量调整 resourceName 和 deployment mapper 的值 5. 保存并部署 Cloudflare Worker 6. https://github.com/haibbo/cf-openai-azure-proxy/issues/3 **可选**绑定自定义域名: 在 Worker 详情页 -> Trigger -> Custom Domains 中为这个 Worker 添加一个自定义域名 @@ -29,14 +38,15 @@ // The name of your Azure OpenAI Resource. const resourceName="codegpt" -const mapper:any = { +// deployment model mapper +const mapper = { 'gpt-3.5-turbo': 'gpt35', 'gpt-4': 'gpt4' }; 其他的map规则直接按这样的格式续写即可 ``` - 或者通过 cloudflare worker 控制台, 进入 Workers script > Settings > Add variable under Environment Variables. -env +env ### 客户端 以 OpenCat 为例: 自定义 API 域名填写 第六步绑定的域名: @@ -44,10 +54,3 @@ const mapper:any = { opencat 我已经尝试了多种客户端, 如果遇到其他客户端有问题, 欢迎创建issue. - -QA: -- 我没有服务器可以使用吗? - - 这段脚本跑在Cloudflare Worker, 不需要服务器, 不需要绑卡, 每天10W次请求 免费 -- 我没有自己的域名可以使用吗? - - 也可以, 参考: https://github.com/haibbo/cf-openai-azure-proxy/issues/3 - diff --git a/README_en.md b/README_en.md index cc30750..9d043b7 100644 --- a/README_en.md +++ b/README_en.md @@ -10,7 +10,7 @@ This script proxies requests to Azure OpenAI Service for OpenAI clients. The cod Register and log in to your Cloudflare account. - Create a new Cloudflare Worker. - Copy and paste cf-openai-azure-proxy.js into the Cloudflare Worker editor. -- Adjust the values of **resourceName** and **deployName** by either direct modification or using environment variables.. +- Adjust the values of **resourceName** and deployment **mapper** by either direct modification or using environment variables.. - Save and deploy the Cloudflare Worker. - https://github.com/haibbo/cf-openai-azure-proxy/issues/3 Optional: Bind a custom domain name: Add a custom domain name for this worker in the Worker details page -> Trigger -> Custom Domains. @@ -29,12 +29,10 @@ const resourceName="codegpt" 'gpt-4': 'gpt4' }; ``` -**Mapper configuration example**: If you have deployed the GPT-3.5 Turbo and GPT-4 models on Azure with deployment names 'gpt35' and 'gpt4', respectively, then the mapper should be configured as follows. Other map rules can be continued directly in this format. +- **OR** go to the Cloudflare Worker console, navigate to Workers script > Settings > Add variable under Environment Variables. - -- go to the Cloudflare Worker console, navigate to Workers script > Settings > Add variable under Environment Variables. -env +env ## Client Take OpenCat as an example: fill in the custom API domain name with the domain name bound in step 6: diff --git a/cf-openai-azure-proxy.js b/cf-openai-azure-proxy.js index 9695c9a..7c36390 100644 --- a/cf-openai-azure-proxy.js +++ b/cf-openai-azure-proxy.js @@ -9,8 +9,6 @@ const mapper = { const apiVersion="2023-03-15-preview" - - addEventListener("fetch", (event) => { event.respondWith(handleRequest(event.request)); }); @@ -62,8 +60,14 @@ async function handleRequest(request) { body: typeof body === 'object' ? JSON.stringify(body) : '{}', }; - let { readable, writable } = new TransformStream() const response = await fetch(fetchAPI, payload); + + // Since Azure has fixed gpt-3's printer effect, do not have to stream it. + if (modelName.startsWith('gpt-3') || body?.stream != true){ + return response + } + + let { readable, writable } = new TransformStream() stream(response.body, writable); return new Response(readable, response); @@ -98,7 +102,7 @@ async function stream(readable, writable) { // Loop through all but the last line, which may be incomplete. for (let i = 0; i < lines.length - 1; i++) { await writer.write(encoder.encode(lines[i] + delimiter)); - await sleep(30); + await sleep(50); } buffer = lines[lines.length - 1];