把所有的積木全部拼裝起來!
我們在前面的三個章節,已經把打造企業級 AI 的三個核心組件都準備好了:
- 第一章:ChatGPT 大腦 (負責看懂問題並把答案講出來)
- 第二章:Embedding 與向量資料庫 (負責把文字變成座標,並提供精準的語意搜尋)
- 第三章:文件切肉機 (負責把厚厚的 PDF 變成一片片整齊的文字方塊)
現在,我們要使用 LangChain 最引以為傲的核心技術:Chain (鏈條)。 就像它的名字一樣,LangChain 允許你把這三個原本不相干的組件,用一根無形的鎖鏈「串」在一起。當這條生產線跑起來的那一瞬間,你的專屬 RAG 企業客服機器人就誕生了!
讓子彈飛:RAG 系統的運作全景
讓我們想像一下,當這條 Chain 組裝好之後,如果客人問了一個問題:「極速旋風 3000 型的保固期是多久?」 這條鎖鏈會自動觸發以下四個步驟:
- 使用者發問:「保固期多久?」
- 搜尋圖書館 (Retriever):鎖鏈把這個問題丟給「向量資料庫」。資料庫快速計算座標,找出 3 塊最相關的「小抄 (文件碎片)」。
- 整理考卷 (Prompt Template):鎖鏈把這 3 塊小抄,連同使用者的原始問題,一起塞進一張精美的「考卷範本」裡面,然後嚴厲地警告 AI:「請只根據小抄回答!」
- 大腦作答 (LLM):ChatGPT 收到考卷,看著小抄,回答:「這台電風扇的保固期為十年喔!」最後把答案顯示給客人看。
在 LangChain 裡,把這 4 個步驟串起來的語法,叫做 LCEL (LangChain Expression Language)。它使用一個非常帥氣的符號 | (管線符號),代表「把前面的產出,餵給後面的機器」。
Vibe Prompt 實戰:終極的大融合腳本
我們現在要請 AI 幫我們寫一份完整的、可執行的 RAG 腳本。為了讓初學者能夠直接在自己的電腦上跑起來,我們會使用輕量級的開源資料庫 Chroma,它不需要你註冊任何雲端帳號。
【終極 RAG 鏈條組合 Prompt】 我正在使用 Python 與 LangChain 開發一個簡單的 RAG 測試系統。 我手邊有一段關於公司產品的「假資料字串」:
docs = ["極速旋風 3000 型電風扇,主打超強風力與靜音,馬達獨家提供十年保固。", "水星牌智慧型冰箱,具備 AI 溫控功能,全機保固一年。"]請幫我寫一個完整的 Python 腳本,流程如下:
- 先引入 OpenAI 的 Embeddings 與 ChatOpenAI 大語言模型。
- 使用 LangChain 的
Chroma向量資料庫(from langchain_community.vectorstores import Chroma),把上面那兩句話變成向量並存入本地記憶體中 (Chroma.from_texts)。- 將資料庫轉換為檢索器 (Retriever)。
- 建立一個 Prompt Template,指示 AI 只能根據提供的 context 來回答問題。
- 使用 LCEL 語法 (
|符號) 將 Retriever, Prompt, LLM 與 OutputParser 串接成一條rag_chain。- 最後,請用這個 chain 來回答問題:「請問水星冰箱的保固是幾年?極速電風扇呢?」。
- 請加上詳細的中文註解,讓完全沒學過 LangChain 的人也能看懂每一步在做什麼。
AI 產出的 RAG 終極組合包:
import os
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_community.vectorstores import Chroma
from langchain_core.prompts import PromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser
# 準備你的 API Key (實戰中請用 .env)
os.environ["OPENAI_API_KEY"] = "sk-你的密碼"
def build_rag_system():
# ==========================================
# 步驟 1:建立向量資料庫 (圖書館)
# ==========================================
docs = [
"極速旋風 3000 型電風扇,主打超強風力與靜音,馬達獨家提供十年保固。",
"水星牌智慧型冰箱,具備 AI 溫控功能,全機保固一年。"
]
print("正在把公司機密文件存入 Chroma 向量資料庫...")
# 把文字丟給 OpenAI 進行 Embedding 轉換成座標,並存入 Chroma 記憶體庫
vectorstore = Chroma.from_texts(texts=docs, embedding=OpenAIEmbeddings())
# 將資料庫設定為「檢索器 (Retriever)」,每次有人問問題,就找出最相關的 2 塊小抄
retriever = vectorstore.as_retriever(search_kwargs={"k": 2})
# ==========================================
# 步驟 2:設計考卷範本 (Prompt Template)
# ==========================================
# 嚴格警告 AI 只能看小抄回答
template = """
你是一個專業的客服人員。請「只」根據以下提供的參考資料來回答問題。
如果在資料中找不到答案,請誠實回答「我不知道」,絕對不可以自己編造答案。
【參考資料 (小抄)】:
{context}
【客人的問題】:
{question}
【你的專業回答】:
"""
custom_prompt = PromptTemplate.from_template(template)
# ==========================================
# 步驟 3:準備 ChatGPT 大腦與輸出過濾器
# ==========================================
# temperature=0 代表要 AI 非常冷靜死板,不要發揮創意亂講話
llm = ChatOpenAI(model_name="gpt-4o-mini", temperature=0)
output_parser = StrOutputParser() # 只把最終的文字答案萃取出來
# ==========================================
# 步驟 4:LCEL 魔法!把它們全部「串」起來 (The Chain)
# ==========================================
# 這個鏈條的邏輯是:
# 1. 取得使用者的問題,交給 retriever 去抓 context (小抄)
# 2. 把小抄跟問題一起塞進 custom_prompt 考卷裡
# 3. 把考卷丟給 ChatGPT 大腦 (llm)
# 4. 把大腦想出來的答案,過濾成純文字 (output_parser)
rag_chain = (
{"context": retriever, "question": RunnablePassthrough()}
| custom_prompt
| llm
| output_parser
)
# ==========================================
# 步驟 5:開始實戰測試!
# ==========================================
question = "請問水星冰箱的保固是幾年?極速電風扇呢?"
print(f"\n🙋♂️ 客人問:{question}")
print("🤖 AI 客服正在查閱內部文件思考中...\n")
# 呼叫 invoke(),這條鎖鏈就會瞬間跑完上面 4 個步驟!
answer = rag_chain.invoke(question)
print(f"✅ AI 回答:\n{answer}")
# 執行系統
build_rag_system()
當你看到終端機印出:
✅ AI 回答:水星牌智慧型冰箱的全機保固為一年。而極速旋風 3000 型電風扇的馬達則獨家提供十年保固。
恭喜你!!你已經成功寫出了一個造價好幾萬元的企業級 AI 客服雛形! 它沒有胡說八道,它完美地找到了資料庫裡的機密小抄,並用極度專業的口吻回答了客人的問題。
在真實的商業世界中,你只要把 docs 替換成上一章我們用 PyPDFLoader 切出來的幾千塊肉丁 (Chunks),這套系統就能瞬間變成一個可以回答一整間公司所有規章制度的「超級知識庫」。
在最後一章,我們將探討 RAG 系統最後一塊拼圖,也是讓它變得更像人類的關鍵:記憶力 (Memory) 與 思考代理人 (Agents)!