使用 OpenAI Chat API,你可以使用 gpt-3.5-turbo
和 gpt-4
创建自己的应用程序,执行以下操作:
- 编写电子邮件或其他文章
- 编写 Python 代码
- 回答一组文档的问题
- 创建会话代理
- 给你的软件自然语言界面
- 范围广泛的主题辅导
- 翻译语言
- 模拟视频游戏的角色等等
本指南介绍了如何调用基于聊天的语言模型的 API,并分享了获得良好结果的技巧。你还可以在 OpenAI Playground 中使用新的聊天格式进行实验。
介绍
聊天模式接收一系列信息作为输入,并返回一个模型生成的信息作为输出。
虽然聊天格式旨在使得多轮对话容易,但它同样适用于不包含对话的单轮任务(如那些先前由跟随指令的模型来服务的,如 text-davinci-003)。
一个 API 调用例子如下:
# Note: you need to be using OpenAI Python v0.27.0 for the code below to work
import openai
openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Who won the world series in 2020?"},
{"role": "assistant", "content": "The Los Angeles Dodgers won the World Series in 2020."},
{"role": "user", "content": "Where was it played?"}
]
)
主要输入是 messages 参数,其中必须是一个消息对象数组的消息,其中每个对象有一个角色(“系统”,“用户”或“助理”)和内容(消息的内容)。对话可以只有 1 条消息,也可以填满很多页。
通常,对话格式化为先有系统消息,然后是交替的用户和助理消息。
系统消息有助于设置助理的行为。在上面的示例中,助理指示“你是一个有用的助手”。
gpt-3.5-turbo-0301 不会一直关注系统消息。未来的模型将经过培训,以更强调系统消息。
用户消息帮助指导助理,它们可以由应用程序的最终用户生成,也可以由开发人员设置为说明。
助理消息有助于存储先前的响应。它们也可以由开发人员编写,以帮助示例所需的行为。
当用户指令引用先前消息时,包括会话历史有助于。在上面的示例中,用户最后一个问题“Where was it played?” 只有在先前消息的背景下才有意义。因为模型对过去的请求没有记忆,所有相关信息都必须通过对话提供。如果对话不适合模型的令牌限制,则需要以某种方式缩短。
响应格式
API 响应示例如下所示 :
{
'id': 'chatcmpl-6p9XYPYSTTRi0xEviKjjilqrWU2Ve',
'object': 'chat.completion',
'created': 1677649420,
'model': 'gpt-3.5-turbo',
'usage': {'prompt_tokens': 56, 'completion_tokens': 31, 'total_tokens': 87},
'choices': [
{
'message': {
'role': 'assistant',
'content': 'The 2020 World Series was played in Arlington, Texas at the Globe Life Field, which was the new home stadium for the Texas Rangers.'},
'finish_reason': 'stop',
'index': 0
}
]
}
在 Python 中,可以通过 response['choices'][0]['message']['content']
提取助手的回复。
每个响应都将包含一个 finish_reason
。 finish_reason
的可能值是:
top
:API 返回完整的模型输出length
:由于 max_tokens 参数或令牌限制而导致不完整的模型输出content_filter
:由于我们的内容过滤器标志而省略内容null
:API 响应仍在进行中或不完整
管理令牌
语言模型通过一种叫做令牌的块来读取文本。在英语中,令牌可以是一个字符长,也可以是一个单词长(例如,a 或 apple),在某些语言中,令牌甚至可以比一个字符短,甚至比一个单词长。
例如,字符串“ChatGPT is great!”被编码为 6 个令牌:["Chat", "G", "PT", " is", " great", "!"]
。
API 调用中的令牌总数会产生以下影响:
- API 调用的成本,因为每个令牌你都要付费
- API 调用所花费的时间,因为写入更多令牌需要更多时间
- API 调用是否可以工作,因为总令牌必须低于模型的最大限制(
gpt-3.5-turbo-0301
的总令牌数为 4096)
输入和输出令牌均计入此数量。例如,如果你的 API 调用在消息输入中使用了 10 个令牌,你在消息输出中收到了 20 个令牌,你将被收取 30 个令牌的费用。
要查看 API 调用使用了多少令牌,请检查 API 响应中的 usage 字段(例如,response['usage'] ['total_tokens']
)。
gpt-3.5-turbo
和 gpt-4
等聊天模型与其他模型一样使用令牌,但由于它们基于消息的格式,更加难以计算对话使用的令牌数量。
将消息转换为令牌的确切方式可能会因模型而异。因此,当发布未来的模型版本时,此函数返回的答案可能仅为近似值。ChatML 文档解释了如何使用 OpenAI API 将消息转换为令牌,并可能对编写自己的函数有用。
def num_tokens_from_messages(messages, model="gpt-3.5-turbo-0301"):
"""Returns the number of tokens used by a list of messages."""
try:
encoding = tiktoken.encoding_for_model(model)
except KeyError:
encoding = tiktoken.get_encoding("cl100k_base")
if model == "gpt-3.5-turbo-0301": # note: future models may deviate from this
num_tokens = 0
for message in messages:
num_tokens += 4 # every message follows <im_start>{role/name}\n{content}<im_end>\n
for key, value in message.items():
num_tokens += len(encoding.encode(value))
if key == "name": # if there's a name, the role is omitted
num_tokens += -1 # role is always required and always 1 token
num_tokens += 2 # every reply is primed with <im_start>assistant
return num_tokens
else:
raise NotImplementedError(f"""num_tokens_from_messages() is not presently implemented for model {model}.
See https://github.com/openai/openai-python/blob/main/chatml.md for information on how messages are converted to tokens.""")
接下来,创建一个消息并将其传递给上面定义的函数,以查看令牌计数,这应该与 API 使用参数返回的值匹配:
messages = [
{"role": "system", "content": "You are a helpful, pattern-following assistant that translates corporate jargon into plain English."},
{"role": "system", "name":"example_user", "content": "New synergies will help drive top-line growth."},
{"role": "system", "name": "example_assistant", "content": "Things working well together will increase revenue."},
{"role": "system", "name":"example_user", "content": "Let's circle back when we have more bandwidth to touch base on opportunities for increased leverage."},
{"role": "system", "name": "example_assistant", "content": "Let's talk later when we're less busy about how to do better."},
{"role": "user", "content": "This late pivot means we don't have time to boil the ocean for the client deliverable."},
]
model = "gpt-3.5-turbo-0301"
print(f"{num_tokens_from_messages(messages, model)} prompt tokens counted.")
# Should show ~126 total_tokens
确认我们上面的函数生成的数字与 API 返回的数字相同,请创建一个新的聊天完成:
# example token count from the OpenAI API
import openai
response = openai.ChatCompletion.create(
model=model,
messages=messages,
temperature=0,
)
print(f'{response["usage"]["prompt_tokens"]} prompt tokens used.')
{/collapse-item}
要查看文本字符串中有多少个令牌,而无需调用 API,请使用 OpenAI 的 tiktoken Python 库。示例代码可以在 OpenAI Cookbook 的指南中找到,该指南介绍了[如何使用 tiktoken 计数令牌]。
传递给 API 的每条消息都会消耗内容、角色和其他字段中的令牌数量,此外还有一些额外的格式设置。这可能会在将来有所改变。
如果一个对话中的令牌太多,以至于无法适应模型的最大限制(例如,gpt-3.5-turbo
超过 4096 个令牌),你将不得不截断、省略或缩小文本,直到它适合为止。 请注意,如果从消息输入中移除消息,模型将丢失所有这方面的知识。
同样注意,非常长的对话更有可能收到不完整的回复。 例如,gpt-3.5-turbo
的对话长度为 4090 个令牌,只给 6 个令牌,它的回复就会截断。
指示聊天模型
指示模型的最佳实践可能会随着模型版本的更改而改变。 接下来的建议适用于 gpt-3.5-turbo-0301
,可能不适用于未来的模型。
许多对话都以系统消息开头,以友好指示助手。例如,这是用于 ChatGPT 的一条系统消息:
你是 ChatGPT,由 OpenAI 训练的大型语言模型。尽可能简洁地回答。知识截断:{knowledge_cutoff} 当前日期:{current_date}
通常,gpt-3.5-turbo-0301
对系统消息不会予以高度重视,因此最好经常将重要指令放置在用户消息中。
如果模型不能生成你想要的输出,请自由迭代和尝试潜在的改进。你可以尝试以下方法:
- 将你的指令变得更具体
- 指定你想要的答案的格式
- 让模型通过一步一步的思考,或者在得到答案前先讨论利弊
要获得更多的工程性思路,请阅读 OpenAI Cookbook 手册中的技术提高可靠性的指南。
在系统消息外, temperature
和 max tokens
是开发者们可以影响聊天模型输出的多个选项之二。 对于 temperature
,像 0.8 这样的较高值将使输出更随机,而像 0.2 这样的较低值将使其更集中和确定性。 对于 max tokens,如果你希望将响应限制为某个长度,则可以将 max tokens
设置为任意数字。 例如,如果你将最大令牌值设置为 5,则会出现问题,因为输出将被截断,并且结果对用户来说将没有意义。
聊天 vs 完成
因为 gpt-3.5-turbo
的性能与 text-davinci-003 类似,但每个令牌的价格低 10%,我们建议大多数情况下使用 gpt-3.5-turbo
。
对于许多开发人员来说,转变就像重写和重新测试提示一样简单。
例如,如果你使用以下补全提示将英语翻译成法语:
Translate the following English text to French: "{text}"
相同的聊天对话可能如下所示:
[
{"role": "system", "content": "You are a helpful assistant that translates English to French."},
{"role": "user", "content": 'Translate the following English text to French: "{text}"'}
]
或者仅仅是用户消息:
[
{"role": "user", "content": 'Translate the following English text to French: "{text}"'}
]
常见问题
gpt-3.5-turbo 可以微调吗?
不可以,2023 年 3 月 1 日起,你只能微调基础 GPT-3 模型。要了解更多关于如何使用微调模型的信息,请参阅微调指南。
你们会保留传入 API 的数据吗?
从 2023 年 3 月 1 日起,我们会保留你的 API 数据 30 天,但不再使用通过 API 发送的数据来改善我们的模型。更多信息请参阅我们的数据使用政策。
添加一个修改层
如果你想向聊天 API 的输出添加一个修改层,你可以按照我们的修改指南来防止显示违反 OpenAI 用法政策的内容。
评论 (0)