Prompt learning 教學[進階篇]:簡介Prompt框架並給出自然語言處理技術:Few-Shot Prompting、Self-Consistency等;專案實戰搭建知識庫內容機器人
1.ChatGPT Prompt Framework
看完基礎篇的各種場景介紹後,你應該對 Prompt 有較深的理解。之前的章節我們講的都是所謂的「術」,更多地集中講如何用,但講「道」的部分不多。高階篇除了會講更高階的運用外,還會講更多「道」的部分。高階篇的開篇,我們來講一下構成 prompt 的框架。
1.1Basic Prompt Framework
查閱了非常多關於 ChatGPT prompt 的框架資料,我目前覺得寫得最清晰的是 Elavis Saravia 總結的框架,他認為一個 prompt 裡需包含以下幾個元素:
- Instruction(必須): 指令,即你希望模型執行的具體任務。
- Context(選填): 背景資訊,或者說是上下文資訊,這可以引導模型做出更好的反應。
- Input Data(選填): 輸入資料,告知模型需要處理的資料。
- Output Indicator(選填): 輸出指示器,告知模型我們要輸出的型別或格式。
只要你按照這個框架寫 prompt ,模型返回的結果都不會差。
當然,你在寫 prompt 的時候,並不一定要包含所有4個元素,而是可以根據自己的需求排列組合。比如拿前面的幾個場景作為例子:
- 推理:Instruction + Context + Input Data
- 資訊提取:Instruction + Context + Input Data + Output Indicator
1.2 CRISPE Prompt Framework
另一個我覺得很不錯的 Framework 是 Matt Nigh 的 CRISPE Framework,這個 framework 更加複雜,但完備性會比較高,比較適合用於編寫 prompt 模板。CRISPE 分別代表以下含義:
- CR: Capacity and Role(能力與角色)。你希望 ChatGPT 扮演怎樣的角色。
- I: Insight(洞察力),背景資訊和上下文(坦率說來我覺得用 Context 更好)。
- S: Statement(指令),你希望 ChatGPT 做什麼。
- P: Personality(個性),你希望 ChatGPT 以什麼風格或方式回答你。
- E: Experiment(嘗試),要求 ChatGPT 為你提供多個答案。
以下是這幾個引數的例子:
Step | Example |
---|---|
Capacity and Role | Act as an expert on software development on the topic of machine learning frameworks, and an expert blog writer. 把你想象成機器學習框架主題的軟體開發專家,以及專業部落格作者。 |
Insight | The audience for this blog is technical professionals who are interested in learning about the latest advancements in machine learning. 這個部落格的讀者主要是有興趣瞭解機器學習最新進展技術的專業人士。 |
Statement | Provide a comprehensive overview of the most popular machine learning frameworks, including their strengths and weaknesses. Include real-life examples and case studies to illustrate how these frameworks have been successfully used in various industries. 提供最流行的機器學習框架的全面概述,包括它們的優點和缺點。包括現實生活中的例子,和研究案例,以說明這些框架如何在各個行業中成功地被使用。 |
Personality | When responding, use a mix of the writing styles of Andrej Karpathy, Francois Chollet, Jeremy Howard, and Yann LeCun. 在回應時,混合使用 Andrej Karpathy、Francois Chollet、Jeremy Howard 和 Yann LeCun 的寫作風格。 |
Experiment | Give me multiple different examples. 給我多個不同的例子。 |
2.Zero-Shot Prompting
在基礎篇裡的推理場景,我提到了 Zero-Shot Prompting 的技術,本章會詳細介紹它是什麼,以及使用它的技巧。Zero-Shot Prompting 是一種自然語言處理技術,可以讓計算機模型根據提示或指令進行任務處理。各位常用的 ChatGPT 就用到這個技術。
傳統的自然語言處理技術通常需要在大量標註資料上進行有監督的訓練,以便模型可以對特定任務或領域進行準確的預測或生成輸出。相比之下,Zero-Shot Prompting 的方法更為靈活和通用,因為它不需要針對每個新任務或領域都進行專門的訓練。相反,它透過使用預先訓練的語言模型和一些示例或提示,來幫助模型進行推理和生成輸出。
舉個例子,我們可以給 ChatGPT 一個簡短的 prompt,比如 描述某部電影的故事情節
,它就可以生成一個關於該情節的摘要,而不需要進行電影相關的專門訓練。
2.1 Zero-Shot Prompting 缺點
但這個技術並不是沒有缺點的:
- Zero-Shot Prompting 技術依賴於預訓練的語言模型,這些模型可能會受到訓練資料集的限制和偏見。比如在使用 ChatGPT 的時候,它常常會在一些投資領域,使用男性的「他」,而不是女性的「她」。那是因為訓練 ChatGPT 的資料裡,提到金融投資領域的內容,多為男性。
- 儘管 Zero-Shot Prompting 技術不需要為每個任務訓練單獨的模型,但為了獲得最佳效能,它需要大量的樣本資料進行微調。像 ChatGPT 就是一個例子,它的樣本數量是過千億。
- 由於 Zero-Shot Prompting 技術的靈活性和通用性,它的輸出有時可能不夠準確,或不符合預期。這可能需要對模型進行進一步的微調或新增更多的提示文字來糾正。
2.2 技巧 :Zero-Shot Chain of Thought
基於上述的第三點缺點,研究人員就找到了一個叫 Chain of Thought 的技巧。
這個技巧使用起來非常簡單,只需要在問題的結尾裡放一句 Let‘s think step by step
(讓我們一步步地思考),模型輸出的答案會更加準確。
這個技巧來自於 Kojima 等人 2022 年的論文 Large Language Models are Zero-Shot Reasoners。在論文裡提到,當我們向模型提一個邏輯推理問題時,模型返回了一個錯誤的答案,但如果我們在問題最後加入 Let‘s think step by step
這句話之後,模型就生成了正確的答案:
論文裡有講到原因,感興趣的朋友可以去看看,我簡單解釋下為什麼(? 如果你有更好的解釋,不妨反饋給我):
- 首先各位要清楚像 ChatGPT 這類產品,它是一個統計語言模型,本質上是基於過去看到過的所有資料,用統計學意義上的預測結果進行下一步的輸出(這也就是為什麼你在使用 ChatGPT 的時候,它的答案是一個字一個字地吐出來,而不是直接給你的原因,因為答案是一個字一個字算出來的)。
- 當它拿到的資料裡有邏輯,它就會透過統計學的方法將這些邏輯找出來,並將這些邏輯呈現給你,讓你感覺到它的回答很有邏輯。
- 在計算的過程中,模型會進行很多假設運算(不過暫時不知道它是怎麼算的)。比如解決某個問題是從 A 到 B 再到 C,中間有很多假設。
- 它第一次算出來的答案錯誤的原因,只是因為它在中間跳過了一些步驟(B)。而讓模型一步步地思考,則有助於其按照完整的邏輯鏈(A > B > C)去運算,而不會跳過某些假設,最後算出正確的答案。
按照論文裡的解釋,零樣本思維鏈涉及兩個補全結果,左側氣泡表示基於提示輸出的第一次的結果,右側氣泡表示其收到了第一次結果後,將最開始的提示一起拿去運算,最後得出了正確的答案:
這個技巧,除了用於解決複雜問題外,還適合生成一些連貫主題的內容,比如寫長篇文章、電影劇本等。
但需要注意其缺點,連貫不代表,它就一定不會算錯,如果其中某一步驟算錯了,錯誤會因為邏輯鏈,逐步將錯誤積累,導致生成的文字可能出現與預期不符的內容。
另外,根據 Wei 等人在 2022 年的論文表明,它僅在大於等於 100B 引數的模型中使用才會有效。如果你使用的是小樣本模型,這個方法不會生效。
根據 Yongchao Zhou 等人的最新論文,更好的 prompt 是:
Let's work this out in a step by step way to be sure we have the right answer.
在吳恩達的 ChatGPT Prompt Engineering 課程中,有提到一個這個技巧的另一種用法,不僅僅只是讓 AI 按步驟行事,還會告知 AI 每一步要做什麼。比如這個案例(注意這個是 python 程式碼):
prompt_2 = f"""
Your task is to perform the following actions:
1 - Summarize the following text delimited by
<> with 1 sentence.
2 - Translate the summary into French.
3 - List each name in the French summary.
4 - Output a json object that contains the
following keys: french_summary, num_names.
Use the following format:
Text: <text to summarize>
Summary: <summary>
Translation: <summary translation>
Names: <list of names in Italian summary>
Output JSON: <json with summary and num_names>
Text: <{text}>
"""
簡單解釋下這個程式碼:
- 開頭是讓 AI 按照 1 ~ 4 步執行
- 然後再讓 AI 根據特定格式輸出內容
最後 AI 的輸出是這樣的:
Summary: Jack and Jill go on a quest to fetch water, but misfortune strikes and they tumble down the hill, returning home slightly battered but with their adventurous spirits undimmed.
Translation: Jack et Jill partent en quête d'eau, mais la malchance frappe et ils dégringolent la colline, rentrant chez eux légèrement meurtris mais avec leurs esprits aventureux intacts.
Names: Jack, Jill
Output JSON: {"french_summary": "Jack et Jill partent en quête d'eau, mais la malchance frappe et ils dégringolent la colline, rentrant chez eux légèrement meurtris mais avec leurs esprits aventureux intacts.", "num_names": 2}
上述的案例只是將任務拆解,能讓 AI 生成的結果更加符合要求,這個方法同樣能提升 AI 的回答準確性,比如這個案例:
Determine if the student's solution is correct or not.
Question:
I'm building a solar power installation and I need help working out the financials.
Land costs $100 / square foot
I can buy solar panels for $250 / square foot
I negotiated a contract for maintenance that will cost \
me a flat $100k per year, and an additional $10 / square foot
What is the total cost for the first year of operations
as a function of the number of square feet.
Student's Solution:
Let x be the size of the installation in square feet.
Costs:
Land cost: 100x
Solar panel cost: 250x
Maintenance cost: 100,000 + 100x
Total cost: 100x + 250x + 100,000 + 100x = 450x + 100,000
AI 的回答是「The student's solution is correct」。但其實學生的答案是錯誤的,應該 360x + 100,000,我們將 prompt 調整成這樣:
prompt = f"""
Your task is to determine if the student's solution \
is correct or not.
To solve the problem do the following:
- First, work out your own solution to the problem.
- Then compare your solution to the student's solution \
and evaluate if the student's solution is correct or not.
Don't decide if the student's solution is correct until
you have done the problem yourself.
Use the following format:
Question:
###
question here
###
Student's solution:
###
student's solution here
###
Actual solution:
###
steps to work out the solution and your solution here
###
Is the student's solution the same as actual solution \
just calculated:
###
yes or no
###
Student grade:
###
correct or incorrect
###
Question:
###
I'm building a solar power installation and I need help \
working out the financials.
- Land costs $100 / square foot
- I can buy solar panels for $250 / square foot
- I negotiated a contract for maintenance that will cost \
me a flat $100k per year, and an additional $10 / square \
foot
What is the total cost for the first year of operations \
as a function of the number of square feet.
###
Student's solution:
###
Let x be the size of the installation in square feet.
Costs:
1. Land cost: 100x
2. Solar panel cost: 250x
3. Maintenance cost: 100,000 + 100x
Total cost: 100x + 250x + 100,000 + 100x = 450x + 100,000
###
Actual solution:
"""
本質上,也是將任務分拆成多步,這次 AI 輸出的結果是這樣的(結果就是正確的了):
Let x be the size of the installation in square feet.
Costs:
1. Land cost: 100x
2. Solar panel cost: 250x
3. Maintenance cost: 100,000 + 10x
Total cost: 100x + 250x + 100,000 + 10x = 360x + 100,000
Is the student's solution the same as actual solution just calculated:
No
Student grade:
Incorrect
下一章我們會結合 Few-Shot Chain of Thought 來詳細講講邏輯鏈的限制。
3. Few-Shot Prompting
我們在技巧2 中,提到我們可以給模型一些示例,從而讓模型返回更符合我們需求的答案。這個技巧其實使用了一個叫 Few-Shot 的方法。
這個方法最早是 Brown 等人在 2020 年發現的,論文裡有一個這樣的例子,非常有意思,透過這個例子你應該更能體會,像 ChatGPT 這類統計語言模型,其實並不懂意思,只是懂機率
Brown 輸入的內容是這樣的(whatpu 和 farduddle 其實根本不存在):
A "whatpu" is a small, furry animal native to Tanzania. An example of a sentence that uses
the word whatpu is:
We were traveling in Africa and we saw these very cute whatpus.
To do a "farduddle" means to jump up and down really fast. An example of a sentence that uses
the word farduddle is:
Output 是這樣的:
When we won the game, we all started to farduddle in celebration.
不過這並不代表,Few-Shot 就沒有缺陷,我們試試下面這個例子:
Prompt:
The odd numbers in this group add up to an even number: 4, 8, 9, 15, 12, 2, 1.
A: The answer is False.
The odd numbers in this group add up to an even number: 17, 10, 19, 4, 8, 12, 24.
A: The answer is True.
The odd numbers in this group add up to an even number: 16, 11, 14, 4, 8, 13, 24.
A: The answer is True.
The odd numbers in this group add up to an even number: 17, 9, 10, 12, 13, 4, 2.
A: The answer is False.
The odd numbers in this group add up to an even number: 15, 32, 5, 13, 82, 7, 1.
A:
Output 是這樣的:
The answer is True.
輸出的答案其實是錯誤的,實際上的答案應該是:
Adding all the odd numbers (15, 5, 13, 7, 1) gives 41. The answer is False.
那我們有沒有什麼方法解決?
技巧8:Few-Shot Chain of Thought
要解決這個缺陷,就要使用到新的技巧,Few-Shot Chain of Thought。
根據 Wei 他們團隊在 2022 年的研究表明:
透過向大語言模型展示一些少量的樣例,並在樣例中解釋推理過程,大語言模型在回答提示時也會顯示推理過程。這種推理的解釋往往會引匯出更準確的結果。
下面是論文裡的案例,使用方法很簡單,在技巧2 的基礎上,再將邏輯過程告知給模型即可。從下面這個案例裡,你可以看到加入解釋後,輸出的結果就正確了。
那本章開頭提的例子就應該是這樣的(注:本例子同樣來自 Wei 團隊論文):
The odd numbers in this group add up to an even number: 4, 8, 9, 15, 12, 2, 1.
A: Adding all the odd numbers (9, 15, 1) gives 25. The answer is False.
The odd numbers in this group add up to an even number: 17, 10, 19, 4, 8, 12, 24.
A: Adding all the odd numbers (17, 19) gives 36. The answer is True.
The odd numbers in this group add up to an even number: 16, 11, 14, 4, 8, 13, 24.
A: Adding all the odd numbers (11, 13) gives 24. The answer is True.
The odd numbers in this group add up to an even number: 17, 9, 10, 12, 13, 4, 2.
A: Adding all the odd numbers (17, 9, 13) gives 39. The answer is False.
The odd numbers in this group add up to an even number: 15, 32, 5, 13, 82, 7, 1.
A:
聊完技巧,我們再結合前面的 Zero-Shot Chain of Thought,來聊聊 Chain of Thought 的關鍵知識。根據 Sewon Min 等人在 2022 年的研究 表明,思維鏈有以下特點:
- "the label space and the distribution of the input text specified by the demonstrations are both key (regardless of whether the labels are correct for individual inputs)" 標籤空間和輸入文字的分佈都是關鍵因素(無論這些標籤是否正確)。
- the format you use also plays a key role in performance, even if you just use random labels, this is much better than no labels at all. 即使只是使用隨機標籤,使用適當的格式也能提高效能。
理解起來有點難,我找一個 prompt 案例給大家解釋(? 如果你有更好的解釋,不妨反饋給我)。我給 ChatGPT 一些不一定準確的例子:
I loved the new Batman movie! // Negative
This is bad // Positive
This is good // Negative
What a good show! //
Output 是這樣的:
Positive
在上述的案例裡,每一行,我都寫了一句話和一個情感詞,並用 // 分開,但我給這些句子都標記了錯誤的答案,比如第一句其實應該是 Positive 才對。但:
- 即使我給內容打的標籤是錯誤的(比如第一句話,其實應該是 Positive),對於模型來說,它仍然會知道需要輸出什麼東西。 換句話說,模型知道 // 劃線後要輸出一個衡量該句子表達何種感情的詞(Positive or Negative)。這就是前面論文裡 #1 提到的,即使我給的標籤是錯誤的,或者換句話說,是否基於事實,並不重要。標籤和輸入的文字,以及格式才是關鍵因素。
- 只要給了示例,即使隨機的標籤,對於模型生成結果來說,都是有幫助的。這就是前面論文裡 #2 提到的內容。
最後,需要記住,思維鏈僅在使用大於等於 100B 引數的模型時,才會生效。
BTW,如果你想要了解更多相關資訊,可以看看史丹佛大學的講義:Natural Language Processing with Deep Learning
4. Self-Consistency
elf-Consistency 自洽是對 Chain of Thought 的一個補充,它能讓模型生成多個思維鏈,然後取最多數答案的作為最終結果。
按照 Xuezhi Wang 等人在 2022 年發表的論文 表明。當我們只用一個邏輯鏈進行最佳化時,模型依然有可能會算錯,所以 XueZhi Wang 等人提出了一種新的方法,讓模型進行多次運算,然後選取最多的答案作為最終結果:
就我目前使用下來,在 ChatGPT 上,其自洽性非常高,暫時沒有遇到過出現多種答案的情況。查閱多份資料,我發現這個自洽性可能更多的用於評估模型的優劣,好的模型一般自洽性會比較高。
在此案例中,考慮如下多步推理問題:
Consider a multi-step reasoning problem like the following:
Question: If a store has 10 apples and 8 oranges, and it sells 6 apples and 4 oranges, how many fruits are left in the store?
Instead of directly answering the question, the chain-of-thought prompting would require the language model to produce a series of short sentences that mimic a human's reasoning process:
The store has 10 apples.
The store has 8 oranges.
6 apples are sold.
4 oranges are sold.
There are 10 - 6 = 4 apples left.
There are 8 - 4 = 4 oranges left.
The store now has 4 apples + 4 oranges = 8 fruits.
Using self-consistency, the language model generates multiple reasoning paths:
Reasoning Path A:
The store has 10 apples.
The store has 8 oranges.
6 apples are sold.
4 oranges are sold.
There are 10 - 6 = 4 apples left.
There are 8 - 4 = 4 oranges left.
The store now has 4 apples + 4 oranges = 8 fruits.
Reasoning Path B:
The store initially has 10 apples and 8 oranges.
It sells 6 apples, so there are 10 - 6 = 4 apples left.
It sells 4 oranges, so there are 8 - 4 = 4 oranges left.
The store now has 4 apples + 4 oranges = 8 fruits.
翻譯過來則為:
問題:如果一家商店有 10 個蘋果和 8 個橙子,此時店裡賣出了 6 個蘋果和 4 個橙子,那麼店裡還剩下多少水果?
思維鏈提示(chain-of-thought prompting)不是直接回答問題,而是要求語言模型生成一系列模仿人類推理過程的短句:
商店有 10 個蘋果。
店裡有 8 個橙子。
賣了 6 個蘋果。
賣了 4 個橙子。
還剩下 10 - 6 = 4 個蘋果。
剩下 8 - 4 = 4 個橙子。
商店現在有 4 個蘋果 + 4 個橙子 = 8 個水果。
使用 Self-consistency,語言模型生成多個推理路徑:
推理路徑A:
商店有 10 個蘋果。
店裡有 8 個橙子。
賣了 6 個蘋果。
賣了 4 個橙子。
還剩下 10 - 6 = 4 個蘋果。
剩下 8 - 4 = 4 個橙子。
商店現在有 4 個蘋果 + 4 個橙子 = 8 個水果。
推理路徑 B:
商店最初有 10 個蘋果和 8 個橙子。
商店賣了 6 個蘋果,所以還剩下 10 - 6 = 4 個蘋果。
商店賣了 4 個橙子,所以還剩下 8 - 4 = 4 個橙子。
商店現在有 4 個蘋果 + 4 個橙子 = 8 個水果。
Self-consistency 從生成的多個推理路徑中選擇最一致的答案。在這個例子中,推理路徑 A 和 B 都得出相同的答案(8 個水果)。可以看到這種做法增加了模型對最終答案正確的信心。
5. Program-Aided Language Models
PAL Models,全稱為 Program-Aided Language Models。需要各位注意,這個方法,真的非常高階,甚至我覺得有點 Hack,而且經過我的多次測試,我覺得以 ChatGPT 目前的能力,已經不再需要使用這個方法。
但我在很多 PE 的教程裡都有看到這個方法,所以我這裡就簡單介紹一下,這個方法來自於 2022 年,Luyu Gao 等人的研究,根據他們的研究,在 LLM 模型中,即使使用了前面提到的 Chain of Thought 的方法,也未必能拿到答案,論文中使用的 prompt 是這樣的:
Q: Roger has 5 tennis balls. He buys 2 more cans of
tennis balls. Each can has 3 tennis balls. How many
tennis balls does he have now?
A: Roger started with 5 tennis balls. 2 cans of 3 tennis
balls each is 6 tennis balls. 5 + 6 = 11. The answer is 11.
Q: The bakers at the Beverly Hills Bakery baked 200
loaves of bread on Monday morning. They sold 93 loaves
in the morning and 39 loaves in the afternoon. A grocery
store returned 6 unsold loaves. How many loaves of
bread did they have left?
論文裡提到,當年他們的模型的 Output 是這樣的:
A: The bakers started with 200 loaves. They sold 93 in
the morning and 39 in the afternoon. So they sold 93 +
39 = 132 loaves. The grocery store returned 6 loaves. So
they had 200 - 132 - 6 = 62 loaves left.
The answer is 62.
如果你現在將這個 prompt 輸入到最新的 ChatGPT 答案已經是正確的:
A: The bakers baked 200 loaves of bread. They sold 93 + 39 = 132 loaves. After the grocery store returned 6 unsold loaves, the bakery had 200 - 132 + 6 = 74 loaves of bread left. The answer is 74.
當年 Luyu Gao 的解決方法是在 prompt 裡引入程式碼,並引導模型使用程式碼來運算和思考,最後答案就是正確的:
6.OpenAI Playground 使用方法
你會在介面的右側看到以下幾個引數:
- Mode: 最近更新了第四種 Chat 模式,一般使用 Complete 就好,當然你可以用其他模式,其他模式能透過 GUI 的方式輔助你撰寫 prompt。
- Model: 這裡可以切換模型。不同的模型會擅長不同的東西,根據場景選對模型,能讓你省很多成本:
- Ada:這是最便宜,但運算速度最快的模型。官方推薦的使用場景是解析文字,簡單分類,地址更正等。
- Babbage:這個模型能處理比 Ada 複雜的場景。但稍微貴一些,速度也比較快。適合分類,語義搜尋等。
- Curie:這個模型官方解釋是「和 Davinci 一樣能力很強,且更便宜的模型」。但實際上,這個模型非常擅長文字類的任務,比如寫文章、語言翻譯、撰寫總結等。
- Davinci:這是 GPT-3 系列模型中能力最強的模型。可以輸出更高的質量、更長的回答。每次請求可處理 4000 個 token。適合有複雜意圖、因果關係的場景,還有創意生成、搜尋、段落總結等。
- Temperature: 這個主要是控制模型生成結果的隨機性。簡而言之,溫度越低,結果越確定,但也會越平凡或無趣。如果你想要得到一些出人意料的回答,不妨將這個引數調高一些。但如果你的場景是基於事實的場景,比如資料提取、FAQ 場景,此引數就最好調成 0 。
- Maximum length: 設定單次生成內容的最大長度。
- Stop Sequence: 該選項設定停止生成文字的特定字串序列。如果生成文字中包含此序列,則模型將停止生成更多文字。
- Top P: 該選項是用於 nucleus 取樣的一種技術,它可以控制模型生成文字的機率分佈,從而影響模型生成文字的多樣性和確定性。如果你想要準確的答案,可以將它設定為較低的值。如果你想要更多樣化的回覆,可以將其設得高一些。
- Presence Penalty: 該選項控制模型生成文字時是否避免使用特定單詞或短語,它可以用於生成文字的敏感話題或特定場景。
- Best of: 這個選項允許你設定生成多少個文字後,從中選擇最優秀的文字作為輸出。預設為1,表示只生成一個文字輸出。
- **Injection start text: ** 這個選項可以讓你在輸入文字的開頭新增自定義文字,從而影響模型的生成結果。
- **Injection restart text: ** 這個選項可以讓你在中間某個位置新增自定義文字,從而影響模型繼續生成的結果。
- **Show probabilities: ** 這個選項可以讓你檢視模型生成每個單詞的機率。開啟此選項後,你可以看到每個生成的文字單詞後面跟著一串數字,表示模型生成該單詞的機率大小。
配置好引數後,你就可以在左側輸入 prompt 然後測試 prompt 了。
7.搭建基於知識庫內容的機器人
<head> <script defer="defer" src="https://embed.trydyno.com/embedder.js"></script> <link href="https://embed.trydyno.com/embedder.css" rel="stylesheet" /> </head>如果你僅想要直接實踐,可以看最後一部分實踐,以及倒數第二部分限制與注意的地方。
最早的時候,我嘗試過非常笨的方法,就是在提問的時候,將我的 newsletter 文字傳給 AI,它的 prompt 大概是這樣的:
Please summarize the following sentences to make them easier to understand.
Text: """
My newsletter
"""
這個方法能用是能用,但目前 ChatGPT 有個非常大的限制,它限制了最大的 token 數是 4096,大約是 16000 多個字元,注意這個是請求 + 響應,實際請求總數並沒那麼多。換句話來說,我一次沒法匯入太多的內容給 ChatGPT(我的一篇 Newsletter 就有將近 5000 字),這個問題就一直卡了我很久,直到我看到了 GPT Index 的庫,以及 Lennys Newsletter 的例子。
試了下,非常好用,而且步驟也很簡單,即使你不懂程式設計也能輕易地按照步驟實現這個功能。
我稍稍最佳化了下例子的程式碼,並增加了一些原理介紹。希望大家能喜歡。
7.1 原理介紹
其實我這個需求,在傳統的機器人領域已經有現成方法,比如你應該看到不少電商客服產品,就有類似的功能,你說一句話,機器人就會回覆你。
這種傳統的機器人,通常是基於意圖去回答人的問題。舉個例子,我們構建了一個客服機器人,它的工作原理簡單說來是這樣的:
當使用者問「忘記密碼怎麼辦?」時,它會去找最接近這個意圖「密碼」,每個意圖裡會有很多個樣本問題,比如「忘記密碼如何找回」「忘記密碼怎麼辦」,然後這些樣本問題都會有個答案「點選 A 按鈕找回密碼」,機器人會匹配最接近樣本問題的意圖,然後返回答案。
但這樣有個問題,我們需要設定特別多的意圖,比如「無法登入」、「忘記密碼」、「登入錯誤」,雖然有可能都在描述一個事情,但我們需要設定三個意圖、三組問題和答案。
雖然傳統的機器人有不少限制,但這種傳統方式,給了我們一些靈感。
我們好像可以用這個方法來解決限制 token 的問題,我們僅需要傳符合某個意圖的文件給 AI,然後 AI 僅用該文件來生成答案:
比如還是上面的那個客服機器人的例子,當使用者提問「忘記密碼怎麼辦?」時,匹配到了「登入」相關的意圖,接著匹配知識庫中相同或相近意圖的文件,比如「登入異常處理解決方案文件」,最後我們將這份文件傳給 GPT-3,它再拿這個文件內容生成答案。
GPTIndex 這個庫簡單理解就是做上圖左邊的那個部分,它的工作原理是這這樣的:
- 建立知識庫或文件索引
- 找到最相關的索引
- 最後將對應索引的內容給 GPT-3
雖然這個方法解決了 token 限制的問題,但也有不少限制:
- 當使用者提一些比較模糊的問題時,匹配有可能錯誤,導致 GPT-3 拿到了錯誤的內容,最終生成了非常離譜的答案。
- 當使用者提問一些沒有多少上下文的資訊時,機器人有時會生成虛假資訊。
所以如果你想用這個技術做客服機器人,建議你:
- 透過一些引導問題來先明確使用者的意圖,就是類似傳統客服機器人那樣,搞幾個按鈕,先讓使用者點選(比如無法登入)。
- 如果相似度太低,建議增加兜底的回答「很抱歉,我無法回答你的問題,你需要轉為人工客服嗎?」
7.2 實踐
為了讓大家更方便使用,我將程式碼放在了 Google Colab,你無需安裝任何環境,只需要用瀏覽器開啟這個:
BTW 你可以將其複製儲存到自己的 Google Drive。
第一步:匯入資料
匯入的方法有兩種,第一種是匯入線上資料。
匯入 GitHub 資料是個相對簡單的方式。如果你是第一次使用,我建議你先用這個方法試試。點選下方程式碼前的播放按鈕,就會執行這段程式碼。
執行完成後,會匯入我寫的幾份 newsletter。如果你也想像我那樣匯入資料,只需要修改 clone 後面的連結地址即可。
第二種方法是匯入離線資料。點選左側的資料夾按鈕(如果你沒有登入,這一步會讓你登入),然後點選下圖示識 2 的上傳按鈕,上傳檔案即可。如果你要傳多個檔案,建議你先建一個資料夾,然後將檔案都上傳到該資料夾內。
第二 & 三步:安裝依賴庫
直接點選播放按鈕即可。
不過第三步裡,你可以嘗試改下引數,你可以改:
- num_ouputs :這個是設定最大的輸出 token 數,越大,回答問題的時候,機器能回答的字就越多。
- Temperature: 這個主要是控制模型生成結果的隨機性。簡而言之,溫度越低,結果越確定,但也會越平凡或無趣。如果你想要得到一些出人意料的回答,不妨將這個引數調高一些。但如果你的場景是基於事實的場景,比如資料提取、FAQ 場景,此引數就最好調成 0。
其他引數不去管它就好,問題不大。
第四步:設定 OpenAI API Key
這個需要你登入 OpenAI(注意是 OpenAI 不是 ChatGPT),點選右上角的頭像,點選 View API Keys,或者你點選這個連結也可以直接訪問。然後點選「Create New Secret Key」,然後複製那個 Key 並貼上到文件裡即可。
第五步:構建索引
這一步程式會將第一步匯入的資料都跑一遍,並使用 OpenAI 的 embedings API。如果第一步你上傳了自己的資料,只需要將 ' ' 裡的 Jimmy-Newsletter-Corpus 修改為你上傳的資料夾名稱即可。
注意:
- 這一步會耗費你的 OpenAI 的 Credit,1000 個 token 的價格是 $0.02,執行以下程式碼前需要注意你的賬號裡是否還有錢。
- 如果你用的 OpenAI 賬號是個免費賬號,你有可能會遇到頻率警告,此時可以等一等再執行下方程式碼(另外你的匯入的知識庫資料太多,也會觸發)。解除這個限制,最好的方式是在你的 OpenAI 賬號的 Billing 頁面裡繫結信用卡。如何綁卡,需要各位自行搜尋。
第六步:提問
這一步你就可以試試提問了,如果你在第一步匯入的是我預設的資料,你可以試試問以下問題:
- Issue 90 主要講了什麼什麼內容?
- 推薦一本跟 Issue 90 裡提到的書類似的書
如果你匯入的是自己的資料,也可以問以下幾個型別的問題:
- 總結
- 提問
- 資訊提取