開源 AI 食譜文件

多智慧體 RAG 系統 🤖🤝🤖

Hugging Face's logo
加入 Hugging Face 社群

並獲得增強的文件體驗

開始使用

Open In Colab

多智慧體 RAG 系統 🤖🤝🤖

作者: Sergio Paniego

🚨 注意:本教程是高階教程。在深入學習之前,您應該對以下食譜中討論的概念有紮實的理解

在本筆記本中,我們將建立一個多智慧體 RAG 系統,這是一個由多個智慧體協作檢索和生成資訊的系統,結合了檢索式系統生成模型的優勢。

什麼是多智慧體 RAG 系統?🤔

一個多智慧體檢索增強生成(RAG)系統由多個協作執行復雜任務的智慧體組成。檢索智慧體檢索相關文件或資訊,而生成智慧體合成這些資訊以生成有意義的輸出。有一個管理器智慧體(Manager Agent)負責協調系統,並根據使用者輸入選擇最合適的智慧體來執行任務。

這個食譜的原始想法來自這篇文章。您可以在那裡找到更多細節。

下面,您可以找到我們將要構建的架構。

multiagent_rag_system (1).png

1. 安裝依賴

首先,讓我們安裝依賴項

!pip install -q smolagents
!pip install markdownify duckduckgo-search spaces gradio-tools langchain langchain-community langchain-huggingface faiss-cpu --upgrade -q

讓我們登入以便呼叫 HF 推理 API

from huggingface_hub import notebook_login

notebook_login()

2. 讓我們建立多智慧體 RAG 系統

在本節中,我們將建立 RAG 系統中的每個智慧體。

我們將擁有 3 個由一箇中心智慧體管理的智慧體(詳情請參閱圖片)

  • 🕵💬 網頁搜尋智慧體:它將包含 DuckDuckGoSearchTool 工具和 VisitWebpageTool。正如您所見,每個智慧體都可能包含一個工具列表。
  • 🕵💬 檢索智慧體:它將包含兩個工具,用於從兩個不同的知識庫中檢索資訊。
  • 🕵💬 影像生成智慧體:除了影像生成工具外,它還將包含一個提示生成器工具。

💡 除了這些智慧體,中心/協調智慧體還可以訪問程式碼直譯器工具來執行程式碼。

我們將使用 Qwen/Qwen2.5-72B-Instruct 作為每個元件的 LLM,它將透過推理 API 訪問。根據智慧體的不同,可以使用不同的 LLM 模型。

注意: 推理 API 根據各種標準託管模型,部署的模型可能會在沒有事先通知的情況下更新或替換。在此處瞭解更多資訊

from smolagents import InferenceClientModel

model_id = "Qwen/Qwen2.5-72B-Instruct"
model = InferenceClientModel(model_id)

讓我們深入瞭解每個智慧體的細節!

2.1 網頁搜尋智慧體 🔍

網頁搜尋智慧體將利用 DuckDuckGoSearchTool 在網路上搜索並收集相關資訊。此工具充當搜尋引擎,根據指定的關鍵字查詢結果。

為了使搜尋結果可操作,我們還需要智慧體訪問 DuckDuckGo 檢索到的網頁。這可以透過使用內建的 VisitWebpageTool 來實現。

讓我們探索如何設定它並將其整合到我們的系統中!

以下程式碼來自原始的 讓多個智慧體在多智慧體層次結構中協作 🤖🤝🤖 食譜,請參閱該食譜以獲取更多詳細資訊。

2.1.1 構建我們的多工具網路智慧體 🤖

現在我們已經設定了基本的搜尋和網頁工具,接下來讓我們構建多工具網路智慧體。該智慧體將結合多個工具來執行更復雜的任務,利用 ToolCallingAgent 的功能。

ToolCallingAgent 特別適合網頁搜尋任務,因為其 JSON 動作公式只需要簡單的引數,並且在單個動作的順序鏈中無縫工作。這使其成為我們需要搜尋網路以獲取相關資訊並從特定網頁檢索詳細內容的場景的絕佳選擇。相比之下,CodeAgent 動作公式更適合涉及大量或並行工具呼叫的場景。

透過整合多個工具,我們可以確保我們的智慧體以複雜而高效的方式與網路互動。

讓我們深入瞭解如何設定它並將其整合到我們的系統中!

from smolagents import CodeAgent, ToolCallingAgent, ManagedAgent, DuckDuckGoSearchTool, VisitWebpageTool

web_agent = ToolCallingAgent(tools=[DuckDuckGoSearchTool(), VisitWebpageTool()], model=model)

現在我們有了第一個智慧體,讓我們將其包裝為 ManagedAgent,以便中心智慧體可以使用它。

managed_web_agent = ManagedAgent(
    agent=web_agent,
    name="search_agent",
    description="Runs web searches for you. Give it your query as an argument.",
)

2.2 檢索智慧體 🤖🔍

我們多智慧體系統中的第二個智慧體是檢索智慧體。該智慧體負責從不同來源收集相關資訊。為了實現這一目標,它將利用兩個工具,從兩個獨立的知識庫中檢索資料。

我們將重用以前在其他 RAG 食譜中使用的兩個資料來源,這將使檢索器能夠高效地收集資訊以供進一步處理。

透過利用這些工具,檢索智慧體可以訪問多樣化的資料集,確保在將資訊傳遞到系統的下一步之前全面收集相關資訊。

讓我們探索如何設定檢索器並將其整合到我們的多智慧體系統中!

2.2.1 HF 文件檢索工具 📚

第一個檢索工具來自 Agentic RAG:透過查詢重構和自查詢加速你的 RAG!🚀 食譜。

對於此檢索器,我們將使用一個數據集,其中包含各種 huggingface 包的文件頁面的編譯,所有這些都儲存為 markdown 檔案。此資料集充當檢索智慧體搜尋和檢索相關文件的知識庫。

為了使該資料集易於我們的智慧體訪問,我們將

  1. 下載資料集:我們將首先獲取 markdown 文件。
  2. 嵌入資料:然後,我們將使用 FAISS 向量儲存將文件轉換為嵌入,以實現高效的相似性搜尋。

透過這樣做,檢索工具可以根據搜尋查詢快速訪問相關文件,使智慧體能夠提供準確詳細的資訊。

讓我們繼續設定工具來處理文件檢索!

import datasets

knowledge_base = datasets.load_dataset("m-ric/huggingface_doc", split="train")
from tqdm import tqdm
from transformers import AutoTokenizer
from langchain.docstore.document import Document
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.vectorstores import FAISS
from langchain_huggingface import HuggingFaceEmbeddings
from langchain_community.vectorstores.utils import DistanceStrategy

source_docs = [
    Document(page_content=doc["text"], metadata={"source": doc["source"].split("/")[1]}) for doc in knowledge_base
]

text_splitter = RecursiveCharacterTextSplitter.from_huggingface_tokenizer(
    AutoTokenizer.from_pretrained("thenlper/gte-small"),
    chunk_size=200,
    chunk_overlap=20,
    add_start_index=True,
    strip_whitespace=True,
    separators=["\n\n", "\n", ".", " ", ""],
)

# Split docs and keep only unique ones
print("Splitting documents...")
docs_processed = []
unique_texts = {}
for doc in tqdm(source_docs):
    new_docs = text_splitter.split_documents([doc])
    for new_doc in new_docs:
        if new_doc.page_content not in unique_texts:
            unique_texts[new_doc.page_content] = True
            docs_processed.append(new_doc)

print("Embedding documents...")
embedding_model = HuggingFaceEmbeddings(model_name="thenlper/gte-small")
huggingface_doc_vector_db = FAISS.from_documents(
    documents=docs_processed,
    embedding=embedding_model,
    distance_strategy=DistanceStrategy.COSINE,
)

現在我們已經將文件嵌入到 FAISS 中,接下來讓我們建立 RetrieverTool。此工具將查詢 FAISS 向量儲存,以根據使用者查詢檢索最相關的文件。

這將允許檢索智慧體在查詢時訪問並提供相關文件。

from smolagents import Tool
from langchain_core.vectorstores import VectorStore


class RetrieverTool(Tool):
    name = "retriever"
    description = "Using semantic similarity, retrieves some documents from the knowledge base that have the closest embeddings to the input 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, vectordb: VectorStore, **kwargs):
        super().__init__(**kwargs)
        self.vectordb = vectordb

    def forward(self, query: str) -> str:
        assert isinstance(query, str), "Your search query must be a string"

        docs = self.vectordb.similarity_search(
            query,
            k=7,
        )

        return "\nRetrieved documents:\n" + "".join(
            [f"===== Document {str(i)} =====\n" + doc.page_content for i, doc in enumerate(docs)]
        )
huggingface_doc_retriever_tool = RetrieverTool(huggingface_doc_vector_db)

2.2.2 PEFT 問題檢索工具

對於第二個檢索器,我們將使用 PEFT issues 作為資料來源,就像在 使用 Hugging Face Zephyr 和 LangChain 對 GitHub 問題進行簡單 RAG 中一樣。

同樣,以下程式碼來自該食譜,請參閱該食譜以獲取更多詳細資訊!

from google.colab import userdata

GITHUB_ACCESS_TOKEN = userdata.get("GITHUB_PERSONAL_TOKEN")
from langchain.document_loaders import GitHubIssuesLoader

loader = GitHubIssuesLoader(repo="huggingface/peft", access_token=GITHUB_ACCESS_TOKEN, include_prs=False, state="all")
docs = loader.load()
splitter = RecursiveCharacterTextSplitter(chunk_size=512, chunk_overlap=30)
chunked_docs = splitter.split_documents(docs)
peft_issues_vector_db = FAISS.from_documents(chunked_docs, embedding=embedding_model)

現在讓我們使用相同的 RetrieverTool 生成第二個檢索工具。

peft_issues_retriever_tool = RetrieverTool(peft_issues_vector_db)

2.2.3 構建檢索智慧體

現在我們已經建立了兩個檢索工具,是時候構建檢索智慧體了。該智慧體將管理這兩個工具,並根據使用者查詢檢索相關資訊。

我們將使用 ManagedAgent 整合這些工具並將智慧體傳遞給中心智慧體進行協調。

retriever_agent = ToolCallingAgent(
    tools=[huggingface_doc_retriever_tool, peft_issues_retriever_tool], model=model, max_iterations=4, verbose=2
)
managed_retriever_agent = ManagedAgent(
    agent=retriever_agent,
    name="retriever_agent",
    description="Retrieves documents from the knowledge base for you that are close to the input query. Give it your query as an argument. The knowledge base includes Hugging Face documentation and PEFT issues.",
)

2.3 影像生成智慧體 🎨

我們系統中的第三個智慧體是影像生成智慧體。該智慧體將有兩個工具:一個用於最佳化使用者查詢,另一個用於根據查詢生成影像。在這種情況下,我們將使用 CodeAgent 而不是 ReactAgent,因為這些動作可以一次性執行。

您可以在 智慧體,超強升級 - 多智慧體、外部工具等 文件中找到有關影像生成智慧體的更多詳細資訊。

讓我們深入瞭解這些工具如何協同工作以根據使用者輸入生成影像!

from transformers import load_tool, CodeAgent

prompt_generator_tool = Tool.from_space(
    "sergiopaniego/Promptist", name="generator_tool", description="Optimizes user input into model-preferred prompts"
)
image_generation_tool = load_tool("m-ric/text-to-image", trust_remote_code=True)
image_generation_agent = CodeAgent(tools=[prompt_generator_tool, image_generation_tool], model=model)

🖼 同樣,我們使用 ManagedAgent 來告知中心智慧體它可以管理它。此外,我們還包含了一個 additional_prompting 引數,以確保智慧體返回生成的影像,而不僅僅是文字描述。

managed_image_generation_agent = ManagedAgent(
    agent=image_generation_agent,
    name="image_generation_agent",
    description="Generates images from text prompts. Give it your prompt as an argument.",
    additional_prompting="\n\nYour final answer MUST BE only the generated image location.",
)

3. 讓我們新增通用智慧體管理器來協調系統

中心智慧體管理器將協調智慧體之間的任務。它將

  • 接收使用者輸入並決定哪個智慧體(網頁搜尋、檢索、影像生成)處理它。
  • 根據使用者的查詢將任務委託給相應的智慧體。
  • 收集併合成來自智慧體的結果。
  • 將最終輸出返回給使用者。

我們將所有開發的智慧體作為 managed_agents 包含在內,並在 additional_authorized_imports 下新增程式碼執行器所需的任何匯入。

manager_agent = CodeAgent(
    tools=[],
    model=model,
    managed_agents=[managed_web_agent, managed_retriever_agent, managed_image_generation_agent],
    additional_authorized_imports=["time", "datetime", "PIL"],
)

現在一切都已設定好,讓我們測試多智慧體 RAG 系統的效能!

為此,我們將提供一些示例查詢,並觀察系統如何在智慧體之間委派任務、處理資訊並返回最終結果。

這將幫助我們瞭解智慧體協同工作的效率和效果,並在必要時確定最佳化領域。

讓我們繼續執行一些測試!

3.1 嘗試觸發搜尋智慧體的示例

manager_agent.run("How many years ago was Stripe founded?")

3.2 嘗試觸發影像生成智慧體的示例

result = manager_agent.run(
    "Improve this prompt, then generate an image of it.", prompt="A rabbit wearing a space suit"
)
>>> from IPython.display import Image, display

>>> display(Image(filename=result))

3.3 嘗試觸發 HF 文件知識庫的檢索智慧體的示例

manager_agent.run("How can I push a model to the Hub?")

3.4 嘗試觸發 PEFT 問題知識庫的檢索智慧體的示例

manager_agent.run("How do you combine multiple adapters in peft?")

🏁 最終想法

我們成功構建了一個多智慧體 RAG 系統,它集成了網頁搜尋、文件檢索和影像生成智慧體,所有這些都由一箇中心智慧體管理器協調。這種架構實現了無縫的任務委派、高效的處理以及處理各種使用者查詢的靈活性。

🔍 探索更多

< > 在 GitHub 上更新

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