具备网络技术知识、后端知识、服务器管理和维护经验,并且能够灵活运用这些知识就可以,当然,你还需要一台海外云服务器。

It's about the network
直接访问 ChatGPT 服务

正向代理或 VPN

一般讲代理就是指正向代理,不过后面我要提到反向代理,所以这里特别强调一下这一节讲的代理是正向代理。

当网络被限制时,使用代理或 VPN 可能是最先想到的办法。你可以选择可靠的代理或 VPN 服务商,也可以自己建代理服务,搭建代理服务很简单我就不讲了。

这么做使用应该没什么问题,不过我想到了一个特别的场景,就是走 Proxy 的话开发基于 Flutter Web 的 AI 应用会有些麻烦,Flutter Web 的 Http 还没法支持 Proxy,就只能开发 Flutter Native 的 AI 应用了。其实移动端应用开发生态很少去关注代理网络,这种方案做移动端 AI 应用可能会遇到不少问题。

反向代理

反向代理的思路是将用户的请求发送到反代服务器,反代服务器再将请求发送给 OpenAI 服务器,最后再将 OpenAI 服务器的响应返回给用户,只要用户与反代服务器的网络是畅通的就行。建反代也不难,我也不讲了。

加了一级中转会增加服务延迟,不过开发 AI 应用更方便,因为使用反向代理就和正常访问一样,不需要设置代理,除了地址不同基本没什么区别。

需要注意的是,有些网站不喜欢被反代,也不喜欢通过 VPN 来访问,因为反代和 VPN 可以隐藏来访者的真实 IP 地址,并且可能会被用于绕过网站的访问控制和限制。

通过服务器来访问 ChatGPT

这个做法客户端不访问 OpenAI 而是你自己的服务器访问 OpenAI,客户端请求发给服务器,服务器执行 OpenAI 的 API 调用并将结果返回给客户端。

封面图就是走的这个方案,相当于在后端开发一个 OpenAI 的 API 调用服务。前端输入问题,后端去问 OpenAI 并将回答显示到页面,这样就像直连一样。下面代码主要是说下思路,代码很粗糙,仅供参考哈。

安装必要的软件

apt-get -y update
apt-get install -y ufw python3-pip

设置防火墙,开放 SSH 和 AI 服务端口

ufw allow 22/tcp
ufw allow 80/tcp
ufw --force enable

安装 OpenAI API 和 Web 服务

pip3 install openai
pip3 install gradio

把下面简单的 Demo 页面代码存储为 demo.py,类似的代码网上也有,改改就行。我简单解释一下,Gradio Web 服务器收到客户端的提问后会将提问(包含历史对话内容)和 ChatGPT 需要的其他参数(模型、温度、回复长度)一起作为输入信息来调用 OpenAI Python API,收到 OpenAI 服务器响应后就把响应内容(附加历史对话内容)一起显示到前端页面。具体的开发可以参考 OpenAI 开发文档

import gradio as gr
import openai

openai.api_key = "YOUR-API-KEY"
prompt_template = "Default ChatGPT"

temperature = 0.7 
max_tokens = 1000 
context_length = 2 

def get_empty_state():
    return {"total_tokens": 0, "messages": []}

def submit_message(prompt, state):
    history = state['messages']

    if not prompt:
        return gr.update(value=''), [(history[i]['content'], history[i+1]['content']) for i in range(0, len(history)-1, 2)], state

    system_prompt = []
    if prompt_template:
        system_prompt = [{ "role": "system", "content": prompt_template }]

    prompt_msg = { "role": "user", "content": prompt }

    try:
        completion = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=system_prompt + history[-context_length*2:] + [prompt_msg], temperature=temperature, max_tokens=max_tokens)

        history.append(prompt_msg)
        history.append(completion.choices[0].message.to_dict())

        state['total_tokens'] += completion['usage']['total_tokens']

    except Exception as e:
        history.append(prompt_msg)
        history.append({
            "role": "system",
            "content": f"Error: {e}"
        })

    chat_messages = [(history[i]['content'], history[i+1]['content']) for i in range(0, len(history)-1, 2)]
    return '', chat_messages, state

css = """
      #col-container {max-width: 96%; margin-left: auto; margin-right: auto;}
      #chatbox {min-height: 400px;}
      #header {text-align: center;}
      #prompt_template_preview {padding: 1em; border-width: 1px; border-style: solid; border-color: #e0e0e0; border-radius: 4px;}
      #label {font-size: 0.8em; padding: 0.5em; margin: 0;}
      .message { font-size: 1.2em;}
      footer {visibility: hidden;}
      """

with gr.Blocks(css=css) as demo:
    state = gr.State(get_empty_state())

    with gr.Column(elem_id="col-container"):
        with gr.Row():
            with gr.Column():
                chatbot = gr.Chatbot(elem_id="chatbox")
                input_message = gr.Textbox(show_label=False, placeholder="在这里输入", visible=True).style(container=False)
                btn_submit = gr.Button("发送")

    btn_submit.click(submit_message, [input_message, state], [input_message, chatbot, state])
    input_message.submit(submit_message, [input_message, state], [input_message, chatbot, state])

demo.queue(concurrency_count=10)
demo.launch(server_name='0.0.0.0', server_port=80, share=False, height='900px', show_api=False)

实际开发不建议这么做,Gradio 适合用于快速构建机器学习模型的交互式应用,它并不是一个专门用来做网站的 Web 服务器,构建一个高性能、高可用性的 Web 服务选择 Nginx、Apache、Gunicorn 等比较好。

运行 Demo,在浏览器上直接访问云服务器的地址就可以看到类似封面图的界面。封面图是在 DigitalOcean 云服务器(Droplets)上部署 OpenAI 的 API 服务的效果。

python3 demo.py