codecamp

OpenAI API 聊天功能

<p>使用 OpenAI Chat API,您可以使用 gpt-3.5-turbo 和 gpt-4 构建自己的应用程序来执行以下操作:</p> <ul> <li><p>起草电子邮件或其他书面文件</p></li> <li><p>编写 Python 代码</p></li> <li><p>回答有关一组文件的问题</p></li> <li><p>创建会话代理</p></li> <li><p>为您的软件提供自然语言界面</p></li> <li><p>一系列科目的导师</p></li> <li><p>翻译语言</p></li> <li><p>模拟视频游戏中的角色等等</p></li> </ul> <p>本指南解释了如何为基于聊天的语言模型进行 API 调用,并分享获得良好结果的技巧。您还可以在 <a href="https://platform.openai.com/playground?mode=chat" target="_blank">OpenAI Playground</a> 中试用新的聊天格式。</p> <p> <a href="https://platform.openai.com/docs/guides/chat/introduction"></a>; </p> <h2>介绍</h2> <p>聊天模型将一系列消息作为输入,并返回模型生成的消息作为输出。 </p><p>尽管聊天格式旨在简化多回合对话,但它对于没有任何对话的单回合任务同样有用(例如之前由指令遵循模型(如 text-davinci-003)提供的任务)。 </p><p>示例 API 调用如下所示:</p><pre lang="text"><code class="text"># 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?"} ] )</code></pre> <p>主要输入是消息参数。消息必须是一个消息对象数组,其中每个对象都有一个角色(“系统”、“用户”或“助手”)和内容(消息的内容)。对话可以短至 1 条消息或填满许多页面。</p> <p>通常,对话首先使用系统消息进行格式化,然后是交替的用户和助理消息。</p> <p>系统消息有助于设置助手的行为。在上面的例子中,助手被指示“你是一个有用的助手”。</p> <blockquote> <p>gpt-3.5-turbo-0301 并不总是高度关注系统消息。未来的模型将被训练为更加关注系统消息。</p> </blockquote> <p>用户消息有助于指导助手。它们可以由应用程序的最终用户生成,或由开发人员设置为指令。 </p><p>助手消息帮助存储先前的响应。它们也可以由开发人员编写,以帮助提供所需行为的示例。</p> <p>当用户指令引用先前的消息时,包括对话历史记录会有所帮助。在上面的示例中,用户的最后一个问题是“它在哪里播放?”仅在有关 2020 年世界大赛的先前消息的上下文中才有意义。由于模型对过去的请求没有记忆,因此必须通过对话提供所有相关信息。如果对话不适合模型的令牌限制,则需要以某种方式缩短它。</p> <p> <a href="https://platform.openai.com/docs/guides/chat/response-format"></a>; </p> <h3><p>响应格式</p></h3> <p>API 响应示例如下所示:</p><pre lang="text"><code class="text">{ '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 } ] }</code></pre> <p>在 Python 中,可以使用 response['choices'][0]['message']['content'] 提取助手的回复。</p> <p>每个响应都将包含一个 finish_reason。 finish_reason 的可能值为:</p> <ul> <li>stop: API 返回完整的模型输出</li> <li>length: 由于 max_tokens 参数或令牌限制,模型输出不完整</li> <li>content_filter: 由于我们的内容过滤器中的标记而省略的内容</li> <li>null: API 响应仍在进行中或未完成</li> </ul> <p> <a href="https://platform.openai.com/docs/guides/chat/managing-tokens"></a>; </p> <h3>管理 tokens</h3> <p>语言模型以称为标记的块形式读取文本。在英语中,token 可以短到一个字符,也可以长到一个单词(例如 a 或 apple),在某些语言中,token 甚至可以短于一个字符,甚至长于一个单词。</p> <p>例如,字符串“ChatGPT 很棒!”被编码为六个标记:["Chat", "G", "PT", "is", "great", "!"]。</p> <p>API 调用中的令牌总数会影响:</p> <ul> <li><p>您为每个令牌支付的 API 调用费用是多少</p></li> <li><p>您的 API 调用需要多长时间,因为写入更多令牌需要更多时间</p></li> <li><p>您的 API 调用是否有效,因为令牌总数必须低于模型的最大限制(gpt-3.5-turbo-0301 为 4096 个令牌)</p></li> </ul> <p>输入和输出令牌都计入这些数量。例如,如果您的 API 调用在消息输入中使用了 10 个令牌,而您在消息输出中收到了 20 个令牌,则您需要支付 30 个令牌的费用。 </p><p>要查看 API 调用使用了多少令牌,请检查 API 响应中的使用字段(例如,response['usage']['total_tokens'])。 </p><p>gpt-3.5-turbo 和 gpt-4 等聊天模型使用令牌的方式与其他模型相同,但由于它们基于消息的格式,因此更难计算对话将使用多少令牌。</p> <blockquote> <p>计算聊天 API 调用的令牌</p> <p>下面是一个示例函数,用于计算传递给 gpt-3.5-turbo-0301 的消息的令牌。</p> <p>消息转换为令牌的确切方式可能因模型而异。因此,当发布未来的模型版本时,此函数返回的答案可能只是近似值。 </p><pre lang="text"><code class="text">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.""")</code></pre> <p>接下来,创建一条消息并将其传递给上面定义的函数以查看令牌计数,这应该与 API 使用参数返回的值相匹配:</p><pre lang="text"><code class="text">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</code></pre>

