DeepSeek R1與Qwen大模型,構建Agentic RAG全攻略
最近,AI社區(qū)被 DeepSeek-R1 “刷屏” 了!作為一款極具變革意義的開源推理大語言模型(LLM),大家討論最多的是它的基礎能力,卻鮮有人關注其在智能體工作流程中的巨大潛力,也就是多個模型動態(tài)協(xié)作的應用場景。
今天,就帶大家實操搭建一個智能體檢索增強生成(RAG,Retrieval-Augmented Generation)系統(tǒng)。這個系統(tǒng)整合了:
- DeepSeek-R1(70億參數(shù)蒸餾版):用于復雜推理,系統(tǒng)的 “智慧大腦”。。
- 阿里云Qwen2.5(70億參數(shù)):主打快速對話交互,讓用戶交流體驗更流暢。
- 輕量級智能體框架:協(xié)調前兩者,保障系統(tǒng)高效運轉。
完成搭建后,Qwen 會處理常規(guī)交互,復雜查詢則交給R1。接下來動手試試!
1 設置環(huán)境
1.1 設置虛擬環(huán)境并安裝依賴項
python3 -m venv .envs/agentic-ai
source .envs/agentic-ai/bin/activate
mkdir agentic-ai
cd agentic-ai
pip install langchain langchain-huggingface langchain-community pypdf langchain_chroma
pip install chromadb smolagents python-dotenv gradio sentence-transformers
pip 'install smolagents[openai]'
1.2 配置Ollama
DeepSeek的第一代推理模型性能可與OpenAI-o1媲美,其中包括基于Llama和Qwen從DeepSeek-R1蒸餾得到的6個密集模型。
Qwen 2.5模型在阿里巴巴最新的大規(guī)模數(shù)據(jù)集上進行預訓練,該數(shù)據(jù)集包含多達18萬億個標記。該模型支持多達12.8萬個標記,并具備多語言能力。
下載模型:
ollama pull deepseek-r1:7b
ollama pull qwen2.5:7b-instruct
增加上下文窗口:
Ollama默認的2048個標記不夠用。創(chuàng)建自定義模型文件??deepseek-r1-7b-8k.Modelfile?
??和??qwen2.5-7b-instruct-8k.Modelfile?
?:
$ cat deepseek-r1-7b-8k.Modelfile
FROM deepseek-r1:7b
PARAMETER num_ctx 8192
$ cat qwen2.5-7b-instruct-8k.Modelfile
FROM qwen2.5:7b-instruct
PARAMETER num_ctx 8192
ollama create deepseek-r1-7b-8k -f ./deepseek-r1-7b-8k.Modelfile
ollama create qwen2.5:7b-instruct-8k -f ./qwen2.5-7b-instruct-8k.Modelfile
2 創(chuàng)建知識庫
2.1 添加文檔
將PDF文件放在??data/?
??目錄下,這些文件將構成知識庫的基礎。使用LangChain的??DirectoryLoader?
??加載PDF文件,并使用??RecursiveCharacterTextSplitter?
?將其拆分為較小的塊,以便進行高效的索引和檢索。這樣能確保內容以結構化方式處理,更便于查詢和管理。
from langchain_community.document_loaders import DirectoryLoader, PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_huggingface import HuggingFaceEmbeddings
from langchain_community.vectorstores import Chroma
import os
import shutil
def load_and_process_pdfs(data_dir: str):
"""從目錄加載PDF并拆分為塊。"""
loader = DirectoryLoader(
data_dir,
glob="**/*.pdf",
loader_cls=PyPDFLoader
)
documents = loader.load()
# 將文檔拆分為塊
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200,
length_function=len,
)
chunks = text_splitter.split_documents(documents)
return chunks
2.2 將塊存儲在向量存儲(Chroma)中
將PDF處理并拆分為塊后,存儲在Chroma向量存儲中,以便基于語義相似性進行高效的搜索和檢索。初始化并配置ChromaDB,然后使用Hugging Face Embeddings將每個塊轉換為向量表示,從而實現(xiàn)相關信息的準確快速檢索。
def create_vector_store(chunks, persist_dir: str):
"""創(chuàng)建并持久化Chroma向量存儲。"""
# 如果存在現(xiàn)有向量存儲,則刪除
if os.path.exists(persist_dir):
print(f"正在從 {persist_dir} 刪除現(xiàn)有向量存儲")
shutil.rmtree(persist_dir)
# 初始化HuggingFace嵌入
embedding_model = HuggingFaceEmbeddings(
model_name="sentence-transformers/all-mpnet-base-v2",
model_kwargs={'device': 'cpu'}
)
# 構建并持久化新的Chroma向量存儲
print("正在構建并保存新的向量存儲...")
vector_db = Chroma.from_documents(
documents=chunks,
embedding=embedding_model,
persist_directory=persist_dir
)
return vector_db
2.3 完成知識庫創(chuàng)建
塊已在ChromaDB中建立索引并存儲后,知識庫就可以進行查詢了。運行最后一個代碼塊,加載并處理PDF文件,創(chuàng)建向量存儲,并基于語義相似性實現(xiàn)相關上下文的高效檢索。
def main():
# 定義輸入數(shù)據(jù)和向量數(shù)據(jù)庫的路徑
input_data_dir = os.path.join(os.path.dirname(__file__), "data")
vector_db_dir = os.path.join(os.path.dirname(__file__), "chroma_db")
# 加載PDF并拆分為較小的塊
print("開始處理PDF...")
document_chunks = load_and_process_pdfs(input_data_dir)
print(f"從PDF生成了 {len(document_chunks)} 個文檔塊")
# 構建并存儲向量數(shù)據(jù)庫
print("正在構建向量存儲...")
vector_db = create_vector_store(document_chunks, vector_db_dir)
print(f"向量存儲已成功創(chuàng)建并保存到 {vector_db_dir}")
if __name__ == "__main__":
main()
運行:
$ python ingest_pdfs.py
開始處理PDF...
從PDF生成了312個文檔塊
正在構建向量存儲...
向量存儲已成功創(chuàng)建并保存到./agentic-ai/chroma_db
$ ls chroma_db
chroma.sqlite3 d4c48cab-0467-4ca8-ad42-bafa5eb83040
$
3 構建智能體系統(tǒng)
3.1 定義推理模型(DeepSeek-R1)
在智能體系統(tǒng)里,推理模型是 “心臟”。DeepSeek-R1 作為強大的推理模型,能夠處理復雜查詢。它可解析自然語言,結合知識庫給出連貫且切題的回答,還能理解文檔并提取關鍵知識。將 DeepSeek-R1 和知識庫融合,系統(tǒng)便能依據(jù)向量數(shù)據(jù)庫內容解決問題、回應查詢以及推理。
推理時,DeepSeek-R1 支持多步迭代,不斷優(yōu)化回復,直至得到滿意答案,或達到預設的??max_steps?
?限制,以此確保推理準確又高效,推動智能體系統(tǒng)穩(wěn)定運行。
# reasoning_model.py
from smolagents import OpenAIServerModel, CodeAgent
import os
# 定義本地模型名稱
reasoning_model_id = "deepseek-r1-7b-8k"# 使用DeepSeek進行推理
def get_model(model_id):
"""返回一個Ollama模型。"""
return OpenAIServerModel(
model_id=model_id,
api_base="http://localhost:11434/v1", # Ollama API端點
api_key="ollama"
)
# 使用DeepSeek創(chuàng)建推理模型
reasoning_model = get_model(reasoning_model_id)
# 創(chuàng)建推理智能體
reasoner = CodeAgent(tools=[], model=reasoning_model, add_base_tools=False, max_steps=2)
3.2 創(chuàng)建RAG工具
這一步創(chuàng)建RAG(檢索增強生成)工具,該工具結合信息檢索和推理來回答用戶查詢。該工具利用向量數(shù)據(jù)庫(Chroma)通過嵌入存儲和檢索相關文檔。當用戶提出問題時,該工具會從數(shù)據(jù)庫中搜索最相關的3個文檔。然后,這些文檔將作為上下文,促使推理模型(DeepSeek-R1)生成相關且簡潔的答案。
這種方法通過將文檔檢索與推理相結合,提高了系統(tǒng)提供準確、有上下文感知答案的能力,適用于復雜或定義不明確的查詢。
# rag_tool.py
from langchain_chroma import Chroma
from langchain_huggingface import HuggingFaceEmbeddings
from reasoning_model import reasoner # 從reasoning_model.py導入reasoner
import os
# 初始化向量存儲和嵌入
embeddings = HuggingFaceEmbeddings(
model_name="sentence-transformers/all-mpnet-base-v2",
model_kwargs={'device': 'cpu'}
)
# 向量數(shù)據(jù)庫目錄
db_dir = os.path.join(os.path.dirname(__file__), "chroma_db")
# 初始化向量存儲
vectordb = Chroma(persist_directory=db_dir, embedding_function=embeddings)
def rag_with_reasoner(user_query: str) -> str:
"""
在向量數(shù)據(jù)庫中搜索相關上下文,并使用推理模型生成回復。
參數(shù):
user_query:用戶的問題。
"""
# 檢索相關文檔
docs = vectordb.similarity_search(user_query, k=3)
context = "\n\n".join(doc.page_content for doc in docs)
# 為推理模型創(chuàng)建提示
prompt = f"""根據(jù)以下上下文,簡潔地回答用戶的問題。
如果信息不足,請為RAG提出更好的查詢建議。
上下文:
{context}
問題:{user_query}
答案:"""
# 使用reasoner(DeepSeek-R1)生成回復
response = reasoner.run(prompt, reset=False)
return response
3.3 配置主智能體(Qwen)
主智能體(Qwen)是系統(tǒng)與用戶交互和處理查詢的主要接口。主智能體使用Qwen模型(Qwen-2.5:7b)來解釋用戶輸入,并調用適當?shù)墓ぞ呱苫貜汀?/p>
# primary_agent.py
from smolagents import OpenAIServerModel, ToolCallingAgent
from rag_tool import rag_with_reasoner # 從rag_tool.py導入工具函數(shù)
import os
def get_model(model_id):
"""返回一個Ollama模型。"""
return OpenAIServerModel(
model_id=model_id,
api_base="http://localhost:11434/v1", # Ollama API端點
api_key="ollama"
)
# 加載工具模型(Qwen-2.5:7b)
primary_model = get_model("qwen2.5:7b-instruct-8k")
# 使用Qwen創(chuàng)建主智能體以生成工具回復
primary_agent = ToolCallingAgent(tools=[rag_with_reasoner], model=primary_model, add_base_tools=False, max_steps=3)
# 導出智能體以供應用程序使用
def get_primary_agent():
return primary_agent
主智能體使用??ToolCallingAgent?
??類構建,該類使模型能夠利用特定工具,在本案例中即??rag_with_reasoner?
?工具。該工具從向量數(shù)據(jù)庫中檢索相關文檔,并將其傳遞給推理模型(DeepSeek-R1)以生成回復。智能體配置為最多進行3步推理,確保它根據(jù)提供的上下文迭代并完善答案。
這種設置確保主智能體能夠利用RAG過程,為用戶查詢提供智能且上下文相關的回復,同時控制推理循環(huán)的次數(shù)。它使系統(tǒng)能夠精確高效地處理各種問題。
4 啟動Gradio用戶界面
啟動Gradio用戶界面,使用戶能夠與智能體系統(tǒng)進行交互。Gradio為主智能體創(chuàng)建了一個簡單易用的界面。該界面允許用戶輸入查詢,并接收由推理和RAG工具生成的回復。這一步將后端功能與可視化界面連接起來,使系統(tǒng)對用戶來說可訪問且具有交互性。
# app.py
from primary_agent import get_primary_agent
from smolagents import GradioUI
# 從primary_agent.py獲取主智能體
primary_agent = get_primary_agent()
# 啟動界面的主函數(shù)
def main():
GradioUI(primary_agent).launch()
if __name__ == "__main__":
main()
運行:
$ python app.py
* 正在本地URL運行:http://127.0.0.1:7860
5 工作原理
- 用戶輸入:用戶在Gradio界面提交問題,開啟交互流程。
- Qwen決策:作為主智能體的Qwen迅速判斷,簡單問題直接作答;復雜問題則調用RAG工具。
- RAG工具運作:RAG工具從ChromaDB檢索相關上下文,將分析任務委托給DeepSeek-R1。
- 生成回復:DeepSeek-R1生成見解,Qwen將其整合,給出最終回復。
6 改進方向
- 回退邏輯:當DeepSeek-R1置信度低時,自動觸發(fā)網(wǎng)絡搜索,補充信息。
- 多跳查詢:智能體可迭代優(yōu)化查詢,提升復雜問題處理能力。
- LangGraph集成:構建復雜工作流程,實現(xiàn)高效狀態(tài)管理。
7 架構優(yōu)勢與展望
本系統(tǒng)由Qwen和DeepSeek-R1協(xié)同工作,Qwen保障速度,DeepSeek-R1提供深度。這種架構帶來了明顯優(yōu)勢:
- 效率:DeepSeek-R1僅處理復雜查詢,資源利用高效。
- 靈活性:可輕松更換模型,如采用Llama-3作為主模型。
- 可擴展性:便于添加網(wǎng)絡搜索、計算器等工具。
智能體時代已經(jīng)來臨,快基于此架構,構建更多創(chuàng)新應用吧!
本文轉載自 ??AI科技論談??,作者: AI科技論談
