嗨嚕~我們今天終於要來打造自己的專屬聊天機器人啦!🤖
這次我會使用自己整理的「烏龜頸」資料作為示範,讓 GPT 能回答與烏龜頸相關的問題。
當然,你也可以換成任何你想要的主題資料,看你想打造什麼樣的聊天機器人都行!(例如健康助理、旅遊小幫手等~都行!)
在螢幕前面的你,請抬頭挺胸 別再烏龜頸🫵🏻
事不宜遲我們改快開始吧!
這次用 Google Colab 示範,你也可以用任何喜歡的編輯器呦~
首先免不了的就是要安裝需要的套件
!pip install -q --upgrade openai langchain langchain-community langchain-openai chromadb
引入必要的套件
import os
from google.colab import userdata
from openai import OpenAI
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings
大家還記得前天文章中有教大家如何申請OpenAI 帳好以及創建API 嗎~
我們要先驗證我們的API,之後我們使用模型都會是透過這個API來呼叫模型喔!
os.environ["OPENAI_API_KEY"] = userdata.get("OPENAI_API_KEY")
client = OpenAI()
這樣就驗證完成嚕
💡 這邊的 API Key 是儲存在 Colab 裡的 Secrets,不會顯示在程式碼中,這樣可以避免金鑰外洩喔!
還記得我們昨天有提到RAG 的概念嗎?
因為模型本身有一些限制,所以我們需要給他額外的資料讓他可以根據這些資料去回應,昨天也有提到,基本的RAG 會有三個步驟:
把長文件切成有chunks
把 chunks 轉成 embeddings,存到向量資料庫
依照使用者問題檢索最相關片段,連同問題一起丟給模型
那我們就來一步ㄧ步來看吧!
RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(
separators=["\n\n", "\n", " ", ""],#按照什麼做切分
chunk_size=300,#一個chunck 的大小為何
chunk_overlap=80, #每個chunck之間有多少overlap
)
docs = text_splitter.create_documents([text])
#這邊我們設定要以"相似度"抓回資料,並抓回前4筆最相關的資訊
retriever = db.as_retriever(search_type="similarity", search_kwargs={"k": 4})
persist_dir = "chroma_store_turtleneck"
embeddings = OpenAIEmbeddings()
db = Chroma.from_documents(
documents=docs,
embedding=embeddings,
persist_directory=persist_dir
)
db.persist()
我們這邊是把切分後的文字區塊轉換成向量(embedding),再把這些向量儲存在 Chroma 向量資料庫中,Chroma 是一個專門用來儲存文字向量及其原始內容的資料庫,方便之後根據相似度進行檢索。LangChain還有支援許多不同的向量資料庫(像 FAISS、Pinecone、Weaviate 等),有興趣的朋友可以自己去試試看!
我們前置作業已經完成惹!再來我們寫一個簡易 RAG function,讓他可以先檢索最相關的文字片段,再把片段與使用者問題一併送進模型產生回覆!
def rag_answer(question: str, model_name: str = "gpt-5"):
# 檢索
top_docs = retriever.get_relevant_documents(question)
if not top_docs:
return "目前在知識庫中找不到相關內容,請換個說法或提供更多線索。"
context_text = "\n---\n".join([d.page_content for d in top_docs]) #將檢索到的內容全部合併
#告訴模型需要拿檢索到的資訊生成回應
system_prompt = (
f"你是一位謹慎的助理。請只用檢索到的{context_text}與你的常識,"
"回答使用者的問題。若片段沒有提到,請誠實告知。避免捏造。"
"必要時可用條列給出要點。"
)
user_content = (
f"使用者問題:{question}\n\n"
"請根據以上資訊與你的常識回答問題"
)
resp = client.chat.completions.create(
model=model_name,
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_content},
],
)
return resp.choices[0].message.content
在我們的文字檔裡,有提到「王美珠是烏龜頸的代表人物」,所以如果要問烏龜頸代表人物有誰,模型必須從我們提供的文件中去找到這則訊息才能回覆,那我們就來測試看看它能不能順利回答吧!
query = "烏龜頸代表人物是誰?"
print(rag_answer(query))
輸出答案
王美珠。
將將~~~範例中我們可以看到模型成功結合外部資訊(烏龜頸的內容)和它自己的知識,完美回答了使用者的問題!是不是超讚~
今天的範例只是拿一個簡單的文字檔來示範,讓大家先感受一下 RAG的概念以及它的強大,而在實際案例中,許多公司都希望擁有自己的聊天機器人,能回答員工或客戶的問題,這時候,資料來源就會是公司內部的資訊,而資訊可能不是存成txt檔,可能是pdf、excel 等,我們今天雖然只有示範如何除理文字檔,但其實任何檔案都可以處理喔!只是方式會稍稍不同~
而至於要怎麼做出一個完美的RAG系統,你可以從範例程式碼當中看到,從切chunk的方式、要選用哪個向量資料庫、應該用什麼方式取回相關訊息,這些都可以依照自己的資料型態與需求去客製化調整,所以,只要你理解了 RAG 的基本流程,你就能打造出屬於自己(或公司專用)的智慧助理啦~
好啦!那就讓各位自己玩玩看嚕!掰噗