Skip to content

Nokia-Forever/agentic-rag

Repository files navigation

Agentic-RAG 智能检索增强生成系统

🚀 一个具有自主规划、动态检索、自我反思能力的智能 RAG 系统

📖 目录


项目简介

Agentic-RAG 是一个基于 LangGraph 实现的智能检索增强生成(Agentic Retrieval-Augmented Generation)系统。与传统 RAG 系统相比,它具备:

  • 🔍 问题澄清能力:智能判断用户问题是否清晰、完整
  • 🎯 动态规划能力:协调者负责任务规划,动态调整检索策略
  • 🔧 多工具协同:支持向量检索、网络搜索、数据库查询等多种工具
  • 🗜️ 上下文压缩:Token 超限时自动压缩对话历史
  • 🤔 自我反思能力:评估答案质量,决定是否重新生成或补充检索
  • 📊 评估体系:集成 Ragas 评估框架,支持多维度质量评估

核心特性

1. Agentic 架构

┌─────────────────────────────────────────────────────────────────┐
│                    Agentic RAG 核心流程                           │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  用户问题 → 🔍 Clarify → 🎯 Coordinator → 🔧 Tool Calling      │
│                              ↓                                    │
│                    ✍️ Generator → 🤔 Self Reflect               │
│                              ↓                                    │
│                         ✅ 答案 / 🔄 迭代                         │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

2. 混合检索系统

  • 稠密向量检索:基于语义相似度匹配
  • 稀疏向量检索:基于 BM25 关键词匹配
  • RRF 融合:结合两种检索方式的优势
  • 二次重排序:使用大模型提升相关性

3. 句子窗口检索

  • 为每个文档块生成上下文窗口
  • 扩展左右相邻内容,提升召回率
  • 智能停止:遇到表格/图片时停止扩展

4. 多模态文档处理

  • 支持 PDF、Word 等多种格式
  • 自动提取表格和图片
  • 使用 LLM 生成多模态内容描述

架构设计

整体架构图

flowchart TD
    subgraph 用户层["👤 用户层"]
        Q[用户提问]
    end

    subgraph Agentic层["🤖 Agentic RAG 层"]
        CLARIFY[🔍 Clarify Node<br/>问题澄清]
        COORD[🎯 Coordinator Node<br/>协调者节点]
        TOOL[🔧 Tool Calling Node<br/>工具决策]
        TOKEN[📊 Token Check Node<br/>Token检查]
        COMPRESS[🗜️ Compressor Node<br/>上下文压缩]
        GEN[✍️ Generator Node<br/>答案生成]
        REFLECT[🤔 Self Reflect Node<br/>自我反思]
    end

    subgraph 工具层["🔧 工具层"]
        VECTOR[📊 向量检索工具]
        WEB[🌐 网络搜索工具]
        DB[🗄️ 数据库查询工具]
    end

    subgraph 向量层["🔢 向量处理层"]
        LOAD[📄 文档加载]
        SPLIT[✂️ 文档分块]
        EMBED[🔢 向量化]
        RETRIEVE[🔍 混合检索]
        RERANK[🏆 重排序]
    end

    subgraph 存储层["💾 存储层"]
        MILVUS[(Milvus<br/>向量数据库)]
        OSS[(阿里云 OSS<br/>对象存储)]
    end

    Q --> CLARIFY
    CLARIFY --> COORD
    COORD --> TOOL
    TOOL --> VECTOR
    TOOL --> WEB
    VECTOR --> RETRIEVE
    RETRIEVE --> RERANK
    RERANK --> GEN
    GEN --> REFLECT
    REFLECT -.->|需要补充| COORD

    LOAD --> SPLIT
    SPLIT --> EMBED
    EMBED --> MILVUS
    MILVUS --> RETRIEVE

    style Agentic层 fill:#e3f2fd,stroke:#0288d1
    style 工具层 fill:#fff3e0,stroke:#ef6c00
    style 向量层 fill:#e8f5e9,stroke:#2e7d32
    style 存储层 fill:#fce4ec,stroke:#ad1457
