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類別(如ChatOpenAI、ChatAnthropic)會自動把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_endpoint、api_key等參數,其他程式碼保持不變。
3. 建構 messages 陣列的最佳方式
LangChain 提供 HumanMessage、SystemMessage、AIMessage 三個類別,分別對應 user、system、assistant 角色。使用這些類別能避免手寫字串時的拼寫錯誤,且能自動加入必要的 metadata。
from langchain.schema import HumanMessage, SystemMessage, AIMessage
messages = [
SystemMessage(content="你是一位專業的旅遊顧問,提供簡潔且友善的建議。"),
HumanMessage(content="我想去日本東京,三天的行程該怎麼安排?"),
AIMessage(content="好的,以下是為您安排的三天東京行程...")
]
4. 透過 ChatPromptTemplate 組合動態 Prompt
在實務開發中,常需要根據使用者輸入或外部資料動態生成 messages。ChatPromptTemplate 讓你以 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 條訊息,或使用 LLMChain 的 memory 進行摘要。 |
| 溫度與創意度衝突 | 高溫度會產生多樣化回應,但在需要精確答案的場景(如程式碼生成)會不穩定。 | 根據任務選擇:問答/程式碼使用低溫度(0 |
| 忽視工具呼叫的安全性 | 若工具接受未驗證的使用者輸入,可能導致注入攻擊或資源濫用。 | 對使用者輸入做驗證與過濾,並在工具層面加入速率限制。 |
| 過度依賴單一模型 | 不同模型在成本、速度、語意表現上各有優缺點。 | 建立抽象層(如 ChatModel 介面),根據需求動態切換模型或使用多模型 ensemble。 |
實際應用場景
客製化客服聊天機器人
- 使用
ChatOpenAI搭配SystemMessage設定品牌語氣。 - 結合搜尋工具與資料庫檢索,讓機器人能即時查詢訂單狀態或常見問題。
- 使用
文件問答(RAG)系統
- 先用
Retriever抓取相關段落,再把段落與使用者問題組成ChatPromptTemplate,交給 Chat Model 產生自然答案。
- 先用
程式碼輔助 IDE
- 低溫度、具備
function_call的 Chat Model 能產生結構化的程式碼片段,並即時回饋錯誤訊息。
- 低溫度、具備
多語言翻譯與本地化
- 透過
system設定「你是專業的翻譯家」並提供目標語言,Chat Model 能保持術語一致性。
- 透過
教育與互動式教學平台
- 使用
ChatPromptTemplate動態產生測驗題目,根據學生回答即時給予提示與解說。
- 使用
總結
Chat Models 是 LangChain 中最具彈性與威力的元件之一。相較於傳統的 Completion Model,Chat Model 透過結構化的 messages、system prompt 與 function call,讓開發者能更自然地管理多輪對話、控制語氣、以及結合外部工具。
在實務開發時,正確構建 messages、適時使用 ChatPromptTemplate、並將工具安全地整合,是提升系統穩定性與使用者體驗的關鍵。透過本文提供的範例與最佳實踐,你現在已具備在 LangChain 上構建聊天型應用的基本能力,接下來只要根據具體需求調整模型參數、記憶策略與工具組合,即可打造出符合商業與技術要求的智慧對話解決方案。
祝開發順利,期待看到你用 LangChain 打造的精彩作品! 🚀