<p>要确认我们上面的函数生成的数字与 API 返回的数字相同,请创建一个新的 Chat Completion:</p><pre lang="text"><code class="text"># 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.')</code></pre> </blockquote>

<p>要在不调用 API 的情况下查看文本字符串中有多少个标记,请使用 OpenAI 的 tiktoken Python 库。</p><p>传递给 API 的每条消息都会消耗内容、角色和其他字段中的令牌数量,外加一些额外的用于幕后格式化。这在未来可能会略有改变。</p><p>如果对话中的标记太多而无法满足模型的最大限制(例如,gpt-3.5-turbo 的标记超过 4096 个),您将不得不截断、省略或以其他方式缩小文本直到适合。请注意,如果从消息输入中删除一条消息,模型将失去所有关于它的知识。</p><p>另请注意,很长的对话更有可能收到不完整的回复。例如,长度为 4090 个令牌的 gpt-3.5-turbo 对话将在仅 6 个令牌后被切断回复。</p><p><a href="https://platform.openai.com/docs/guides/chat/instructing-chat-models"></a></p><h2><p>指导聊天模型</p></h2><p>指导模型的最佳实践可能因模型版本而异。以下建议适用于 gpt-3.5-turbo-0301,可能不适用于未来的模型。 </p><p>许多对话以系统消息开始,以温和地指示助手。例如,这是用于 ChatGPT 的系统消息之一:</p><pre lang="text"><code class="text">You are ChatGPT, a large language model trained by OpenAI. Answer as concisely as possible. Knowledge cutoff: {knowledge_cutoff} Current date: {current_date}</code></pre><p>总的来说,gpt-3.5-turbo-0301 对系统消息的关注度不高,因此重要的说明往往放在用户消息中比较好。 </p><p>如果模型没有生成您想要的输出,请随意迭代并尝试潜在的改进。您可以尝试以下方法:</p><ul><li><p>让你的指示更明确</p></li><li><p>指定您想要答案的格式</p></li><li><p>在确定答案之前让模型逐步思考或讨论利弊</p></li></ul><p>如需更及时的工程创意,请阅读有关提高可靠性的技术的 <a href="https://github.com/openai/openai-cookbook/blob/main/techniques_to_improve_reliability.md" target="_blank">OpenAI Cookbook</a> 指南。</p><p>除了系统消息之外,temperature 和最大令牌是开发人员必须影响聊天模型输出的众多选项中的两个。对于 temperature,较高的值(如 0.8)将使输出更加随机,而较低的值(如 0.2)将使输出更加集中和确定。在 max tokens 的情况下,如果要将响应限制为特定长度,可以将 max tokens 设置为任意数字。这可能会导致问题,例如,如果您将最大标记值设置为 5,因为输出将被切断并且结果对用户没有意义。</p><p><a href="https://platform.openai.com/docs/guides/chat/chat-vs-completions"></a></p><h2>Chat vs Completions</h2><p>由于 gpt-3.5-turbo 的性能与 text-davinci-003 相似,但每个令牌的价格低 10%,因此我们建议在大多数用例中使用 gpt-3.5-turbo。 </p><p>对于许多开发人员来说,转换就像重写和重新测试提示一样简单。 </p><p>例如,如果您使用以下完成提示将英语翻译成法语:</p><pre lang="text"><code class="text">Translate the following English text to French: "{text}"</code></pre><p>等效的聊天对话可能如下所示:</p><pre lang="text"><code class="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}"'} ]</code></pre><p>或者甚至只是用户消息:</p><pre lang="text"><code class="text">[ {"role": "user", "content": 'Translate the following English text to French: "{text}"'} ]</code></pre><p><a href="https://platform.openai.com/docs/guides/chat/faq"></a></p><h2>FAQ</h2><p><a href="https://platform.openai.com/docs/guides/chat/is-fine-tuning-available-for-gpt-3-5-turbo"></a></p><h3><p>gpt-3.5-turbo 是否可以进行微调?</p></h3><p>不可以。自 2023 年 3 月 1 日起,您只能微调基础 GPT-3 模型。</p><p><a href="https://platform.openai.com/docs/guides/chat/do-you-store-the-data-that-is-passed-into-the-api"></a></p><h3><p>您是否存储传递到 API 中的数据?</p></h3><p>自 2023 年 3 月 1 日起,我们会将您的 API 数据保留 30 天,但不再使用您通过 API 发送的数据来改进我们的模型。</p><p><a href="https://platform.openai.com/docs/guides/chat/adding-a-moderation-layer"></a></p><h3><p>添加审核层</p></h3><p>如果您想向聊天 API 的输出添加审核层,您可以按照我们的审核指南来防止显示违反 OpenAI 使用政策的内容。</p><p><br></p>使用 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?"}
    ]
)

主要输入是消息参数。消息必须是一个消息对象数组,其中每个对象都有一个角色(“系统”、“用户”或“助手”)和内容(消息的内容)。对话可以短至 1 条消息或填满许多页面。 通常,对话首先使用系统消息进行格式化,然后是交替的用户和助理消息。 系统消息有助于设置助手的行为。在上面的例子中,助手被指示“你是一个有用的助手”。 gpt-3.5-turbo-0301 并不总是高度关注系统消息。未来的模型将被训练为更加关注系统消息。 用户消息有助于指导助手。它们可以由应用程序的最终用户生成,或由开发人员设置为指令。 助手消息帮助存储先前的响应。它们也可以由开发人员编写,以帮助提供所需行为的示例。 当用户指令引用先前的消息时,包括对话历史记录会有所帮助。在上面的示例中,用户的最后一个问题是“它在哪里播放?”仅在有关 2020 年世界大赛的先前消息的上下文中才有意义。由于模型对过去的请求没有记忆,因此必须通过对话提供所有相关信息。如果对话不适合模型的令牌限制,则需要以某种方式缩短它。

响应格式

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 的可能值为: stop: API 返回完整的模型输出length: 由于 max_tokens 参数或令牌限制,模型输出不完整content_filter: 由于我们的内容过滤器中的标记而省略的内容null: API 响应仍在进行中或未完成

管理 tokens

语言模型以称为标记的块形式读取文本。在英语中,token 可以短到一个字符,也可以长到一个单词(例如 a 或 apple),在某些语言中,token 甚至可以短于一个字符,甚至长于一个单词。 例如,字符串“ChatGPT 很棒!”被编码为六个标记:["Chat", "G", "PT", "is", "great", "!"]。 API 调用中的令牌总数会影响: 您为每个令牌支付的 API 调用费用是多少 您的 API 调用需要多长时间,因为写入更多令牌需要更多时间 您的 API 调用是否有效,因为令牌总数必须低于模型的最大限制(gpt-3.5-turbo-0301 为 4096 个令牌) 输入和输出令牌都计入这些数量。例如,如果您的 API 调用在消息输入中使用了 10 个令牌,而您在消息输出中收到了 20 个令牌,则您需要支付 30 个令牌的费用。 要查看 API 调用使用了多少令牌,请检查 API 响应中的使用字段(例如,response['usage']['total_tokens'])。 gpt-3.5-turbo 和 gpt-4 等聊天模型使用令牌的方式与其他模型相同,但由于它们基于消息的格式,因此更难计算对话将使用多少令牌。 计算聊天 API 调用的令牌 下面是一个示例函数,用于计算传递给 gpt-3.5-turbo-0301 的消息的令牌。 消息转换为令牌的确切方式可能因模型而异。因此,当发布未来的模型版本时,此函数返回的答案可能只是近似值。 

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 返回的数字相同,请创建一个新的 Chat Completion:

## 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.')

要在不调用 API 的情况下查看文本字符串中有多少个标记,请使用 OpenAI 的 tiktoken Python 库。 传递给 API 的每条消息都会消耗内容、角色和其他字段中的令牌数量,外加一些额外的用于幕后格式化。这在未来可能会略有改变。 如果对话中的标记太多而无法满足模型的最大限制(例如,gpt-3.5-turbo 的标记超过 4096 个),您将不得不截断、省略或以其他方式缩小文本直到适合。请注意,如果从消息输入中删除一条消息,模型将失去所有关于它的知识。 另请注意,很长的对话更有可能收到不完整的回复。例如,长度为 4090 个令牌的 gpt-3.5-turbo 对话将在仅 6 个令牌后被切断回复。 OpenAI Cookbook 指南。 除了系统消息之外,temperature 和最大令牌是开发人员必须影响聊天模型输出的众多选项中的两个。对于 temperature,较高的值(如 0.8)将使输出更加随机,而较低的值(如 0.2)将使输出更加集中和确定。在 max tokens 的情况下,如果要将响应限制为特定长度,可以将 max tokens 设置为任意数字。这可能会导致问题,例如,如果您将最大标记值设置为 5,因为输出将被切断并且结果对用户没有意义。

Chat vs Completions

由于 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}"'}
]

FAQ

gpt-3.5-turbo 是否可以进行微调?

不可以。自 2023 年 3 月 1 日起,您只能微调基础 GPT-3 模型。

您是否存储传递到 API 中的数据?

自 2023 年 3 月 1 日起,我们会将您的 API 数据保留 30 天,但不再使用您通过 API 发送的数据来改进我们的模型。

添加审核层

如果您想向聊天 API 的输出添加审核层,您可以按照我们的审核指南来防止显示违反 OpenAI 使用政策的内容。

OpenAI API 文本补全
OpenAI API 图像生成
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }