# Agentic-RAG 规范文档 v1.0 > GraphRAG 问答阶段核心流程:Knowledge Graph → LangChain Agent → QA > > 数据来源:Bridge Pipeline 输出(`kg_nodes.json` + `kg_edges.json`) > 测试验证日期:2026-03-05 > 全流程运行耗时:~40s(4 个测试查询) --- ## 目录 - [一、完整执行思路与脚本位置](#一完整执行思路与脚本位置) - [二、LangChain Agent 输入输出规范](#二langchain-agent-输入输出规范) - [三、MinerU ↔ Agentic-RAG 对接规范与核心架构](#三mineru--agentic-rag-对接规范与核心架构) - [四、问答流程最终数据返回格式规范](#四问答流程最终数据返回格式规范) - [五、虚拟环境与依赖](#五虚拟环境与依赖) --- ## 一、完整执行思路与脚本位置 ### 1.1 总体架构定位 Agentic-RAG 是 GraphRAG 系统的**问答阶段**,位于 Bridge Pipeline 之后,负责将知识图谱转化为可交互的智能问答能力。 ``` 【已完成阶段】 【本阶段:Agentic-RAG】 ──────────────────── ────────────────────────── PDF ↓ MinerU Cloud API content_list.json ↓ Bridge Pipeline kg_nodes.json (40 nodes) ──────────→ NetworkX Graph (内存) kg_edges.json (780 edges) ↓ 4 个 LangChain @tool ↓ LangChain v1 create_agent (DeepSeek deepseek-chat) ↓ ReAct 推理循环 ↓ 自然语言答案 ``` ### 1.2 五步执行流程 | 步骤 | 模块 | 说明 | |------|------|------| | Step 0 | 环境 + 配置 | 加载 `.env`(DEEPSEEK_API_KEY),初始化 `ChatOpenAI` | | Step 1 | KG 加载 | 读取 `kg_nodes.json` + `kg_edges.json`,构建 NetworkX 无向图 | | Step 2 | Tool 注册 | 用 `@tool` 装饰器注册 4 个 KG 检索工具 | | Step 3 | Agent 构建 | `create_agent(model, tools, system_prompt)` 编译 LangGraph | | Step 4 | 问答调用 | `agent.invoke({"messages": [("human", question)]})` | | Step 5 | 结果提取 | `result["messages"][-1].content` 获取最终答案 | ### 1.3 测试脚本存放位置 ``` F:\GraphRAGAgent\graphrag_pipeline\ ├── agentic_rag_mvp.py ← 主测试脚本(本规范对应文件) ├── .env ← DEEPSEEK_API_KEY 配置 └── output/ ├── kg_nodes.json ← Bridge Pipeline 生成(40 节点) └── kg_edges.json ← Bridge Pipeline 生成(780 边) ``` ### 1.4 运行命令 ```bash # MVP 连通性测试(4 个预设测试查询) F:/GraphRAGAgent/langextract_src/.venv/Scripts/python.exe \ F:/GraphRAGAgent/graphrag_pipeline/agentic_rag_mvp.py ``` ### 1.5 ReAct 推理循环详解 Agent 使用 **ReAct(Reasoning + Acting)** 模式,每个问题的处理流如下: ``` 用户输入 (question: str) │ ▼ ┌─────────────────────────────────────────────────┐ │ LLM Reasoning(DeepSeek deepseek-chat) │ │ 决策:需要调用哪个工具?参数是什么? │ └─────────────────────────────────────────────────┘ │ tool_call ▼ ┌─────────────────────────────────────────────────┐ │ Tool Execution(NetworkX 本地计算,无 API 调用) │ │ search_entities / get_neighbors / │ │ get_entities_by_type / describe_graph │ └─────────────────────────────────────────────────┘ │ ToolMessage(工具返回的文本结果) ▼ ┌─────────────────────────────────────────────────┐ │ LLM Observation(观察工具结果) │ │ 决策:结果够用了吗?还需要调更多工具? │ └─────────────────────────────────────────────────┘ │ 继续 tool_call 或输出最终答案 ▼ AIMessage(最终自然语言答案) ``` **实测工具调用模式(4 个测试查询):** | 查询类型 | 工具调用序列 | 特点 | |---------|------------|------| | 图谱整体概览 | `describe_graph` | 单次工具调用 | | 类型枚举 | `get_entities_by_type` | 单次工具调用 | | 多跳关系推理 | `search_entities` → `get_neighbors` | 两步串行调用 | | 概念精确查找 | `search_entities` → `get_neighbors` | 两步串行调用 | --- ## 二、LangChain Agent 输入输出规范 ### 2.1 LLM 适配规范 #### 2.1.1 DeepSeek → LangChain 标准组件 LangChain v1 使用 `ChatOpenAI` 通过 `base_url` 覆盖接入任何 OpenAI 兼容 API: ```python from langchain_openai import ChatOpenAI llm = ChatOpenAI( model="deepseek-chat", # DeepSeek 模型名 api_key=DEEPSEEK_API_KEY, # 来自 graphrag_pipeline/.env base_url="https://api.deepseek.com", # OpenAI 兼容端点 temperature=0, # 问答场景确定性输出 ) ``` | 参数 | 值 | 说明 | |------|-----|------| | `model` | `"deepseek-chat"` | DeepSeek 实际模型标识 | | `api_key` | `${DEEPSEEK_API_KEY}` | 从 `.env` 读取,与 Bridge Pipeline 共用 | | `base_url` | `"https://api.deepseek.com"` | SDK 自动补全 `/v1` 路径 | | `temperature` | `0` | 问答场景设为 0,保证可重现性 | #### 2.1.2 与 LangExtract 中 DeepSeek 的区别 | 对比项 | LangExtract 中的 DeepSeek | Agentic-RAG 中的 DeepSeek | |--------|--------------------------|--------------------------| | 接入方式 | 直接实例化 `OpenAILanguageModel` | LangChain `ChatOpenAI` 标准组件 | | API Key 环境变量 | `OPENAI_API_KEY` | `DEEPSEEK_API_KEY` | | 调用方式 | `lx.extract(model=model)` | `agent.invoke({"messages": ...})` | | 输出格式 | JSON(实体抽取) | 自然语言(问答) | | Tool Calling | 不支持(单轮推理) | 支持(ReAct 多轮) | ### 2.2 Agent 构建规范 #### 2.2.1 LangChain v1 create_agent ```python from langchain.agents import create_agent agent = create_agent( model=llm, # ChatOpenAI 实例 tools=_tools, # List[BaseTool],4 个工具 system_prompt=SYSTEM_PROMPT, # 系统提示词字符串 ) ``` **版本注意事项:** | API | 状态 | 说明 | |-----|------|------| | `langchain.agents.create_agent` | ✅ LangChain v1 推荐 | 本项目使用 | | `langgraph.prebuilt.create_react_agent` | ⚠️ Deprecated in LangGraph V1.0 | 已废弃,勿用 | | `langchain.agents.create_react_agent` (旧版) | ❌ Legacy | 已移除 | #### 2.2.2 System Prompt 规范 ``` You are a Knowledge Graph QA assistant. You have access to a knowledge graph extracted from academic documents about GraphRAG and related technologies. The graph contains: - {node_count} deduplicated entities ({type_list} types) - {edge_count} CO_OCCURS_IN edges representing same-page co-occurrence Available tools: 1. search_entities — find entities by keyword substring 2. get_neighbors — explore entity relationships (N-hop BFS) 3. get_entities_by_type — list all entities of a type 4. describe_graph — get graph statistics overview Reasoning strategy: - Always use at least one tool before answering a factual question - For relationship questions, use get_neighbors after identifying the entity with search_entities - For enumeration questions, use get_entities_by_type - Synthesize tool results into a clear, concise answer - Cite the entity names and types in your final answer ``` ### 2.3 Agent 输入规范 #### 2.3.1 invoke 输入格式 ```python result = agent.invoke({ "messages": [ ("human", question) # 用户问题(自然语言字符串) ] }) ``` **输入字段规范:** | 字段 | 类型 | 说明 | |------|------|------| | `messages` | `list[tuple[str, str]]` | 消息列表,格式 `(role, content)` | | `role` | `"human"` \| `"ai"` \| `"system"` | 消息角色 | | `content` | `str` | 消息内容 | **多轮对话输入(支持历史上下文):** ```python result = agent.invoke({ "messages": [ ("human", "What is GraphRAG?"), ("ai", "GraphRAG is a knowledge graph-enhanced RAG system..."), ("human", "How does it relate to LLMs?"), # 当前问题 ] }) ``` ### 2.4 Agent 输出规范 #### 2.4.1 invoke 原始返回 ```python { "messages": [ HumanMessage(content="What is GraphRAG?"), AIMessage(content="", tool_calls=[...]), # 工具调用 ToolMessage(content="...", tool_call_id="..."), # 工具结果 AIMessage(content="GraphRAG is an advanced...") # 最终答案 ] } ``` #### 2.4.2 消息类型枚举 | 消息类型 | 角色 | 说明 | |---------|------|------| | `HumanMessage` | `human` | 用户输入 | | `AIMessage`(tool_calls 非空) | `ai` | LLM 决策发起工具调用 | | `ToolMessage` | `tool` | 工具执行结果 | | `AIMessage`(tool_calls 为空) | `ai` | 最终自然语言答案 | #### 2.4.3 最终答案提取 ```python final_msg = result["messages"][-1] answer = final_msg.content # str,最终自然语言答案 ``` ### 2.5 四个工具输入输出规范 #### Tool 1: `search_entities` | 项目 | 规范 | |------|------| | 入参 | `query: str` — 关键词(大小写不敏感子串匹配) | | 匹配逻辑 | `query.lower() in entity_name.lower()` | | 返回格式 | 多行文本,每行格式:`[{type}] "{name}" (confidence={c}, page={p}, id={id})` | | 无匹配时 | 返回提示 + 前 8 个样例实体名 | | 最多返回 | 15 条 | **实际调用示例:** ``` 输入: query="GraphRAG" 输出: Found 3 entity(ies) matching 'GraphRAG': [TECHNOLOGY] "GraphRAG" (confidence=match_exact, page=0, id=node_0) [CONCEPT] "GraphRAG pipeline" (confidence=match_exact, page=0, id=node_12) [CONCEPT] "GraphRAG (Global)" (confidence=match_exact, page=0, id=node_15) ``` #### Tool 2: `get_neighbors` | 项目 | 规范 | |------|------| | 入参 | `entity_name: str`,`hops: int = 1`(范围 1-3) | | 匹配逻辑 | 子串匹配找起始节点,取 `candidates[0]` | | 遍历算法 | `nx.single_source_shortest_path_length(G, node_id, cutoff=hops)` | | 返回格式 | 按 hop 分组,每组 `[{type}] {name}`,每组最多 20 条 | | 未找到时 | 返回提示,建议先用 `search_entities` | **实际调用示例:** ``` 输入: entity_name="GraphRAG", hops=1 输出: Neighbors of 'GraphRAG' [TECHNOLOGY] within 1 hop(s): Hop 1 — 39 related entities: [CONCEPT] Knowledge Graph Enhanced RAG System [CONCEPT] retrieval-augmented generation ... Total related entities: 39 ``` #### Tool 3: `get_entities_by_type` | 项目 | 规范 | |------|------| | 入参 | `entity_type: str`(自动 `.upper()` 处理) | | 有效类型 | `TECHNOLOGY`, `CONCEPT`, `PERSON`, `ORGANIZATION`, `LOCATION` | | 返回格式 | 按 `name` 字母序排列,每行 `• {name} (confidence={c}, page={p})` | | 无效类型时 | 返回错误 + 图谱中实际存在的类型列表 | **实际调用示例:** ``` 输入: entity_type="TECHNOLOGY" 输出: TECHNOLOGY entities (4 total): • GraphRAG (confidence=match_exact, page=0) • LLMs (confidence=match_exact, page=0) • LangExtract (confidence=match_exact, page=0) • MinerU (confidence=match_exact, page=0) ``` #### Tool 4: `describe_graph` | 项目 | 规范 | |------|------| | 入参 | 无参数 | | 计算指标 | 节点数、边数、关系类型、图密度(`nx.density`)、度中心性(`nx.degree_centrality`) | | 返回格式 | 结构化文本,包含概览 + 类型分布 + Top-5 中心节点 | **实际调用示例(实测输出):** ``` === Knowledge Graph Overview === Nodes (entities): 40 Edges (relations): 780 Relation type: CO_OCCURS_IN (same-page co-occurrence) Graph density: 1.0000 Entity type distribution: CONCEPT : 36 TECHNOLOGY : 4 Top-5 most connected entities (by degree centrality): [TECHNOLOGY] GraphRAG (centrality=1.000) [CONCEPT] Knowledge Graph Enhanced RAG System (centrality=1.000) [CONCEPT] retrieval-augmented generation (centrality=1.000) [CONCEPT] knowledge graphs (centrality=1.000) [CONCEPT] large language models (centrality=1.000) ``` --- ## 三、MinerU ↔ Agentic-RAG 对接规范与核心架构 ### 3.1 全链路技术架构 ``` ┌─────────────────────────────────────────────────────────────────────┐ │ 阶段一:文档解析(MinerU Cloud API) │ │ │ │ PDF 文件 │ │ │ POST /file-urls/batch (enable_table=True, language="en") │ │ ├─ PUT {presigned_url}(裸上传,不带 Content-Type) │ │ └─ GET /extract-results/batch/{batch_id}(轮询 done) │ │ ↓ │ │ full_zip_url → 解压 → {uuid}_content_list.json │ │ │ │ 关键输出字段:type, text, text_level, table_body, page_idx, bbox │ └─────────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────────┐ │ 阶段二:知识图谱构建(Bridge Pipeline) │ │ │ │ content_list.json │ │ │ text_assembler.py │ │ ├─ text blocks → .rstrip() 拼接 │ │ ├─ table blocks → BeautifulSoup HTML → pipe 分隔文本 │ │ └─ PageText(page_idx, text, block_spans) │ │ ↓ │ │ entity_extractor.py (LangExtract + DeepSeek) │ │ ↓ │ │ kg_builder.py (去重 + CO_OCCURS_IN 边) │ │ ↓ │ │ kg_nodes.json (40 nodes) + kg_edges.json (780 edges) │ └─────────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────────┐ │ 阶段三:Agentic-RAG 问答(LangChain + LangGraph) │ │ │ │ kg_nodes.json → NetworkX.G.add_node(**node) │ │ kg_edges.json → NetworkX.G.add_edge(source, target, **edge) │ │ │ │ @tool search_entities ← 子串匹配 │ │ @tool get_neighbors ← BFS N-hop 遍历 │ │ @tool get_entities_by_type ← 类型过滤 │ │ @tool describe_graph ← 图统计 │ │ ↓ │ │ create_agent(ChatOpenAI("deepseek-chat"), tools, system_prompt) │ │ ↓ │ │ ReAct 推理循环(think → tool_call → observe → repeat) │ │ ↓ │ │ 自然语言答案(AIMessage.content) │ └─────────────────────────────────────────────────────────────────────┘ ``` ### 3.2 MinerU → KG 关键参数对接 | MinerU 输出字段 | Bridge Pipeline 处理 | Agentic-RAG 使用 | |---------------|-------------------|----------------| | `block["type"]` | 区分 `text`/`table`/`image` | 不直接使用(已由 Bridge 转换) | | `block["text"]` | `.rstrip()` 后加入 PageText | 已内化为 `node["name"]` | | `block["table_body"]` | BeautifulSoup → pipe 分隔文本 | 已内化为实体描述 | | `block["page_idx"]` | 分组依据,记入 BlockSpan | `node["page"]` 字段 | | `block["bbox"]` | 记录字符偏移位置 | `node["char_start"]` / `node["char_end"]` | | `{uuid}_content_list.json 文件名` | UUID 作为 `source_doc_id` | `node["source_doc"]` / `edge["doc_id"]` | ### 3.3 NetworkX 图构建规范 ```python import networkx as nx G = nx.Graph() # 无向图(CO_OCCURS_IN 关系无方向) # 节点:来自 kg_nodes.json for node in kg_nodes: G.add_node( node["id"], # 主键:node_0, node_1, ... **node # 所有字段作为节点属性 ) # 边:来自 kg_edges.json for edge in kg_edges: G.add_edge( edge["source"], # node_0 edge["target"], # node_1 relation=edge["relation"], # "CO_OCCURS_IN" doc_id=edge["doc_id"], # UUID page=edge["page"], # 0-indexed ) ``` **图属性:** | 属性 | 实测值 | 说明 | |------|--------|------| | `G.number_of_nodes()` | `40` | 去重实体数 | | `G.number_of_edges()` | `780` | CO_OCCURS_IN 边数 | | `nx.density(G)` | `1.0` | 完全图(单页文档所有节点两两连接) | | `G.nodes[nid]` | `dict` | 节点属性字典(id, name, type, page, confidence, ...) | ### 3.4 MinerU API 关键参数(与 Agentic-RAG 相关部分) | 参数 | 推荐值 | 影响 Agentic-RAG 的原因 | |------|--------|----------------------| | `enable_table` | `True` | 表格被解析为 HTML `