LangChain 提供了強大的輸出解析器,能將大語言模型的文字輸出轉換成結構化資料,方便後續應用。搭配 Pydantic,更能確保資料的正確性和一致性。文章中示範瞭如何使用 Pydantic 定義資料模型、驗證欄位,並結合 LangChain 的輸出解析器將模型輸出轉換成 Python 物件。此外,也說明瞭如何設定 OpenAI API 金鑰、選擇語言模型,以及如何使用 LangChain 建立聊天機器人,包含定義聊天範本、建立提示範本和取得使用者輸入等步驟。文章提供了完整的程式碼範例和流程圖,方便讀者理解和實作。

大衛像的雕刻師是誰?

大衛像是由米開朗基羅·布歐納羅蒂雕刻的。這個答案是根據對「誰雕刻了大衛像?」的問題進行生成的,使用了預先存在的知識和相關例子。

在生成答案的過程中,語言模型使用了提供的例子和其自身的知識來產生正確的答案。這些例子作為指導或上下文,幫助模型瞭解所問問題的型別和預期的答案格式。

輸出解析器

最後,我們來看輸出解析器。有時,您可能希望您的語言模型生成特定格式的輸出,例如 JSON 或問題-答案模式。您可以使用輸出解析器從模型的回應中提取相關資訊,並根據您的需求進行結構化。

輸出解析器在構建需要從語言模型的輸出中提取特定資料型別的應用程式時非常有用。也許您需要一個 Python datetime 物件或一個格式良好的 JSON 物件。您可以使用輸出解析器輕鬆地將語言模型的字串輸出轉換為您需要的確切資料型別,甚至可以使用 pydantic 建立自定義類別例項。

輸出解析器通常執行兩個主要功能:

  1. 取得格式指令:此方法為語言模型提供瞭如何結構化和呈現資訊的指導方針。
  2. 解析:一旦語言模型生成回應,此方法就會根據提供的指令對文字進行結構化。

在語言模型的回應不完全符合所需格式的情況下,輸出解析器提供了一種額外的方法:

  1. 帶提示的解析:此方法作為第二次嘗試,以正確結構化資料。它考慮了語言模型的回應和原始提示,並提供更多上下文以精煉輸出。

瞭解 LangChain 輸出解析器

LangChain 提供了多種輸出解析器,能夠滿足不同需求,無論是 JSON 物件還是 CSV 檔案,LangChain 都有相應的解析器。許多這些解析器都支援串流處理,可以處理連續的資料輸入。

解析器型別

  • OpenAITools 解析器:此解析器在處理最新的 OpenAI 函式時非常方便。它根據給定的引數、工具和工具選擇來結構化輸出。
  • OpenAIFunctions 解析器:當使用舊版 OpenAI 函式呼叫引數(如函式和函式呼叫)時,此解析器很有用。它可靠且以 JSON 物件的形式串流輸出。
  • JSON 解析器:這是一個非常可靠的解析器,傳回一個 JSON 物件,可以由玄貓定義。
  • XML 解析器:當輸出需要以 XML 格式呈現時,使用此解析器。
  • CSV 解析器:此解析器將輸出轉換為一個整齊的列表,非常適合電子試算表。
  • OutputFixing 解析器:有時,第一次輸出的結果可能不是完美的。此解析器包裝另一個解析器,並在出錯時介入,要求 LLM 修正輸出。
  • RetryWithError 解析器:此解析器與 OutputFixing 相似,但更全面,因為它也考慮原始輸入和指令,並在出錯時要求 LLM 重做。
  • Pydantic 解析器:Pydantic 幫助您定義模型輸出的結構,並確保輸出符合您想要的結構。
  • YAML 解析器:對於需要以 YAML 格式呈現的輸出,特別是在您的資料結構以 YAML 定義時很有用。

實際應用案例

假設您正在構建一個應用程式,以確定科學發現的日期,您希望這些日期以 Python 中的 datetime 物件形式呈現。您可能會面臨兩個主要挑戰:

  1. LLM 的輸出始終是一個字串,無論您如何與之互動或提供什麼指令。
  2. 日期格式可能會有所不同。LLM 可能會以「2020 年 1 月 1 日」、「2020-01-01」等形式回應。

這就是解析器可以發揮作用的地方。它們使用格式指令來確保輸出以正確的格式(例如「2020-01-01」用於 datetime)呈現,並提供了一種解析方法將字串轉換為所需的 Python 物件型別。

使用 PydanticOutputParser 的實際範例

在這個範例中,您將建立一個系統來儲存和組織電影資訊。

匯入所需函式庫

您需要匯入以下函式庫:

  • pydantic:提供 BaseModelFieldValidationErrorfield_validator 類別,用於定義資料模型和驗證。
  • langchain.output_parsers:提供 PydanticOutputParser 類別,用於解析語言模型的輸出。
  • langchain.prompts:提供 PromptTemplate 類別,用於建立提示範本。
  • langchain.chat_models:提供 ChatOpenAI 類別,用於與 OpenAI 聊天模型互動。
  • langchain.schema:提供 HumanMessage 類別,用於代表對話中的人類訊息。

定義電影資料模型

您定義了一個繼承自 BaseModelMovie 類別,以代表電影的結構。 該類別有三個欄位:titledirectoryear,每個欄位都有一個描述。 您使用 @field_validator 裝飾器來確保電影標題是大寫。如果標題不是以大寫開頭,則會引發 ValidationError

from pydantic import BaseModel, Field, ValidationError, field_validator
from langchain.output_parsers import PydanticOutputParser
from langchain.prompts import PromptTemplate
from langchain.chat_models import ChatOpenAI
from langchain.schema import HumanMessage

class Movie(BaseModel):
    title: str = Field(description="電影標題")
    director: str = Field(description="電影導演")
    year: int = Field(description="電影年份")

    @field_validator('title')
    def title_must_be_capitalized(cls, v):
        if not v.istitle():
            raise ValueError('標題必須以大寫開頭')
        return v

使用 PydanticOutputParser

您可以使用 PydanticOutputParser 來解析 LLM 的輸出,並將其轉換為 Movie 物件。

parser = PydanticOutputParser(model=Movie)

這樣,您就可以使用 LangChain 的強大功能來處理和分析您的電影資料了。

電影資料結構與輸出格式設定

在處理電影資料時,需要確保資料的正確性和一致性。以下是如何使用 Pydantic 來定義電影資料結構,並設定輸出格式。

電影資料模型

首先,定義一個電影資料模型 Movie,其中包含 titleyear 兩個欄位。title 欄位需要進行資格檢查,以確保電影標題的首字母大寫。

from pydantic import Field, validator

class Movie:
    title: str = Field(description="The title of the movie")
    year: int = Field(description="The release year of the movie")

    @validator('title')
    def title_must_be_capitalized(cls, value):
        if not value.istitle():
            raise ValueError("Movie title must be capitalized.")
        return value

輸出解析器初始化

接下來,初始化一個 Pydantic 輸出解析器 PydanticOutputParser,並傳入 Movie 類別作為 pydantic_object 引數,以指定期望的輸出結構。

parser = PydanticOutputParser(pydantic_object=Movie)

提示範本建立

定義一個提示範本 PromptTemplate,名為 prompt,提供給語言模型的格式化指令。範本包含兩個佔位符:{format_instructions}{query}

prompt = PromptTemplate(
    template="Format the movie information as follows: {format_instructions}. Query: {query}"
)

這個範本告訴語言模型如何格式化電影資料,並提供了輸入變數 query 以及格式化指令的佔位符。

資料輸出與格式化

使用 parserprompt 來輸出格式化的電影資料。這涉及到將電影資料模型例項化,並使用 parser 將其轉換為所需的輸出格式。然後,使用 prompt 來生成最終的格式化輸出。

movie = Movie(title="Inception", year=2010)
output = parser.parse(movie)
formatted_output = prompt.format(format_instructions="Title: {title}, Year: {year}", query="What is the movie Inception about?")
print(formatted_output)

這樣就完成了電影資料的結構定義、輸出格式設定、提示範本建立,以及最終的資料輸出與格式化。

設定 OpenAI API 金鑰

為了使用 OpenAI 的 API,您需要先設定 API 金鑰。您可以從環境變數中取得 API 金鑰,方法是使用 os.environ.get() 函式。如果環境變數中沒有設定 API 金鑰,您可以使用預設值作為替代。

import os

# 從環境變數中取得 OpenAI API 金鑰
openai_api_key = os.environ.get("OPENAI_API_KEY")

# 如果環境變數中沒有設定 API 金鑰,使用預設值
if openai_api_key is None:
    openai_api_key = "您的實際 API 金鑰"  # 請替換為您的實際 API 金鑰

選擇語言模型和設定

在設定好 API 金鑰後,您需要選擇適合您的語言模型和設定。OpenAI 提供了多種語言模型,每個模型都有其優缺點和適用場景。您可以根據您的需求選擇合適的模型。

# 選擇語言模型和設定
model = "您的選擇的模型"  # 請替換為您選擇的模型

內容解密:

以上程式碼片段展示瞭如何設定 OpenAI API 金鑰和選擇語言模型。首先,我們從環境變數中取得 API 金鑰,如果沒有設定金鑰,我們使用預設值。然後,我們選擇適合的語言模型和設定。

圖表翻譯:

圖表說明:

此流程圖展示了設定 OpenAI API 和選擇語言模型的步驟。首先,我們取得 API 金鑰,然後選擇適合的語言模型,接著設定模型引數,最後執行模型。

結合自然語言處理和結構化資料的力量

在上述範例中,我們看到了一個強大的示範,展示瞭如何將大語言模型(LLM)的文字回應轉換為結構化的電影物件。這個過程涉及多個步驟,包括定義查詢、建立人類訊息、生成 LLM 回應、解析回應等。

步驟 1:定義查詢和建立人類訊息

首先,我們定義了一個查詢變數,內容是電影標題。在這個例子中,查詢是「Tell me about the movie ‘Inception’。」接著,我們建立了一個HumanMessage例項,內容是格式化的提示,使用prompt.format(query=query)

步驟 2:生成 LLM 回應

然後,我們將包含人類訊息的列表傳遞給 LLM 例項,以生成回應。這裡使用的是ChatOpenAI類別,指定了模型名稱、溫度和 OpenAI API 金鑰。

步驟 3:解析 LLM 回應

接下來,我們使用 Pydantic 的OutputParser來解析 LLM 的回應。為了處理可能出現的驗證錯誤,我們使用了 try-except 塊。如果解析成功,我們列印預出結構化的電影資料;如果發生驗證錯誤,我們列印預出錯誤訊息。

結果和應用

這個示範展示瞭如何將 LLM 的文字回應轉換為結構化的資料,可以應用於各種領域,如組織電影、書籍、產品等資訊。這種方法可以幫助我們從 LLM 的回應中提取有用的結構化資料,從而更好地理解和利用這些資訊。

範例程式碼

# 定義查詢和建立人類訊息
query = "Tell me about the movie 'Inception'."
human_message = HumanMessage(content=prompt.format(query=query))

# 生成LLM回應
llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0, openai_api_key=openai_api_key)
response = llm([human_message])

# 解析LLM回應
try:
    parsed_movie = OutputParser.parse(response)
    print(parsed_movie)
except ValidationError as e:
    print(f"Validation Error: {e}")

Plantuml 圖表

圖表翻譯

此圖表展示了從定義查詢到列印結構化資料的整個過程,包括建立人類訊息、生成 LLM 回應、解析 LLM 回應和處理驗證錯誤等步驟。每個步驟都對應著特定的程式碼段,共同實作了從 LLM 回應中提取結構化資料的功能。

使用 LangChain 建立聊天機器人

LangChain 提供了一個名為 OutputFixingParser 的工具,負責檢查輸出格式並糾正任何錯誤。這個工具就像一個幫助模型檢查工作的助手,確保輸出正確無誤。

隨著模型的不斷改進,它們越來越擅長於遵循指令。此外,使用大語言模型(LLMs)還有一定的隨機性。因此,如果你正在跟著這個教程做,你可能會發現模型直接生成正確的輸出,且一切運作順暢。這是一個好訊息!但是,如果你無法重現錯誤,也不要擔心,你仍然可以從這個過程中學到東西。

在下一節中,你將探索另一種稱為「聊天提示範本」的提示型別,這種範本非常適合用於構建聊天機器人和對話代理。

聊天提示範本

聊天提示範本是一種有用的提示範本變體,可以使你在使用大語言模型(LLMs)進行對話任務時的工作變得更容易。

正如你之前所學,Chat Completions API 使用了一個包含系統訊息、人類訊息(提示)和 AI 訊息的列表。LangChain 提供了一些有用的類別,使得與這些訊息合作變得容易。

建立聊天提示範本

讓我們看看如何使用 ChatPromptTemplate 類別建立這樣的一個範本。

匯入所需的函式庫

首先,處理基本的匯入工作,例如匯入以下函式庫:

from langchain.prompts import ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplate
from langchain.chat_models import ChatOpenAI
import os

設定 OpenAI API 金鑰

做任何必要的事情來設定 API 金鑰:

openai_api_key = os.environ.get("OPENAI_API_KEY")
if openai_api_key is None:
    openai_api_key = "your_api_key_here"  # 用你的實際 API 金鑰替換

建立聊天模型例項

現在,你可以使用 ChatOpenAI 類別建立一個聊天模型例項:

chat_model = ChatOpenAI(openai_api_key)

內容解密:

以上程式碼的作用是匯入必要的函式庫,設定 OpenAI API 金鑰,並建立一個聊天模型例項。這些步驟為建立一個聊天機器人或對話代理奠定了基礎。

圖表翻譯:

此圖表示出了建立聊天機器人的步驟,從匯入函式庫到設定 API 金鑰,再到建立聊天模型例項和聊天提示範本。

建立聊天機器人例項

首先,我們需要建立一個聊天機器人例項,指定所需的溫度(0)和 OpenAI API 金鑰。這個步驟對於確保聊天機器人的行為和回應是可控和可預測的至關重要。

chat = ChatOpenAI(temperature=0, openai_api_key=openai_api_key)

定義聊天範本

接下來,我們定義一個聊天範本作為一個多行字串,使用三個引號(“””)。這個範本包含了一個系統訊息,描述了助手的角色和行為。它還包含了一個用於使用者輸入的佔位符({text})。

template = """
你是一個熱情的助手,負責將使用者的文字重寫得更具吸引力。

使用者:{text}
助手:"""

建立提示範本

然後,我們建立一個名為promptChatPromptTemplate例項,使用from_messages()方法。這個方法接受一個訊息提示範本列表作為引數。列表中包含系統訊息提示範本和人類訊息提示範本,後者包含使用者輸入的佔位符({text})。

prompt = ChatPromptTemplate.from_messages([
    SystemMessagePromptTemplate.from_template(
        "你是一個熱情的助手,負責將使用者的文字重寫得更具吸引力。"
    ),
    HumanMessagePromptTemplate.from_template(
        "{text}"
    ),
])

取得使用者輸入

最後,我們使用input()函式提示使用者輸入一些文字,並將輸入儲存在變數中。

user_input = input("請輸入一些文字:")

內容解密:

在上述程式碼中,我們使用了ChatOpenAI類別來建立一個聊天機器人例項。temperature引數設定為 0,表示我們想要獲得最直接和最可預測的回應。openai_api_key是用於驗證 OpenAI API 請求的金鑰。

聊天範本定義了助手的角色和行為,以及使用者輸入的佔位符。提示範本使用from_messages()方法建立,包含系統訊息和人類訊息。

獲得使用者輸入後,我們可以使用這些輸入來生成聊天機器人的回應。

圖表翻譯:

以下是程式碼邏輯的 Plantuml 流程圖:

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title LangChain 輸出解析器與聊天機器人實作流程

actor "使用者" as user
participant "ChatPromptTemplate" as prompt
participant "ChatOpenAI\n(LLM)" as llm
participant "StrOutputParser" as strparser
participant "PydanticOutputParser" as parser
participant "Pydantic\nBaseModel" as model
database "輸出結果" as output

user -> prompt : 輸入查詢
note right of prompt
  系統提示:定義助手角色
  使用者提示:包含變數 {query}
end note

prompt -> llm : 格式化提示
note right of llm
  model="gpt-3.5-turbo"
  temperature=0
end note

llm -> strparser : 生成文字回應
strparser -> parser : 解析字串

alt 驗證成功
    parser -> model : 建立 Pydantic 物件
    note right of model
      驗證欄位:
      - title (必須大寫)
      - director
      - year
    end note
    model --> output : 結構化資料
    output --> user : 返回電影物件
else 驗證失敗
    parser -> user : ValidationError
end

note bottom
  LCEL Chain 範例:
  chain = prompt | model | StrOutputParser() |
          remove_back_slashes | output_parser
end note

@enduml

這個流程圖展示了建立聊天機器人例項、定義聊天範本、建立提示範本和取得使用者輸入的步驟。最終,聊天機器人根據使用者輸入生成回應。

總結:LangChain 輸出解析器與聊天機器人實作

本文深入探討了 LangChain 輸出解析器和聊天機器人實作的關鍵技術。從大衛像雕塑家的簡單例子出發,逐步介紹了輸出解析器的功能和應用,涵蓋了不同解析器型別,例如 JSON、CSV、Pydantic 等,並以電影資料模型為例,詳細說明瞭如何使用 Pydantic 進行資料驗證和結構化輸出。

文章接著闡述瞭如何設定 OpenAI API 金鑰、選擇語言模型,以及如何結合自然語言處理和結構化資料,將 LLM 的文字回應轉換為可操作的結構化資訊。此外,也介紹了 LangChain 的 OutputFixingParser 工具,用於自動修正輸出格式錯誤,提升模型輸出可靠性。

最後,文章詳細說明瞭如何使用 LangChain 建立聊天機器人,包括定義聊天範本、建立提示範本,以及取得使用者輸入。透過 ChatPromptTemplateSystemMessagePromptTemplate 等工具,可以輕鬆構建複雜的對話流程。

展望未來,LLM 結合結構化資料的應用將更加廣泛,輸出解析器的重要性也將日益凸顯。LangChain 提供的豐富工具和靈活框架,將有助於開發者更有效率地構建根據 LLM 的應用,並在各種場景下實作更精確、可靠的輸出控制。對於追求高效能和高可靠性的應用開發者而言,深入理解和掌握 LangChain 的輸出解析器和聊天機器人實作技術至關重要。

建議開發者持續關注 LangChain 的發展,探索更多進階功能,並根據實際需求選擇合適的工具和策略,以充分發揮 LLM 的潛力,打造更具智慧和實用價值的應用程式。