一、拋磚引玉
經過一段時間的接觸,大型語言模型(LLM),展現出了令人驚歎的文本生成、對話和推理能力。它們飽讀詩書、才華橫溢,能夠就幾乎任何話題進行流暢的對話。然而,這個天才有一個致命的弱點:它的知識完全來源於其訓練數據,存在截止日期,並且它有時會為了保持對話的流暢性而“捏造”事實。這種現象在AI領域被稱為“幻覺”或“胡説八道”。想象一下,你結合實際問了一個問題,最新的員工報銷政策是什麼,LLM可能會根據它訓練時學到的通用財務知識,生成一個看似合理但完全錯誤的答案,因為它根本“不知道”你們公司今年剛修改的具體規定,這種幻覺在醫療、法律、金融等高風險領域是絕對不可接受的。
正是為了解決這一核心問題,RAG技術應運而生。它本質上是一種為LLM“賦能”的框架,讓其能夠從外部、權威、最新的知識源中獲取信息,並基於這些真實信息生成答案,從而大幅提高回答的準確性和可靠性。
二、什麼是RAG
RAG,全稱為Retrieval-Augmented Generation,即“檢索增強生成”,是檢索、增強、生成的完美融合。我們可以將其拆解為三個關鍵步驟來理解:
- 檢索: 當用户提出一個問題時,系統不會直接讓LLM回答。而是首先將這個問題的核心語義,在一個預先設定好的外部知識庫(如公司文檔、產品手冊、最新網頁文章等)中進行搜索,找到與問題最相關的文檔片段。
- 增強: 將這些檢索到的、包含真實信息的文檔片段,與用户的原始問題“打包”在一起,組合成一個新的、內容更豐富的“提示”。這個過程相當於為LLM提供了答題的參考資料。
- 生成: 最後,將這個增強了背景信息的提示發送給LLM,LLM基於這些可靠的參考資料,生成最終答案。
一個簡單的類比:閉卷考試 vs 開卷考試
- 傳統LLM(無RAG): 像一場閉卷考試。模型只能依靠自己記憶(訓練數據)中的知識來答題。一旦題目超出它的記憶範圍或記憶模糊,它就可能會猜錯或編造。
- RAG+LLM: 像一場開卷考試。允許模型在答題時先去查閲指定的、權威的參考資料(外部知識庫),然後基於這些資料組織答案。這樣得出的答案自然更準確、有據可循。
相比於另一種更新模型知識的方法——“微調”,RAG無需昂貴的重新訓練成本,可以實時更新知識庫,且答案的可追溯性更強,能知道答案來源於哪份文檔,因此在實踐中更具靈活性和成本效益。
三、RAG的核心組件
- 檢索器: 通常由嵌入模型和向量數據庫構成。嵌入模型負責將文本(無論是用户問題還是知識庫文檔)轉換為數學意義上的向量,即一長串數字,這個向量可以代表文本的語義。向量數據庫則存儲了所有知識庫文檔的向量。檢索的本質就是在這個向量空間中,快速找到與問題向量最相似的文檔向量。
- 生成器: 即大型語言模型本身,它的角色是根據提供的資料“撰寫”答案。
四、RAG的工作流程
- 知識庫預處理: 首先,將外部知識源(如PDF、Word、網頁)進行分塊,通過嵌入模型轉換為向量,並存入向量數據庫。這一步是離線完成的。
- 用户提問: 用户提出一個問題,例如:“我們公司2024年的帶薪年假政策有什麼變化?”
- 檢索相關文檔: 系統使用相同的嵌入模型將用户問題轉換為向量,然後在向量數據庫中進行相似度搜索,找出最相關的幾個文檔片段(例如,《2024年人力資源政策更新V2.0》中的具體條款)。
- 增強提示: 系統將這些檢索到的文檔片段和用户問題組合成一個結構化的提示,例如:
“請嚴格根據以下參考資料回答問題: [參考資料開始]
文檔1:... 自2024年1月1日起,員工帶薪年假天數將根據司齡計算:1-3年增至7天,3-5年增至10天...
[參考資料結束]
問題:我們公司2024年的帶薪年假政策有什麼變化?” - 生成答案: LLM接收到這個增強後的提示,它會嚴格遵守參考資料的內容生成答案:“根據公司2024年最新政策,帶薪年假天數有所增加。具體變化為:司齡1-3年的員工,年假天數增至7天;司齡3-5年的員工,年假天數增至10天...” 這樣生成的答案不僅準確,還能註明來源,極大提升了可信度。
原理流程圖:
流程分析:
上述流程可以清晰地分為兩個主要階段:離線處理(知識庫構建)和在線處理(用户查詢應答)。
階段一:離線處理 - 知識庫構建
此階段是準備工作,將原始知識源處理成可供快速檢索的向量數據庫,通常只需執行一次或在知識更新時重複執行。
1. 原始文檔加載
從各種來源(如公司內部的PDF手冊、Word文檔、官網網頁、Markdown文件等)加載原始文本數據。例如一家電商公司希望構建一個客服機器人,它加載了《退貨政策文檔》、《配送範圍説明》、《最新促銷活動頁面》和《常見問題解答(FAQ)》作為其知識源。
2. 文檔分割
使用文本分割器(如 RecursiveCharacterTextSplitter)將長文檔切割成較小的、語義完整的“塊”(chunks)。這是因為大語言模型(LLM)和嵌入模型都有輸入長度限制,且小塊信息更利於精準檢索。例如一篇長達10頁的《退貨政策》被分割成多個小塊,例如“7天無理由退貨條件”、“退貨物流流程”、“退款到賬時間”等獨立的段落。
3. 文本向量化 (Embedding)
使用嵌入模型(Embedding Model)將每個文本塊轉換為一個高維向量(即一組數字)。這個向量代表了文本的語義信息。語義相似的文本,其向量在空間中的距離也更近。例如文本塊“退款通常需要1-7個工作日到賬”和“請問我的退款多久可以到銀行卡?”這兩個語義相似的句子,經過嵌入模型轉換後,它們的向量在數學空間中的“距離”會非常近。
4. 存入向量數據庫
將所有文本塊對應的向量以及原始的文本內容,存儲到專門的向量數據庫(如FAISS、Chroma、Pinecone)中。這種數據庫針對“近似最近鄰(ANN)”搜索進行了優化,能快速找到相似的向量。例如將所有關於退貨、配送、促銷的文本塊向量存入數據庫,構建成一個專屬於該電商公司的“知識大腦”。
階段二:在線處理 - 用户查詢應答
此階段是實時響應用户查詢的流程,每次用户提問都會觸發以下步驟。
1. 用户輸入問題 (Query)
用户提出一個自然語言問題。例如用户問:“請問商品破損了,如何申請退貨?”
2. 問題向量化 (Query Embedding)
使用同一個嵌入模型將用户的問題也轉換為一個向量。例子:將“商品破損了,如何申請退貨?”轉換為一個向量。這個向量會與向量數據庫中所有關於“破損退貨”的文本塊向量很相似。
3. 語義相似度檢索
在向量數據庫中進行相似度搜索(計算餘弦相似度或歐氏距離),尋找與“問題向量”最相似的“文本塊向量”(通常返回前k個,如前3個)。這一步是RAG的核心,它找到了回答問題最相關的原始材料。例如系統檢索到最相關的文本塊是:《退貨政策》中的“商品破損退貨流程”段落和FAQ中的“如何處理運輸途中損壞的商品”。
4. 構建增強提示
將檢索到的多個相關文本塊(作為上下文背景)與用户的原始問題組合成一個新的、內容豐富的提示(Prompt),併發送給大語言模型(LLM)。這是“增強”的關鍵一步。例如組合成的提示可能看起來像這樣:
“請嚴格根據以下背景信息回答問題:
[背景信息開始]
如收到商品破損,請拍攝破損部位照片,在訂單頁面提交退貨申請並上傳照片,審核通過後客服將聯繫您安排上門取件。
運輸途中損壞的商品可全額退款,無需承擔退回運費。
[背景信息結束]
問題:請問商品破損了,如何申請退貨?”
5. 生成最終答案
LLM接收到這個“增強後”的提示,它會嚴格遵守提供的背景信息來組織語言,生成一個準確、可靠且流暢的自然語言答案。因為它有了“參考資料”,所以極大地避免了幻覺。
針對上一部的問題,LLM可能生成:
“1. 如果您收到的商品有破損,請按以下步驟操作:
2. 拍攝清晰的商品破損部位照片。
3. 登錄您的賬户,找到相應訂單,提交退貨申請。
4. 在申請中上傳破損照片以供審核。
5. 審核通過後,我們的客服會聯繫您安排免費上門取件服務。您無需支付退回運費。”
(答案完全來源於知識庫,且格式清晰)
6. 輸出答案
將LLM生成的答案返回給用户,完成一次查詢。
通過這個流程,RAG成功地將大語言模型的強大生成能力與外部知識源的準確性、實時性結合了起來,既利用了LLM的理解和表達能力,又將其“框定”在可靠的信息範圍內,從而生產出既流暢又可信的答案。
五、基於RAG的問答系統
下面我們實現一個基於RAG的問答系統,結合前期的知識點,使用了阿里千問模型(qwen-max)作為生成模型,使用ModelScope的嵌入模型(damo/nlp_corom_sentence-embedding_chinese-base)來生成文本的向量表示,處理文本向量化,並使用FAISS作為向量數據庫進行高效相似性檢索,從而實現完整的RAG流程:文檔處理→向量化→檢索→增強提示→生成回答;
代碼示例:
import os
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain_community.vectorstores import FAISS # 使用FAISS替代Chroma
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import TextLoader
from langchain_core.prompts import ChatPromptTemplate
from langchain.schema import Document
from typing import List
import requests
import json
import dashscope
from dashscope import Generation
from modelscope import snapshot_download
from modelscope.models import Model
from modelscope.pipelines import pipeline
from modelscope.utils.constant import Tasks
# 配置阿里千問模型
class QwenLLM:
def __init__(self):
# 設置阿里雲API密鑰
self.api_key = os.environ["DASHSCOPE_API_KEY"] # 從環境變量獲取API密鑰
dashscope.api_key = self.api_key # 設置dashscope的API密鑰
def invoke(self, prompt: str) -> str:
try:
# 調用阿里千問大模型API生成回答
response = Generation.call(
model="qwen-max", # 使用千問最大模型
prompt=prompt, # 傳入提示詞
temperature=0.1, # 低温度值使輸出更確定性
top_p=0.9, # 核採樣參數,控制生成多樣性
result_format='message' # 返回消息格式
)
# 檢查響應狀態
if response.status_code == 200:
return response.output.choices[0].message.content # 返回模型生成的內容
else:
return f"請求失敗: {response.message}" # 返回錯誤信息
except Exception as e:
return f"請求異常: {str(e)}" # 返回異常信息
# 從ModelScope下載並使用嵌入模型
class ModelScopeEmbeddings:
def __init__(self, model_name="damo/nlp_corom_sentence-embedding_chinese-base"):
# 從ModelScope下載中文句子嵌入模型
self.model_dir = snapshot_download(model_name, cache_dir='D:\modelscope\hub\models')
print(f"模型已下載到: {self.model_dir}")
# 使用HuggingFaceEmbeddings包裝ModelScope模型,使其兼容LangChain
self.embeddings = HuggingFaceEmbeddings(
model_name=self.model_dir, # 使用下載的模型路徑
model_kwargs={'device': 'cpu'}, # 指定使用CPU設備
encode_kwargs={'normalize_embeddings': True} # 對嵌入向量進行歸一化
)
def embed_documents(self, texts: List[str]) -> List[List[float]]:
"""將文檔列表轉換為嵌入向量"""
return self.embeddings.embed_documents(texts)
def embed_query(self, text: str) -> List[float]:
"""將查詢文本轉換為嵌入向量"""
return self.embeddings.embed_query(text)
# 初始化RAG系統
def setup_rag_system(knowledge_texts: List[str]):
# 1. 文本分割 - 將長文本分割成適合處理的小塊
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500, # 每個文本塊的最大字符數
chunk_overlap=50, # 塊之間的重疊字符數,保持上下文連貫
length_function=len # 使用Python內置len函數計算長度
)
# 創建文檔對象
documents = []
for i, text in enumerate(knowledge_texts):
docs = text_splitter.split_text(text) # 分割文本
for doc in docs:
# 創建LangChain文檔對象,包含內容和元數據
documents.append(Document(page_content=doc, metadata={"source": f"doc_{i}"}))
# 2. 初始化ModelScope嵌入模型
embeddings = ModelScopeEmbeddings()
# 3. 創建FAISS向量數據庫 - 高效的相似性搜索庫
vectorstore = FAISS.from_documents(
documents=documents, # 文檔列表
embedding=embeddings.embeddings # 嵌入模型
)
return vectorstore, embeddings # 返回向量存儲和嵌入模型
# 構建RAG鏈
def create_rag_chain(vectorstore, embeddings):
# 創建檢索器 - 用於從向量庫中搜索相關文檔
retriever = vectorstore.as_retriever(
search_type="similarity", # 使用相似性搜索
search_kwargs={"k": 3} # 返回最相關的3個文檔
)
# 定義提示模板 - 指導模型如何基於上下文回答問題
template = """
你是一個專業的助手,請根據以下背景信息回答問題。
背景信息:
{context}
問題:{question}
請根據背景信息提供準確、簡潔的回答。如果背景信息中沒有相關答案,請如實告知。
"""
prompt = ChatPromptTemplate.from_template(template) # 創建提示模板
# 創建RAG處理函數
def rag_chain(question: str) -> str:
# 檢索相關文檔 - 基於問題查找最相關的文檔片段
relevant_docs = retriever.invoke(question)
# 合併檢索到的文檔內容作為上下文
context = "\n\n".join([doc.page_content for doc in relevant_docs])
# 構建提示 - 將上下文和問題填入模板
formatted_prompt = prompt.invoke({
"context": context,
"question": question
})
# 調用千問模型生成回答
qwen_llm = QwenLLM()
response = qwen_llm.invoke(str(formatted_prompt))
return response, context # 返回模型回答和使用的上下文
return rag_chain # 返回RAG處理函數
# 示例知識庫數據
knowledge_data = [
"""
人工智能發展趨勢:2024年,生成式AI技術將繼續快速發展,多模態能力成為重點。
企業應用AI的主要方向包括智能客服、內容生成、數據分析等。深度學習和神經網絡
技術不斷突破,大模型參數規模持續增長。
""",
"""
公司規章制度:員工工作時間為每週5天,每天8小時。年假根據工齡計算,1-3年員工
享有5天年假,3-5年員工享有10天年假。所有員工需要遵守保密協議,不得泄露公司
商業秘密和技術信息。
""",
"""
產品介紹:我司主要產品包括智能客服系統、企業知識管理平台和AI內容生成工具。
智能客服系統支持多渠道接入,能夠自動回答常見問題,提升客户服務效率。知識管理
平台幫助企業構建專屬知識庫,實現知識的集中管理和智能檢索。
"""
]
# 初始化RAG系統
print("正在初始化RAG系統...")
vectorstore, embeddings = setup_rag_system(knowledge_data)
rag_chain = create_rag_chain(vectorstore, embeddings)
# 進行問答測試
questions = [
"公司的年假政策是怎樣的?",
"智能客服系統有哪些功能?",
"2024年AI發展趨勢是什麼?"
]
for question in questions:
print(f"\n問題:{question}")
answer, context = rag_chain(question)
print(f"答案:{answer}")
print(f"檢索到的上下文:{context[:100]}...") # 只顯示前100個字符
代碼結構説明:
1. 導入必要的庫。
2. 定義QwenLLM類:用於調用阿里千問模型生成答案。
3. 定義ModelScopeEmbeddings類:從ModelScope下載嵌入模型,並用HuggingFaceEmbeddings進行包裝,處理中文文本嵌入,將文本轉換為向量表示。
4. setup_rag_system函數:處理知識庫文本,分割文本,初始化嵌入模型,創建FAISS向量數據庫。初始化RAG系統,處理文檔分割和向量庫構建。
5. create_rag_chain函數:創建RAG鏈,包括檢索器、提示模板和調用千問模型生成答案的函數。完整的RAG處理流水線。
6. 示例知識庫數據:包含三個方面的文本。
7. 初始化RAG系統並進行問答測試。
注意:代碼中使用了阿里雲的dashscope庫調用千問模型,需要設置DASHSCOPE_API_KEY環境變量。
- 代碼執行會先下載指定模型
運行結果:
正在初始化RAG系統...
Downloading Model from https://www.modelscope.cn to directory: D:\modelscope\hub\models\damo\nlp_corom_sentence-embedding_chinese-base
2025-08-29 15:09:10,402 - modelscope - WARNING - Model revision not specified, use revision: v1.1.0
模型已下載到: D:\modelscope\hub\models\damo\nlp_corom_sentence-embedding_chinese-base
問題:公司的年假政策是怎樣的?
答案:根據公司規章制度,年假政策如下:
- 工齡在1至3年的員工享有5天年假。
- 工齡在3至5年的員工享有10天年假。
檢索到的上下文:公司規章制度:員工工作時間為每週5天,每天8小時。年假根據工齡計算,1-3年員工
享有5天年假,3-5年員工享有10天年假。所有員工需要遵守保密協議,不得泄露公司
商業秘密和技術信息。...
問題:智能客服系統有哪些功能?
答案:根據背景信息,智能客服系統的主要功能包括:
- **多渠道接入**:支持通過多種溝通渠道(如網站、社交媒體等)與客户進行互動。
- **自動回答常見問題**:能夠識別並自動回覆客户的常見諮詢,提高服務效率。
這些功能旨在提升客户服務體驗的同時,也幫助企業更高效地管理客户關係。
檢索到的上下文:產品介紹:我司主要產品包括智能客服系統、企業知識管理平台和AI內容生成工具。
智能客服系統支持多渠道接入,能夠自動回答常見問題,提升客户服務效率。知識管理
平台幫助企業構建專屬知識庫,...
問題:2024年AI發展趨勢是什麼?
答案:2024年AI發展趨勢主要體現在生成式AI技術的持續快速發展上,其中多模態能力成為重點發展方向。同時,深度學習和神經網絡技術
也將不斷取得新突破,大模型的參數規模會繼續增長。這些技術進步將推動企業在智能客服、內容生成、數據分析等領域的應用更加廣泛和
深入。
檢索到的上下文:人工智能發展趨勢:2024年,生成式AI技術將繼續快速發展,多模態能力成為重點。
企業應用AI的主要方向包括智能客服、內容生成、數據分析等。深度學習和神經網絡
技術不斷突破,大模型參數...
六、RAG的應用場景
- 智能客服與問答機器人:電商、SaaS企業的客服系統。
- 企業知識庫管理:任何擁有大量內部文檔(操作手冊、規章制度、項目報告)的大中型企業。
- 內容創作與市場研究:市場分析師、內容寫手。可以讓RAG系統先從最新的行業報告、財經新聞、財報電話會議記錄中檢索相關信息。LLM基於這些新鮮出爐的數據,幫助他生成一份論據充分、數據翔實的文章大綱或初稿,極大提升了研究效率和內容質量。
- 教育與個性化學習:在線教育平台,RAG系統可以從教科書、相對論科普文章、教學視頻講義等多樣化資料中檢索出最適合該學生理解水平的解釋,然後讓LLM整合成一個深入淺出的答案,從而實現因材施教。
七、總結
RAG技術通過巧妙地結合信息檢索與大型語言模型,為解決LLM的“幻覺”問題提供了一條高效且實用的路徑。它極大地增強了AI在專業和實時領域應用的可靠性和可信度,是AI真正融入企業核心工作流的關鍵一步。
但RAG技術仍面臨一些挑戰和發展方向,如何更精準地找到最相關的片段、處理複雜多步問題的能力,簡化多輪檢索、多模態RAG,不僅能處理文本,還能理解圖片、表格中的信息,以及溯源驗證,如何更直觀地向用户展示答案來源,確保透明度。所以我們廣大的IT工作者,既是指引,也是被指引,技術永遠革新,我們也會持續突破。加油,奧裏給!