前言
昨天根据 Azure OpenAI Service 注册申请与配置心得 这篇 Blog 成功注册了 Azure OpenAI Service 。
注册过程大家看上面👆的 Blog 文章就好,这里我仅仅就我踩过的坑来做个说明。
⚠️注意
-
Azure OpenAI Service 目前需要以企业的身份来申请试用。
Azure OpenAI Service 接受来自中国的企业申请,请依照表单如实填写信息,其中最重要的是:
Your Company Email Address:请填写你在你公司的企业邮箱地址。
经过我的试验使用自定义域名结尾的邮箱可以作为申请,使用个人邮箱如
gmail/hotmail/QQ/outlook
等。基本都是不给过的。Company Website:请填写你所在公司的网站的网址。网址里最好能展示一个与你企业邮箱地址同一个域名的邮箱地址。**你的企业邮箱的域名、公司网站的域名需要保持一致,域名的主体需要与公司的名称保持一致,否则会在审核时被拒绝。**
-
在使用
Cloudflare
转换Azure OpenAI Service API
时需要使用 cf-openai-azure-proxy 这个项目。其中
- 直接修改他们的值, 如:
注意以上修改代码值的时候请务必加上
' '
我一开始没加,一直报错。或者通过
cloudflare worker
控制台, 进入Workers script > Settings > Add variable under Environment Variables.
附上完整代码:
// The name of your Azure OpenAI Resource. const resourceName=RESOURCE_NAME // The deployment name you chose when you deployed the model. const mapper = { 'gpt-3.5-turbo': DEPLOY_NAME_GPT35, 'gpt-4': DEPLOY_NAME_GPT4 }; const apiVersion=2023-05-15 addEventListener(fetch, (event) => { event.respondWith(handleRequest(event.request)); }); async function handleRequest(request) { if (request.method === 'OPTIONS') { return handleOPTIONS(request) } const url = new URL(request.url); if (url.pathname === '/v1/chat/completions') { var path=chat/completions } else if (url.pathname === '/v1/completions') { var path=completions } else if (url.pathname === '/v1/models') { return handleModels(request) } else { return new Response('404 Not Found', { status: 404 }) } let body; if (request.method === 'POST') { body = await request.json(); } const modelName = body?.model; const deployName = mapper[modelName] || '' if (deployName === '') { return new Response('Missing model mapper', { status: 403 }); } const fetchAPI = <code>https://${resourceName}.openai.azure.com/openai/deployments/${deployName}/${path}?api-version=${apiVersion}</code> const authKey = request.headers.get('Authorization'); if (!authKey) { return new Response(Not allowed, { status: 403 }); } const payload = { method: request.method, headers: { Content-Type: application/json, api-key: authKey.replace('Bearer ', ''), }, body: typeof body === 'object' ? JSON.stringify(body) : '{}', }; let response = await fetch(fetchAPI, payload); response = new Response(response.body, response); response.headers.set(Access-Control-Allow-Origin, *); if (body?.stream != true){ return response } let { readable, writable } = new TransformStream() stream(response.body, writable); return new Response(readable, response); } function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } // support printer mode and add newline async function stream(readable, writable) { const reader = readable.getReader(); const writer = writable.getWriter(); // const decoder = new TextDecoder(); const encoder = new TextEncoder(); const decoder = new TextDecoder(); // let decodedValue = decoder.decode(value); const newline = n; const delimiter = nn const encodedNewline = encoder.encode(newline); let buffer = ; while (true) { let { value, done } = await reader.read(); if (done) { break; } buffer += decoder.decode(value, { stream: true }); // stream: true is important here,fix the bug of incomplete line let lines = buffer.split(delimiter); // 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(20); } buffer = lines[lines.length - 1]; } if (buffer) { await writer.write(encoder.encode(buffer)); } await writer.write(encodedNewline) await writer.close(); } async function handleModels(request) { const data = { object: list, data: [] }; for (let key in mapper) { data.data.push({ id: key, object: model, created: 1677610602, owned_by: openai, permission: [{ id: modelperm-M56FXnG1AsIr3SXq8BYPvXJA, object: model_permission, created: 1679602088, allow_create_engine: false, allow_sampling: true, allow_logprobs: true, allow_search_indices: false, allow_view: true, allow_fine_tuning: false, organization: *, group: null, is_blocking: false }], root: key, parent: null }); } const json = JSON.stringify(data, null, 2); return new Response(json, { headers: { 'Content-Type': 'application/json' }, }); } async function handleOPTIONS(request) { return new Response(null, { headers: { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': '*', 'Access-Control-Allow-Headers': '*' } }) }
最后
如果你成功做完了所有的步骤。那么你应该有一个可以取代 OpenAI API
功能的密钥以及 Cloudflare Worker
的 URL
链接了。
使用方法如下:
- 请在设置中选择
OpenAI
作为Default Service Provider
。 - API KEY:请填写
Azure OpenAI Service
的密钥
。 - API URL:请填写
Cloudflare Worker
的 URL。 - API Model 选择你已部署的 Model,例如
gpt-35-turbo (version 0301)
,而这个Model需要你在Cloudflare Worker
代码最前面的 mapper 中做好映射。
0