LangChain 提供了許多進階技巧,讓開發者能更有效率地運用大語言模型。其中,OpenAI 函式呼叫與平行處理是兩個重要的功能。OpenAI 函式呼叫允許開發者定義外部函式,並讓語言模型在需要時呼叫這些函式,實作更複雜的應用。平行處理則能大幅提升處理效率,尤其在處理大量資料時效果顯著。本文將會介紹如何結合 LCEL 鏈、評估模型、交易分類別與評估等實務應用,並提供程式碼範例與流程圖解說。這些技巧能幫助開發者更好地控制模型行為、提升模型效能,並構建更強大的應用。

重新定義函式以修復和移除反斜線

def 移除反斜線(字串):
    # 雙反斜線用於轉義反斜線
    清理後字串 = 字串.replace("\\", "")
    return 清理後字串

建立一個LCEL鏈以修復格式

 = 提示 | 模型 | 字串輸出解析器() | 移除反斜線 | 輸出解析器
交易 = df.iloc[0]["交易描述"]
結果 = .invoke(
    {
        "交易": 交易,
        "格式指令": 輸出解析器.get_format_instructions(),
    }
)

對整個資料集呼叫鏈

結果列表 = []

for 索引,  in tqdm(df.iterrows(), total=len(df)):
    交易 = ["交易描述"]
    try:
        結果 = .invoke(
            {
                "交易": 交易,
                "格式指令": 輸出解析器.get_format_instructions(),
            }
        )
    except:
        結果 = EnrichedTransactionInformation(
            交易型別=None,
            交易類別=None
        )
    結果列表.append(結果)

將結果新增到資料框中作為欄位

df["交易型別"] = [結果.交易型別 for 結果 in 結果列表]
df["交易類別"] = [結果.交易類別 for 結果 in 結果列表]

內容解密:

以上程式碼定義了一個函式 移除反斜線,用於移除字串中的反斜線。然後,建立了一個LCEL鏈,以修復格式並對整個資料集進行呼叫。最終,將結果新增到資料框中作為欄位。

圖表翻譯:

  flowchart TD
    A[開始] --> B[定義移除反斜線函式]
    B --> C[建立LCEL鏈]
    C --> D[對整個資料集呼叫鏈]
    D --> E[將結果新增到資料框中]

此圖表展示了程式碼的邏輯流程,從定義函式到建立鏈,再到呼叫鏈和新增結果到資料框中。

交易類別處理

在進行交易類別處理時,我們需要根據交易型別和交易描述來進行分類別。以下是相關的程式碼實作:

# 定義交易型別和交易類別列表
transaction_types = []
transaction_categories = []

# 迭代結果,提取交易型別和交易類別
for result in results:
    transaction_types.append(result.transaction_type)
    transaction_categories.append(result.transaction_category)

# 將交易型別和交易類別新增到 DataFrame 中
df["mistral_transaction_type"] = transaction_types
df["mistral_transaction_category"] = transaction_categories

# 顯示 DataFrame 的前幾行資料
print(df.head())

內容解密:

在上述程式碼中,我們首先定義了兩個空列表 transaction_typestransaction_categories,用於儲存交易型別和交易類別的資料。接著,我們使用 for 迴圈迭代結果,提取每筆交易的型別和類別,並將其新增到對應的列表中。最後,我們將這些列表新增到 DataFrame 中,並使用 head() 方法顯示 DataFrame 的前幾行資料。

圖表翻譯:

以下是 Mermaid 圖表,展示了交易類別處理的流程:

  flowchart TD
    A[結果迭代] --> B[提取交易型別]
    B --> C[提取交易類別]
    C --> D[新增到 DataFrame]
    D --> E[顯示 DataFrame]

圖表說明:

此圖表展示了交易類別處理的流程。首先,我們迭代結果(A),然後提取每筆交易的型別(B)和類別(C)。接著,我們將這些資料新增到 DataFrame 中(D),最後顯示 DataFrame 的前幾行資料(E)。

金融交易記錄分析

