本文 AI 產出,尚未審核

LangChain 課程 – Models:語言模型整合

主題:Chat Models 與差異


簡介

LangChain 生態系中,語言模型(LLM)是所有鏈(Chain)與代理(Agent)運作的核心。隨著大型語言模型(LLM)的快速演進,市面上出現了兩大類型的模型:Completion(完成)模型Chat(對話)模型

  • Completion 模型 主要接受單一文字提示(prompt),返回一段連續的文字;
  • Chat 模型 則模擬多輪對話,接受一組「角色」與「訊息」的結構(messages),回傳符合對話上下文的回應。

對於使用 LangChain 開發聊天機器人、文件問答或自動化工作流的開發者而言,正確選擇與使用 Chat Models,能顯著提升回應的自然度、上下文保持能力與成本效益。本篇文章將深入說明 Chat Models 的特性、在 LangChain 中的實作差異,並提供實用範例、常見陷阱與最佳實踐,協助你快速上手並在真實專案中發揮最大價值。


核心概念

1. Chat Model 與 Completion Model 的結構差異

項目 Completion Model Chat Model
輸入格式 純文字字串(prompt) messages 陣列,每筆包含 role(system、user、assistant)與 content
多輪對話支援 需要自行在 prompt 中拼接歷史對話 內建對話歷史管理,直接傳入多筆訊息
系統指令(System Prompt) 只能透過文字前綴實作 有專屬 system 角色,語意更清晰
回應格式 純文字 文字 + 可能的工具呼叫、function call 參數等結構化資訊
成本 Token 計算較單一 每輪訊息皆計算 token,總成本稍高但可降低錯誤率

重點:在 LangChain 中,ChatModel 類別(如 ChatOpenAIChatAnthropic)會自動把 messages 轉換成對應 API 所需的 JSON 結構,開發者只需要關注「角色」與「內容」的編排即可。

2. LangChain 中的 ChatModel 基礎使用

LangChain 為不同 LLM 供應商提供統一的抽象層,讓你只需要更換模型類別,即可切換底層服務(OpenAI、Azure、Anthropic、Gemini 等)。以下以 OpenAI 的 GPT‑4o 為例,說明如何建立一個 ChatOpenAI 實例:

from langchain_openai import ChatOpenAI

# 建立 ChatOpenAI,指定模型與溫度
chat = ChatOpenAI(
    model="gpt-4o-mini",   # 依需求選擇 gpt-4o、gpt-4o-mini 等
    temperature=0.2,       # 越低越 deterministic
    max_tokens=1024        # 回應上限
)

提示:如果你使用的是 Azure OpenAI,只需要換成 AzureChatOpenAI 並提供 azure_endpointapi_key 等參數,其他程式碼保持不變。

3. 建構 messages 陣列的最佳方式

LangChain 提供 HumanMessageSystemMessageAIMessage 三個類別,分別對應 usersystemassistant 角色。使用這些類別能避免手寫字串時的拼寫錯誤,且能自動加入必要的 metadata。

from langchain.schema import HumanMessage, SystemMessage, AIMessage

messages = [
    SystemMessage(content="你是一位專業的旅遊顧問,提供簡潔且友善的建議。"),
    HumanMessage(content="我想去日本東京,三天的行程該怎麼安排?"),
    AIMessage(content="好的,以下是為您安排的三天東京行程...")
]

4. 透過 ChatPromptTemplate 組合動態 Prompt

在實務開發中,常需要根據使用者輸入或外部資料動態生成 messagesChatPromptTemplate 讓你以 Jinja2 樣板語法撰寫「可變」訊息,然後使用 format_messages 產生完整陣列。

from langchain.prompts import ChatPromptTemplate

template = ChatPromptTemplate.from_messages([
    ("system", "你是一位 {role},請以 {tone} 的口吻回覆。"),
    ("human", "{question}")
])

# 依需求填入變數
formatted_messages = template.format_messages(
    role="程式設計教學專家",
    tone="友善且專業",
    question="什麼是 LangChain 的 Retriever?"
)

5. Chat Model 與工具(Tool)結合

LangChain 允許 Chat Model 在回覆中自動呼叫外部工具(如搜尋 API、資料庫查詢)。在 GPT‑4o 之後,模型會返回 function_call 結構,開發者只要提供工具的 schema,即可完成「自動化」的對話流程。

from langchain.tools import StructuredTool
from langchain_openai import ChatOpenAI
from langchain import AgentExecutor, create_openai_functions_agent

# 定義一個簡單的搜尋工具
def web_search(query: str) -> str:
    # 假設這裡呼叫外部搜尋 API,回傳結果文字
    return f"搜尋結果:{query} 的相關資訊..."

search_tool = StructuredTool.from_function(
    func=web_search,
    name="web_search",
    description="根據使用者提供的關鍵字在網路上搜尋相關資訊"
)

# 建立 Chat Model 與 Agent
chat = ChatOpenAI(model="gpt-4o-mini")
agent = create_openai_functions_agent(chat, tools=[search_tool])
executor = AgentExecutor(agent=agent, tools=[search_tool])

# 測試對話
response = executor.invoke({"input": "請告訴我最新的 AI 研討會資訊"})
print(response["output"])

程式碼範例

以下提供 5 個實用範例,展示在 LangChain 中如何使用 Chat Models 完成不同任務。每個範例均附上說明與關鍵點。

範例 1:最簡單的單輪對話

from langchain_openai import ChatOpenAI
from langchain.schema import HumanMessage

chat = ChatOpenAI(model="gpt-4o-mini", temperature=0.0)

msg = HumanMessage(content="請用一句話說明什麼是區塊鏈。")
response = chat.invoke([msg])

print("Assistant:", response.content)

說明:只傳入一筆 HumanMessage,模型會回傳 AIMessage。此方式適合快速測試或單句問答。

範例 2:多輪對話保持上下文

from langchain.schema import SystemMessage, HumanMessage, AIMessage

messages = [
    SystemMessage(content="你是一位熱情的客服代表,請保持禮貌。"),
    HumanMessage(content="我的訂單遲遲沒到,能幫我查一下嗎?")
]

# 第一次回覆
first_reply = chat.invoke(messages)
print("Assistant:", first_reply.content)

# 使用者回覆
messages.append(AIMessage(content=first_reply.content))
messages.append(HumanMessage(content="謝謝!還有其他需要注意的嗎?"))

second_reply = chat.invoke(messages)
print("Assistant:", second_reply.content)

關鍵:將 AI 的回應加入 messages 陣列,確保模型在第二輪能「看到」完整對話歷史。

範例 3:使用 ChatPromptTemplate 動態產生 Prompt

from langchain.prompts import ChatPromptTemplate

prompt = ChatPromptTemplate.from_messages([
    ("system", "你是 {role},說話風格要 {tone}。"),
    ("human", "{question}")
])

messages = prompt.format_messages(
    role="旅遊規劃師",
    tone="熱情且具體",
    question="請推薦台北兩天的美食行程。"
)

reply = chat.invoke(messages)
print(reply.content)

技巧:將角色、語氣等變數抽離,使 Prompt 更具可重用性與可讀性。

範例 4:結合工具(Function Call)實作自動搜尋

from langchain.tools import StructuredTool
from langchain_openai import ChatOpenAI
from langchain import AgentExecutor, create_openai_functions_agent

def search_api(query: str) -> str:
    # 這裡僅示範,實際可呼叫 Google、Bing 等 API
    return f"找到以下資訊:{query} 的最新消息..."

search_tool = StructuredTool.from_function(
    func=search_api,
    name="search",
    description="在網路上搜尋指定關鍵字的最新資訊"
)

chat = ChatOpenAI(model="gpt-4o-mini", temperature=0.0)
agent = create_openai_functions_agent(chat, tools=[search_tool])
executor = AgentExecutor(agent=agent, tools=[search_tool])

result = executor.invoke({"input": "請告訴我 2024 年台灣 AI 產業的趨勢"})
print(result["output"])

重點:只要模型判斷需要搜尋,它會自動回傳 function_call,Agent 會接收並呼叫 search_api,最後把結果回傳給使用者。

範例 5:使用 ChatOpenAI 串接 Azure OpenAI

from langchain_azure_openai import AzureChatOpenAI

azure_chat = AzureChatOpenAI(
    deployment_name="gpt-4o-mini-deployment",
    temperature=0.3,
    api_version="2024-02-01",
    azure_endpoint="https://your-resource.openai.azure.com/",
    api_key="YOUR_AZURE_API_KEY"
)

msg = HumanMessage(content="請說明什麼是 LangChain 的 Retrievers。")
reply = azure_chat.invoke([msg])
print(reply.content)

提示:在企業環境中,Azure OpenAI 常用於資料安全與合規需求,只需改變類別與認證資訊,即可無縫切換。


常見陷阱與最佳實踐

陷阱 說明 最佳實踐
忘記加入 System Prompt 缺少系統指令會讓模型產生不一致的語氣或行為。 始終messages 開頭加入 SystemMessage,明確設定角色與限制。
一次傳入過多訊息 若對話歷史過長,會超過模型的 token 限制,導致錯誤或被截斷。 實作摘要或窗口(sliding‑window):只保留最近 N 條訊息,或使用 LLMChainmemory 進行摘要。
溫度與創意度衝突 高溫度會產生多樣化回應,但在需要精確答案的場景(如程式碼生成)會不穩定。 根據任務選擇:問答/程式碼使用低溫度(00.2),創意寫作則可調高(0.71.0)。
忽視工具呼叫的安全性 若工具接受未驗證的使用者輸入,可能導致注入攻擊或資源濫用。 對使用者輸入做驗證與過濾,並在工具層面加入速率限制。
過度依賴單一模型 不同模型在成本、速度、語意表現上各有優缺點。 建立抽象層(如 ChatModel 介面),根據需求動態切換模型或使用多模型 ensemble。

實際應用場景

  1. 客製化客服聊天機器人

    • 使用 ChatOpenAI 搭配 SystemMessage 設定品牌語氣。
    • 結合搜尋工具與資料庫檢索,讓機器人能即時查詢訂單狀態或常見問題。
  2. 文件問答(RAG)系統

    • 先用 Retriever 抓取相關段落,再把段落與使用者問題組成 ChatPromptTemplate,交給 Chat Model 產生自然答案。
  3. 程式碼輔助 IDE

    • 低溫度、具備 function_call 的 Chat Model 能產生結構化的程式碼片段,並即時回饋錯誤訊息。
  4. 多語言翻譯與本地化

    • 透過 system 設定「你是專業的翻譯家」並提供目標語言,Chat Model 能保持術語一致性。
  5. 教育與互動式教學平台

    • 使用 ChatPromptTemplate 動態產生測驗題目,根據學生回答即時給予提示與解說。

總結

Chat Models 是 LangChain 中最具彈性與威力的元件之一。相較於傳統的 Completion Model,Chat Model 透過結構化的 messagessystem promptfunction call,讓開發者能更自然地管理多輪對話、控制語氣、以及結合外部工具。

在實務開發時,正確構建 messages、適時使用 ChatPromptTemplate、並將工具安全地整合,是提升系統穩定性與使用者體驗的關鍵。透過本文提供的範例與最佳實踐,你現在已具備在 LangChain 上構建聊天型應用的基本能力,接下來只要根據具體需求調整模型參數、記憶策略與工具組合,即可打造出符合商業與技術要求的智慧對話解決方案。

祝開發順利,期待看到你用 LangChain 打造的精彩作品! 🚀