Loading

核心工作流

flowchart LR
    START([👤]) --> CLARIFY
    CLARIFY -->|清晰| COORD
    CLARIFY -->|不清晰| END1([⚠️])
    
    COORD -->|需要工具| TOOL
    COORD -->|不需要工具| GEN
    
    TOOL --> VECTOR
    VECTOR --> TOKEN
    TOKEN -->|压缩| COMPRESS
    TOKEN -->|不压缩| COORD
    COMPRESS --> COORD
    
    GEN --> REFLECT
    REFLECT -->|合格| END2([✅])
    REFLECT -->|重新生成| GEN
    REFLECT -->|补充检索| COORD
Loading

快速开始

环境要求

  • Python 3.12+
  • Milvus 2.4+(向量数据库)
  • 阿里云 OSS(对象存储)
  • VLLM 或 DashScope(模型服务)

安装步骤

# 1. 克隆项目
git clone https://github.com/your-repo/agentic-rag.git
cd agentic-rag

# 2. 安装依赖
pip install uv
uv sync

# 3. 配置环境变量
cp .env.example .env
# 编辑 .env 文件,填入必要的 API Key 和配置

# 4. 初始化 Milvus
python -m init.init_milvus

# 5. 上传文档
python -m init.batch_upload --path document/your_document.pdf

# 6. 运行问答
python main.py

快速测试

import asyncio
from rag.graph.rag_graph import build_rag_graph

async def test_rag():
    graph = build_rag_graph()
    result = await graph.ainvoke({
        "original_question": "传音控股2024年的营收是多少?",
        "prompt_info": "",
        "conversation_summary": "",
        "messages": [],
    })
    print(result['answer'])

asyncio.run(test_rag())

项目结构

agentic-rag/
├── main.py                      # 主程序入口
├── config.yaml                   # 全局配置文件
│
├── rag/                          # Agentic RAG 核心模块
│   ├── graph/
│   │   ├── rag_graph.py         # LangGraph 工作流编排
│   │   ├── prompt.py             # Prompt 模板
│   │   └── schemas.py            # 结构化输出 Schema
│   └── tools/
│       ├── vector_tools.py       # 向量检索工具
│       └── web_tools.py          # 网络搜索工具
│
├── vector/                       # 向量处理模块
│   ├── core/
│   │   ├── loaders.py           # 文档加载器
│   │   ├── splitters.py         # 文档分块策略
│   │   ├── embeddings.py        # 向量化处理
│   │   └── retrieve.py          # 混合检索
│   └── graph/
│       ├── vector_search_graph.py    # 检索工作流
│       └── save_graph.py             # 文档上传工作流
│
├── shared/                       # 共享模块
│   ├── config/                   # 配置管理
│   │   ├── config.py             # YAML 配置加载
│   │   ├── model_config.py       # 模型配置
│   │   └── *_choice.py           # 模型选择工厂
│   ├── client/                   # 客户端
│   │   ├── milvus_client.py      # Milvus 连接
│   │   └── aliyun_oss_client.py  # OSS 连接
│   └── utils/
│       └── unstructured_util.py   # 文档解析工具
│
├── rag_eval/                     # 评估模块
│   ├── rag_evals.py              # RAG 评估
│   └── evals/datasets/           # 测试数据集
│
├── init/                         # 初始化脚本
│   ├── init_milvus.py            # Milvus 初始化
│   ├── batch_upload.py           # 批量文档上传
│   └── test_rag.py               # 测试脚本
│
└── document/                     # 文档存储目录

配置说明

config.yaml 结构