在進行金融交易記錄分析時,瞭解每筆交易的型別和目的至關重要。以下是一些交易記錄的例子:

  1. 提款租金支付:這類別交易涉及從帳戶中提款,以支付租金。
  2. 提款週末支出:這類別交易是為了滿足週末的個人支出而進行的提款。
  3. 購買書籍:這類別交易涉及購買書籍,可能是透過書店或線上平臺進行的。

程式碼實作

from langchain_mistralai.chat_models import ChatMistralAI
from langchain.output_parsers import PydanticOutputParser

# 取得Mistral API金鑰
mistral_api_key = os.environ["MISTRAL_API_KEY"]

# 初始化ChatMistralAI模型
model = ChatMistralAI(model="mistral-small", mistral_api_key=mistral_api_key)

# 定義系統提示和使用者提示範本
system_prompt = "分析金融交易記錄"
user_prompt = "請輸入交易記錄"

# 處理交易記錄
def process_transaction(record):
    # 根據交易型別進行處理
    if record["type"] == "Withdrawal":
        if record["purpose"] == "Rent":
            print("提款租金支付")
        elif record["purpose"] == "Other":
            print("提款週末支出")
    elif record["type"] == "Purchase":
        if record["category"] == "Other":
            print("購買書籍")

# 範例交易記錄
transactions = [
    {"type": "Withdrawal", "purpose": "Rent"},
    {"type": "Withdrawal", "purpose": "Other"},
    {"type": "Purchase", "category": "Other"}
]

# 處理每筆交易記錄
for transaction in transactions:
    process_transaction(transaction)

內容解密

上述程式碼定義了一個簡單的金融交易記錄分析系統。系統首先初始化一個ChatMistralAI模型,然後定義系統提示和使用者提示範本。接著,系統定義了一個process_transaction函式,用於處理每筆交易記錄。根據交易型別和目的,系統會列印預出相應的訊息。

圖表翻譯

  flowchart TD
    A[開始] --> B[初始化模型]
    B --> C[定義系統提示和使用者提示範本]
    C --> D[處理交易記錄]
    D --> E[根據交易型別進行處理]
    E --> F[列印訊息]

圖表翻譯

此圖表展示了金融交易記錄分析系統的流程。系統首先初始化模型,然後定義系統提示和使用者提示範本。接著,系統處理每筆交易記錄,根據交易型別進行處理,並列印預出相應的訊息。

進階LangChain技術:評估模型與交易分類別

在上一節中,我們探討瞭如何使用LangChain來實作交易分類別。現在,我們將更深入地探討如何評估模型的效能,並使用LangChain提供的工具來比較不同模型之間的差異。

評估模型

LangChain提供了一個簡單的評估指標,即字串匹配。這個指標會根據預測結果是否與參考答案完全匹配來傳回1或0的分數。然而,這個方法有一定的侷限性,因為它只能比較字串之間的相似度。

LangChain的評估方法

LangChain提供了一種更先進的評估方法,稱為labeled_pair_wise_string。這個方法使用GPT-4來比較兩個輸出結果,並給出選擇其中一個的理由。這個方法在比較兩個不同模型或提示之間的差異時尤其有用。

交易分類別示例

在以下示例中,我們使用labeled_pair_wise_string方法來比較Mistral和GPT-3.5模型之間的差異。首先,我們定義了一個EnrichedTransactionInformation模型,該模型包含兩個欄位:transaction_typetransaction_category

from pydantic import BaseModel

class EnrichedTransactionInformation(BaseModel):
    transaction_type: str
    transaction_category: str

接下來,我們定義了一個函式remove_back_slashes,用於從字串中刪除反斜線。

def remove_back_slashes(string):
    return string.replace("\\", "")

然後,我們建立了一個LangChain,該鏈包含一個字串輸出解析器和remove_back_slashes函式。

chain = prompt | model | StrOutputParser() | remove_back_slashes | output_parser

我們從資料框中提取第一筆交易描述,並使用LangChain進行處理。

transaction = df.iloc[0]["Transaction Description"]
result = chain.invoke(transaction)

如果發生異常,我們建立一個預設的EnrichedTransactionInformation物件,其中包含空值。

except:
    result = EnrichedTransactionInformation(transaction_type=None, transaction_category=None)

最後,我們將交易型別和類別新增到資料框中,並顯示結果。

df["mistral_transaction_type"] = transaction_types
df["mistral_transaction_category"] = transaction_categories
print(df.head())

比較模型

使用labeled_pair_wise_string方法,我們可以比較Mistral和GPT-3.5模型之間的差異。以下示例展示瞭如何實作這一點。

model = ChatOpenAI(model="gpt-3.5-turbo-1106", model_kwargs={"response_format": {"type": "json_object"}})
chain = prompt | model | StrOutputParser() | remove_back_slashes | output_parser
result = chain.invoke(transaction)

透過比較兩個模型之間的差異,我們可以更好地瞭解每個模型的優缺點,並根據需要選擇最合適的模型。

圖表翻譯:

  graph LR
    A[交易描述] -->|輸入|> B[LangChain]
    B -->|處理|> C[交易型別和類別]
    C -->|輸出|> D[結果]
    D -->|評估|> E[模型比較]
    E -->|輸出|> F[最終結果]

在這個圖表中,我們展示瞭如何使用LangChain進行交易分類別,並比較不同模型之間的差異。透過這個過程,我們可以更好地瞭解每個模型的優缺點,並根據需要選擇最合適的模型。

評估答案使用 LangChain 評估器

首先,我們需要載入評估器並設定評估的資料。以下是相關程式碼:

from langchain.evaluation import load_evaluator
evaluator = load_evaluator("labeled_pairwise_string")

接下來,我們需要從資料框架 (df) 中提取相關資料,包括交易描述、GPT-3.5 分類別、Mistral 分類別、參考分類別等。

row = df.iloc[0]
transaction = row["Transaction Description"]
gpt3pt5_category = row["gpt3.5_transaction_category"]
gpt3pt5_type = row["gpt3.5_transaction_type"]
mistral_category = row["mistral_transaction_category"]
mistral_type = row["mistral_transaction_type"]
reference_category = row["transaction_category"]
reference_type = row["transaction_type"]

然後,我們需要將這些資料轉換成 JSON 格式,以便評估器可以使用。

gpt3pt5_data = f"""{{
"transaction_category": "{gpt3pt5_category}",
"transaction_type": "{gpt3pt5_type}"
}}"""

mistral_data = f"""{{
"transaction_category": "{mistral_category}",
"transaction_type": "{mistral_type}"
}}"""

reference_data = f"""{{
"transaction_category": "{reference_category}",
"transaction_type": "{reference_type}"
}}"""

最後,我們需要設定評估器的輸入提示,包括交易描述和評估的格式要求。

input_prompt = """您是一位銀行交易分析專家,
您將會對單一交易進行分類別。
請始終傳回交易型別和分類別:不得傳回 None。
格式指示:"""

內容解密:

以上程式碼是用於評估答案的 LangChain 評估器。評估器將會根據輸入的資料和提示,對交易進行分類別和評估。評估的結果將會以 JSON 格式傳回,包含交易型別和分類別。

圖表翻譯:

以下是評估流程的 Mermaid 圖表:

  flowchart TD
    A[載入評估器] --> B[設定評估資料]
    B --> C[轉換資料為 JSON 格式]
    C --> D[設定輸入提示]
    D --> E[評估交易]
    E --> F[傳回評估結果]

圖表翻譯:

此圖表展示了評估流程的步驟,從載入評估器到傳回評估結果。每個步驟都對應到上述程式碼的部分,展示了評估過程的邏輯流程。

transaction 分析與評估

在進行 transaction 分析時,我們需要考慮多個因素,包括 transaction 型別、transaction 分類別以及相關的評分標準。在這個過程中,我們會使用 transaction_typestransaction_categories 來儲存相關的評分結果。

transaction 型別與分類別

首先,我們需要定義 transaction 型別和分類別的評分標準。這通常涉及到對 transaction 文字的分析,以確定其型別和分類別。例如,transaction 型別可能包括 “存款”、“提款” 等,而 transaction 分類別可能包括 “其他”、“購買” 等。

評分標準

評分標準是根據 transaction 型別和分類別的匹配情況來計算的。例如,如果 transaction 型別和分類別都正確匹配,則評分會較高。如果只有一個匹配,則評分會較低。

精確度計算

精確度是根據所有 transaction 型別和分類別的評分結果來計算的。它是所有評分結果的平均值,反映了整體的準確程度。

實作細節

以下是實作細節:

transaction_types = []
transaction_categories = []

# 對每個 transaction 進行分析
for transaction in transactions:
    # 計算 transaction 型別和分類別的評分
    transaction_type_score = calculate_transaction_type_score(transaction)
    transaction_category_score = calculate_transaction_category_score(transaction)
    
    # 儲存評分結果
    transaction_types.append(transaction_type_score)
    transaction_categories.append(transaction_category_score)

# 計算精確度
accuracy_score = 0
for transaction_type_score, transaction_category_score in zip(transaction_types, transaction_categories):
    accuracy_score += transaction_type_score['score'] + transaction_category_score['score']
accuracy_score /= (len(transaction_types) * 2)

print(f"Accuracy score: {accuracy_score}")

結果評估

最終的結果評估是根據精確度和其他相關因素來進行的。例如,如果精確度較高,則表明 transaction 分析的結果較為準確。如果精確度較低,則可能需要重新檢視 transaction 分析的過程和評分標準。

LangChain Evals

LangChain Evals 是一個用於評估語言模型效能的工具。它可以根據輸入和參考資料來計算模型的準確度和相關指標。

evaluator.evaluate_string_pairs(
    prediction=gpt3pt5_data,
    prediction_b=mistral_data,
    input=input_prompt.format(
        format_instructions=output_parser.get_format_instructions(),
        transaction=transaction
    ),
    reference=reference_data,
)

這個過程可以幫助我們瞭解模型的效能和準確度,並對模型進行最佳化和改進。

LangChain 評估器與函式呼叫

LangChain 提供了一種簡單的字串匹配評估器,稱為 labeled_pairwise_string。此評估器可以用於比較兩個字串之間的相似度。以下是使用此評估器的示例程式碼:

evaluator = load_evaluator("labeled_pairwise_string")
row = df.iloc[0]
gpt3pt5_data = f"""{{: To use the pairwise comparison evaluator, we need to pass the results in a way that is formatted correctly for the prompt. This is done for Mistral and GPT-3.5, as well as the reference data."""
input_prompt = """You are an expert..."""
evaluator.evaluate_string_pairs(gpt3pt5_data, input_prompt, reference_data)

此評估器需要三個引數:兩個字串和一個參考資料。評估器會根據字串之間的相似度傳回一個分數。

除了字串匹配評估器外,LangChain 還提供了其他型別的評估器,例如 Levenshtein 距離評估器和嵌入距離評估器。這些評估器可以用於比較兩個字串之間的語義相似度。

函式呼叫

LangChain 還提供了一種函式呼叫機制,允許使用者定義自己的函式並使用 OpenAI 模型來呼叫它們。以下是使用函式呼叫的示例程式碼:

from openai import OpenAI
import json
from os import getenv

def schedule_meeting(date, time, attendees):
    # 定義一個函式來安排會議
    pass

# 定義一個 JSON schema 來描述函式的引數
json_schema = {
    "type": "object",
    "properties": {
        "date": {"type": "string"},
        "time": {"type": "string"},
        "attendees": {"type": "array", "items": {"type": "string"}}
    }
}

# 使用 OpenAI 模型來呼叫函式
openai = OpenAI()
response = openai.call_function("schedule_meeting", json_schema, ["2023-03-01", "14:00", ["John", "Mary"]])
print(response)

此示例定義了一個 schedule_meeting 函式,該函式需要三個引數:日期、時間和與會者。然後,定義了一個 JSON schema 來描述函式的引數。最後,使用 OpenAI 模型來呼叫函式並傳遞引數。

圖表翻譯:

  flowchart TD
    A[定義函式] --> B[定義 JSON schema]
    B --> C[使用 OpenAI 模型呼叫函式]
    C --> D[傳遞引數]
    D --> E[傳回結果]

此圖表展示了函式呼叫的流程:定義函式、定義 JSON schema、使用 OpenAI 模型呼叫函式、傳遞引數和傳回結果。

進階文字生成技術:使用 LangChain 進行 OpenAI 函式呼叫

在本文中,我們將探討如何使用 LangChain 進行 OpenAI 函式呼叫。首先,讓我們定義一個模擬的會議安排函式 schedule_meeting,該函式傳回會議詳細資訊,包括 event_idstatusdatetimeattendees

def schedule_meeting(date, time, attendees):
    return {
        "event_id": "1234",
        "status": "Meeting scheduled successfully!",
        "date": date,
        "time": time,
        "attendees": attendees
    }

接下來,讓我們建立一個 OPENAI_FUNCTIONS 字典,將函式名稱對映到實際的函式,以便於參照。

OPENAI_FUNCTIONS = {
    "schedule_meeting": schedule_meeting
}

然後,讓我們定義一個 functions 列表,提供函式的 JSON 結構。這個結構包括函式名稱、描述和引數,指導 LLM 如何與函式互動。

functions = [
    {
        "type": "function",
        "name": "schedule_meeting",
        "description": "Set a meeting at a specified date and time for designated attendees",
        "parameters": {
            "type": "object",
            "properties": {
                "date": {"type": "string", "format": "date"},
                "time": {"type": "string", "format": "time"},
                "attendees": {"type": "array", "items": {"type": "string"}}
            },
            "required": ["date", "time", "attendees"]
        }
    }
]

當使用 OpenAI 函式呼叫時,請務必定義詳細的 JSON 結構,包括函式名稱和描述。這個結構作為函式的藍圖,指導模型瞭解何時和如何正確地呼叫它。

接下來,讓我們建立一個 OpenAI API 請求。首先,設定一個 messages 列表,包含使用者查詢。然後,使用 OpenAI 客戶端物件,將這個訊息和函式結構傳送給模型。LLM 分析對話,判斷需要觸發函式,並提供函式名稱和引數。然後,從 LLM 回應中解析函式和函式引數,並執行函式。最後,將結果增加回對話中,並再次呼叫模型以獲得整個過程的使用者友好摘要。

client = OpenAI(api_key=getenv("OPENAI_API_KEY"))

# 啟動對話
messages = [
    {
        "role": "user",
        "content": "Schedule a meeting on 2023-11-01 at 14:00 with Alice and Bob."
    }
]

# 將對話和函式結構傳送給模型
response = client.chat(
    model="gpt-3.5-turbo-1106",
    messages=messages,
    tools=functions,
)

# 檢查模型是否想要呼叫我們的函式
if response.tool_calls:
    # 取得第一個函式呼叫
    first_tool_call = response.tool_calls[0]

    # 找到函式名稱和函式引數
    function_name = first_tool_call.function.name
    function_args = json.loads(first_tool_call.function.arguments)
    print("This is the function name: ", function_name)
    print("These are the function arguments: ", function_args)

內容解密:

上述程式碼展示瞭如何使用 LangChain 進行 OpenAI 函式呼叫。首先,我們定義了一個模擬的會議安排函式 schedule_meeting,然後建立了一個 OPENAI_FUNCTIONS 字典將函式名稱對映到實際的函式。接下來,我們定義了一個 functions 列表,提供函式的 JSON 結構。最後,我們建立了一個 OpenAI API 請求,將對話和函式結構傳送給模型,並執行函式以獲得結果。

圖表翻譯:

  flowchart TD
    A[啟動對話] --> B[定義函式結構]
    B --> C[建立 OpenAI API 請求]
    C --> D[執行函式]
    D --> E[獲得結果]
    E --> F[再次呼叫模型]

上述 Mermaid 圖表展示了整個過程的流程。首先,我們啟動對話,然後定義函式結構。接下來,我們建立 OpenAI API 請求,並執行函式以獲得結果。最後,我們再次呼叫模型以獲得整個過程的使用者友好摘要。

進階文字生成技術:函式呼叫與平行處理

在 LangChain 中,函式呼叫是一個強大的功能,允許模型呼叫外部函式以執行特定任務。這個功能可以用來與外部系統進行互動,例如安排會議或傳送電子郵件。

這篇文章涵蓋了多個使用 LangChain 與 OpenAI 進行進階文字處理和分析的技巧,包含清除字串、建立和運用 LCEL 鏈、資料框操作、交易類別處理、模型評估、以及函式呼叫。

從字串處理的 移除反斜線 函式開始,我們逐步建構了一個可以分析金融交易記錄的流程。利用 LCEL 鏈,我們能將提示、模型、解析器和清理函式串連起來,有效地處理整個資料集。此外,文章也示範瞭如何將處理結果新增至 Pandas DataFrame,方便後續分析。

文章進一步探討了交易類別處理的流程,並以視覺化的 Mermaid 流程圖清楚地呈現了資料處理步驟。更重要的是,文章深入探討了模型評估的重要性,比較了字串匹配和 labeled_pairwise_string 等評估方法,並示範如何使用 LangChain Evals 來比較不同模型(如 Mistral 和 GPT-3.5)的效能。

最後,文章介紹了 LangChain 中的 OpenAI 函式呼叫功能,示範如何定義函式、建立 JSON schema,以及如何使用 OpenAI 模型呼叫這些函式。更進一步地,文章也提到了如何利用函式呼叫與平行處理來提升效率。

雖然文章涵蓋了許多進階技巧,但仍有一些可以改進的地方。例如,可以更深入地探討不同評估方法的優缺點,以及如何根據特定任務選擇合適的評估方法。此外,也可以探討如何最佳化函式呼叫的效能,例如使用快取機制或非同步呼叫。

總體而言,這篇文章提供了一個實用的 LangChain 與 OpenAI 應用,對於想要深入瞭解這些技術的讀者來說,是一個很好的起點。隨著技術的發展,我們預見 LangChain 和 OpenAI 將在更多領域發揮更大的作用,例如自然語言理解、機器翻譯和程式碼生成等。密切關注這些新興使用案例,它們很可能重新定義整個技術領域的價值。玄貓認為,LangChain 和 OpenAI 的結合,為開發者提供了強大的工具,可以更有效地構建和佈署根據 AI 的應用程式。

技術架構視角

這篇文章展現瞭如何利用 LangChain 框架構建一個模組化的文字處理和分析流程。從底層的字串處理函式到高階的模型評估和函式呼叫,每個模組都清晰地定義和組織。LCEL 鏈的應用更進一步提升了系統的靈活性和可擴充套件性,允許開發者輕鬆地新增、移除或替換不同的模組。

然而,文章並未深入討論如何處理更複雜的技術架構挑戰,例如:

  • 錯誤處理和日誌記錄: 在實際應用中,完善的錯誤處理和日誌記錄機制至關重要。文章可以補充說明如何在 LCEL 鏈中加入錯誤處理機制,以及如何記錄重要的執行資訊。
  • 效能最佳化: 對於大型資料集,效能最佳化是不可避免的。文章可以探討如何利用平行處理或快取機制來提升 LCEL 鏈的執行效率。
  • 模組化設計最佳實務: 文章可以提供更具體的模組化設計最佳實務,例如如何定義模組介面、如何管理模組之間的依賴關係,以及如何進行單元測試。

對於重視長期穩定性的企業,採取漸進式整合策略將帶來最佳平衡。從小規模的原型設計開始,逐步驗證和最佳化系統架構,可以有效降低技術風險,並確保系統的長期可維護性。