smolagents 文件
Agentic RAG
並獲得增強的文件體驗
開始使用
Agentic RAG
檢索增強生成 (RAG) 簡介
檢索增強生成 (RAG) 將大型語言模型的能力與外部知識檢索相結合,以產生更準確、真實和上下文相關的響應。RAG 的核心是“使用 LLM 回答使用者查詢,但答案基於從知識庫中檢索到的資訊。”
為何使用 RAG?
與使用普通或微調 LLM 相比,RAG 具有顯著優勢:
- 事實依據:透過將響應錨定在檢索到的事實中來減少幻覺。
- 領域專業化:無需模型再訓練即可提供領域特定知識。
- 知識時效性:允許訪問超出模型訓練截止日期的資訊。
- 透明度:能夠引用生成內容的來源。
- 控制:對模型可以訪問的資訊提供精細控制。
傳統 RAG 的侷限性
儘管有其優點,但傳統 RAG 方法面臨一些挑戰:
- 單次檢索步驟:如果初始檢索結果不佳,最終生成也會受到影響。
- 查詢-文件不匹配:使用者查詢(通常是問題)可能與包含答案(通常是陳述)的文件不匹配。
- 有限推理:簡單的 RAG 管道不允許進行多步推理或查詢最佳化。
- 上下文視窗限制:檢索到的文件必須在模型的上下文視窗內。
代理 RAG:一種更強大的方法
我們可以透過實現一個**代理 RAG** 系統來克服這些限制——本質上是一個配備檢索功能的代理。這種方法將 RAG 從僵硬的管道轉變為互動式、推理驅動的過程。
代理 RAG 的主要優勢
配備檢索工具的代理可以:
- ✅ 制定最佳化的查詢:代理可以將使用者問題轉換為適合檢索的查詢。
- ✅ 執行多次檢索:代理可以根據需要迭代檢索資訊。
- ✅ 對檢索內容進行推理:代理可以分析、綜合並從多個來源得出結論。
- ✅ 自我批評和完善:代理可以評估檢索結果並調整其方法。
這種方法自然地實現了高階 RAG 技術:
構建代理 RAG 系統
讓我們一步步構建一個完整的代理 RAG 系統。我們將建立一個代理,透過從 Hugging Face Transformers 庫的文件中檢索資訊來回答有關該庫的問題。
您可以跟著下面的程式碼片段進行操作,也可以檢視 smolagents GitHub 倉庫中的完整示例:examples/rag.py。
步驟 1:安裝必要的依賴項
首先,我們需要安裝必要的軟體包:
pip install smolagents pandas langchain langchain-community sentence-transformers datasets python-dotenv rank_bm25 --upgrade
如果您打算使用 Hugging Face 的推理 API,則需要設定您的 API 令牌。
# Load environment variables (including HF_TOKEN)
from dotenv import load_dotenv
load_dotenv()
步驟 2:準備知識庫
我們將使用包含 Hugging Face 文件的資料集,並將其準備好進行檢索。
import datasets
from langchain.docstore.document import Document
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.retrievers import BM25Retriever
# Load the Hugging Face documentation dataset
knowledge_base = datasets.load_dataset("m-ric/huggingface_doc", split="train")
# Filter to include only Transformers documentation
knowledge_base = knowledge_base.filter(lambda row: row["source"].startswith("huggingface/transformers"))
# Convert dataset entries to Document objects with metadata
source_docs = [
Document(page_content=doc["text"], metadata={"source": doc["source"].split("/")[1]})
for doc in knowledge_base
]
# Split documents into smaller chunks for better retrieval
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500, # Characters per chunk
chunk_overlap=50, # Overlap between chunks to maintain context
add_start_index=True,
strip_whitespace=True,
separators=["\n\n", "\n", ".", " ", ""], # Priority order for splitting
)
docs_processed = text_splitter.split_documents(source_docs)
print(f"Knowledge base prepared with {len(docs_processed)} document chunks")
步驟 3:建立檢索器工具
現在,我們將建立一個自定義工具,我們的代理可以使用它從知識庫中檢索資訊。
from smolagents import Tool
class RetrieverTool(Tool):
name = "retriever"
description = "Uses semantic search to retrieve the parts of transformers documentation that could be most relevant to answer your query."
inputs = {
"query": {
"type": "string",
"description": "The query to perform. This should be semantically close to your target documents. Use the affirmative form rather than a question.",
}
}
output_type = "string"
def __init__(self, docs, **kwargs):
super().__init__(**kwargs)
# Initialize the retriever with our processed documents
self.retriever = BM25Retriever.from_documents(
docs, k=10 # Return top 10 most relevant documents
)
def forward(self, query: str) -> str:
"""Execute the retrieval based on the provided query."""
assert isinstance(query, str), "Your search query must be a string"
# Retrieve relevant documents
docs = self.retriever.invoke(query)
# Format the retrieved documents for readability
return "\nRetrieved documents:\n" + "".join(
[
f"\n\n===== Document {str(i)} =====\n" + doc.page_content
for i, doc in enumerate(docs)
]
)
# Initialize our retriever tool with the processed documents
retriever_tool = RetrieverTool(docs_processed)
我們使用 BM25,一種詞彙檢索方法,以簡化和提高速度。對於生產系統,您可能需要使用帶有嵌入的語義搜尋,以獲得更好的檢索質量。請檢視 MTEB 排行榜以獲取高質量的嵌入模型。
步驟 4:建立高階檢索代理
現在,我們將建立一個可以使用我們的檢索工具回答問題的代理。
from smolagents import InferenceClientModel, CodeAgent
# Initialize the agent with our retriever tool
agent = CodeAgent(
tools=[retriever_tool], # List of tools available to the agent
model=InferenceClientModel(), # Default model "Qwen/Qwen2.5-Coder-32B-Instruct"
max_steps=4, # Limit the number of reasoning steps
verbosity_level=2, # Show detailed agent reasoning
)
# To use a specific model, you can specify it like this:
# model=InferenceClientModel(model_id="meta-llama/Llama-3.3-70B-Instruct")
推理提供商允許訪問數百個模型,這些模型由無伺服器推理合作伙伴提供支援。支援的提供商列表可以在這裡找到。
步驟 5:執行代理回答問題
讓我們使用我們的代理來回答一個關於 Transformers 的問題。
# Ask a question that requires retrieving information
question = "For a transformers model training, which is slower, the forward or the backward pass?"
# Run the agent to get an answer
agent_output = agent.run(question)
# Display the final answer
print("\nFinal answer:")
print(agent_output)
代理 RAG 的實際應用
代理 RAG 系統可應用於各種用例:
- 技術文件輔助:幫助使用者瀏覽複雜的技術文件。
- 研究論文分析:從科學論文中提取和綜合資訊。
- 法律檔案審查:在法律檔案中查詢相關的判例和條款。
- 客戶支援:根據產品文件和知識庫回答問題。
- 教育輔導:根據教科書和學習材料提供解釋。
結論
代理 RAG 代表了對傳統 RAG 管道的重大進步。透過將 LLM 代理的推理能力與檢索系統的事實依據相結合,我們可以構建更強大、更靈活、更準確的資訊系統。
我們演示的方法:
- 克服了單步檢索的侷限性。
- 實現了與知識庫更自然的互動。
- 透過自我批評和查詢最佳化提供了一個持續改進的框架。
在構建自己的代理 RAG 系統時,請考慮嘗試不同的檢索方法、代理架構和知識來源,以找到最適合您特定用例的最佳配置。
< > 在 GitHub 上更新