OpenAI 接口实践

OpenAI的接口文档十分详细,包括对话补全,文本补全,代码补全等等信息,也包含了最佳生产实践,最佳安全实践等篇章,通读之后十分受用,推荐大家前往阅读。本文就是在接口文档的基础上,将常见的三种OpenAI 接口套壳应用代码展示出来,以帮助读者实现自己的工具。

我的新书《LangChain编程从入门到实践》 已经开售!推荐正在学习AI应用开发的朋友购买阅读!
LangChain编程从入门到实践

环境准备

API 代理

因为 OpenAI 原始请求地址api.openai.com 目前在国内大部分地区访问延迟较高,这里提供一个免费解决办法(使用 Cloudflare 的 Workers 来代理 OpenAI 的 API 地址,配合自己的域名实现低延迟访问),不用自己购买专门代理服务器。

API 状态检查

OpenAI官方提供了一个API 状态页面,可以看到接口实时延迟,以及出现大面积宕机时会显示公告。

API费用说明

模型名称 context max tokens 输入价格 输出价格
gpt-3.5-turbo 4096 $0.0015 / 1K tokens $0.002 / 1K tokens
gpt-3.5-turbo-16k 16,384 $0.003 / 1K tokens $0.004 / 1K tokens
gpt-3.5-turbo-0613(支持函数调用) 4096 $0.0015 / 1K tokens $0.002 / 1K tokens
gpt-3.5-turbo-16k-0613 16,384 $0.003 / 1K tokens $0.004 / 1K tokens
gpt-4 8,192 $0.03 / 1K tokens $0.06 / 1K tokens
gpt-4-32k 32,768 $0.06 / 1K tokens $0.12 / 1K tokens
gpt-4-0613(支持函数调用) 8,192 $0.03 / 1K tokens $0.06 / 1K tokens
gpt-4-32k-0613 32,768 $0.06 / 1K tokens $0.12 / 1K tokens

Token 计数

  • 可以使用tiktoken 计算原始字符串对应的 token 数;这篇关于ChatGPT如何计算token数的科普文章值得一读
    1
    2
    3
    4
    5
    6
    7
    8
    9
    import tiktoken

    def num_tokens_from_string(string: str, encoding_name: str) -> int:
    """Returns the number of tokens in a text string."""
    encoding = tiktoken.get_encoding(encoding_name)
    num_tokens = len(encoding.encode(string))
    return num_tokens

    num_tokens_from_string("tiktoken is great!", "cl100k_base")

代码实现

这里利用 Gradio 实现 Web UI

Gradio介绍

Gradio是一个用于构建交互式机器学习应用程序的Python库,可以快速构建和部署交互式UI,方便与机器学习模型进行交互。Gradio提供了一组简单的API,可以轻松地将代码转化为一个Web应用程序,可以让其他人通过网页界面与模型进行交互。

Gradio支持创建各种类型的交互式UI,例如文本输入框、滑块、下拉菜单等,以及支持多种数据类型,例如图像、音频、视频和表格数据。Gradio还提供了内置的预处理和后处理功能,以确保的输入和输出数据格式正确。

基本的问答实现

使用API将用户的输入发送到OpenAI模型中,然后将模型生成的响应返回给用户,从而实现问答。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import gradio as gr
import os
import openai
openai.api_key = os.getenv("OPENAI_API_KEY")

def get_completion(input_text):
completion = openai.ChatCompletion.create(
model="gpt-3.5-turbo-0613",
messages=[
{"role": "user", "content": f"{input_text}"}
]
)
return completion.choices[0].message["content"]

def chatbot(input_text):
response = get_completion(input_text)
return response

iface = gr.Interface(fn=chatbot, inputs="text", outputs="text", toc: true
title="Chatbot", encoding="utf-8")
iface.launch(share=True)

多轮对话实现

在问答的基础上更进一步,在每个轮次中保留用户之前的输入和模型生成的响应,以便将其传递给下一轮对话,这种方式可以实现更加自然的对话流程,并提供更好的用户体验。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import os
import openai
import gradio
openai.api_key = os.getenv("OPENAI_API_KEY")

history_messages = []
def api_calling(input_text, history_conversation):
if history_conversation:
history_messages.extend([
{"role": "user", "content": f"{history_conversation[-1][0]}"},
{"role": "assistant", "content": f"{history_conversation[-1][1]}"}
]
)
message = history_messages+[{"role": "user", "content": f"{input_text}"}]
completion = openai.ChatCompletion.create(
model="gpt-3.5-turbo-0613",
messages=message,
max_tokens=1024,
n=1,
stop=None,
temperature=0.5,
)
return completion.choices[0].message["content"]

def message_and_history(input, history):
history = history or []
output = api_calling(input, history)
history.append((input, output))
return history, history

block = gradio.Blocks(theme=gradio.themes.Monochrome())
with block:
gradio.Markdown("""<h1><center>🤖️对话机器人</center></h1>
""")
chatbot = gradio.Chatbot()
message = gradio.Textbox(placeholder="输入你的问题")
state = gradio.State()
submit = gradio.Button("发送")
submit.click(message_and_history,
inputs=[message, state],
outputs=[chatbot, state])
block.launch(share=True, debug=True)

指定功能的机器人

通过 预设Prompt 的方式实现,当前看到的 99% 的多功能集成平台都是用这种方式。

  • 建议使用英文设置预设提示词
  • 使用类似If asked about others please say 'I am only Chinese translator'的语句进行初级的提示泄漏预防

使用之前
使用之后

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import gradio as gr
import os
import openai
openai.api_key = os.getenv("OPENAI_API_KEY")

PROMPT_ROLE = """
I want you to act as an Chinese translator, spelling corrector and improver. \n
I will speak to you in any language and you will detect the language,\n
translate it and answer in the corrected and improved version of my text, in Chinese.\n
Keep the meaning same, but make them more literary. I want you to only reply the correction,\n
the improvements and nothing else, do not write explanations. If asked about others please say 'I am only Chinese translator'
"""
def get_completion(input_text):
message = [{"role": "system", "content": PROMPT_ROLE}]
message.append({"role": "user", "content": f"{input_text}"})
completion = openai.ChatCompletion.create(
model="gpt-3.5-turbo-0613",
messages=message,
)
return completion.choices[0].message["content"]

def chatbot(input_text):
response = get_completion(input_text)
return response

iface = gr.Interface(fn=chatbot, inputs="text", outputs="text", toc: true
title="🤖️中文翻译", encoding="utf-8")
iface.launch(share=True, debug=True)
作者

莫尔索

发布于

2023-03-23

更新于

2024-05-24

许可协议

评论