Skip to content

Instantly share code, notes, and snippets.

@lewangdev
Last active June 6, 2023 11:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lewangdev/b03a53399a682aefd28a5ee030722bce to your computer and use it in GitHub Desktop.
Save lewangdev/b03a53399a682aefd28a5ee030722bce to your computer and use it in GitHub Desktop.
Building Systems with the ChatGPT API 视频的中英文字幕,用 Faster-Whisper 和 GPT-3.5 自动生成:https://learn.deeplearning.ai/chatgpt-building-system/lesson/6/chaining-prompts
1
00:00:04,880 --> 00:00:11,880
在这个视频中,我们将学习如何通过将多个提示链接在一起将复杂任务分解为一系列简单子任务。
In this video, we'll learn how to split complex tasks into a series of simple sub-tasks by chaining multiple prompts together.
2
00:00:12,340 --> 00:00:13,540
你可能会问,
You might be wondering,
3
00:00:13,780 --> 00:00:20,620
为什么要将任务拆分为多个提示,而不是像我们在之前的视频中学习的那样使用一个提示和思维链推理来实现呢?
why would you split up a task into multiple prompts when you could achieve it with one prompt and chain of thought reasoning like we learned in the previous video.
4
00:00:21,100 --> 00:00:25,020
我们已经证明了语言模型非常擅长执行复杂指令,
We've already shown that language models are very good at following complex instructions,
5
00:00:25,500 --> 00:00:27,580
特别是像GPT-4这样的高级模型。
especially the more advanced models like GPT-4.
6
00:00:28,100 --> 00:00:34,360
让我解释一下为什么我们要用两个类比来比较思维链的推理和多个提示的链接。
So let me explain why we would do this with two analogies comparing chain of thought reasoning and chaining multiple prompts.
7
00:00:34,860 --> 00:00:40,860
第一个比喻是比较一次性烹饪复杂餐点和分阶段烹饪的区别。
The first analogy to compare the two is the difference between cooking a complex meal in one go versus cooking it in stages.
8
00:00:41,780 --> 00:00:43,120
使用一个长而复杂的指令就像是试图一次性烹饪复杂的餐点,你必须管理多个配料,
Using one long,
9
00:00:43,680 --> 00:00:47,100
而分阶段烹饪则更像是按照步骤完成每个部分,最后将它们组合成一道美味的餐点。
complicated instruction can be like trying to cook a complex meal all at once,
10
00:00:47,420 --> 00:00:49,140
因此,对话系统通常会使用多个提示来引导用户完成任务。
where you have to manage multiple ingredients,
11
00:00:49,580 --> 00:00:51,740
同时掌握烹饪技巧和时间是一项挑战。
cooking techniques, and timings simultaneously.
12
00:00:52,520 --> 00:00:55,920
很难跟踪每个组件并确保每个组件都烹饪完美。
It can be challenging to keep track of everything and ensure that each component is
13
00:00:56,420 --> 00:00:56,580
另一方面,链接提示就像分阶段烹饪餐点一样,
cooked perfectly.
14
00:00:57,460 --> 00:01:00,260
您可以一次专注于一个组件。
Chaining prompts, on the other hand, is like cooking the meal in stages,
15
00:01:00,580 --> 00:01:02,740
这样更容易掌握每个组件的烹饪。
where you focus on one component at a time,
16
00:01:03,100 --> 00:01:05,880
确保每一部分煮熟后再进行下一步。
ensuring that each part is cooked correctly before moving on to the next.
17
00:01:06,600 --> 00:01:08,980
这种方法可以分解任务的复杂性,
This approach breaks down the complexity of the task,
18
00:01:09,260 --> 00:01:11,960
使其更易于管理并降低出错的可能性。
making it easier to manage and reducing the likelihood of errors.
19
00:01:12,520 --> 00:01:12,840
然而,
However,
20
00:01:13,160 --> 00:01:16,680
对于非常简单的食谱,这种方法可能是不必要和过于复杂的。
this approach might be unnecessary and overcomplicated for a very simple recipe.
21
00:01:17,580 --> 00:01:25,060
同样的事情,一个更好的比喻是阅读一长串代码和一个简单的模块化程序之间的区别。
A slightly better analogy for the same thing is the difference between reading spaghetti code with everything in one long file and a simple modular program.
22
00:01:25,260 --> 00:01:32,140
使意大利面条代码变坏和难以调试的因素是逻辑的不确定性和复杂的依赖关系。
The thing that can make spaghetti code bad and difficult to debug is ambiguity and complex dependencies between different parts of the logic.
23
00:01:32,620 --> 00:01:36,580
对于提交给语言模型的复杂单步任务也是如此。
The same can be true of a complex single-step task submitted to a language model.
24
00:01:37,320 --> 00:01:46,340
当您拥有可以在任何给定点维护系统状态并根据当前状态采取不同操作的工作流程时,链接提示是一种强大的策略。
Chaining prompts is a powerful strategy when you have a workflow where you can maintain the state of the system at any given point and take different actions depending on the current state.
25
00:01:46,920 --> 00:01:51,920
因此,当前状态的一个示例是在分类传入的客户查询之后。
And so an example of the current state would be after you've classified an incoming customer query,
26
00:01:52,360 --> 00:01:54,060
状态将是分类。
the state would be the classification.
27
00:01:54,940 --> 00:01:57,380
所以这是一个账户问题还是一个产品问题。
So it's an account question or it's a product question.
28
00:01:58,220 --> 00:02:00,360
然后根据状态,你可能会做一些不同的事情。
And then based on the state, you might do something different.
29
00:02:01,600 --> 00:02:07,920
每个子任务只包含执行任务所需的单个状态的说明,这使得系统更易于管理,
Each subtask contains only the instructions required for a single state of the task, which makes the system easier to manage,
30
00:02:08,420 --> 00:02:11,520
确保模型具有完成任务所需的所有信息,
makes sure the model has all the information it needs to carry out a task,
31
00:02:11,780 --> 00:02:13,300
并且减少了错误的可能性,
and reduces the likelihood of errors,
32
00:02:13,780 --> 00:02:14,520
正如我之前提到的。
as I mentioned.
33
00:02:15,320 --> 00:02:20,600
这种方法还可以降低成本,因为带有更多标记的较长提示的运行成本更高,
This approach can also reduce and lower costs since longer prompts with more tokens cost more to run,
34
00:02:21,000 --> 00:02:23,940
在某些情况下,概述所有步骤可能是不必要的。
and outlining all steps might be unnecessary in some cases.
35
00:02:24,620 --> 00:02:29,860
这种方法的另一个好处是更容易测试哪些步骤可能更容易失败,
Another benefit of this approach is that it is also easier to test which steps might be failing more often,
36
00:02:30,080 --> 00:02:32,860
或者在特定步骤中有人参与。
or to have a human in the loop at a specific step.
37
00:02:33,180 --> 00:02:34,140
所以总结一下,
So to summarize,
38
00:02:34,380 --> 00:02:35,440
因为这是一个漫长的解释,
because this was a long explanation,
39
00:02:35,960 --> 00:02:40,700
不是在一个提示中用几十个项目符号或几个段落描述整个复杂的工作流程,
instead of describing a whole complex workflow in dozens of bullet points or several paragraphs in one prompt,
40
00:02:40,960 --> 00:02:41,920
就像在之前的视频中一样。
like in the previous video,
41
00:02:42,260 --> 00:02:47,300
可能更好的做法是在外部跟踪状态,然后在需要时注入相关指令。
it might be better to keep track of the state externally and then inject relevant instructions as needed.
42
00:02:48,020 --> 00:02:50,080
那么什么会让一个问题变得复杂呢?
And what makes a problem complex?
43
00:02:50,580 --> 00:02:56,900
我认为,一般来说,如果有很多不同的指令,而且潜在地所有这些指令都可能适用于任何给定的情况,那么问题就是复杂的。
I think in general, a problem is complex if there are many different instructions and potentially all of them could apply to any given situation,
44
00:02:57,240 --> 00:03:01,180
因为这些情况下,模型很难推理出该做什么。
as these are the cases where it could become hard for the model to reason about what to do.
45
00:03:01,380 --> 00:03:03,480
随着您越来越多地使用和与这些模型交互,情况会变得越来越复杂。
And as you build with and interact with these models more,
46
00:03:03,740 --> 00:03:06,580
你会逐渐形成何时使用这种策略与之前策略的直觉。
you'll gain an intuition for when to use this strategy versus the previous.
47
00:03:07,340 --> 00:03:15,720
而且我还没提到的另一个好处是,如果必要的话,它也允许模型在工作流的某些节点使用外部工具。
And one additional benefit that I didn't mention yet is that it also allows the model to use external tools at certain points of the workflow if necessary.
48
00:03:15,960 --> 00:03:16,820
例如,
For example,
49
00:03:17,060 --> 00:03:22,560
它可能决定在产品目录中查找某些东西,或者调用API或搜索知识库,
it might decide to look something up in a product catalog or call an API or search a knowledge base,
50
00:03:22,800 --> 00:03:25,020
这些都无法通过单个提示实现。
something that could not be achieved with a single prompt.
51
00:03:25,740 --> 00:03:27,780
那么,让我们来看一个例子。
So with that, let's dive into an example.
52
00:03:28,740 --> 00:03:40,540
我们将使用与上一个视频中相同的示例,其中我们想回答客户有关特定产品的问题,但这次我们将使用更多的产品,并将步骤分解为多个不同的提示。
So we're going to use the same example as in the previous video, where we want to answer a customer's question about a specific product, but this time we'll use more products and also break the steps down into a number of different prompts.
53
00:03:41,440 --> 00:03:45,700
所以我们将使用我们之前一直使用的相同分隔符,让我们阅读一下我们的系统消息。
So we'll use the same delimiter that we've been using in the previous
54
00:03:46,760 --> 00:03:49,600
您将获得客户服务查询。
videos, and let's read through our system message.
55
00:03:51,480 --> 00:03:55,080
You will be provided with customer service queries.
56
00:03:55,560 --> 00:03:59,680
客服查询会以四个井号字符为分隔符。
The customer service query will be delimited with four hashtag characters.
57
00:04:00,520 --> 00:04:03,720
输出一个 Python 对象列表,每个对象的格式如下。
Output a Python list of objects where each object has the following format.
58
00:04:04,960 --> 00:04:05,620
类别,
Category,
59
00:04:06,160 --> 00:04:08,500
这是这些预定义字段之一,
which is one of these predefined fields,
60
00:04:09,380 --> 00:04:10,500
或产品。
or products.
61
00:04:10,760 --> 00:04:14,280
这是必须在下面的允许产品列表中找到的产品列表。
And this is a list of products that must be found in the allowed products below.
62
00:04:14,640 --> 00:04:17,960
其中类别和产品必须在客户服务查询中找到。
Where the categories and products must be found in the customer service query.
63
00:04:19,060 --> 00:04:24,020
如果提到了一个产品,它必须与下面的允许产品列表中的正确类别相关联。
If a product is mentioned, it must be associated with the correct category in the allowed products list below.
64
00:04:24,540 --> 00:04:27,400
如果没有找到产品或类别,则输出一个空列表。
If no products or categories are found, output an empty list.
65
00:04:27,900 --> 00:04:30,380
现在我们有了允许产品的列表。
And so now we have our allowed list of products.
66
00:04:30,640 --> 00:04:33,700
那么我们有分类,然后是这些分类中的产品。
So we have the categories and then the products within those categories.
67
00:04:35,540 --> 00:04:39,860
最后的指令是仅输出列表中的对象,没有其他内容。
And our final instruction is only output the list of objects with nothing else.
68
00:04:43,240 --> 00:04:45,920
接下来是用户消息。
So next we have our user message.
69
00:04:46,180 --> 00:04:47,440
因此这条消息是:
And so this message is,
70
00:04:48,020 --> 00:04:51,300
告诉我关于智能X Pro手机和照片快照相机的信息。
tell me about the smart X pro phone and the photo snap camera,
71
00:04:51,620 --> 00:04:52,780
关于单反相机那个。
the DSLR one.
72
00:04:52,960 --> 00:04:54,460
也告诉我关于你们的电视。
Also tell me about your TVs.
73
00:04:54,860 --> 00:05:02,120
我们在询问两个具体的产品,以及这个电视产品的总类。
So we're asking about two specific products and also this general category of televisions.
74
00:05:02,600 --> 00:05:07,120
这两个产品都在允许销售产品列表中提到。
And both of these products are mentioned in the allowed products list.
75
00:05:07,300 --> 00:05:09,840
然后我们有一个电视栏目。
And then we have a television section.
76
00:05:09,840 --> 00:05:10,360
然后我们还有一个相机部分。
And then we have a camera section as well.
77
00:05:12,200 --> 00:05:17,240
然后我们将系统消息和用户消息格式化为消息数组。
Then we format the system message and user message into the messages array.
78
00:05:18,080 --> 00:05:20,340
然后我们从模型中获取完成情况。
And then we get the completion from the model.
79
00:05:22,640 --> 00:05:25,060
所以你可以看到,
So as you can see,
80
00:05:25,660 --> 00:05:33,740
对于我们的输出,我们有一个对象列表,每个对象都有类别和产品。
for our output, we have a list of objects and each object has category and products.
81
00:05:33,800 --> 00:05:40,720
所以我们有智能X Pro手机和照片快照DSLR相机。
So we have the smart X pro phone and the photo snap DSLR camera.
82
00:05:40,960 --> 00:05:45,840
然后在最终的对象中,我们实际上只有一个类别,因为我们没有提到任何特定的电视。
And then in the final object, we actually only have a category because we didn't mention any specific TVs.
83
00:05:46,700 --> 00:05:55,640
因此输出这个结构化响应的好处是,我们可以将其读入Python列表中,
And so the benefit of outputting this structured response is that we can then read it into a list in Python,
84
00:05:56,100 --> 00:05:57,060
这非常好。
which is very nice.
85
00:05:57,680 --> 00:06:00,240
所以让我们尝试另一个例子。
And so let's try another example.
86
00:06:00,400 --> 00:06:06,520
所以我们的第二个用户留言是我的路由器坏了。
So our second user message is my router isn't working.
87
00:06:06,900 --> 00:06:10,020
如果你注意列表,我们实际上没有任何路由器。
And if you notice in the list, we don't actually have any routers.
88
00:06:10,620 --> 00:06:15,340
然后让我们正确地格式化并完成这个步骤。
And then let's format this correctly and get the completion.
89
00:06:17,400 --> 00:06:23,080
因此,你可以看到,在这种情况下,输出是一个空列表。
And so, as you can see, in this case, the output is an empty list.
90
00:06:24,220 --> 00:06:27,860
现在我们有了这一步,来确定类别和产品,
And so now that we have this step to identify the category and products,
91
00:06:28,440 --> 00:06:36,960
如果我们找到任何产品和类别,我们希望将有关这些请求的产品和类别的一些信息加载到提示中,以便更好地回答客户问题。
if we find any products and categories, we want to load some information about those requested products and categories into the prompt so that we can better answer the customer question.
92
00:06:37,580 --> 00:06:44,600
所以在我们的工作流程中,此提示运行后的状态要么是产品已列出,要么是产品未列出。
And so in our workflow, the state now after this prompt has run is either products have been listed or they haven't been listed.
93
00:06:45,040 --> 00:06:49,600
在那种情况下,我们不会尝试查找任何东西,因为没有可查找的内容。
And in that case, we wouldn't try to look anything up because there's nothing to look up.
94
00:06:49,900 --> 00:06:54,780
此外,如果我真的将其构建到系统中,我可能会使用类别名称,
Also, if I were to actually build this into a system, I might use category names,
95
00:06:55,120 --> 00:07:03,940
也许像电脑和笔记本电脑之类的东西,以避免任何空格和特殊字符的奇怪情况,
maybe something like computers and laptops or something to avoid any weirdness with spaces and special characters,
96
00:07:04,420 --> 00:07:05,760
但现在应该可以用了。
but this should work for now.
97
00:07:06,560 --> 00:07:10,120
现在我们想要查找一些关于用户提到的产品的信息,
So now we want to look up some information about the products that the user mentioned,
98
00:07:10,360 --> 00:07:13,380
关于这个手机,这个相机以及关于电视的一般信息。
so about this phone, this camera and about the TVs in general.
99
00:07:14,120 --> 00:07:17,480
所以我们需要有某种产品目录来查找这些信息。
And so we need to have some kind of product catalog to look up this information from.
100
00:07:17,860 --> 00:07:21,380
这里是我们刚刚粘贴进来的产品信息。
So here we have our product information that I just pasted in.
101
00:07:23,300 --> 00:07:29,680
所以你们可以看到,我们的商店有大量的产品可供选择。
So as you can see, we have a large number of products available at our store.
102
00:07:30,340 --> 00:07:36,020
而且所有这些产品都是假的,实际上是由GPT-4生成的。
And all of these products are fake and were actually generated by GPT-4.
103
00:07:36,860 --> 00:07:40,100
对于每个产品,我们有几个不同的字段。
And so for each product, we have a couple of different fields.
104
00:07:40,300 --> 00:07:41,760
我们有名称,类别,
We have name, category,
105
00:07:42,260 --> 00:07:42,780
品牌,
brand,
106
00:07:43,600 --> 00:07:44,100
保修,等等。
warranty,
107
00:07:44,640 --> 00:07:45,680
所以产品只是一个从产品名称到包含有关产品信息的对象的字典。
and so on.
108
00:07:46,040 --> 00:07:52,880
注意,每个产品都有一个类别。
And so the products is just a dictionary from product name to this object that contains the information about the product.
109
00:07:53,880 --> 00:07:56,280
所以记住,我们要查找用户询问的产品的信息。
Notice that each product has a category.
110
00:07:56,880 --> 00:08:00,620
So remember, we want to look up information about the products that the user asks about.
111
00:08:00,720 --> 00:08:06,820
因此,我们需要定义一些辅助函数来通过产品名称查找产品信息。
So we need to define some helper functions to allow us to look up product information by product name.
112
00:08:07,440 --> 00:08:09,700
所以让我们创建一个函数,
So let's create a function,
113
00:08:10,180 --> 00:08:12,560
按名称获取产品。
get product by name.
114
00:08:13,580 --> 00:08:28,100
我们输入名称,然后我们将返回产品字典,我们将获取名称为键的项目的值,然后我们的后备只是没有。
We input the name and then we're going to return product dictionary and we're going to get the value for the item with the name as the key, and then our fallback is just going to be none.
115
00:08:28,580 --> 00:08:33,400
因此,我们还想定义另一个辅助函数来获取某个类别的所有产品。
And so we also want to define another helper function to get all of the products for a certain category.
116
00:08:33,680 --> 00:08:34,120
例如,当用户询问我们拥有哪些电视时,我们希望加载有关所有不同电视的所有信息。因此,按类别获取产品,请输入类别名称字符串。为此,我们希望循环遍历产品字典中的所有产品,并检查每个产品,以查看类别是否等于输入类别。
For example,
117
00:08:34,440 --> 00:08:39,940
when the user is asking about the TVs we have, we'd want to load all of the information about all of the different TVs.
118
00:08:41,240 --> 00:08:45,320
So get products by category,
119
00:08:46,740 --> 00:08:49,120
input the category name string.
120
00:08:50,060 --> 00:09:01,460
And to do this, we want to loop through all of the products in the products dictionary and check each one to see if the category is equal to the input category.
121
00:09:01,660 --> 00:09:03,220
如果是这样,我们希望返回它。
And if so, we want to return that.
122
00:09:04,080 --> 00:09:06,280
那么我们将按如下方式进行。
So we'll do this as follows.
123
00:09:06,940 --> 00:09:14,680
所以首先我们要循环遍历每个产品并获取值,因为我们需要实际访问类别,
So first we want to loop through each product and we have to get the values because we need to actually access the category,
124
00:09:14,880 --> 00:09:15,980
它在值中。
which is in the value.
125
00:09:17,140 --> 00:09:31,340
然后如果产品类别等于我们的输入类别,我们将返回此产品。
And then we'll return this product if the product category is equal to our input category.
126
00:09:32,680 --> 00:09:40,360
那么我们来为这些辅助功能举个例子。
So let's do an example for each of these helper functions.
127
00:09:41,620 --> 00:09:42,040
首先,
So first,
128
00:09:42,660 --> 00:09:46,020
我们有一款名为TechPro Ultrabook的产品。
we have a product called the TechPro Ultrabook.
129
00:09:46,300 --> 00:09:48,560
那么让我们通过名称获取产品信息。
So let's get the product information by name.
130
00:09:50,240 --> 00:09:53,700
在这里,您可以看到我们刚刚获取了所有产品信息。
So here you can see we've just fetched all of the product information.
131
00:09:55,360 --> 00:09:59,580
让我们举个例子,获取一个类别中的所有产品。
And let's do an example to get all of the products for a category.
132
00:09:59,820 --> 00:10:04,180
那么,让我们获取计算机和笔记本电脑类别中的所有产品。
So let's get all of the products in the computers and laptops category.
133
00:10:06,020 --> 00:10:10,260
所以,在这里你可以看到,我们使用这个类别获取了所有的产品。
So here you see, we fetched all of the products with this category.
134
00:10:18,120 --> 00:10:23,020
那么,让我们继续我们的例子,并且为了记住我们所在的位置,让我们打印用户消息。
So let's continue our example and just to remember where we are, let's print the user message.
135
00:10:23,540 --> 00:10:24,640
所以,用户消息是,
So the user message was,
136
00:10:25,180 --> 00:10:28,740
讲讲SmartX Pro手机、相机和电视
tell me about the SmartX Pro phone and the camera and the TVs.
137
00:10:29,420 --> 00:10:34,120
然后第一步模型的初始输出是这个
And then the initial output from the model from the first step was this.
138
00:10:35,280 --> 00:10:46,540
我们还需要做的是读取这个模型输出结果,将其转换成列表,这样我们才能将其作为我们刚刚写的辅助函数的输入
And so what we also need to do is read this output from the model, which is a string, we need to pass that into a list so that we can use it as input to the helper functions that we just wrote.
139
00:10:47,940 --> 00:10:50,660
那么让我们写一个辅助函数来完成这个任务
So let's write a helper function to do this.
140
00:10:52,260 --> 00:11:01,760
我们将使用Python的JSON模块,并编写一个称为readStringToList的函数
So we're going to use the Python JSON module and we're going to write a function called readStringToList,
141
00:11:01,980 --> 00:11:04,220
一个非常描述性的标题,
a very descriptive title,
142
00:11:04,820 --> 00:11:05,760
一个输入字符串。
an input string.
143
00:11:08,540 --> 00:11:12,600
那么首先,我们将检查输入字符串是否为空。
And so first, we'll just check if the input string is none.
144
00:11:14,260 --> 00:11:18,540
如果前面的步骤有任何问题,我们将什么都不返回。
In case something in a previous step failed, we're just going to return nothing.
145
00:11:20,680 --> 00:11:26,960
现在我们将使用try except块来确保捕获任何错误。
And now we're going to have a try except block to make sure that we catch any errors.
146
00:11:28,580 --> 00:11:30,020
所以首先,我们会在输入字符串中将任何单引号替换为双引号。
And so first,
147
00:11:30,460 --> 00:11:35,580
然后我们将使用JSON loads函数将输入字符串读入数组或列表中。
we replace any single quotes with double quotes in the input string.
148
00:11:38,100 --> 00:11:45,940
然后我们将返回它。
And then we're going to use the JSON loads function to read the input string into the array or the list.
149
00:11:46,080 --> 00:11:47,880
如果有解码错误,
And then we're going to return this.
150
00:11:48,220 --> 00:11:50,720
请注意:保持口语化风格,避免过长的句子,并忽略像“so”、“you know”等口头习惯用语。
And if there's a decode error,
151
00:11:51,140 --> 00:11:53,220
我们将打印错误,然后返回无。
we're going to print the error and then return none.
152
00:11:53,480 --> 00:11:56,720
那么让我们用我们的示例来尝试一下。
So let's try this with our example.
153
00:12:00,540 --> 00:12:08,960
所以我们将使用readStringToList助手函数获取我们的类别和产品列表,并将其应用于模型的此响应。
So we're going to get our category and product list using the readStringToList helper function and apply it to this response from the model.
154
00:12:09,300 --> 00:12:11,640
然后我们将打印此列表。
And then we're going to print this list.
155
00:12:12,380 --> 00:12:13,560
所以它应该看起来一样。
So it should look the same.
156
00:12:14,400 --> 00:12:15,380
先让我先运行这个。
Let me run this first.
157
00:12:16,180 --> 00:12:24,400
所以你可以看到,这只是相同的东西,只不过现在这个变量的类型实际上是一个列表,而不是一个字符串。
And so as you can see, it's just the same thing, except now the type of this variable is actually a list instead of a string.
158
00:12:24,680 --> 00:12:35,480
所以我们所做的整个目的就是将产品信息转换为列表,然后将其添加到模型的下一条指令中,即我们要求它回答用户问题的指令。
So the whole point of what we're doing is to get the product information into a list that we can add to the next instruction to the model, which is going to be the instruction where we ask it to answer the user question.
159
00:12:35,900 --> 00:12:41,940
因此,为了做到这一点,我们需要将产品信息放入一个漂亮的字符串格式中,以便将其添加到提示中。
And so to do this, we need to put the product information into a nice string format that we can add to the prompt.
160
00:12:42,120 --> 00:12:44,480
因此,让我们也创建一个辅助函数来完成这个任务。
And so let's also create a helper function to do this.
161
00:12:45,620 --> 00:12:48,520
所以我们要把它称为生成输出字符串。
So we're going to call it generate output string.
162
00:12:49,260 --> 00:12:53,160
它将接收刚刚创建的数据列表。
And it's going to take in the list of data that we just created.
163
00:12:53,780 --> 00:12:53,340
就像这样。
So this.
164
00:12:54,660 --> 00:12:58,900
然后我将复制一些代码,然后我们将讨论它的功能。
And then I'm going to copy in some code and then we'll walk through what it's doing.
165
00:12:59,380 --> 00:13:02,400
现在我将粘贴一些代码并向您展示一个例子,
So now I'm going to paste in some code and show you an example,
166
00:13:02,680 --> 00:13:04,480
然后我们会讨论这个函数在做什么。
and then we'll talk about what this function is doing.
167
00:13:05,100 --> 00:13:10,840
所以我们将从第一个用户消息中获取产品信息。
So we're going to get the product information from our first user message.
168
00:13:11,220 --> 00:13:17,980
因此,我们将在我们的类别和产品列表上使用这个帮助函数“生成输出字符串”,如果我们记得,它是这样的。
And so we're going to use this helper function generate output string on our category and product list, which if we remember was this.
169
00:13:22,340 --> 00:13:30,240
所以在这里,我们有所有在用户消息中提到的产品的产品信息。
And so here we have all of the product information for the products that were in the mentioned in the user message.
170
00:13:30,800 --> 00:13:32,940
所以我们有他们提到的手机。
So we have the phone that they mentioned,
171
00:13:33,300 --> 00:13:38,400
我们有他们提到的相机,还有所有电视产品信息。
we have the camera that they mentioned, and then we have all of the product information for all of our TVs.
172
00:13:40,600 --> 00:13:47,200
这些信息将有助于模特能够回答用户的初始问题。
And this is information that will be helpful for the model to be able to answer the user's initial question.
173
00:13:47,820 --> 00:13:50,180
如果你对这个功能如何工作感兴趣,
And if you're interested in how this function works,
174
00:13:50,540 --> 00:13:52,220
我会简要介绍一下,
I'll give a brief overview,
175
00:13:52,440 --> 00:13:55,800
但你可以随时暂停视频,更仔细地阅读它。
but you can feel free to pause the video and read it more thoroughly.
176
00:13:56,180 --> 00:14:02,280
所以它基本上只是循环遍历该列表中的所有对象,并首先检查是否存在产品。
So it basically just loops through all of the objects in this list and first checks if there are products.
177
00:14:02,680 --> 00:14:08,300
如果有产品,则获取每个产品的信息,然后检查是否有类别,
If so, it gets the information for each product and then it checks if there's a category,
178
00:14:08,500 --> 00:14:09,500
如果没有任何产品。
if there weren't any products.
179
00:14:10,000 --> 00:14:13,240
例如,对于此对象,
So that would be for this object, for example,
180
00:14:13,700 --> 00:14:18,440
然后获取该类别中产品的所有产品信息。
and then it gets all of the product information for the products in that category.
181
00:14:18,660 --> 00:14:20,800
然后将它们添加到这个字符串中。
And it just adds them to this string.
182
00:14:21,140 --> 00:14:22,820
然后这就是它返回的内容。
And then that's what it returns.
183
00:14:23,780 --> 00:14:28,700
所以此时,我们已经找到了相关的产品信息来回答用户的问题。
So at this point, we've found the relevant product information to answer the user question.
184
00:14:29,000 --> 00:14:31,400
现在是模型实际回答问题的时候了。
Now it's time for the model to actually answer the question.
185
00:14:32,160 --> 00:14:35,420
那么让我们来看看我们的系统消息。
So let's have our system message.
186
00:14:35,660 --> 00:14:37,180
所以这是指示。
So this is the instruction.
187
00:14:37,440 --> 00:14:40,320
你是一家大型电子商店的客户服务助理。
You're a customer service assistant for a large electronics store.
188
00:14:40,700 --> 00:14:43,240
友好和乐于助人地回答,
Respond in a friendly and helpful tone with,
189
00:14:43,700 --> 00:14:45,660
用非常简洁的答案,
let's say, with very concise answers.
190
00:14:46,080 --> 00:14:48,520
确保向用户提出相关的后续问题。
Make sure to ask the user relevant follow up questions.
191
00:14:48,820 --> 00:14:51,140
所以我们希望这对用户来说是一种交互体验。
So we want this to be an interactive experience for the user.
192
00:14:51,960 --> 00:14:53,240
作为提醒,
And so just as a reminder,
193
00:14:53,560 --> 00:14:55,280
这是我们最初的用户消息。
this was our initial user message.
194
00:14:55,700 --> 00:14:56,720
我会再添加一遍。
I'll just add it again.
195
00:14:58,000 --> 00:15:01,200
现在我们将有我们的消息数组。
And so now we're going to have our messages array.
196
00:15:02,900 --> 00:15:04,880
这是模型的输入。
And this is the input to the model.
197
00:15:05,160 --> 00:15:06,300
那我们来看一下。
So let's go through this.
198
00:15:06,300 --> 00:15:09,320
我们有第一条消息,就像往常一样是系统消息。
We have our first message, which is the system message as usual.
199
00:15:09,840 --> 00:15:12,600
我们有用户的消息。
We have the user message.
200
00:15:13,520 --> 00:15:18,920
然后我们有这个额外的助手消息。
And then we have this additional assistant message.
201
00:15:19,200 --> 00:15:23,180
这是包含我们刚才查找的所有产品信息的消息。
And this is the message that contains all of the product information that we just looked up.
202
00:15:23,620 --> 00:15:26,360
所以我们正在提供相关的产品信息,
And so we're saying relevant product information,
203
00:15:26,580 --> 00:15:30,540
新的一行,然后是我们刚刚找到的产品信息。
new line, and then this product information that we just found.
204
00:15:31,920 --> 00:15:36,020
现在模型有了需要回答用户问题的相关上下文。
And so now the model has the relevant context it needs to be able to answer this user's question.
205
00:15:37,260 --> 00:15:40,520
那么让我们得到最终的响应并打印出来。
So let's get the final response and print it.
206
00:15:41,940 --> 00:15:53,880
我们希望模型能够利用产品信息中的相关信息以便以有益的方式回答用户。
And we're hoping that the model is going to use relevant information from the product information in order to answer the user in a helpful way.
207
00:15:55,620 --> 00:15:58,000
首先,
So first,
208
00:15:58,200 --> 00:16:00,460
它告诉用户智能X Pro手机的情况。
it tells the user about the Smart X Pro phone.
209
00:16:01,760 --> 00:16:04,580
它告诉用户关于Photosnap相机的情况,
It tells the user about the Photosnap camera,
210
00:16:05,280 --> 00:16:11,660
然后谈论我们库存中的不同电视,并且问一个后续问题。
and then talks about the different televisions that we have in stock, and then asks the follow up question.
211
00:16:12,540 --> 00:16:13,940
所以,正如你所看到的,
So as you can see,
212
00:16:14,220 --> 00:16:16,400
通过将其分解为一系列步骤,
by breaking this up into a series of steps,
213
00:16:16,660 --> 00:16:24,200
我们能够加载与用户查询相关的信息,为模型提供必要的上下文,从而有效地回答问题。
we were able to load information relevant to the user query to give the model the relevant context it needed to answer the question effectively.
214
00:16:24,420 --> 00:16:25,440
所以你可能会想,
So you might be wondering,
215
00:16:25,660 --> 00:16:28,260
为什么我们要有选择地将产品描述加载到提示中,
why are we selectively loading product descriptions into the prompt,
216
00:16:28,620 --> 00:16:32,180
为什么不把它们全部包含在内,让模型使用它需要的信息呢?
instead of including all of them and letting the model use the information it needs?
217
00:16:32,740 --> 00:16:34,140
我的意思是,
And so what I mean by this is,
218
00:16:34,700 --> 00:16:43,060
为什么我们不把所有的产品信息都包含在提示中,这样就不必费心去查找所有这些中间步骤来查找产品信息了。
why didn't we just include all of this product information in the prompt, and we wouldn't have to bother with all of those intermediate steps to actually look up the product information.
219
00:16:44,140 --> 00:16:45,660
这其中有几个原因。
There's a couple of reasons for this.
220
00:16:46,820 --> 00:16:47,240
首先,
Firstly,
221
00:16:47,480 --> 00:16:55,320
包括所有的产品描述可能会让模型更加困惑,就像一个人试图一次处理大量信息一样。
including all of the product descriptions might make the context more confusing for the model, just as it would for a person trying to process a large amount of information at once.
222
00:16:55,820 --> 00:16:56,440
我会说,
I will say,
223
00:16:56,800 --> 00:17:00,380
这对于像 GPT-4 这样更先进的模型来说,相对不那么重要,
this is a lot less relevant for more advanced models like GPT-4,
224
00:17:00,740 --> 00:17:03,620
尤其是当上下文像这个例子一样结构良好,
especially when the context is well structured like it is in this example,
225
00:17:04,200 --> 00:17:07,560
而模型足够聪明,只会忽略明显不相关的信息。
and the model is smart enough just to ignore the information that clearly isn't relevant.
226
00:17:08,980 --> 00:17:10,780
下面的理由更有说服力。
The next reasons are more compelling.
227
00:17:11,340 --> 00:17:14,540
因此,第二个原因是语言模型有上下文限制,即输入和输出的令牌数量固定。
So the second reason is that language models have context limitations,
228
00:17:15,080 --> 00:17:15,280
如果您有大量产品,想象一下您拥有一个庞大的产品目录。
i .e.
229
00:17:15,280 --> 00:17:18,560
也就是说。
a fixed number of tokens allowed as input and output.
230
00:17:18,980 --> 00:17:22,700
So if you have a large number of products, imagine you had a huge product catalogue,
231
00:17:23,000 --> 00:17:26,300
你甚至无法将所有的描述都放进上下文窗口。
you wouldn't even be able to fit all of the descriptions into the context window.
232
00:17:26,840 --> 00:17:30,960
最后一个原因是,包括所有产品描述可能会很昂贵,因为使用语言模型时按标记付费。
And the final reason is that including all of the product descriptions could be expensive,
233
00:17:31,280 --> 00:17:33,860
因此,通过有选择地加载信息,您可以减少生成响应的成本。
as you pay per token when using language models.
234
00:17:33,860 --> 00:17:35,900
所以,我们需要选择性地加载信息。
So by selectively loading information,
235
00:17:36,180 --> 00:17:38,280
另外,我们需要减少生成响应的成本。
you can reduce the cost of generating responses.
236
00:17:39,340 --> 00:17:40,500
一般来说,
In general,
237
00:17:40,860 --> 00:17:49,360
确定何时在模型上下文中动态加载信息并允许模型决定何时需要更多信息是增强这些模型能力的最佳方法之一。
determining when to dynamically load information into the model's context and allowing the model to decide when it needs more information is one of the best ways to augment the capabilities of these models.
238
00:17:50,020 --> 00:17:50,600
并且要再次强调的是,
And to reiterate,
239
00:17:51,000 --> 00:17:57,360
您应该将语言模型视为需要必要上下文以得出有用结论和执行有用任务的推理代理。
you should think of a language model as a reasoning agent that requires the necessary context to draw useful conclusions and perform useful tasks.
240
00:17:58,060 --> 00:18:02,440
所以在这种情况下,我们必须给模型提供产品信息。
And so in this case, we had to give the model the product information,
241
00:18:02,940 --> 00:18:07,760
然后它能够根据产品信息进行推理,为用户创建一个有用的答案。
and then it was able to reason about that product information to create a useful answer for the user.
242
00:18:08,580 --> 00:18:17,040
在这个例子中,我们只添加了对一个特定函数或多个函数的调用,以通过产品名称获取产品描述或通过类别名称获取类别产品。
And in this example, we only added a call to a specific function or functions to get the product description by product name or to get the category products by category name.
243
00:18:17,380 --> 00:18:23,820
但是模型实际上很擅长决定何时使用各种不同的工具,并能够根据指示正确地使用它们。
But the models are actually good at deciding when to use a variety of different tools and can use them properly with instructions.
244
00:18:24,160 --> 00:18:26,740
这就是chatGBT插件背后的想法。
And this is the idea behind chatGBT plugins.
245
00:18:27,220 --> 00:18:36,040
我们告诉模型它可以访问哪些工具以及它们的作用,当它需要从特定来源获取信息或想要执行其他适当的操作时,它会选择使用它们。
We tell the model what tools it has access to and what they do, and it chooses to use them when it needs information from a specific source or wants to take some other appropriate action.
246
00:18:36,500 --> 00:18:37,480
在我们的例子中,我们只能通过精确的产品和类别名称匹配来查找信息,但是还有更高级的信息检索技术。
In our example,
247
00:18:37,760 --> 00:18:44,400
最有效的检索信息的方法之一是使用文本嵌入。
we can only look up information by exact product and category name match, but there are also more advanced techniques for information retrieval.
248
00:18:44,760 --> 00:18:48,460
嵌入可以用于在大语料库上实现高效的知识检索,以查找与给定查询相关的信息。
One of the most effective ways to retrieve information is using text embeddings.
249
00:18:48,900 --> 00:18:55,240
使用文本嵌入的关键优势之一是它们使模糊或语义搜索成为可能,
Embeddings can be used to implement efficient knowledge retrieval over a large corpus to find information related to a given query.
250
00:18:55,960 --> 00:19:01,000
One of the key advantages of using text embeddings is that they enable fuzzy or semantic search,
251
00:19:01,240 --> 00:19:04,760
它允许您在不使用确切关键字的情况下找到相关信息。
which allows you to find relevant information without using the exact keywords.
252
00:19:05,420 --> 00:19:08,640
因此,在我们的例子中,我们不一定需要产品的确切名称,
So in our example, we wouldn't necessarily need the exact name of the product,
253
00:19:09,100 --> 00:19:13,900
但我们可以使用更一般的查询进行更多的搜索,比如手机。
but we could do a more a search with a more general query like a mobile phone.
254
00:19:15,120 --> 00:19:20,980
我们计划很快创建一门关于如何在各种应用中使用嵌入的全面课程,敬请关注。
We're planning to create a comprehensive course on how to use embeddings for various applications soon, so stay tuned.
255
00:19:21,560 --> 00:19:27,920
好的,让我们继续下一个视频,我们将讨论如何评估语言模型的输出。
And with that, let's move on to the next video where we're going to talk about how to evaluate the outputs from the language model.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment