大模型开发(十):Chat Completion Models API 详解

news2024/10/6 10:27:37

全文共8000余字,预计阅读时间约18~28分钟 | 满满干货(附代码案例),建议收藏!

本文目标:详解Chat Completion Models的参数及应用实例,并基于该API实现一个本地知识库的多轮对话智能助理

请添加图片描述

代码&文件下载点这里

一、介绍

在OpenAI大模型生态中的文本模型包括了Completion模型和Chat模型,之前的文章已经详细介绍了OpenAI的完整大模型生态和Completion模型,如还不了解的可以看这两篇文章:

大模型实战(三):OpenAI大模型生态

大模型开发(六):OpenAI Completions模型详解并实现多轮对话机器人

本文介绍Chat类模型及其API使用方法,在OpenAI官网中可以看到模型列表如下:

image-20230722105356566

从模型的发展顺序上来看,Chat模型是Completion模型的升级版

1

二、Chat Completion Models与Completions Models的关系

Completion模型核心功能是根据提示(prompt)进⾏提示语句的补全(即继续进行后续⽂本创作),它本质上是文本补全模型。

Chat模型升级的核心功能是对话能力, 它基于大量高质量对话文本进行微调,能够更好的理解用户对话意图,所以它能更顺利的完成与用户的对话。

大语言模型本质上都是概率模型,根据前文提示进⾏补全是⼤语⾔模型的原始功能,而对话类的功能则是加⼊额外数据集之后训练的结果

当Completions Models和Chat Completions 接收不完整信息时,推理差异也是比较明显的,运行如下代码:

chat_completions_res = openai.ChatCompletion.create(
    model = "gpt-3.5-turbo-16k-0613",
    messages = [
     {"role": "user", "content":"你好呀,请问我"}   
    ]
)

chat_completions_res.choices[0].message["content"]
completions_res = openai.Completion.create(
    model = "text-davinci-003",
    prompt = "你好呀,请问我",
    max_tokens = 1000
)

completions_res["choices"][0]["text"].strip()

看下推理结果:

image-20230722114419319

其实可以能看出来,Chat模型能够比较好的理解对话意图,而Completions模型则是根据概率进行对话补全。

Chat模型的核心优势也就体现出来了: 理解⼈类意图的能力,与大语⾔模型(LLMs)交互最低⻔槛的形式就是对话,如果模型能够非常好的理解人类对话意图,才会更有利于模型的发展和社会价值的认同,这就是为什么gpt-3.5和davinci模型同属于⼀代模型,但基于gpt-3.5的 ChatGPT⼀炮而红,而早两年推出的davinci模型却远不及gpt-3.5影响力大。

据OpenAI官网数据,自gpt-3.5 API发布以来,约97%的开发者更偏向于使用Chat模型API进行开发

三、Chat Completion Models发展历程

Chat Completion Models 发展是非常迅速的,截止到目前2023年7月22日,OpenAI的官方数据如下:

  • 2023年3月1日,gpt-3.5-turbo API正式发布
  • 2023年3月14日,gpt-4 API正式发布,但是需要申请使用

在这两个里程碑后,也在不断的更新迭代,可用性不断的提升,经费也在不断的下降,如下图:

3

  • 2023年6月13日:OpenAI宣布在Chat Completion模型中加入函数调用(Function calling)功能,全面开放16K对话长度的模型、降低模型调用资费等

这代表着Chat模型不再需要借助LangChain框架就可以直接在模型内部调用外部工具API,可以更加便捷的构建以LLM为核心的AI应用程序。

  • 2023年7月6日:真正的王炸更新,申明将全面开放gpt-4 API,同时重点强调了原先的编程模型(code)模型的功能将合并入chat模型,同时,未来将更新Chat模型的fine - tunes API。

四、 Chat Completions Model API基本情况

截至目前,OpenAI发布的Chat Completions模型主要包括gpt-3.5和gpt-4两类模型,这两个模型也是目前ChatGPT应用程序背后的对话大模型。

根据官网给出的说明,gpt-3.5模型是基于text-davinci-003微调的模型,由code-davinci-002这一基座模型经过几轮微调后训练得到,对应的模型微调关系如下所示:

4

gpt-4则是完全重新训练的最新一代的对话类大模型,在诸多国内外大模型评测榜单上,gpt-4也是目前(多语种)对话效果最好的一类对话类大模型。

OpenAI发布的Chat Completions模型如下:

image-20230722121114581

但目前为止,Chat Completions模型并未开放全部的API,大多数模型的长文本对话模型(即标注为32k的模型),也需要填写申请方可使用,填写地址:申请地址 。

4.1 调用示例

与调用Completion模型需要使用Completion.create函数类似,若要调用Chat类大模型,则需要使用ChatCompletion.create函数。调用代码如下:

response = openai.ChatCompletion.create(
  model="gpt-3.5-turbo-16k-0613",
  messages=[
    {"role": "user", "content": "什么是机器学习?"}
  ]
)

reponse

和Completion.create非常明显的一个区别在于,ChatCompletion.create函数的调用不再需要prompt参数,而是换成了messages参数,并且,不同于prompt参数对象是以简单的字符串形式呈现,messages参数则是一个基本构成元素为字典的列表,其内每个字典都代表一条独立的消息,每个字典都包含两个键值(Key-value)对,其中第一个Key都是字符串role(角色)表示某条消息的作者,第二个key为content(内容)表示消息具体内容。

看下推理结果:

image-20230722131604281

messages参数是ChatCompletion.create函数最重要的参数之一,它可以简单理解为输入给模型的信息,模型接收到message之后也会输出对应的回答信息,代码如下:

# 查看第一个返回结果的message
response.choices[0].message['content']

看下推理结果:

image-20230722131901363

对话模型需要输入“message”,返回也是“message”,可以说这种文本交互形式确实非常符合人类在进行聊天时的问答习惯。

和Completion模型一样,Chat模型同样也可以在返回结果的usage中查看本次对话所占用的token数量,其中"prompt_tokens"表示提示词占用token数量,"completion_tokens"则表示返回结果所占用token数量,而"total_tokens"则是二者相加,代表本次对话总共占用token数量。

image-20230722132222974

4.2 参数详解

ChatCompletion.create函数的详细参数解释,官网介绍 。和Completion.create函数相比,ChatCompletion.create函数的参数结构发生了以下变化:

  • 用messages参数代替了prompt参数,使之更适合能够执行对话类任务
  • 新增functions和function_call参数,使之能够在函数内部调用其他工具的API
  • 其他核心参数完全一致,例如temperature、top_p、max_tokens、n、presence_penalty等参数的解释和使用方法都完全一致,且这些参数具体的调整策略也完全一致.
  • 剔除了best_of参数,即Chat模型不再支持从多个答案中选择一个最好的答案这一功能

各参数具体情况如下图:

5

五、messages参数详解

5.1 参数结构

messages是一种用于描述ChatCompletion模型和用户之间通信信息的高级抽象,从表示形式上来说,一个messages是一个列表,包含多个字典,每个字典都是一条消息,其中,一条消息由包含两个键值对(即每个字典都包含两个键值对),第一个键值对用于表示消息发送者,其中第一个Key为字符串’role’,Value为参与对话的角色名称,或者可以理解为本条消息的作者或消息发送人名称,第二个键值对表示具体消息内容,Key为字符串’content’,Value为具体的消息内容,用字符串表示。

例如下面的代码指代:messages包含一条信息,一个名为user的角色发送了一条名为’请问什么是机器学习?'的消息:

image-20230723105434799

返回的message结果也是一个“字典”,也包含了信息的发送方和具体信息内容

image-20230723105704860

即发送方是一个名为’assistant’的角色,具体内容则是一段关于什么是机器学习的描述。

image-20230723105741482Chat模型的每个对话任务都是通过输入和输出message来完成的。

5.2 message中的角色划分

5.2.1 user role和assistant role

一个最简单的对话就是扮演user(用户)这个角色(‘role’:‘user’),然后在content中输入问题并等待模型回答。而模型在实际回答过程中,会扮演一个名为assistant(助手)这个角色(‘role’:‘assistant’)进行回答,这里的user和assistant是具有明确含义的字符串,即如果一条信息的role是user,则表明这是用户向模型发送的聊天信息,相当于是Completion模型中的prompt,而如果一条信息的role是assistant,则表示这是当前模型围绕某条用户信息做出的回应,相当于是相当于是Completion模型中的text

基于这样的一个定义的规则,最简单的Chat模型的调用方法就是在messages参数中设置一条role为user的参数,在content中输入聊天的内容,而模型则会根据这条用户输入给模型的消息进行回答,代码如下:

response = openai.ChatCompletion.create(
  model="gpt-3.5-turbo-16k-0613",
  messages=[
    {"role": "user", "content": "什么是机器学习?"}
  ]

image-20230723110236561

同时,Messages可以包含多条信息,但模型只会对于最后一条用户信息进行回答,代码如下:

response = openai.ChatCompletion.create(
  model="gpt-3.5-turbo-16k-0613",
  messages=[
    {"role": "user", "content": "什么是机器学习?"},
    {"role": "user", "content": "什么是深度学习?"}
  ]
)

image-20230723110422293

assistant消息和role消息是一一对应的,在一般情况下,assistant消息只会围绕messages参数中的最后一个role信息进行回答。

5.2.2 system role

user和assistant的这种提问方式尽管足够清晰,但往往形式上不够丰富,在实践中人们发现,给聊天机器人进行一个身份设置,是非常有效的引导模型创作出想要的结果的方法,例如如果希望获得一个关于“什么是机器学习?”更加严谨且丰富的答案,可以以“假设你是一名机器学习领域的资深专家,具备20年以上的研究经历”为模型进行身份设置,代码如下:

response = openai.ChatCompletion.create(
  model="gpt-3.5-turbo-16k-0613",
  messages=[
    {"role": "user", "content": "假设你是一名机器学习领域的资深专家,具备20年以上的研究经历,请帮我回答,什么是机器学习?"}
  ]
)

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

看下模型给出的推理:

image-20230723111028245

如果使用system role 身份设定,代码如下:

response = openai.ChatCompletion.create(
  model="gpt-3.5-turbo-16k-0613",
  messages=[
    {"role": "system", "content": "你是一名机器学习领域的资深专家,具备20年以上的研究经历"},
    {"role": "user", "content": "请问什么是机器学习?"}
  ]
)

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

看下推理结果:

image-20230723111233301

在原有消息之前,新增一条消息{“role”: “system”, “content”: “你是一名机器学习领域的资深专家,具备20年以上的研究经历”},能起到设定模型身份的作用。所以这条消息的实际含义是,以system的身份发送一条消息,消息内容为“你是一名机器学习领域的资深专家,具备20年以上的研究经历”。system就是messages参数的role可以选取的第三个字符串,意为该消息为一条系统消息。

相比用户消息,系统消息有以下几点需要注意,其一是系统消息的实际作用是给整个对话系统进行背景设置,不同的背景设置会极大程度影响后续对话过程中模型的输出结果,例如如果系统设置为“你是一位资深医学专家”,那么接下来系统在进行回答医学领域相关问题时则会引用大量医学术语,而如果系统设置为“你是一位资深喜剧演员”,那么接下来系统进行的回答则会更加风趣幽默:

response = openai.ChatCompletion.create(
  model="gpt-3.5-turbo-16k-0613",
  messages=[
    {"role": "system", "content": "你是一名资深的喜剧演员"},
    {"role": "user", "content": "请问什么是机器学习?"}
  ]
)

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

看下推理结果:

image-20230723111734280

很明显能看出来风格的转变是非常大的。

另外,当messages中只包含一条system消息时,系统会围绕system进行回答,此时系统的assistant的应答消息则更像是一个completion的过程,即围绕system的prompt进行进一步的文本补全:

response = openai.ChatCompletion.create(
  model="gpt-3.5-turbo-16k-0613",
  messages=[
    {"role": "system", "content": "你是一名机器学习领域的资深专家,具备20年以上的研究经历"},
  ]
)

看下推理结果:

image-20230723111928889

需要根据system系统信息对系统进行设置,然后再提问,那么先system消息再user消息的顺序是非常重要的,例如还是上面的例子,还是希望以喜剧演员的身份介绍机器学习,但如果调换了system消息和user消息的顺序,system消息的作用就会失效,代码如下:

response = openai.ChatCompletion.create(
  model="gpt-3.5-turbo-16k-0613",
  messages=[
    {"role": "user", "content": "请问什么是机器学习?"},
    {"role": "system", "content": "你是一名资深的喜剧演员"}
  ]
)

看下推理结果:

image-20230723112145201

模型能解答“请问什么是机器学习?”这个问题,但却没有正确接受“你是一名资深喜剧演员”这个设定。

根据OpenAI官网说明,截至目前,gpt-3.5系列模型仍然无法对system提供的系统消息保持长期关注,即在多轮对话中,模型极有可能逐渐忘记自己的身份设定。根据长期使用情况来看,gpt-4模型对system设置的长期关注要好于gpt-3.5系列模型。

对于messages中可选的role来说,除了ueser、assistant、system之外,还有一个function role,用于表示某条消息为某函数的调用指令,function role是OpenAI 0613更新中提供的新的role选项,用于Chat模型调用外部定义函数或者工具API时使用。

六、message参数应用实例

对ChatCompletion.create函数来说,通过灵活的messages参数,能够非常便捷高效的实现诸多类型的对话需求,例如基于提示词模板的提问、Few-shot提问、基于某背景知识的提问等

在大模型开发(八):基于思维链(CoT)的进阶提示工程文章中提出了四个经典的推理题,本文就以这四个问题作为示例,看一下如何用用在Chat模型下如何进行推理。

先提前定义好四组问题的问题和答案:

Q1 = '罗杰有五个网球,他又买了两盒网球,每盒有3个网球,请问他现在总共有多少个网球?'
A1 = '现在罗杰总共有11个网球。'

Q2 = '食堂总共有23个苹果,如果他们用掉20个苹果,然后又买了6个苹果,请问现在食堂总共有多少个苹果?'
A2 = '现在食堂总共有9个苹果。'

Q3 = '杂耍者可以杂耍16个球。其中一半的球是高尔夫球,其中一半的高尔夫球是蓝色的。请问总共有多少个蓝色高尔夫球?'
A3 = '现在总共有4个蓝色高尔夫球。'

Q4 = '艾米需要4分钟才能爬到滑梯顶部,她花了1分钟才滑下来,水滑梯将在15分钟后关闭,请问在关闭之前她能滑多少次?'
A4 = '关闭之前艾米能滑3次。'

gpt-3.5是基于对话语料进行的微调,它具有比text-davinci-003更强大的推理能力,四个推理问题对于gpt-3.5来说,除了最后一个问题不一定能得出正确答案外,其他问题均能在不进行额外提示的情况下进行很好的回答。

经过测试,gpt-4模型能够非常好的回答第四个推理问题。但这并不代表此前的CoT和LtM技术就不再重要,面对超出模型原生能力的更加复杂的推理问题(如SCAN数据集的命令解释问题),仍然还是需要使用这些提示工程技术。

6.1 借助多轮user-assistant消息进行few-shot

先看下使用Zero-shot提示对第二个推理题Q2 进行提问,代码如下:

response = openai.ChatCompletion.create(
  model="gpt-3.5-turbo-16k-0613",
  messages=[
    {"role": "user", "content": Q2}
  ]
)

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

看下推理结果:

image-20230723113800955

如果想在Chat模型中进行Few-shot,最好的办法就是在messages中设置多轮user-assistant消息,所以做法就是:尝试以第一个问题的问题和答案作为提示示例,引导模型解答第二个问题,则可以按照如下方式设置messages,代码如下:

response = openai.ChatCompletion.create(
  model="gpt-3.5-turbo-16k-0613",
  messages=[
    {"role": "user", "content": Q1},
    {"role": "assistant", "content": A1},
    {"role": "user", "content": Q2}
  ]
)

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

看下推理结果:

image-20230723113517951

相比单独进行Q2的提问,经过Few-shot的提示回答的结果,会更加接近A1结果(‘现在罗杰总共有11个网球。’)的表示格式

assistant消息是可以自定义的,用于给模型提供回答的范本,不仅可以按照system-user的形式规定回答风格,而且还可以按照user-assistant-user-assistant…形式来进行Few-shot。

6.2 借助system role进行Few-shot

可以把提示示例写进一条system信息中,作为当前问答的背景信息,代码如下:

response = openai.ChatCompletion.create(
  model="gpt-3.5-turbo-16k-0613",
  messages=[
    {"role": "system", "content": 'Q: ' + Q1 + 'A: ' + A1},
    {"role": "user", "content": 'Q: ' + Q2 }
  ]
)

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

看下推理结果:

image-20230723121232551

6.3 借助system role输入提示模板

即然system消息能够作为背景设定的基本消息并对后续的问答消息造成影响,那么很容易想到的system消息的一个应用场景就是借助system role输入提示模板,例如在Completions模型中为了更好的提高模型推理能力,可以在每个prompt中加入一句“请一步步推理并得出结论”进而实现Zero-shot-CoT。而在Chat模型中,这种prompt模板信息是非常适合通过system role进行输入的,例如围绕第四个推理问题,可以通过输入一条内容为“请一步步推理并得出结论”的系统信息,来引导模型完成Zero-shot-CoT,代码如下:

prompt_temp_cot = '请一步步思考并解决问题'

response = openai.ChatCompletion.create(
  model="gpt-3.5-turbo-16k-0613",
  messages=[
    {"role": "system", "content": prompt_temp_cot},
    {"role": "user", "content": Q1}
  ]
)

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

看下推理结果:

image-20230723121537422

再测试一下LtM提示法,代码如下:

prompt_temp_ltm = '为了解决当前这个问题,请列举我们先要解决的问题,并逐步解决原问题。'

response = openai.ChatCompletion.create(
  model="gpt-3.5-turbo",
  messages=[
    {"role": "system", "content": prompt_temp_ltm},
    {"role": "user", "content": Q1}
  ]
)

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

看下推理结果:

image-20230723122316738

其实在多次尝试中也发现了,gpt-3.5的推导过程复杂且不稳定,使用LtM提示法回答Q4这个最难的推理题时,10次能回答正确3次,直接提问更是一次都回答不对,

prompt_temp_ltm = '为了解决当前这个问题,请列举我们先要解决的问题,并逐步解决原问题。'

response = openai.ChatCompletion.create(
  model="gpt-3.5-turbo",
  messages=[
    {"role": "system", "content": prompt_temp_ltm},
    {"role": "user", "content": Q4}
  ]
)

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

推理结果如下:

image-20230723122644100

**gpt-4模型在相同提示策略下,会表现出更强大的推理性能。**同样是围绕第四个问题,对gpt-4模型进行CoT和LtM提示结果如下:

response = openai.ChatCompletion.create(
  model="gpt-4-0613",
  messages=[
    {"role": "system", "content": prompt_temp_cot},
    {"role": "user", "content": Q4}
  ]
)

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

第一次推理结果:

image-20230723122836023

第二次推理结果:

image-20230723122914037

除了推理能力外,gpt-4各方面性能都属于目前大模型领域的顶流。

6.4 借助system role设置聊天背景信息

一个非常常见的system role的使用方法,就是借助system消息进行聊天背景信息的设定,很多时候可以在system消息中输入一段长文本,这段长文本将在聊天开始之前输入到系统中,而在之后的聊天中,即可让assistant围绕这个长文本进行回答,这是一种最简单的实现大语言模型围绕本地知识库进行问答的方法。

在system消息中输入一段关于虚拟人物“算法小陈”的个人简介,而在之后的提问中,user和assistant将可以自由的围绕这段输入的背景信息进行问答:

text = '陈某,男,1995123日出生于内蒙古赤峰市。\
        2017年毕业于北京某大学计算机系,同时获得计算机博士学位。\
        毕业后在硅谷的一家著名科技公司工作了五年,专注于人工智能和机器学习的研发。'

response = openai.ChatCompletion.create(
  model="gpt-3.5-turbo-16k-0613",
  messages=[
    {"role": "system", "content": text},
    {"role": "user", "content": '请问陈某是哪一年出生的?'}
  ]
)

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

看下回答结果:

image-20230723123909082

背景背景信息能够被模型学习并以此进行特定问题的回答。这就是一种非常简单的围绕本地知识进行问答的实现形式。

不过需要注意的是,system role输入的信息也算是输入给模型的信息,因此受限于大语言模型的最大输入信息长度,单独借助system role在ChatCompletion.create函数中输入背景信息并不能真正意义上实现高度定制化、超大规模文本的本地知识库问答。但是,如果围绕着超大规模本地文本知识库先进行基于滑动窗口的文本切分,以确保切分后的小文本段落满足Max tokens要求,并且配合Embedding过程进行user问题和短文本的实时匹配,再把每个user问题匹配的关联度最高的文本以system消息的形式输入到模型中,再进行回答,则可以非常高效并且准确的实现本地知识库问答。而在这个过程中,借助system role进行背景文字的输入就非常基本的技术手段。

6.5 借助.append方法进行多轮对话

除了通过内部参数修改来实现不同功能外,messages参数的另一个重要应用是借助append方法来高效实现多轮对话。

不同于Completion模型需要将历史问答都拼接为一个字符串并输入到新的prompt中来实现历史消息的输入,对于Chat模型来说,只需要将模型返回的message消息+用户新的提问message拼接到模型的messages参数中,并再次向模型进行提问,即可非常便捷的实现多轮对话。

单独设置messages参数,并将此前的问题+答案进行拼接,代码如下:

text = '陈某,男,1995123日出生于内蒙古赤峰市。\
        2017年毕业于北京某大学计算机系,同时获得计算机博士学位。\
        毕业后在硅谷的一家著名科技公司工作了五年,专注于人工智能和机器学习的研发。'

messages=[
    {"role": "system", "content": text},
    {"role": "user", "content": '请问陈某是哪一年出生?'}
]

messages.append(response.choices[0].message.to_dict())

messages

此时的messages是这样的:

image-20230723124348367

此时messages参数包含了最开始的问题+问题答案。接下来在messages消息中添加下一个问题:

messages.append({'role': 'user', 'content': '请问我刚才的问题是?'})

messages

此时的messages是这样的:

image-20230723124547738

接下来再次调用模型,并输入messages作为参数,此时模型将同时结合此前的所有消息,并围绕最后一个user信息进行回答:

response = openai.ChatCompletion.create(
  model="gpt-3.5-turbo-16k-0613",
  messages=messages
)

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

此时推理结果:

image-20230723124656717

能够发现,相比Completions模型,Chat类模型能够更加便捷的实现多轮对话。

七、实操:训练一个本地知识库的智能助理

最后,尝试实现一个手动实操项目,即训练一个简易的大模型开发内容智能助理,要求让这个智能助理能够理解Chat Completions模型的相关内容,同时也能够围绕该问题进行多轮对话,以辅助进行学习。

gpt系列模型的知识库截止于2021年9月,因此模型本身是不知道ChatCompletion.create函数的,因此只通过模型原始的知识库是无法完成多轮对话函数编写的,因此需要先把Chat Completions模型的相关内容输入给模型,然后再引导模型完成多轮对话。

image-20230723130221315

Step 1:打开并读取Markdown文件

# 打开并读取Markdown文件
with open('大模型开发(十):Chat Completion Models API使用指南.md', 'r', encoding='utf-8') as f:
    md_content = f.read()

image-20230723130450164

Step 2:作为system message输入给模型

读取之后尝试将其作为system message输入给模型,然后要求模型根据本节内容编写一个能够实现多轮对话的函数,可以先通过如下message测试模型是否已经学习到ChatCompletion.create相关信息:

response = openai.ChatCompletion.create(
  model="gpt-3.5-turbo-16k-0613",
  messages=[
    {"role": "system", "content": md_content},
    {"role": "user", "content": '请帮我介绍下openai.ChatCompletion.create这个函数'}
  ]
)

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

看下推理结果:

image-20230723130700029

此时模型已经能够了解openai.ChatCompletion.create函数使用方法与基本规则。

Step 3:创建多轮对话函数

接下来尝试令其编写一个多轮对话函数,代码如下:

response = openai.ChatCompletion.create(
  model="gpt-3.5-turbo-16k-0613",
  messages=[
    {"role": "system", "content": md_content},
    {"role": "user", "content": '请帮编写一个基于openai.ChatCompletion.create这个函数的能够实现多轮对话的函数'}
  ]
)

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

看下推理结果:

image-20230723130916142

Step 4:将编写结果转化为markdown格式,并写入本地

with open('chatCompletionsModelTest.md', 'a', encoding='utf-8') as f:
    f.write(response.choices[0].message['content'])

保存后打开看一下:

image-20230723131049068

Step 5:运行函数

def chat_with_model(messages):
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo-16k-0613",
        messages=messages
    )
    return response.choices[0].message['content']

