LangChain 提供了便捷的 Few-Shot Prompt Templates 工具,讓開發者能以少量範例引導大語言模型 (LLM) 生成更精確的文字。透過 FewShotChatMessagePromptTemplate 和 FewShotPromptTemplate,我們可以輕鬆建構包含固定數量範例的提示範本。同時,LengthBasedExampleSelector 能根據輸入長度動態調整範例,提升模型的靈活性。
理解文字分割對於處理長篇內容至關重要。LangChain 提供了 CharacterTextSplitter、TokenTextSplitter 和 RecursiveCharacterTextSplitter 等工具,讓開發者能根據字元或詞彙數量,將長文字分割成適合 LLM 處理的區塊。此外,妥善處理特殊字元和格式,能確保分割結果的準確性,避免模型誤判。LangChain 的核心元件,包含檔案載入器、轉換器、嵌入模型、向量資料函式庫和檢索器,則提供更全面的資料處理流程,讓開發者能有效地載入、修改、儲存和檢索資料,進一步提升文字生成的效率和品質。任務分解的策略,能將複雜的文字生成任務拆解成更小的子任務,例如生成大綱、撰寫段落等,讓模型更容易處理,並產出更結構化的結果。
使用Few-Shot Prompt Templates進行文字生成
在使用大語言模型(LLM)進行文字生成時,Few-Shot Prompt Templates是一種強大的工具,可以幫助您最佳化模型的行為,從而產生更好的輸出。這種方法涉及在提示中提供幾個例子,以展示所需的任務效能。
固定長度的Few-Shot例子
首先,讓我們看看如何使用固定數量的例子建立Few-Shot Prompt Templates。這種方法的基礎是建立一個強大的Few-Shot例子集:
from langchain_openai.chat_models import ChatOpenAI
from langchain_core.prompts import FewShotChatMessagePromptTemplate, ChatPromptTemplate
examples = [
{"question": "法國的首都是什麼?", "answer": "巴黎"},
{"question": "西班牙的首都是什麼?", "answer": "馬德里"},
#...更多例子...
]
example_prompt = ChatPromptTemplate.from_messages(
[
("human", "{question}"),
("ai", "{answer}"),
]
)
few_shot_prompt = FewShotChatMessagePromptTemplate(
example_prompt=example_prompt,
examples=examples,
)
print(few_shot_prompt.format())
這將輸出:
Human: 法國的首都是什麼?
AI: 巴黎
Human: 西班牙的首都是什麼?
AI: 馬德里
...更多例子...
使用LengthBasedExampleSelector選擇Few-Shot例子
現在,讓我們探索如何使用LengthBasedExampleSelector選擇Few-Shot例子。這種方法可以根據使用者輸入的長度來適應提示:
from langchain_core.prompts import FewShotPromptTemplate, PromptTemplate
from langchain.prompts.example_selector import LengthBasedExampleSelector
from langchain_openai.chat_models import ChatOpenAI
from langchain_core.messages import SystemMessage
import tiktoken
examples = [
{"input": "戈勒姆", "output": "<戈勒姆的故事>"},
{"input": "甘道夫", "output": "<甘道夫的故事>"},
{"input": "比爾博", "output": "<比爾博的故事>"},
]
story_prompt = PromptTemplate(
input_variables=["input", "output"],
template="角色:{input}\n故事:{output}",
)
這些例子展示瞭如何使用Few-Shot Prompt Templates進行文字生成。透過提供固定數量的例子或使用LengthBasedExampleSelector選擇例子,您可以最佳化模型的行為,從而產生更好的輸出。
內容解密:
在上面的例子中,我們使用了FewShotChatMessagePromptTemplate和FewShotPromptTemplate來建立Few-Shot Prompt Templates。這些類別提供了一種方便的方式來建立具有固定數量的例子的提示。同時,我們還使用了LengthBasedExampleSelector來選擇Few-Shot例子,根據使用者輸入的長度來適應提示。
圖表翻譯:
flowchart TD
A[使用者輸入] --> B[LengthBasedExampleSelector]
B --> C[選擇Few-Shot例子]
C --> D[建立Few-Shot Prompt Template]
D --> E[輸出文字]
這個圖表展示瞭如何使用LengthBasedExampleSelector選擇Few-Shot例子,然後建立Few-Shot Prompt Template,最終輸出文字。
自動化文字生成的基礎:Few-Shot Prompt Templates
在自然語言處理(NLP)中,Few-Shot Prompt Templates是一種強大的工具,能夠幫助我們根據給定的示例生成高品質的文字。這種方法透過提供少量的示例來引導模型生成新的文字,從而實作了更好的控制和定製。
Few-Shot Prompt Templates的工作原理
Few-Shot Prompt Templates的核心思想是定義一個範本,該範本包含了一個或多個變數,然後使用這些變數來生成新的文字。例如,我們可以定義一個範本,該範本包含一個character變數,然後使用這個變數來生成一個故事。
dynamic_prompt = FewShotPromptTemplate(
example_selector=example_selector,
example_prompt=story_prompt,
prefix='''Generate a story for {character} using the
current Character/Story pairs from all of the characters
as context.''',
suffix="Character: {character}\nStory:",
input_variables=["character"],
)
在這個例子中,dynamic_prompt是一個Few-Shot Prompt Template的例項,該例項包含了一個prefix、一個suffix和一個input_variables列表。prefix和suffix分別定義了生成文字的開頭和結尾,而input_variables列表包含了需要被替換的變數。
自動化文字生成的應用
Few-Shot Prompt Templates可以被用於各種自動化文字生成的任務,例如:
- 根據給定的示例生成新的故事
- 根據給定的產品描述生成新的產品介紹
- 根據給定的使用者評價生成新的評價
實作Few-Shot Prompt Templates
要實作Few-Shot Prompt Templates,我們需要定義一個範本,然後使用這個範本來生成新的文字。以下是實作Few-Shot Prompt Templates的一個簡單示例:
def num_tokens_from_string(string: str) -> int:
"""Returns the number of tokens in a text string."""
encoding = tiktoken.get_encoding("cl100k_base")
num_tokens = len(encoding.encode(string))
return num_tokens
example_selector = LengthBasedExampleSelector(
examples=examples,
example_prompt=story_prompt,
max_length=1000,
get_text_length=num_tokens_from_string,
)
dynamic_prompt = FewShotPromptTemplate(
example_selector=example_selector,
example_prompt=story_prompt,
prefix='''Generate a story for {character} using the
current Character/Story pairs from all of the characters
as context.''',
suffix="Character: {character}\nStory:",
input_variables=["character"],
)
formatted_prompt = dynamic_prompt.format(character="Frodo")
chat = ChatOpenAI()
response = chat.invoke([SystemMessage(content=formatted_prompt)])
在這個示例中,我們定義了一個FewShotPromptTemplate的例項,然後使用這個例項來生成一個新的故事。formatted_prompt是生成的提示,該提示包含了需要被替換的變數。最後,我們使用這個提示來生成新的文字。
文字生成的高階技巧
文字生成是自然語言處理的一個重要領域,LangChain是一個強大的工具,能夠幫助開發者建立高品質的文字生成模型。在本章中,我們將探討如何使用LangChain建立高階文字生成模型。
幾何學習的限制
幾何學習是一種強大的技術,但它也有一些限制。首先,預訓練模型可能會過度適應幾何學習的例子,這可能會導致模型過度優先考慮例子而不是實際的提示。其次,LLM有令牌限制,這意味著在提供的例子數量和回應長度之間存在權衡。
儲存和載入LLM提示
LangChain支援將提示儲存為JSON和YAML檔案。這使得提示的分享、儲存和版本控制更加容易。使用PromptTemplate和load_prompt函式,可以輕鬆地儲存和載入提示。
資料連線
LangChain提供了一種連線資料的方法,可以利用LLM應用程式和資料來提高效率和最佳化決策過程。資料可以以多種形式存在,包括非結構化資料和結構化資料。非結構化資料需要進行載入、轉換、嵌入和儲存,而結構化資料可以使用LangChain代理進行中間查詢。
LangChain的元件
LangChain提供了多種元件,包括檔案載入器、檔案轉換器、文字嵌入模型、向量資料函式庫和檢索器。這些元件可以幫助開發者載入、修改、儲存和檢索資料。
圖表翻譯:
此圖表展示瞭如何使用LangChain建立高階文字生成模型的流程。首先,文字生成是自然語言處理的一個重要領域。然後,幾何學習是一種強大的技術,但它也有一些限制。接下來,儲存和載入LLM提示是非常重要的,因為它可以幫助開發者分享、儲存和版本控制提示。然後,資料連線是另一種重要的技術,可以利用LLM應用程式和資料來提高效率和最佳化決策過程。最後,LangChain的元件可以幫助開發者載入、修改、儲存和檢索資料。透過使用LangChain,開發者可以建立高品質的文字生成模型。
資料載入器
讓我們想象一下,你被委託負責建立一個大語言模型(LLM)資料收集管道,為 NutriFusion Foods 這間公司服務。所需的資料包含在以下幾個檔案中:
- 一份名為「行銷原理」(Principles of Marketing)的 PDF 書籍
- 兩份以.docx 格式儲存的行銷報告,存放在公共的 Google Cloud Storage 儲存桶中
- 三份.csv 檔案,展示 2021 年、2022 年和 2023 年的行銷績效資料
首先,建立一個新的 Jupyter Notebook 或 Python 檔案,存放在分享儲存函式庫中的 content/chapter_4 目錄下。接著,執行 pip install pdf2image docx2txt pypdf 指令,以安裝必要的套件。
除了.docx 檔案外,所有其他資料都可以在 content/chapter_4/data 目錄中找到。現在,讓我們開始使用 Python 來載入這些資料。
from langchain_community.document_loaders import Docx2txtLoader
from langchain_community.document_loaders import PyPDFLoader
from langchain_community.document_loaders.csv_loader import CSVLoader
import glob
from langchain.text_splitter import CharacterTextSplitter
# 宣告一個列表來儲存所有載入的檔案
all_documents = []
# 載入 PDF 檔案
loader = PyPDFLoader("data/principles_of_marketing_book.pdf")
pages = loader.load_and_split()
print(pages[0])
# 為每個頁面新增額外的中繼資料
for page in pages:
page.metadata["description"] = "行銷原理書籍"
# 驗證中繼資料是否已新增
for page in pages[0:2]:
print(page.metadata)
# 將行銷書籍頁面新增到 all_documents 列表中
all_documents.extend(pages)
# 找到所有.csv 檔案
csv_files = glob.glob("data/*.csv")
# 篩選只包含 "Marketing" 字串的檔案名稱
csv_files = [f for f in csv_files if "Marketing" in f]
# 載入每個.csv 檔案
for csv_file in csv_files:
#... (待續)
內容解密:
上述程式碼片段示範瞭如何使用 PyPDFLoader 來載入 PDF 檔案,並將其分割成個別頁面。同時,也展示瞭如何為每個頁面新增中繼資料,例如描述。接著,程式碼會將載入的頁面新增到 all_documents 列表中,以便後續處理。最後,程式碼會找到所有.csv 檔案,並篩選出包含 “Marketing” 字串的檔案名稱,以便進行後續的資料載入和處理。
圖表翻譯:
flowchart TD
A[載入 PDF] --> B[分割成頁面]
B --> C[新增中繼資料]
C --> D[儲存頁面]
D --> E[找到.csv 檔案]
E --> F[篩選檔案]
F --> G[載入.csv 檔案]
此圖表展示了程式碼的執行流程,從載入 PDF 檔案開始,到找到和篩選.csv 檔案為止。每個步驟都對應到程式碼中的特定部分,清楚地展示了資料載入和處理的過程。
檔案載入和分割技術
檔案載入和分割是自然語言處理中的一個重要步驟,尤其是在使用大語言模型(LLM)時。LangChain是一個強大的工具,提供了多種檔案載入和分割方法,以適應不同的需求。
檔案載入
LangChain提供了多種檔案載入方法,包括:
- CSVLoader:用於載入CSV檔案。
- Docx2txtLoader:用於載入DOCX檔案。
- PyPDFLoader:用於載入PDF檔案。
這些載入器可以用於載入不同格式的檔案,並將其轉換為LangChain檔案物件。
檔案分割
檔案分割是指將大型檔案分割為小塊,以適應LLM的上下文視窗。LangChain提供了多種檔案分割方法,包括:
- CharacterTextSplitter:根據字元數量分割檔案。
- TokenTextSplitter:根據令牌數量分割檔案。
- RecursiveCharacterTextSplitter:遞迴地根據字元數量分割檔案。
這些分割器可以用於分割不同格式的檔案,並將其轉換為LangChain檔案物件。
檔案分割的挑戰
檔案分割可能會遇到一些挑戰,例如:
- 特殊字元:特殊字元,如#、@符號或連結,可能會影響檔案分割的結果。
- 格式:檔案中的格式,如表格、列表或多級標題,可能會影響檔案分割的結果。
解決方案
為瞭解決這些挑戰,LangChain提供了多種工具和方法,包括:
- tiktoken:一個用於計算令牌數量的工具。
- langchain-text-splitters:一個提供多種檔案分割方法的函式庫。
範例
以下是一個使用CharacterTextSplitter分割檔案的範例:
from langchain_text_splitters import CharacterTextSplitter
# 建立一個CharacterTextSplitter
splitter = CharacterTextSplitter.from_tiktoken_encoder(chunk_size=50, chunk_overlap=0)
# 載入一個檔案
text = "這是一個示範檔案。"
# 分割檔案
chunks = splitter.split_text(text)
# 列印分割結果
print(chunks)
這個範例展示瞭如何使用CharacterTextSplitter分割一個檔案,並列印出分割結果。
文字分割技術
文字分割是一種將大塊文字分解成小塊、可管理的文字片段的技術。這種技術在自然語言處理和文字分析中非常重要,因為它可以幫助我們更好地理解和處理大塊文字。
文字分割的方法
有多種文字分割的方法,包括:
- 根據字元的分割:這種方法是根據字元(如空格、換行符等)來分割文字。
- 根據詞彙的分割:這種方法是根據詞彙(如單詞、短語等)來分割文字。
- 根據句子的分割:這種方法是根據句子來分割文字。
RecursiveCharacterTextSplitter
RecursiveCharacterTextSplitter是一種根據字元的分割方法,它可以根據一組字元來分割文字。這種方法可以保留文字的語義內容,並且可以根據需要調整分割的粒度。
使用RecursiveCharacterTextSplitter
使用RecursiveCharacterTextSplitter需要先初始化一個分割器物件,然後設定分割的引數,例如分割的大小(chunk_size)和重疊的大小(chunk_overlap)。最後,可以使用.split_text()方法來分割文字。
from langchain_text_splitters import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=100,
chunk_overlap=20,
length_function=len,
)
texts = text_splitter.split_text(text)
TokenTextSplitter
TokenTextSplitter是一種根據詞彙的分割方法,它可以根據詞彙來分割文字。這種方法可以保留文字的語義內容,並且可以根據需要調整分割的粒度。
使用TokenTextSplitter
使用TokenTextSplitter需要先初始化一個分割器物件,然後設定分割的引數,例如分割的大小(chunk_size)和重疊的大小(chunk_overlap)。最後,可以使用.split_text()方法來分割文字。
from langchain.text_splitter import TokenTextSplitter
text_splitter = TokenTextSplitter(chunk_size=500, chunk_overlap=50)
loader = PyPDFLoader("data/principles_of_marketing_book.pdf")
pages = loader.load_and_split(text_splitter=text_splitter)
CharacterTextSplitter
CharacterTextSplitter是一種根據字元的分割方法,它可以根據字元來分割文字。這種方法可以保留文字的語義內容,並且可以根據需要調整分割的粒度。
使用CharacterTextSplitter
使用CharacterTextSplitter需要先初始化一個分割器物件,然後設定分割的引數,例如分割的大小(chunk_size)和重疊的大小(chunk_overlap)。最後,可以使用.split_text()方法來分割文字。
text_splitter = CharacterTextSplitter.from_tiktoken_encoder(
chunk_size=50, chunk_overlap=0, separator="\n",
)
texts = text_splitter.split_text(text)
圖表翻譯:
flowchart TD
A[文字] --> B[分割器]
B --> C[分割引數]
C --> D[分割結果]
D --> E[輸出]
內容解密:
以上程式碼展示瞭如何使用不同的文字分割方法來分割文字。每種方法都有其優缺點,需要根據具體需求選擇合適的方法。
文字分割和任務分解的應用
在自然語言處理中,文字分割是一種重要的技術,能夠將長文字分割成更小的、可管理的塊,以便於後續的處理和分析。同時,任務分解是一種戰略性的過程,能夠將複雜的問題分解成一系列可管理的子問題,以便於解決。
文字分割的實作
文字分割可以透過多種方法實作,例如根據字元的分割、根據詞彙的分割等。在 LangChain 中,提供了多種文字分割器,例如 RecursiveCharacterTextSplitter,可以根據字元數量將文字分割成更小的塊。
text_splitter = RecursiveCharacterTextSplitter(chunk_size=300)
texts = text_splitter.split_text(text)
任務分解的應用
任務分解是一種重要的技術,能夠將複雜的問題分解成一系列可管理的子問題,以便於解決。在自然語言處理中,任務分解可以應用於多種場景,例如:
- 複雜問題解決:將複雜的問題分解成一系列可管理的子問題,以便於解決。
- 內容生成:將內容生成任務分解成多個子任務,例如生成大綱、撰寫個別章節等。
- 檔案摘要:將檔案摘要任務分解成多個子任務,例如理解個別章節、生成摘要等。
flowchart TD
A[任務分解] --> B[複雜問題解決]
A --> C[內容生成]
A --> D[檔案摘要]
B --> E[子問題1]
B --> F[子問題2]
C --> G[生成大綱]
C --> H[撰寫個別章節]
D --> I[理解個別章節]
D --> J[生成摘要]
圖表翻譯:
上述流程圖展示了任務分解的過程。首先,將任務分解成多個子任務,然後對每個子任務進行處理。例如,在複雜問題解決中,將問題分解成多個子問題,以便於解決。在內容生成中,將內容生成任務分解成生成大綱、撰寫個別章節等子任務。在檔案摘要中,將檔案摘要任務分解成理解個別章節、生成摘要等子任務。
從技術架構視角來看,Few-Shot Prompt Templates 作為一種最佳化大語言模型(LLM)文字生成能力的技術,其核心價值在於引導模型理解任務需求並產生更符合預期的輸出。透過提供少量示例,Few-Shot Learning 能夠有效降低 LLM 生成 irrelevant 或 nonsensical 內容的風險,並提升生成文字的準確性和相關性。分析段落中提供的程式碼示例,清晰地展示瞭如何利用 LangChain 構建 Few-Shot Prompt Templates,並結合 LengthBasedExampleSelector 根據輸入長度動態調整提示內容,從而提升模型的適應性。然而,Few-Shot Learning 的有效性高度依賴於示例的品質和數量,選擇不當的示例反而可能誤導模型。此外,LLM 的 token 限制也制約了示例的數量和生成的文字長度。展望未來,隨著 LLM 技術的持續發展,預計 Few-Shot Learning 的效率將進一步提升,並與其他技術如 meta-learning 和 transfer learning 融合,以更有效地利用少量資料提升 LLM 的泛化能力。對於開發者而言,深入理解 Few-Shot Learning 的原理和侷限性,並結合 LangChain 等工具,將是構建高效能文字生成應用的關鍵。玄貓認為,Few-Shot Prompt Templates 已成為 LLM 應用的重要組成部分,值得技術團隊深入研究並應用於實際專案中。