logo
Loading...

Langgraph AgenticRAG basic - AI Agent 開發特訓營:短期實現智能自動化 - Cupoy

LangGraph Agentic RAG 教學:建構智能檢索代理系統 簡介 Agentic RAG(Retrieval-Augmented Generation)是一個強大的架構,結合了檢索增強生成...

LangGraph Agentic RAG 教學:建構智能檢索代理系統 簡介 Agentic RAG(Retrieval-Augmented Generation)是一個強大的架構,結合了檢索增強生成和代理系統的概念。這個系統能夠智能地決定何時需要從知識庫中檢索資訊,何時可以直接回應用戶。本教學將逐步帶你了解如何使用 LangGraph 建構一個完整的 Agentic RAG 系統。 概述 在這個教學中,我們將建立一個檢索代理,能夠: 自動判斷是否需要從向量資料庫中檢索上下文 評估檢索文件的相關性 必要時重寫查詢以獲得更好的結果 基於檢索到的內容生成準確的回答 系統架構圖 graph TD    A[開始] --> B[生成查詢或回應]    B --> C{需要檢索?}    C -->|是| D[檢索工具]    C -->|否| E[結束]    D --> F{文件相關?}    F -->|是| G[生成答案]    F -->|否| H[重寫問題]    H --> B    G --> E 環境設置 首先,安裝所需的套件: pip install -U --quiet langgraph "langchain[openai]" langchain-community langchain-text-splitters 設置 API 金鑰: import getpass import os def _set_env(key: str):    if key not in os.environ:        os.environ[key] = getpass.getpass(f"{key}:") _set_env("OPENAI_API_KEY") 步驟 1:預處理文件 1.1 載入文件 使用 WebBaseLoader 從網路載入文件: from langchain_community.document_loaders import WebBaseLoader urls = [    "https://lilianweng.github.io/posts/2024-11-28-reward-hacking/",    "https://lilianweng.github.io/posts/2024-07-07-hallucination/",    "https://lilianweng.github.io/posts/2024-04-12-diffusion-video/", ] docs = [WebBaseLoader(url).load() for url in urls] 1.2 分割文件 將文件分割成較小的區塊以便索引: from langchain_text_splitters import RecursiveCharacterTextSplitter docs_list = [item for sublist in docs for item in sublist] text_splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(    chunk_size=100, chunk_overlap=50 ) doc_splits = text_splitter.split_documents(docs_list) 步驟 2:建立檢索工具 2.1 創建向量存儲 使用 OpenAI 嵌入創建記憶體向量存儲: from langchain_core.vectorstores import InMemoryVectorStore from langchain_openai import OpenAIEmbeddings vectorstore = InMemoryVectorStore.from_documents(    documents=doc_splits, embedding=OpenAIEmbeddings() ) retriever = vectorstore.as_retriever() 2.2 創建檢索工具 將檢索器包裝成工具: from langchain.tools.retriever import create_retriever_tool retriever_tool = create_retriever_tool(    retriever,    "retrieve_blog_posts",    "搜尋並返回關於 Lilian Weng 部落格文章的資訊。", ) 步驟 3:構建圖形節點 3.1 生成查詢或回應節點 創建決定是否需要檢索的節點: from langgraph.graph import MessagesState from langchain.chat_models import init_chat_model response_model = init_chat_model("openai:gpt-4", temperature=0) def generate_query_or_respond(state: MessagesState):    """呼叫模型生成回應。根據問題決定是否使用檢索工具。"""    response = (        response_model        .bind_tools([retriever_tool])        .invoke(state["messages"])    )    return {"messages": [response]} 3.2 評分文件節點 創建評估文件相關性的節點: from pydantic import BaseModel, Field from typing import Literal class GradeDocuments(BaseModel):    """使用二元分數評分文件相關性"""    binary_score: str = Field(        description="相關性分數:'yes' 表示相關,'no' 表示不相關"    ) grader_model = init_chat_model("openai:gpt-4", temperature=0) def grade_documents(    state: MessagesState, ) -> Literal["generate_answer", "rewrite_question"]:    """判斷檢索到的文件是否與問題相關"""    question = state["messages"][0].content    context = state["messages"][-1].content        # 評分邏輯...    if score == "yes":        return "generate_answer"    else:        return "rewrite_question" 3.3 重寫問題節點 當文件不相關時,重寫原始問題: def rewrite_question(state: MessagesState):    """重寫原始用戶問題"""    messages = state["messages"]    question = messages[0].content    # 重寫邏輯...    return {"messages": [{"role": "user", "content": response.content}]} 3.4 生成答案節點 基於檢索到的內容生成最終答案: def generate_answer(state: MessagesState):    """生成答案"""    question = state["messages"][0].content    context = state["messages"][-1].content    # 生成答案邏輯...    return {"messages": [response]} 步驟 4:組裝圖形 將所有節點組合成完整的工作流程: from langgraph.graph import StateGraph, START, END from langgraph.prebuilt import ToolNode, tools_condition workflow = StateGraph(MessagesState) # 添加節點 workflow.add_node("generate_query_or_respond", generate_query_or_respond) workflow.add_node("retrieve", ToolNode([retriever_tool])) workflow.add_node("rewrite_question", rewrite_question) workflow.add_node("generate_answer", generate_answer) # 添加邊 workflow.add_edge(START, "generate_query_or_respond") # 條件邊 workflow.add_conditional_edges(    "generate_query_or_respond",    tools_condition,    {        "tools": "retrieve",        END: END,    }, ) workflow.add_conditional_edges(    "retrieve",    grade_documents, ) workflow.add_edge("generate_answer", END) workflow.add_edge("rewrite_question", "generate_query_or_respond") # 編譯圖形 graph = workflow.compile() 步驟 5:運行 Agentic RAG 使用完整的系統來處理查詢: # 執行查詢 for chunk in graph.stream(    {        "messages": [            {                "role": "user",                "content": "Lilian Weng 對獎勵駭客的類型說了什麼?",            }        ]    } ):    for node, update in chunk.items():        print(f"來自節點 {node} 的更新")        update["messages"][-1].pretty_print()        print("\n") 實際應用範例 以下是一個完整的使用範例: # 初始化系統 agentic_rag = workflow.compile() # 處理複雜查詢 response = agentic_rag.invoke({    "messages": [        {            "role": "user",            "content": "解釋 Lilian Weng 文章中關於強化學習中獎勵駭客的主要觀點",        }    ] }) # 顯示最終答案 print(response["messages"][-1].content) 最佳實踐 文件分塊策略:根據內容類型調整 chunk_size 和 chunk_overlap 評分閾值:調整文件相關性評分的標準 重寫策略:使用更智能的提示來改進問題重寫 錯誤處理:添加適當的異常處理機制 監控和日誌:使用 LangSmith 追蹤系統性能 擴展建議 多語言支援:添加多語言文件處理能力 多源檢索:整合多個知識來源 快取機制:實現查詢和回答的快取 回饋循環:加入用戶回饋來改進系統 安全措施:添加內容過濾和安全檢查 結論 Agentic RAG 系統結合了智能決策和檢索增強生成的優勢,能夠提供更準確、更相關的回答。透過 LangGraph 的圖形架構,我們可以輕鬆地構建和維護這樣的複雜系統。 這個系統的主要優勢包括: 智能判斷何時需要外部資訊 自動評估和改進檢索品質 靈活的工作流程控制 易於擴展和客製化 希望這個教學能幫助你建立自己的 Agentic RAG 系統!