# ============ 文档处理配置 ============
rag:
  object_store:
    policy: "oss"                  # 对象存储:oss
    endpoint: "oss-cn-beijing.aliyuncs.com"
    bucket_name: "agentic-core"

  split:
    policy: 4                      # 分块策略:4=句子窗口
    chunk_size: 200                # 分块大小
    overlap: 0                     # 分块重叠
    window_size: 3                # 句子窗口大小

  # ============ 检索配置 ============
  retrieve:
    top_k: 100                     # 检索返回数量
    rerank:
      enable: true                 # 启用重排序
      top_n: 20                   # 重排序返回数量

  # ============ 向量数据库配置 ============
  vector_store:
    policy: "milvus"
    uri: "http://localhost:19530"
    db_name: "agentic_rag"
    collection_name: "doc_collection"

  # ============ AI 模型配置 ============
  ai:
    embedding:                     # Embedding 模型
      - name: "qwen3_vl_embeddings"
        policy: "openai"
        model: ${VLLM_QWEN_EMBEDDING_MODEL}
        dimension: 2048

    rerank:                       # 重排序模型
      - name: "qwen3_vl_rerank"
        policy: "dashscope"
        model: "qwen3-vl-rerank"

    chat:                         # Chat 模型
      - name: "qwen3.5_plus"
        policy: "openai"
        model: "qwen3.5-flash"
        temperature: 0.2
        max_tokens: 8192

环境变量配置

# .env 文件

# 阿里云 AI
ALIYUN_AI_API_KEY=your_api_key
ALIYUN_AI_BASE_URL=https://dashscope.aliyuncs.com/api/v1

# VLLM(Embedding 服务)
VLLM_API_KEY=your_vllm_key
VLLM_BASE_URL=http://localhost:8000/v1
VLLM_QWEN_EMBEDDING_MODEL=Qwen/Qwen3-Embedding-2048

# 阿里云 OSS
ALIYUN_OSS_ACCESSKEY_ID=your_access_key
ALIYUN_OSS_ACCESSKEY_SECRET=your_secret_key

使用指南

1. 文档上传

单文档上传

from vector.graph import build_save_graph
import asyncio

async def upload_document():
    graph = build_save_graph()
    result = await graph.ainvoke({
        "file_path": "document/report.pdf"
    })
    print(f"上传成功: {len(result['doc_list'])} 个文档块")

asyncio.run(upload_document())

批量上传

python -m init.batch_upload --path document/ --pattern "*.pdf"

2. 问答查询

基础查询

import asyncio
from rag.graph.rag_graph import build_rag_graph

async def query():
    graph = build_rag_graph()
    result = await graph.ainvoke({
        "original_question": "传音控股2024年的营收增长情况如何?",
        "prompt_info": "",
        "conversation_summary": "",
        "messages": [],
    })
    print(result['answer'])

asyncio.run(query())

带过滤条件的查询

# 通过 question_expr 过滤特定文件
result = await graph.ainvoke({
    "original_question": "研发投入情况?",
    "question_expr": "file_name like '%传音%' and pub_year == '2024'",
    ...
})

3. 评估测试

from rag_eval import evaluate_rag

# 评估 RAG 系统
results = evaluate_rag(
    dataset="rag_eval/evals/datasets/new_test_dataset.csv",
    metrics=["faithfulness", "answer_relevancy", "context_relevance"]
)

评估体系

测试数据集

测试集基于传音控股、艾力斯、广联达三份上市公司研究报告设计,共 20 道题目:

类型 数量 占比 说明
single_doc 6 30% 单文档事实型问题
multi_doc 5 25% 多文档综合型问题
semantic_ambiguous 5 25% 语义模糊型问题
irrelevant 4 20% 无关型问题(防幻觉)

评估指标

指标 说明 目标值
Faithfulness 生成内容与检索内容的忠诚度 > 0.9
Answer Relevancy 答案与问题的相关性 > 0.85
Context Precision 上下文精确度 > 0.8
Context Recall 上下文召回率 > 0.85

评估命令

# 运行评估
python -m rag_eval.rag_evals

# 查看结果
# 结果保存在 rag_eval/experiments/ 目录

开发指南

添加新工具

  1. rag/tools/ 目录下创建新工具文件:
# rag/tools/mysql_tools.py
from langchain.tools import tool

@tool
def mysql_query_tool(query: str) -> str:
    """执行 MySQL 查询"""
    # 实现查询逻辑
    return result
  1. rag/graph/rag_graph.py 中注册工具:
from rag.tools import mysql_tools

tool_list = [
    vector_search_tool,
    web_search_tool,
    mysql_query_tool,  # 新增
]

自定义 Prompt

rag/graph/prompt.py 中添加新的 Prompt 模板:

def get_custom_prompt() -> str:
    return """
    ## 角色
    你是一个...
    """

自定义分块策略

vector/core/splitters.py 中扩展分块器:

def semantic_chunk_splitter(documents: List[Document]) -> List[Document]:
    """基于语义的智能分块"""
    # 实现语义分块逻辑
    pass

核心模块详解

1. RAG Graph(工作流编排)

节点 职责 循环上限
Clarify 问题澄清 1次
Coordinator 问题重写 + 工具决策 5次
Tool Calling 工具选择 3次
Token Check Token 计算 -
Compressor 上下文压缩 -
Generator 答案生成 2次
Self Reflect 质量评估 -

2. 向量处理流程

文档加载 → 元素清洗 → 分块处理 → 向量化 → Milvus 入库
                          ↓
                   表格/图片处理 → LLM 描述
                          ↓
                    句子窗口生成 → 扩展上下文

3. 混合检索流程

查询 → Embedding → 稠密检索 ─┐
        ↓                   │
查询 → BM25 → 稀疏检索 ─────┼─→ RRF 融合 → 重排序 → 结果
                           │
← ← ← ← ← ← ← ← ← ← ← ← ← ┘

常见问题

Q1: 检索结果为空怎么办?

A: 检查以下几点:

  1. 确认文档已成功上传到 Milvus
  2. 检查 question_expr 过滤条件是否过于严格
  3. 尝试使用更通用的查询词

Q2: Token 超限怎么办?

A: 系统会自动触发上下文压缩。如果仍然超限:

  1. 降低 chunk_size 重新上传文档
  2. 减少 window_size 缩小上下文窗口

Q3: 如何选择分块策略?

策略 适用场景
固定大小 通用场景,简单高效
递归字符 需要更细致的分块
语义分块 需要保持语义完整性
句子窗口 推荐,兼顾上下文和精确性

Q4: 如何优化检索质量?

A: 从以下几个方面入手:

  1. 调整 top_krerank.top_n
  2. 优化 Embedding 模型
  3. 使用更好的重排序模型
  4. 调整 window_size 扩展更多上下文

性能基准

指标 数值 说明
文档处理速度 50+ docs/s 向量化并发处理
检索延迟 < 500ms P99
端到端问答延迟 < 3s 含重排序
Token 压缩效率 70%+ 平均压缩比

技术栈

组件 技术选型 版本
LLM 框架 LangChain + LangGraph 1.2+ / 1.0+
向量数据库 Milvus 2.4+
对象存储 阿里云 OSS -
Embedding 通义 Embedding Qwen3-Embedding
重排序 通义 Rerank qwen3-vl-rerank
Chat 模型 通义千问 qwen3.5-flash
文档解析 Unstructured -
评估框架 Ragas 0.4+
日志美化 Rich 14+

贡献指南

欢迎提交 Issue 和 Pull Request!

  1. Fork 本仓库
  2. 创建特性分支 (git checkout -b feature/AmazingFeature)
  3. 提交更改 (git commit -m 'Add some AmazingFeature')
  4. 推送到分支 (git push origin feature/AmazingFeature)
  5. 创建 Pull Request

许可证

本项目采用 MIT 许可证 - 详见 LICENSE 文件


联系方式


致谢


⭐ 如果这个项目对你有帮助,请给个 Star!

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages