当前位置:   article > 正文

大模型系列:OpenAI使用技巧_如何格式化ChatGPT模型的输入_openai大模型工具调用的格式

openai大模型工具调用的格式

如何格式化ChatGPT模型的输入

ChatGPT由gpt-3.5-turbogpt-4提供支持,这是OpenAI最先进的模型。

您可以使用OpenAI API构建自己的应用程序,使用gpt-3.5-turbogpt-4

聊天模型将一系列消息作为输入,并返回一个由AI编写的消息作为输出。

本指南通过几个示例API调用说明聊天格式。

1. 导入openai库

# 安装并升级OpenAI Python库的最新版本(如果需要)
%pip install --upgrade openai
  • 1
  • 2
# 导入OpenAI Python库,以便调用OpenAI API
import openai
  • 1
  • 2

2. 一个聊天API调用的示例

一个聊天API调用有两个必需的输入:

  • model:你想要使用的模型的名称(例如,gpt-3.5-turbogpt-4gpt-3.5-turbo-0613gpt-3.5-turbo-16k-0613
  • messages:一个消息对象的列表,每个对象有两个必需的字段:
    • role:发送者的角色(可以是systemuserassistant
    • content:消息的内容(例如,写一首美丽的诗给我

消息还可以包含一个可选的name字段,用于给发送者命名。例如,example-userAliceBlackbeardBot。名称不能包含空格。

截至2023年6月,您还可以选择提交一个functions列表,告诉GPT是否可以生成JSON以供函数使用。详细信息请参见文档API参考,或Cookbook指南如何使用聊天模型调用函数

通常,一个对话会以一个系统消息开始,告诉助手如何行为,然后是用户和助手消息的交替,但您不必遵循这种格式。

让我们看一个示例聊天API调用,以了解聊天格式在实践中是如何工作的。

# 定义模型名称
MODEL = "gpt-3.5-turbo"

# 发送请求,获取OpenAI的聊天机器人的回复
response = openai.ChatCompletion.create(
    model=MODEL,  # 指定使用的模型
    messages=[  # 指定对话的消息列表
        {"role": "system", "content": "You are a helpful assistant."},  # 系统发送的消息
        {"role": "user", "content": "Knock knock."},  # 用户发送的消息
        {"role": "assistant", "content": "Who's there?"},  # 机器人发送的消息
        {"role": "user", "content": "Orange."},  # 用户发送的消息
    ],
    temperature=0,  # 控制回复的创造性程度,0表示完全按照输入回复
)

# 输出机器人的回复
response
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
<OpenAIObject chat.completion id=chatcmpl-7UkgnSDzlevZxiy0YjZcLYdUMz5yZ at 0x118e394f0> JSON: {
  "id": "chatcmpl-7UkgnSDzlevZxiy0YjZcLYdUMz5yZ",
  "object": "chat.completion",
  "created": 1687563669,
  "model": "gpt-3.5-turbo-0301",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "Orange who?"
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 39,
    "completion_tokens": 3,
    "total_tokens": 42
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

如您所见,响应对象具有几个字段:

  • id:请求的ID
  • object:返回对象的类型(例如,chat.completion
  • created:请求的时间戳
  • model:用于生成响应的模型的完整名称
  • usage:用于生成回复的令牌数量,包括提示、完成和总数
  • choices:完成对象的列表(除非将n设置为大于1,否则只有一个)
    • message:模型生成的消息对象,包括rolecontent
    • finish_reason:模型停止生成文本的原因(如果达到了max_tokens限制,则为stoplength
    • index:完成在选择列表中的索引

提取仅包含回复的部分。

response['choices'][0]['message']['content']

  • 1
  • 2
'Orange who?'
  • 1

即使是非对话型任务也可以适应聊天格式,只需将指令放在第一个用户消息中即可。

例如,要求模型以海盗黑胡子的风格解释异步编程,我们可以按以下方式构建对话:


# 创建一个聊天完成的请求
response = openai.ChatCompletion.create(
    model=MODEL,  # 指定模型
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},  # 系统消息,指定角色为系统,内容为“你是一个有帮助的助手”
        {"role": "user", "content": "Explain asynchronous programming in the style of the pirate Blackbeard."},  # 用户消息,指定角色为用户,内容为“以海盗黑胡子的风格解释异步编程”
    ],
    temperature=0,  # 温度参数,控制生成文本的多样性,0表示完全确定性
)

# 打印生成的回复消息内容
print(response['choices'][0]['message']['content'])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
Ahoy matey! Asynchronous programming be like havin' a crew o' pirates workin' on different tasks at the same time. Ye see, instead o' waitin' for one task to be completed before startin' the next, ye can assign tasks to yer crew and let 'em work on 'em simultaneously. This way, ye can get more done in less time and keep yer ship sailin' smoothly. It be like havin' a bunch o' pirates rowin' the ship at different speeds, but still gettin' us to our destination. Arrr!
  • 1
# 导入openai库后,我们可以使用其中的ChatCompletion类来进行对话生成任务
response = openai.ChatCompletion.create(
    model=MODEL,
    messages=[
        {"role": "user", "content": "Explain asynchronous programming in the style of the pirate Blackbeard."},
    ],
    temperature=0,
)

print(response['choices'][0]['message']['content'])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
Ahoy mateys! Let me tell ye about asynchronous programming, arrr! It be like havin' a crew of sailors workin' on different tasks at the same time, without waitin' for each other to finish. Ye see, in traditional programming, ye have to wait for one task to be completed before movin' on to the next. But with asynchronous programming, ye can start multiple tasks at once and let them run in the background while ye focus on other things.

It be like havin' a lookout keepin' watch for enemy ships while the rest of the crew be busy with their own tasks. They don't have to stop what they're doin' to keep an eye out, because the lookout be doin' it for them. And when the lookout spots an enemy ship, they can alert the crew and everyone can work together to defend the ship.

In the same way, asynchronous programming allows different parts of yer code to work together without gettin' in each other's way. It be especially useful for tasks that take a long time to complete, like loadin' large files or connectin' to a server. Instead of makin' yer program wait for these tasks to finish, ye can let them run in the background while yer program continues to do other things.

So there ye have it, me hearties! Asynchronous programming be like havin' a crew of sailors workin' together without gettin' in each other's way. It be a powerful tool for any programmer, and one that can help ye sail the seas of code with ease!
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

3. 指导gpt-3.5-turbo-0301的技巧

指导模型的最佳实践可能会随着模型版本的变化而改变。以下建议适用于gpt-3.5-turbo-0301,可能不适用于未来的模型。

系统消息

系统消息可用于为助手提供不同的个性或行为。

请注意,gpt-3.5-turbo-0301通常不像gpt-4-0314gpt-3.5-turbo-0613那样关注系统消息。因此,对于gpt-3.5-turbo-0301,我们建议将重要的指令放在用户消息中。一些开发者发现,将系统消息不断移动到对话末尾可以防止模型在对话变得越来越长时注意力分散。

# 导入openai库

# 定义一个系统消息,用于提示助手以深入的方式解释概念
response = openai.ChatCompletion.create(
    model=MODEL,  # 指定模型
    messages=[
        {"role": "system", "content": "You are a friendly and helpful teaching assistant. You explain concepts in great depth using simple terms, and you give examples to help people learn. At the end of each explanation, you ask a question to check for understanding"},  # 系统角色的消息,描述助手的特点和行为方式
        {"role": "user", "content": "Can you explain how fractions work?"},  # 用户角色的消息,提出问题
    ],
    temperature=0,  # 温度参数,控制生成的回复的多样性
)

# 打印助手的回复内容
print(response["choices"][0]["message"]["content"])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
Sure! Fractions are a way of representing a part of a whole. The top number of a fraction is called the numerator, and it represents how many parts of the whole we are talking about. The bottom number is called the denominator, and it represents how many equal parts the whole is divided into.

For example, if we have a pizza that is divided into 8 equal slices, and we take 3 slices, we can represent that as the fraction 3/8. The numerator is 3 because we took 3 slices, and the denominator is 8 because the pizza was divided into 8 slices.

To add or subtract fractions, we need to have a common denominator. This means that the denominators of the fractions need to be the same. To do this, we can find the least common multiple (LCM) of the denominators and then convert each fraction to an equivalent fraction with the LCM as the denominator.

To multiply fractions, we simply multiply the numerators together and the denominators together. To divide fractions, we multiply the first fraction by the reciprocal of the second fraction (flip the second fraction upside down).

Now, here's a question to check for understanding: If we have a pizza that is divided into 12 equal slices, and we take 4 slices, what is the fraction that represents how much of the pizza we took?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
# 创建一个系统消息,用于提示助手以简洁、简明扼要的方式回答问题
response = openai.ChatCompletion.create(
    model=MODEL,  # 指定模型
    messages=[
        {"role": "system", "content": "You are a laconic assistant. You reply with brief, to-the-point answers with no elaboration."},  # 系统消息,提示助手回答问题时要简洁明了,不要有过多的解释
        {"role": "user", "content": "Can you explain how fractions work?"},  # 用户消息,询问如何解释分数的工作原理
    ],
    temperature=0,  # 温度参数为0,表示助手的回答是确定性的,不会有随机性
)

print(response["choices"][0]["message"]["content"])  # 打印助手的回答内容
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
Fractions represent a part of a whole. They consist of a numerator (top number) and a denominator (bottom number) separated by a line. The numerator represents how many parts of the whole are being considered, while the denominator represents the total number of equal parts that make up the whole.
  • 1

少样本提示

在某些情况下,向模型展示你想要的东西比告诉模型你想要的东西更容易。

向模型展示你想要的一种方式是使用伪造的示例消息。

例如:

# 导入了openai模块,不需要再增加import语句
# 这段代码是一个示例,用于展示如何使用openai模块进行对话生成
# response变量存储了openai.ChatCompletion.create()方法的返回值,即生成的对话结果
# 在调用openai.ChatCompletion.create()方法时,需要传入模型名称和消息列表
# 消息列表中包含了对话中的每一条消息,每条消息都有一个角色和内容
# temperature参数设置为0,表示生成的对话结果尽可能接近给定的消息
response = openai.ChatCompletion.create(
    model=MODEL,
    messages=[
        {"role": "system", "content": "You are a helpful, pattern-following assistant."},
        {"role": "user", "content": "Help me translate the following corporate jargon into plain English."},
        {"role": "assistant", "content": "Sure, I'd be happy to!"},
        {"role": "user", "content": "New synergies will help drive top-line growth."},
        {"role": "assistant", "content": "Things working well together will increase revenue."},
        {"role": "user", "content": "Let's circle back when we have more bandwidth to touch base on opportunities for increased leverage."},
        {"role": "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."},
    ],
    temperature=0,
)

# 打印生成的对话结果中的第一条消息的内容
print(response["choices"][0]["message"]["content"])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
We don't have enough time to complete the entire project perfectly.
  • 1

为了帮助澄清示例消息不是真实对话的一部分,也不应该由模型参考,您可以尝试将“system”消息的“name”字段设置为“example_user”和“example_assistant”。

将上面的few-shot示例转换,我们可以编写:

# 导入了openai库,可以使用其中的ChatCompletion类
# 该代码展示了一个企业术语翻译的例子,使用了一些示例名称来代替示例消息
# 创建了一个ChatCompletion对象,传入了模型和消息列表
# 消息列表中包含了多个字典,每个字典代表一条消息,包含了消息的角色、名称和内容
# temperature参数设置为0,表示生成的回复尽可能接近给定的消息
# 调用create方法,返回一个响应对象
# 从响应对象中获取第一条回复的内容,并打印出来
import openai

MODEL = "text-davinci-002"

response = openai.ChatCompletion.create(
    model=MODEL,
    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."},
    ],
    temperature=0,
)

print(response["choices"][0]["message"]["content"])
  • 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
This sudden change in plans means we don't have enough time to do everything for the client's project.
  • 1

并不是每一次尝试引导对话都会一开始就成功。

如果你的第一次尝试失败了,不要害怕尝试不同的方式来引导或训练模型。

例如,有一个开发者发现当他们插入了一个用户消息,说“到目前为止做得很好,这些都是完美的”,来帮助训练模型提供更高质量的回复时,准确性有所提高。

如果想要提高模型的可靠性,可以考虑阅读我们的提高可靠性的技巧指南。虽然它是为非聊天模型编写的,但其中的许多原则仍然适用。

4. 计算令牌数

当您提交请求时,API会将消息转换为一系列令牌。

使用的令牌数量会影响以下方面:

  • 请求的成本
  • 生成响应所需的时间
  • 当回复达到最大令牌限制时被截断的时间(对于gpt-3.5-turbo为4,096个令牌,对于gpt-4为8,192个令牌)

您可以使用以下函数计算一组消息将使用的令牌数。

请注意,从消息中计算令牌的确切方式可能因模型而异。请将下面函数中的计数视为估计,而不是永恒的保证。

特别是,使用可选函数输入的请求将消耗额外的令牌,超出下面计算的估计。

了解有关使用tiktoken计算令牌数的更多信息

import tiktoken


def num_tokens_from_messages(messages, model="gpt-3.5-turbo-0613"):
    """返回消息列表使用的令牌数量。"""
    try:
        encoding = tiktoken.encoding_for_model(model)  # 获取指定模型的编码方式
    except KeyError:
        print("警告:找不到模型。使用cl100k_base编码。")
        encoding = tiktoken.get_encoding("cl100k_base")  # 使用默认的编码方式
    if model in {
        "gpt-3.5-turbo-0613",
        "gpt-3.5-turbo-16k-0613",
        "gpt-4-0314",
        "gpt-4-32k-0314",
        "gpt-4-0613",
        "gpt-4-32k-0613",
        }:
        tokens_per_message = 3  # 每条消息使用的令牌数量
        tokens_per_name = 1  # 每个名称使用的令牌数量
    elif model == "gpt-3.5-turbo-0301":
        tokens_per_message = 4  # 每条消息遵循的格式为<|im_start|>{role/name}\n{content}<|end|>\n
        tokens_per_name = -1  # 如果有名称,则省略角色
    elif "gpt-3.5-turbo" in model:
        print("警告:gpt-3.5-turbo可能会随时间更新。返回假设为gpt-3.5-turbo-0613的令牌数量。")
        return num_tokens_from_messages(messages, model="gpt-3.5-turbo-0613")  # 返回假设为gpt-3.5-turbo-0613的令牌数量
    elif "gpt-4" in model:
        print("警告:gpt-4可能会随时间更新。返回假设为gpt-4-0613的令牌数量。")
        return num_tokens_from_messages(messages, model="gpt-4-0613")  # 返回假设为gpt-4-0613的令牌数量
    else:
        raise NotImplementedError(
            f"""num_tokens_from_messages()未实现模型{model}。请参阅https://github.com/openai/openai-python/blob/main/chatml.md了解有关如何将消息转换为令牌的信息。"""
        )  # 抛出未实现错误,提示该模型未实现该函数
    num_tokens = 0
    for message in messages:
        num_tokens += tokens_per_message  # 每条消息的令牌数量
        for key, value in message.items():
            num_tokens += len(encoding.encode(value))  # 每个消息的值的编码长度
            if key == "name":
                num_tokens += tokens_per_name  # 如果是名称,则增加名称的令牌数量
    num_tokens += 3  # 每个回复以<|im_start|>assistant<|im_sep|>开头
    return num_tokens  # 返回总令牌数量
  • 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
# 导入openai模块
import openai

# 定义一个包含多个消息的列表
example_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.",
    },
]

# 遍历模型列表
for model in [
    "gpt-3.5-turbo-0301",
    "gpt-3.5-turbo-0613",
    "gpt-3.5-turbo",
    "gpt-4-0314",
    "gpt-4-0613",
    "gpt-4",
    ]:
    # 输出当前模型名称
    print(model)
    # 调用之前定义的函数,计算输入消息的token数
    print(f"{num_tokens_from_messages(example_messages, model)} prompt tokens counted by num_tokens_from_messages().")
    # 调用OpenAI API,计算输入消息的token数
    response = openai.ChatCompletion.create(
        model=model,
        messages=example_messages,
        temperature=0,
        max_tokens=1,  # 我们只计算输入token数,不浪费token计算输出
    )
    print(f'{response["usage"]["prompt_tokens"]} prompt tokens counted by the OpenAI API.')
    print()
  • 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
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
gpt-3.5-turbo-0301
127 prompt tokens counted by num_tokens_from_messages().
127 prompt tokens counted by the OpenAI API.

gpt-3.5-turbo-0613
129 prompt tokens counted by num_tokens_from_messages().
129 prompt tokens counted by the OpenAI API.

gpt-3.5-turbo
Warning: gpt-3.5-turbo may update over time. Returning num tokens assuming gpt-3.5-turbo-0613.
129 prompt tokens counted by num_tokens_from_messages().
127 prompt tokens counted by the OpenAI API.

gpt-4-0314
129 prompt tokens counted by num_tokens_from_messages().
129 prompt tokens counted by the OpenAI API.

gpt-4-0613
129 prompt tokens counted by num_tokens_from_messages().
129 prompt tokens counted by the OpenAI API.

gpt-4
Warning: gpt-4 may update over time. Returning num tokens assuming gpt-4-0613.
129 prompt tokens counted by num_tokens_from_messages().
129 prompt tokens counted by the OpenAI API.
  • 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
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/435923
推荐阅读
相关标签
  

闽ICP备14008679号