# 测试函数
def test_chat_with_model():
    # 初始问候
    messages = [
        {"role": "user", "content": "你好!"},
        {"role": "assistant", "content": "你好!我是一个智能助理,有什么问题我可以帮助你?"}
    ]
    print(chat_with_model(messages))

    # 进行对话
    while True:
        user_input = input("用户:")
        messages.append({"role": "user", "content": user_input})
        assistant_response = chat_with_model(messages)
        messages.append({"role": "assistant", "content": assistant_response})
        print("助理:" + assistant_response)

        # 判断是否结束对话
        if user_input.lower() == 'bye':
            break

test_chat_with_model()

看下运行情况:

image-20230723131350798

至此,就成功完成了将本地的Chat Completions Models的相关知识输入到模型中,然后借助模型完成Chat模型多轮对话的编写需求。

Step 6:优化

以更进一步将Chat Completions Models的相关知识作为system message进行输入,即可完成围绕课程问题的问答机器人,优化代码如下:

def chat_with_model(prompt, model="gpt-3.5-turbo-16k-0613"):
    messages = [
        {"role": "system", "content": md_content},
        {"role": "user", "content": prompt}
    ]
    
    while True:
        response = openai.ChatCompletion.create(
            model=model,
            messages=messages
        )
        
        # 获取模型回答
        answer = response.choices[0].message['content']
        print(f"模型回答: {answer}")

        # 询问用户是否还有其他问题
        user_input = input("您还有其他问题吗?(输入退出以结束对话): ")
        if user_input == "退出":
            break

        # 记录用户回答
        messages.append({"role": "user", "content": user_input})

运行一下:

image-20230723131747203

可以看出来,回答的问题都是本文上述说到内容和知识,其实这样就可以认为是它完成了本地知识库的问题。

八、总结

文章从介绍Chat Completion Models开始,阐述了其与Completions Models的关系及其发展历程。深入解读了Chat Completions Model API,包括调用示例及参数详解。在此基础上,专门对messages参数进行了详解,包括参数结构,以及message中的角色划分。并且,提供了丰富的message参数应用实例,如借助多轮user-assistant消息进行few-shot,使用system role进行Few-shot,输入提示模板,设置聊天背景信息,以及使用.append方法进行多轮对话。文章的最后部分提供了实际操作示例,训练一个本地知识库的智能助理,为实际应用Chat Completion Models提供了参考。

最后,感谢您阅读这篇文章!如果您觉得有所收获,别忘了点赞、收藏并关注我,这是我持续创作的动力。您有任何问题或建议,都可以在评论区留言,我会尽力回答并接受您的反馈。如果您希望了解某个特定主题,也欢迎告诉我,我会乐于创作与之相关的文章。谢谢您的支持,期待与您共同成长!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/779226.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

通过ETL自动化同步飞书数据到本地数仓

一、飞书数据同步到数据库需求 使用飞书的企业都有将飞书的数据自动同步到本地数据库、数仓以及其他业务系统表的需求,主要是为了实现飞书的数据与业务系统进行流程拉通或数据分析时使用,以下是一些具体的同步场景示例: 组织架构同步&#…

windows版docker部署mysql并导入数据

会用到的操作命令: 1.退出容器中的bash界面:exit 2.停止某个容器:docker stop container_name_or_id 3.要强制删除 Docker 中的某个容器: docker rm -f container_name_or_id 1.先下载并配置好docker 2.拉取 MySQL 镜像&#x…

深度学习——过拟合和Dropout

基本概念 什么是过拟合? 过拟合(Overfitting)是机器学习和深度学习中常见的问题之一,它指的是模型在训练数据上表现得很好,但在未见过的新数据上表现较差的现象。 当一个模型过度地学习了训练数据的细节和噪声&#…

数据仓库发展历史

数据仓库发展历史 一、演变 数据仓库是企业中用于存储、整合和分析数据的关键组件。随着时间的推移,数据仓库经历了三代演化:从需求驱动到平台化、从平台化到智能(AI)化 二、第一代(过时) 第一代数据仓…

【《Spring Boot微服务实战(第2版)》——一本关于如何在Spring Boot中构建微服务的全面指南】

使用Spring Boot框架构建基于Java的微服务架构,将应用程序从小型单体架构蜕变为由多个服务组成的事件驱动架构。这个最新版本围绕服务发现、负载均衡、路由、集中式日志、按环境配置和容器化等知识点,循序渐进地讲述微服务架构、测试驱动的开发和分布式系…

Radare2:using test

Radare2:using test └─$ sudo apt install radare2 100 ⨯ [sudo] kwkl 的密码: 正在读取软件包列表... 完成…

【Bug记录篇】IDEA双击打不开,报错的问题

早上,带着满满的干劲来实验室,准备继续我的IDEA之旅,结果好嘛,一打开IDEA,给我这样?!!!😲😲😲 这是怎么回事!!…

FPGA-DFPGL22学习7-gpio

系列文章目录 FPGA-DFPGL22学习6-led 文章目录 系列文章目录前言一、原理图1)key2)beeptouch端口对应1)key2)beeptouch 二、程序设计1)KEY2)beeptouch 三、程序编写1.KEY代码:2.beeptouch代码: 结论 前言 和原子哥一起学习FPGA …

blender 基础材质篇

材质展示 材质背景介绍 什么是PBR? PBR 全称为 Physically Based Rendering,译为基于物理属性的引擎渲染,也就是说会把物质的颜色、粗糙度、高光属性等进行分别处理,使物质体现出更真实的感觉; 什么是BRDF&#xff…

【Linux】初识多线程深入理解进程地址空间

目录 1 多线程的引入 1.1 相关概念 1.2 Linux操作系统理解多线程 特殊的进程结构 创建子进程的过程 创建多线程 进程与线程之间的关系 1.3 对多线程结构的管理 Windows管理多线程 Linux管理多线程 1.4 理解多线程与多进程相比,调度的成本更低 2 深入理…

[JAVAee]volatile关键字

目录 1.volatile的特性 ①保持线程可见性 2.volatile注意事项及适用场景 ①注意事项 ②适用场景 1.volatile的特性 ①保持线程可见性 volatile,译为"易变的". 对此我们就可以这样理解,对于被volatile修饰的变量的数值,是容易变化的. 在之前的线程安全文章中,…

XILINX ZYNQ 7000 AXI总线 (二)

了解了AXI 的大部分内容后,开始做一个实战,就是完成AXI 结构的输入输出搭建。 一.创建一个IP 3. 4. 5. 6.选择AXI FULL,创界主接口和从接口 7. 8.可以看到XILINX AXI FULL 的源代码 二.创建一个新的工程,把IP导入到这个工…

ARP系统的命令行基础

系列文章目录 华为数通学习(2) 一、基本命令结构 二、命令行视图 设备提供了多样的配置和查询命令,为便于用户使用这些命令,VRP系统按功能分类将命令分别注册在不同的命令行视图下。 2.1,命令行视图介绍 我们接下来…

DevOps系列文章 之GitLabCI模板库的流水线

目录结构,jobs目录用于存放作业模板。templates目录用于存放流水线模板。这次使用​​default-pipeline.yml​​作为所有作业的基础模板。 作业模板 作业分为Build、test、codeanalysis、artifactory、deploy部分,在每个作业中配置了rules功能开关&…

栈和队列 --- C语言实现

本篇文章来详细介绍一下栈和队列,并且通过数组或链表来实现。 目录 1.栈 1.1栈的概念及结构 1.2栈的实现 2.队列 2.1队列的概念及结构 2.2队列的实现 3.栈和队列面试题 4.相关概念选择题 1.栈 1.1栈的概念及结构 栈:一种特殊的线性表&#xff…

项目初始化--uniapp--vscode--vue3--ts

HBuilderX 创建 uni-app 项目 注意开启服务端口 目录结构 ├─pages 业务页面文件存放的目录 │ └─index │ └─index.vue index页面 ├─static 存放应用引用的本地静态资源的目录(注意:静态资源只能存放于此) ├─unpackage …

eclipse中经常遇到的maven相关的问题

maven工程依赖的jar包无法部署到tomcat中 右键maven工程&#xff0c;选择“属性” 将工程在tomcat重新发布即可。 2、Update Project or use Quick Fix maven工程总是提示更新&#xff0c;一更新java版本又回到1.5 在pom.xml添加如下&#xff1a; <build><finalN…

【jenkins】idea+jenkins+docker+dockerfile+compose流水线部署java应用

目录 整体架构 环境准备 安装docker以及docker-compose jenkins安裝 maven安装 portainer面板安装 sonarqube安装 在项目中增加dockerfile和compose.yml脚本 Dockerfile脚本内容 compose.yml脚本内容 jenkins安装必要插件 jenkins增加流水线任务 增加pipeline任务j…

windows下搭建php开发环境

http://wed.xjx100.cn/news/139397.html?actiononClick https://www.bilibili.com/read/cv23429835/ https://www.php.cn/faq/498307.html 安装iis 选择卸载程序 安装php 官网https://www.php.net/下载 选择线程安全 国内地址 下载完成后解压放到想存放的路径 添加p…

【Deviation】50 Matplotlib Visualizations, Python实现,源码可复现

详情请参考博客: Top 50 matplotlib Visualizations 因编译更新问题&#xff0c;本文将稍作更改&#xff0c;以便能够顺利运行。 本文介绍一下5中图示&#xff1a; Diverging Bars Diverging Texts Diverging Dot Plot Diverging Lollipop Chart with Markers Area Chart 1 Di…