smolagents 文件

Agentic RAG

Hugging Face's logo
加入 Hugging Face 社群

並獲得增強的文件體驗

開始使用

Agentic RAG

檢索增強生成 (RAG) 簡介

檢索增強生成 (RAG) 將大型語言模型的能力與外部知識檢索相結合,以產生更準確、真實和上下文相關的響應。RAG 的核心是“使用 LLM 回答使用者查詢,但答案基於從知識庫中檢索到的資訊。”

為何使用 RAG?

與使用普通或微調 LLM 相比,RAG 具有顯著優勢:

  1. 事實依據:透過將響應錨定在檢索到的事實中來減少幻覺。
  2. 領域專業化:無需模型再訓練即可提供領域特定知識。
  3. 知識時效性:允許訪問超出模型訓練截止日期的資訊。
  4. 透明度:能夠引用生成內容的來源。
  5. 控制:對模型可以訪問的資訊提供精細控制。

傳統 RAG 的侷限性

儘管有其優點,但傳統 RAG 方法面臨一些挑戰:

  • 單次檢索步驟:如果初始檢索結果不佳,最終生成也會受到影響。
  • 查詢-文件不匹配:使用者查詢(通常是問題)可能與包含答案(通常是陳述)的文件不匹配。
  • 有限推理:簡單的 RAG 管道不允許進行多步推理或查詢最佳化。
  • 上下文視窗限制:檢索到的文件必須在模型的上下文視窗內。

代理 RAG:一種更強大的方法

我們可以透過實現一個**代理 RAG** 系統來克服這些限制——本質上是一個配備檢索功能的代理。這種方法將 RAG 從僵硬的管道轉變為互動式、推理驅動的過程。

代理 RAG 的主要優勢

配備檢索工具的代理可以:

  1. 制定最佳化的查詢:代理可以將使用者問題轉換為適合檢索的查詢。
  2. 執行多次檢索:代理可以根據需要迭代檢索資訊。
  3. 對檢索內容進行推理:代理可以分析、綜合並從多個來源得出結論。
  4. 自我批評和完善:代理可以評估檢索結果並調整其方法。

這種方法自然地實現了高階 RAG 技術:

  • 假設文件嵌入 (HyDE):代理不是直接使用使用者查詢,而是制定最佳化檢索的查詢(論文參考)。
  • 自查詢最佳化:代理可以分析初始結果並使用最佳化後的查詢執行後續檢索(技術參考)。

構建代理 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 系統可應用於各種用例:

  1. 技術文件輔助:幫助使用者瀏覽複雜的技術文件。
  2. 研究論文分析:從科學論文中提取和綜合資訊。
  3. 法律檔案審查:在法律檔案中查詢相關的判例和條款。
  4. 客戶支援:根據產品文件和知識庫回答問題。
  5. 教育輔導:根據教科書和學習材料提供解釋。

結論

代理 RAG 代表了對傳統 RAG 管道的重大進步。透過將 LLM 代理的推理能力與檢索系統的事實依據相結合,我們可以構建更強大、更靈活、更準確的資訊系統。

我們演示的方法:

  • 克服了單步檢索的侷限性。
  • 實現了與知識庫更自然的互動。
  • 透過自我批評和查詢最佳化提供了一個持續改進的框架。

在構建自己的代理 RAG 系統時,請考慮嘗試不同的檢索方法、代理架構和知識來源,以找到最適合您特定用例的最佳配置。

< > 在 GitHub 上更新

© . This site is unofficial and not affiliated with Hugging Face, Inc.