1.系统概览

下一代多模态智能

        现代文档中包含的多模态内容日益丰富,涵盖文本、图像、表格、公式、图表及多媒体等形式 —— 而传统以文本为核心的检索增强生成(RAG)系统无法对这些内容进行有效处理。万物检索增强生成(RAG-Anything)以 LightRAG 为基础构建,是一款全面的 “一体化多模态文档处理 RAG 系统”,专门用于应对这一挑战。

        作为一种统一解决方案,RAG-Anything 无需依赖多种专用工具,可在单一集成框架内实现对所有内容模态的无缝处理与查询。传统 RAG 方法在处理非文本元素时表现不佳,与之不同,我们的一体化系统具备全面的多模态检索能力。

        用户可通过一个统一界面,对包含交错文本、可视化图表、结构化表格及数学公式的文档进行查询。这种整合式方法使 RAG-Anything 在学术研究、技术文档、财务报告及企业知识管理等场景中具有极高价值 —— 这些场景中的文档往往包含丰富的混合内容,亟需统一的处理框架。

 核心功能

  • 端到端多模态处理流程—— 涵盖从文档导入、解析到智能多模态问答的完整工作流
  • 通用文档支持—— 无缝处理 PDF、Office 文档、图像及各类文件格式
  • 专项内容分析—— 为图像、表格、数学公式及异质内容类型配备专用处理器
  • 多模态知识图谱—— 自动提取实体并发现跨模态关系,提升理解能力
  • 自适应处理模式—— 支持基于 MinerU 的灵活解析,或直接注入多模态内容的工作流
  • 直接插入内容列表—— 无需文档解析,可直接插入来自外部来源的预解析内容列表
  • 混合智能检索—— 具备上下文理解能力,可对文本及多模态内容进行高级搜索

2.算法&架构

2.1 核心算法

万物检索增强生成(RAG-Anything)实现了一套高效的多阶段多模态处理流程。该流程通过智能协同与跨模态理解,从根本上扩展了传统检索增强生成(RAG)架构的能力,使其能够无缝处理各类内容模态。

2.1.1 文档解析阶段

系统通过自适应内容分解实现高保真文档提取,能智能分割异质元素,同时保留上下文关联。借助经过专项优化的解析器,系统可实现通用格式兼容。

核心组件:

  • MinerU 集成:借助 MinerU 实现高保真文档结构提取,在复杂布局中保留语义信息。
  • 自适应内容分解:自动将文档分割为连贯的文本块、视觉元素、结构化表格、数学公式及专项内容类型,同时保留上下文关联。
  • 通用格式支持:通过具备格式专属优化的专项解析器,全面处理 PDF、Office 文档(DOC/DOCX/PPT/PPTX/XLS/XLSX)、图像及新兴格式。

2.1.2 多模态内容理解与处理

系统会自动对内容进行分类,并通过优化后的渠道进行流转。它采用并行处理流程,对文本和多模态内容同时开展处理。在内容转换过程中,文档的层级结构及元素间关联会得到保留。

核心组件:

  • 自主内容分类与流转:自动识别不同内容类型、进行分类,并通过优化后的执行渠道完成流转。
  • 并行多流程架构:通过专用处理流程实现文本内容与多模态内容的并行执行。该方式在最大限度提升处理效率的同时,确保内容完整性不受影响。
  • 文档层级提取:在内容转换过程中,提取并保留文档原有的层级结构及元素间关联。

2.1.3. 多模态分析引擎

系统针对异质数据模态,部署具备模态感知能力的处理单元:

专项分析器:

视觉内容分析器:

  • 集成视觉模型用于图像分析
  • 基于视觉语义生成具备上下文感知能力的描述性说明文字
  • 提取视觉元素间的空间关系与层级结构

结构化数据解析器

  • 对表格及结构化数据格式进行系统性解析
  • 采用统计模式识别算法开展数据趋势分析
  • 识别多个表格数据集间的语义关系与依赖关系

数学表达式解析器

  • 高精度解析复杂数学表达式与公式
  • 原生支持 LaTeX 格式,实现与学术工作流的无缝集成
  • 建立数学公式与领域专属知识库间的概念映射

 可扩展模态处理器

  • 为自定义及新兴内容类型提供可配置的处理框架
  • 通过插件架构支持新模态处理器的动态集成
  • 支持为专项用例对处理流程进行运行时配置

2.1.4. 多模态知识图谱索引

多模态知识图谱构建模块将文档内容转化为结构化语义表征,提取多模态实体、建立跨模态关系,并保留层级化组织形式。系统通过加权相关性评分,实现优化的知识检索。

核心功能:

  • 多模态实体提取:将重要的多模态元素转化为结构化知识图谱实体,该过程包含语义标注与元数据保留。
  • 跨模态关系映射:通过自动关系推理算法,建立文本实体与多模态组件之间的语义关联及依赖关系。
  • 层级结构保留:通过 “从属(belongs_to)” 关系链维持文档原有组织形式,这些关系链可保留内容的逻辑层级与章节依赖。
  • 加权关系评分:为不同关系类型分配量化相关性分数,评分依据文档结构内的语义相近度与上下文重要性确定。

2.1.5. 模态感知检索

混合检索系统将向量相似性搜索与图遍历算法相结合,实现全面的内容检索。该系统采用模态感知排序机制,并维持检索元素间的关系连贯性,以确保交付具备上下文关联性的整合信息。

检索机制:

  • 向量 - 图融合:将向量相似性搜索与图遍历算法相集成。该方法同时利用语义嵌入与结构关系,实现全面的内容检索。
  • 模态感知排序:采用自适应评分机制,根据内容类型相关性对检索结果进行加权。系统会依据查询专属的模态偏好调整排序结果。
  • 关系连贯性维持:保留检索元素间的语义与结构关系,确保信息交付的连贯性及上下文完整性。

3.本地部署

3.1 Python 库部署(面向用户)

# Basic installation
pip install raganything

# With optional dependencies for extended format support:
pip install 'raganything[all]'              # All optional features
pip install 'raganything[image]'            # Image format conversion (BMP, TIFF, GIF, WebP)
pip install 'raganything[text]'             # Text file processing (TXT, MD)
pip install 'raganything[image,text]'       # Multiple features

3.2 源代码部署

1)下载 uv

# Install uv (if not already installed)
curl -LsSf https://astral.sh/uv/install.sh | sh

 2)基于 uv 进行源代码安装

# Clone and setup the project with uv
# git clone:将远程仓库(RAG-Anything,一个可能与 “万物检索” 相关的项目)克隆到本地。
git clone https://github.com/HKUDS/RAG-Anything.git
# 进入克隆后的项目目录,后续操作均在该目录下进行。
cd RAG-Anything

# 在虚拟环境中安装该软件包及其依赖项
uv sync

# 若遇到网络超时(尤其是针对 opencv 包时):
# UV_HTTP_TIMEOUT=120 uv sync

# 直接使用 uv 运行命令(推荐方式)
uv run python examples/raganything_example.py --help

# 安装可选依赖项
uv sync --extra image --extra text  # Specific extras
uv sync --all-extras                 # All optional features

可选依赖

  • [image] - 支持处理 BMP、TIFF、GIF、WebP 图像格式(需依赖 Pillow 库)
  • [text] - 支持处理 TXT 和 MD(Markdown)文件(需依赖 ReportLab 库)
  • [all] - 包含所有 Python 可选依赖项

办公文档处理要求

办公文档(.doc、.docx、.ppt、.pptx、.xls、.xlsx 格式)需安装 LibreOffice(自由办公套件)请从 LibreOffice 官方网站下载

  • Windows 系统:从官方网站下载安装程序
  • macOS 系统:执行命令 brew install --cask libreoffice 进行安装
  • Ubuntu/Debian 系统:执行命令 sudo apt-get install libreoffice 进行安装
  • CentOS/RHEL 系统:执行命令 sudo yum install libreoffice 进行安装

检查 MinerU 的安装情况

# Verify installation
mineru --version

# Check if properly configured
python -c "from raganything import RAGAnything; rag = RAGAnything(); print('✅ MinerU installed properly' if rag.check_parser_installation() else '❌ MinerU installation issue')"

3.2 参数设置

系统优化参数

环境变量

创建一个.env 文件(可参考.env.example 示例文件):

OPENAI_API_KEY=your_openai_api_key
OPENAI_BASE_URL=your_base_url  # Optional
OUTPUT_DIR=./output             # Default output directory for parsed documents
PARSER=mineru                   # Parser selection: mineru or docling
PARSE_METHOD=auto              # Parse method: auto, ocr, or txt

4.开发部署示例

4.1 端到端文档处理

  • 核心含义:指从文档的 “输入”(如上传、扫描、抓取)到 “输出”(如解析结果、结构化数据、存储或应用调用)的全流程自动化处理,无需人工在中间环节进行干预。例如,将一份 PDF 合同上传后,系统自动完成文字识别、信息提取(如甲方乙方、金额)、格式转换、数据校验并同步至数据库,即属于端到端文档处理。
  • 应用场景:广泛用于企业办公自动化(OA)、金融风控(如审核贷款材料)、医疗病历管理、政务文档处理等领域,能大幅提升文档处理效率并减少人为错误。
import asyncio
# 从raganything库导入核心类:RAGAnything(主处理类)和RAGAnythingConfig(配置类)
from raganything import RAGAnything, RAGAnythingConfig
# 从lightrag库导入OpenAI相关工具:带缓存的LLM调用函数和嵌入生成函数
from lightrag.llm.openai import openai_complete_if_cache, openai_embed
# 从lightrag工具类导入嵌入函数封装类
from lightrag.utils import EmbeddingFunc


async def main():
    # 设置API配置(调用OpenAI兼容模型的必要参数)
    api_key = "your-api-key"  # 替换为你的API密钥
    base_url = "your-base-url"  # 可选:API基础地址(如使用本地部署的模型)

    # 创建RAGAnything的配置对象
    config = RAGAnythingConfig(
        working_dir="./rag_storage",  # 工作目录:用于存储处理过程中的临时文件
        parser="mineru",  # 解析器选择:支持mineru或docling(文档解析工具)
        parse_method="auto",  # 解析方式:auto(自动判断)、ocr(光学字符识别)、txt(纯文本提取)
        enable_image_processing=True,  # 启用图像处理功能
        enable_table_processing=True,  # 启用表格处理功能
        enable_equation_processing=True,  # 启用公式处理功能
    )

    # 定义LLM模型调用函数(用于文本生成)
    def llm_model_func(prompt, system_prompt=None, history_messages=[], **kwargs):
        # 调用带缓存的OpenAI兼容接口,使用gpt-4o-mini模型
        return openai_complete_if_cache(
            "gpt-4o-mini",  # 模型名称
            prompt,  # 用户提示词
            system_prompt=system_prompt,  # 系统提示词(可选)
            history_messages=history_messages,  # 对话历史(可选)
            api_key=api_key,  # API密钥
            base_url=base_url,  # API基础地址
            **kwargs,  # 其他可选参数
        )

    # 定义视觉模型调用函数(用于处理图像等多模态内容)
    def vision_model_func(
        prompt, system_prompt=None, history_messages=[], image_data=None, messages=None, **kwargs
    ):
        # 若提供了messages格式(用于多模态增强查询),直接使用该格式调用
        if messages:
            return openai_complete_if_cache(
                "gpt-4o",  # 视觉模型使用gpt-4o(支持图像理解)
                "",  # 提示词为空(因messages已包含完整内容)
                system_prompt=None,
                history_messages=[],
                messages=messages,  # 多模态消息结构
                api_key=api_key,
                base_url=base_url,** kwargs,
            )
        # 传统单图像格式处理
        elif image_data:
            return openai_complete_if_cache(
                "gpt-4o",
                "",  # 提示词为空(内容在messages中定义)
                system_prompt=None,
                history_messages=[],
                # 构造包含文本和图像的消息(符合OpenAI API格式)
                messages=[
                    # 可选:添加系统提示词
                    {"role": "system", "content": system_prompt}
                    if system_prompt
                    else None,
                    # 用户消息:包含文本和图像数据(base64编码)
                    {
                        "role": "user",
                        "content": [
                            {"type": "text", "text": prompt},  # 文本部分
                            {
                                "type": "image_url",
                                "image_url": {
                                    "url": f"data:image/jpeg;base64,{image_data}"  # 图像部分(base64格式)
                                },
                            },
                        ],
                    }
                    if image_data
                    else {"role": "user", "content": prompt},  # 若无图像则仅文本
                ],
                api_key=api_key,
                base_url=base_url,
                **kwargs,
            )
        # 纯文本格式:直接复用LLM模型函数
        else:
            return llm_model_func(prompt, system_prompt, history_messages, **kwargs)

    # 定义嵌入函数(用于将文本转换为向量,支持语义检索)
    embedding_func = EmbeddingFunc(
        embedding_dim=3072,  # 嵌入向量维度(需与模型输出一致,text-embedding-3-large对应3072)
        max_token_size=8192,  # 最大令牌长度(模型支持的文本长度上限)
        # 嵌入生成函数:调用OpenAI的文本嵌入接口
        func=lambda texts: openai_embed(
            texts,  # 输入文本列表
            model="text-embedding-3-large",  # 嵌入模型名称
            api_key=api_key,
            base_url=base_url,
        ),
    )

    # 初始化RAGAnything实例(整合配置、模型和嵌入功能)
    rag = RAGAnything(
        config=config,  # 配置对象
        llm_model_func=llm_model_func,  # LLM文本生成函数
        vision_model_func=vision_model_func,  # 视觉模型处理函数
        embedding_func=embedding_func,  # 嵌入生成函数
    )

    # 处理文档(全流程:解析→处理→存储)
    await rag.process_document_complete(
        file_path="path/to/your/document.pdf",  # 待处理文档路径(替换为实际路径)
        output_dir="./output",  # 处理结果输出目录
        parse_method="auto"  # 解析方式(覆盖配置中的默认值)
    )

    # 查询处理后的内容
    # 纯文本查询 - 用于基础知识库检索
    text_result = await rag.aquery(
        "图表中显示的主要发现是什么?",  # 查询问题
        mode="hybrid"  # 检索模式:hybrid(混合检索,结合关键词和语义)
    )
    print("文本查询结果:", text_result)

    # 带特定多模态内容的多模态查询
    multimodal_result = await rag.aquery_with_multimodal(
        "解释这个公式及其与文档内容的相关性",  # 查询问题
        # 多模态内容:包含一个公式(LaTeX格式)和说明
        multimodal_content=[{
            "type": "equation",  # 内容类型:公式
            "latex": "P(d|q) = \\frac{P(q|d) \\cdot P(d)}{P(q)}",  # 公式的LaTeX表示
            "equation_caption": "文档相关性概率"  # 公式说明
        }],
        mode="hybrid"  # 检索模式:混合检索
    )
    print("多模态查询结果:", multimodal_result)


# 程序入口:运行异步主函数
if __name__ == "__main__":
    asyncio.run(main())

4.2 直接多模态内容处理

  • 核心含义:指不经过中间转换环节,直接对包含多种模态(如文本、图像、表格、公式、音频等)的内容进行解析、处理和理解的技术方式。例如,直接读取一份同时包含文字、图表和数学公式的 PDF 文档,无需先将图表转为纯文本或单独提取公式文件,即可完成信息识别与结构化处理。
  • 应用场景:常见于智能文档分析、多模态检索(如同时根据文本描述和图像特征查找内容)、AI 辅助的科研文献处理(需同时理解文字和公式)等领域,能减少信息损耗并提升处理效率。
import asyncio
# 从lightrag库导入核心类LightRAG(用于构建检索增强生成系统)
from lightrag import LightRAG
# 从lightrag的OpenAI模块导入带缓存的LLM调用函数和嵌入生成函数
from lightrag.llm.openai import openai_complete_if_cache, openai_embed
# 从lightrag工具类导入嵌入函数封装类(用于统一嵌入功能接口)
from lightrag.utils import EmbeddingFunc
# 从raganything的模态处理器模块导入图像和表格的专用处理器
from raganything.modalprocessors import ImageModalProcessor, TableModalProcessor


async def process_multimodal_content():
    # 设置API配置(调用OpenAI兼容模型的必要参数)
    api_key = "your-api-key"  # 替换为你的API密钥
    base_url = "your-base-url"  # 可选参数:API基础地址(如使用本地部署的模型)

    # 初始化LightRAG实例(构建检索增强生成系统核心)
    rag = LightRAG(
        working_dir="./rag_storage",  # 工作目录:用于存储检索所需的数据(如向量、缓存等)
        # 定义LLM模型调用函数(使用lambda匿名函数简化定义)
        llm_model_func=lambda prompt, system_prompt=None, history_messages=[], **kwargs: openai_complete_if_cache(
            "gpt-4o-mini",  # 指定使用的LLM模型:gpt-4o-mini(轻量型模型,适合基础文本生成)
            prompt,  # 用户输入的提示词
            system_prompt=system_prompt,  # 系统提示词(可选,用于定义模型角色/规则)
            history_messages=history_messages,  # 对话历史(可选,用于多轮对话上下文关联)
            api_key=api_key,  # 传入API密钥
            base_url=base_url,  # 传入API基础地址
            **kwargs,  # 其他可选参数(如温度系数、最大生成长度等)
        ),
        # 定义嵌入函数(用于将文本转换为向量,支持语义检索)
        embedding_func=EmbeddingFunc(
            embedding_dim=3072,  # 嵌入向量维度(需与使用的嵌入模型输出一致,text-embedding-3-large对应3072维)
            max_token_size=8192,  # 嵌入模型支持的最大令牌(token)长度
            # 嵌入生成逻辑(使用lambda匿名函数调用OpenAI嵌入接口)
            func=lambda texts: openai_embed(
                texts,  # 待转换为向量的文本列表
                model="text-embedding-3-large",  # 指定使用的嵌入模型
                api_key=api_key,  # 传入API密钥
                base_url=base_url,  # 传入API基础地址
            ),
        )
    )
    # 初始化LightRAG的存储系统(如向量数据库、缓存存储等,需异步调用)
    await rag.initialize_storages()

    # 初始化图像模态处理器(用于专门处理图像类多模态内容)
    image_processor = ImageModalProcessor(
        lightrag=rag,  # 关联已初始化的LightRAG实例(复用检索和存储能力)
        # 定义图像描述生成函数(用于生成图像的文本描述,支持多模态输入)
        modal_caption_func=lambda prompt, system_prompt=None, history_messages=[], image_data=None, **kwargs: 
            # 若存在图像数据(image_data不为空),使用gpt-4o模型处理多模态请求
            openai_complete_if_cache(
                "gpt-4o",  # 指定支持图像理解的模型:gpt-4o
                "",  # 提示词为空(完整内容通过messages参数传递)
                system_prompt=None,
                history_messages=[],
                # 构造符合OpenAI多模态API格式的消息
                messages=[
                    # 可选:若有系统提示词,添加系统角色消息
                    {"role": "system", "content": system_prompt} if system_prompt else None,
                    # 若有图像数据,构造包含文本和图像URL的用户消息
                    {"role": "user", "content": [
                        {"type": "text", "text": prompt},  # 文本部分(用户指令)
                        # 图像部分(base64编码的图像URL,用于模型直接识别图像内容)
                        {"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{image_data}"}}
                    ]} if image_data else {"role": "user", "content": prompt}  # 无图像时仅传递文本
                ],
                api_key=api_key,
                base_url=base_url,** kwargs,
            ) 
            # 若无图像数据,复用轻量型模型gpt-4o-mini处理纯文本请求
            if image_data else openai_complete_if_cache(
                "gpt-4o-mini",
                prompt,
                system_prompt=system_prompt,
                history_messages=history_messages,
                api_key=api_key,
                base_url=base_url,
                **kwargs,
            )
    )

    # 定义待处理的图像内容数据(包含路径、说明和脚注)
    image_content = {
        "img_path": "path/to/image.jpg",  # 图像文件路径(需替换为实际路径)
        "image_caption": ["图1:实验结果"],  # 图像标题(描述图像核心内容)
        "image_footnote": ["2024年采集的数据"]  # 图像脚注(补充图像相关背景信息)
    }

    # 处理图像内容(生成图像描述和实体信息,需异步调用)
    # 返回值:description(图像的文本描述)、entity_info(图像中的关键实体信息)
    description, entity_info = await image_processor.process_multimodal_content(
        modal_content=image_content,  # 传入图像内容数据
        content_type="image",  # 指定内容类型为图像
        file_path="research_paper.pdf",  # 关联的源文件路径(如该图像来自某篇研究论文)
        entity_name="实验结果图"  # 该图像实体的名称(用于后续检索和标识)
    )

    # 初始化表格模态处理器(用于专门处理表格类多模态内容)
    table_processor = TableModalProcessor(
        lightrag=rag,  # 关联已初始化的LightRAG实例
        # 定义表格描述生成函数(表格无需图像模型,用轻量型模型即可)
        modal_caption_func=lambda prompt, system_prompt=None, history_messages=[], **kwargs: openai_complete_if_cache(
            "gpt-4o-mini",  # 指定使用轻量型模型处理表格文本
            prompt,  # 用户对表格的处理指令(如"分析表格数据")
            system_prompt=system_prompt,
            history_messages=history_messages,
            api_key=api_key,
            base_url=base_url,
            **kwargs,
        )
    )

    # 定义待处理的表格内容数据(Markdown格式表格,包含标题和脚注)
    table_content = {
        "table_body": """
        | 方法        | 准确率  | F1分数  |
        |-------------|---------|---------|
        | RAGAnything | 95.2%   | 0.94    |
        | 基准方法    | 87.3%   | 0.85    |
        """,  # 表格主体(Markdown格式,清晰展示数据对比)
        "table_caption": ["性能对比"],  # 表格标题(说明表格核心用途)
        "table_footnote": ["测试数据集上的结果"]  # 表格脚注(说明数据来源场景)
    }

    # 处理表格内容(生成表格描述和实体信息,需异步调用)
    description, entity_info = await table_processor.process_multimodal_content(
        modal_content=table_content,  # 传入表格内容数据
        content_type="table",  # 指定内容类型为表格
        file_path="research_paper.pdf",  # 关联的源文件路径(如该表格来自某篇研究论文)
        entity_name="性能结果表"  # 该表格实体的名称(用于后续检索和标识)
    )


# 程序入口:运行异步函数process_multimodal_content
if __name__ == "__main__":
    asyncio.run(process_multimodal_content())

4.3 批量处理

# Process multiple documents
await rag.process_folder_complete(
    folder_path="./documents",
    output_dir="./output",
    file_extensions=[".pdf", ".docx", ".pptx"],
    recursive=True,
    max_workers=4
)

4.4 自定义模态处理器

from raganything.modalprocessors import GenericModalProcessor

class CustomModalProcessor(GenericModalProcessor):
    async def process_multimodal_content(self, modal_content, content_type, file_path, entity_name):
        # Your custom processing logic
        enhanced_description = await self.analyze_custom_content(modal_content)
        entity_info = self.create_custom_entity(enhanced_description, entity_name)
        return await self._create_entity_and_chunk(enhanced_description, entity_info, file_path)

5.询问选项

RAG-Anything 提供三种查询方式:

1)纯文本查询:使用 LightRAG 进行直接知识库检索

# Different query modes for text queries
text_result_hybrid = await rag.aquery("Your question", mode="hybrid")
text_result_local = await rag.aquery("Your question", mode="local")
text_result_global = await rag.aquery("Your question", mode="global")
text_result_naive = await rag.aquery("Your question", mode="naive")

# Synchronous version
sync_text_result = rag.query("Your question", mode="hybrid")

2)VLM 增强型查询 —— 利用 VLM 自动分析检索上下文内的图像

# VLM增强型查询(当提供vision_model_func时会自动启用)
# 说明:当RAG实例初始化时配置了视觉模型函数(vision_model_func),系统会自动开启VLM增强
vlm_result = await rag.aquery(
    "分析文档中的图表和图形",  # 查询内容:针对文档中的图表和图形进行分析
    mode="hybrid"  # 检索模式:混合模式(结合关键词检索和语义检索)
    # 当vision_model_func可用时,vlm_enhanced=True会被自动设置(无需手动指定)
)

# 手动控制VLM增强功能
# 强制启用VLM增强(即使系统未自动启用,也会触发VLM处理图像)
vlm_enabled = await rag.aquery(
    "文档中的图像展示了什么内容?",  # 查询内容:询问图像的具体内容
    mode="hybrid",  # 检索模式:混合模式
    vlm_enhanced=True  # 手动强制启用VLM增强(确保调用视觉模型分析图像)
)

# 强制禁用VLM增强(即使系统支持,也不使用VLM处理图像)
vlm_disabled = await rag.aquery(
    "文档中的图像展示了什么内容?",  # 查询内容:同样询问图像内容,但禁用VLM
    mode="hybrid",  # 检索模式:混合模式
    vlm_enhanced=False  # 手动强制禁用VLM增强(仅用文本检索,不分析图像)
)

# 当文档包含图像时,VLM可以直接查看并分析这些图像
# 系统会自动执行以下步骤:
# 1. 检索包含图像路径的相关上下文(从知识库中找到关联图像的文本信息)
# 2. 加载图像并编码为base64格式(便于通过API传递给VLM)
# 3. 将文本上下文和图像一并发送给VLM,进行综合分析(结合图文信息生成回答)

3)多模态查询 —— 支持特定多模态内容分析的增强型查询

# 带表格数据的查询(将外部表格与文档内容对比分析)
table_result = await rag.aquery_with_multimodal(
    "将这些性能指标与文档内容进行对比",  # 查询指令:要求对比外部表格数据与文档中的内容
    # 多模态内容:包含一个表格数据(用于查询的外部信息)
    multimodal_content=[{
        "type": "table",  # 内容类型:表格
        "table_data": """Method,Accuracy,Speed
                        RAGAnything,95.2%,120ms
                        Traditional,87.3%,180ms""",  # 表格数据(CSV格式,包含方法、准确率、速度)
        "table_caption": "性能对比"  # 表格标题(说明表格核心内容)
    }],
    mode="hybrid"  # 检索模式:混合模式(结合关键词和语义检索文档内容)
)

# 带公式内容的查询(分析特定公式与文档的关联性)
equation_result = await rag.aquery_with_multimodal(
    "解释这个公式及其与文档内容的相关性",  # 查询指令:要求解释公式含义及与文档的关联
    # 多模态内容:包含一个公式(用于查询的外部信息)
    multimodal_content=[{
        "type": "equation",  # 内容类型:公式
        "latex": "P(d|q) = \\frac{P(q|d) \\cdot P(d)}{P(q)}",  # 公式的LaTeX格式(贝叶斯定理,用于文档相关性计算)
        "equation_caption": "文档相关性概率"  # 公式标题(说明公式的物理意义)
    }],
    mode="hybrid"  # 检索模式:混合模式(结合关键词和语义检索文档内容)
)

6.加载已有的 LightRAG 实例

import asyncio
# 从raganything库导入核心类:RAGAnything(多模态RAG主类)和RAGAnythingConfig(配置类)
from raganything import RAGAnything, RAGAnythingConfig
# 从lightrag库导入核心类LightRAG(检索增强生成框架)
from lightrag import LightRAG
# 从lightrag的OpenAI模块导入带缓存的LLM调用函数和嵌入生成函数
from lightrag.llm.openai import openai_complete_if_cache, openai_embed
# 从lightrag的知识图谱模块导入流水线状态初始化函数
from lightrag.kg.shared_storage import initialize_pipeline_status
# 从lightrag工具类导入嵌入函数封装类
from lightrag.utils import EmbeddingFunc
# 导入os模块用于文件路径操作
import os


async def load_existing_lightrag():
    # 设置API配置(调用OpenAI兼容模型的必要参数)
    api_key = "your-api-key"  # 替换为你的API密钥
    base_url = "your-base-url"  # 可选:API基础地址(如使用本地部署的模型)

    # 第一步:创建或加载已有的LightRAG实例
    lightrag_working_dir = "./existing_lightrag_storage"  # LightRAG实例的工作目录(用于存储数据)

    # 检查是否存在之前的LightRAG实例
    if os.path.exists(lightrag_working_dir) and os.listdir(lightrag_working_dir):
        print("✅ 找到已存在的LightRAG实例,正在加载...")
    else:
        print("❌ 未找到已存在的LightRAG实例,将创建新实例")

    # 用配置创建/加载LightRAG实例(若目录存在则加载,否则新建)
    lightrag_instance = LightRAG(
        working_dir=lightrag_working_dir,  # 工作目录(存储向量数据、缓存等)
        # 定义LLM模型调用函数(使用lambda简化定义,调用带缓存的OpenAI接口)
        llm_model_func=lambda prompt, system_prompt=None, history_messages=[], **kwargs: openai_complete_if_cache(
            "gpt-4o-mini",  # 使用的LLM模型:gpt-4o-mini(轻量型文本生成模型)
            prompt,  # 用户提示词
            system_prompt=system_prompt,  # 系统提示词(可选,定义模型行为)
            history_messages=history_messages,  # 对话历史(可选,支持多轮对话)
            api_key=api_key,  # 传入API密钥
            base_url=base_url,  # 传入API基础地址
            **kwargs,  # 其他可选参数(如温度系数、最大生成长度等)
        ),
        # 定义嵌入函数(将文本转换为向量,用于语义检索)
        embedding_func=EmbeddingFunc(
            embedding_dim=3072,  # 嵌入向量维度(需与模型匹配,text-embedding-3-large对应3072维)
            max_token_size=8192,  # 模型支持的最大令牌长度
            # 嵌入生成逻辑(调用OpenAI的嵌入接口)
            func=lambda texts: openai_embed(
                texts,  # 待转换的文本列表
                model="text-embedding-3-large",  # 使用的嵌入模型
                api_key=api_key,  # 传入API密钥
                base_url=base_url,  # 传入API基础地址
            ),
        )
    )

    # 初始化存储系统(若有现有数据,会自动加载;否则初始化新存储)
    await lightrag_instance.initialize_storages()
    await initialize_pipeline_status()  # 初始化流水线状态(确保处理流程正常运行)

    # 定义用于图像处理的视觉模型函数(支持VLM增强型查询)
    def vision_model_func(
        prompt, system_prompt=None, history_messages=[], image_data=None, messages=None, **kwargs
    ):
        # 若提供messages格式(多模态VLM增强查询专用),直接使用该格式调用模型
        if messages:
            return openai_complete_if_cache(
                "gpt-4o",  # 使用支持图像的模型:gpt-4o(视觉-语言模型)
                "",  # 提示词为空(内容已包含在messages中)
                system_prompt=None,
                history_messages=[],
                messages=messages,  # 多模态消息结构(含文本和图像信息)
                api_key=api_key,
                base_url=base_url,** kwargs,
            )
        # 传统单图像格式处理(当存在图像数据时)
        elif image_data:
            return openai_complete_if_cache(
                "gpt-4o",  # 使用gpt-4o处理图像
                "",  # 提示词为空(内容在messages中定义)
                system_prompt=None,
                history_messages=[],
                # 构造包含文本和图像的消息(符合OpenAI多模态API格式)
                messages=[
                    # 可选:添加系统提示词(若存在)
                    {"role": "system", "content": system_prompt}
                    if system_prompt
                    else None,
                    # 用户消息:包含文本和base64编码的图像
                    {
                        "role": "user",
                        "content": [
                            {"type": "text", "text": prompt},  # 文本部分(用户指令)
                            {
                                "type": "image_url",
                                "image_url": {
                                    "url": f"data:image/jpeg;base64,{image_data}"  # 图像部分(base64格式)
                                },
                            },
                        ],
                    }
                    if image_data
                    else {"role": "user", "content": prompt},  # 若无图像则仅文本
                ],
                api_key=api_key,
                base_url=base_url,
                **kwargs,
            )
        # 纯文本格式:复用LightRAG实例的LLM函数
        else:
            return lightrag_instance.llm_model_func(prompt, system_prompt, history_messages, **kwargs)

    # 使用已有的LightRAG实例初始化RAGAnything(多模态RAG系统)
    rag = RAGAnything(
        lightrag=lightrag_instance,  # 传入已加载/创建的LightRAG实例
        vision_model_func=vision_model_func,  # 关联视觉模型函数(支持图像处理)
        # 注意:工作目录、LLM模型函数、嵌入函数等参数会从lightrag_instance继承
    )

    # 查询已有的知识库(获取该LightRAG实例中已处理的数据信息)
    result = await rag.aquery(
        "这个LightRAG实例中处理过哪些数据?",  # 查询问题
        mode="hybrid"  # 检索模式:混合模式(结合关键词和语义检索)
    )
    print("查询结果:", result)

    # 向已有的LightRAG实例中添加新的多模态文档
    await rag.process_document_complete(
        file_path="path/to/new/multimodal_document.pdf",  # 新文档路径(替换为实际路径)
        output_dir="./output"  # 处理结果输出目录
    )


# 程序入口:运行异步函数load_existing_lightrag
if __name__ == "__main__":
    asyncio.run(load_existing_lightrag())

7.直接插入内容列表

若您已拥有预先解析好的内容列表(例如来自外部解析器或之前的处理流程),可无需进行文档解析,直接将其插入到 RAGAnything 中:

import asyncio
# 从raganything库导入核心类:RAGAnything(多模态RAG主类)和RAGAnythingConfig(配置类)
from raganything import RAGAnything, RAGAnythingConfig
# 从lightrag的OpenAI模块导入带缓存的LLM调用函数和嵌入生成函数
from lightrag.llm.openai import openai_complete_if_cache, openai_embed
# 从lightrag工具类导入嵌入函数封装类(统一嵌入功能接口)
from lightrag.utils import EmbeddingFunc


async def insert_content_list_example():
    # 设置API配置(调用OpenAI兼容模型的必要参数)
    api_key = "your-api-key"  # 替换为你的API密钥
    base_url = "your-base-url"  # 可选:API基础地址(如使用本地部署的模型)

    # 创建RAGAnything的配置对象
    config = RAGAnythingConfig(
        working_dir="./rag_storage",  # 工作目录:存储处理过程中的数据(如向量、缓存)
        enable_image_processing=True,  # 启用图像处理功能
        enable_table_processing=True,  # 启用表格处理功能
        enable_equation_processing=True,  # 启用公式处理功能
    )

    # 定义LLM模型调用函数(用于文本生成)
    def llm_model_func(prompt, system_prompt=None, history_messages=[], **kwargs):
        return openai_complete_if_cache(
            "gpt-4o-mini",  # 使用的LLM模型:gpt-4o-mini(轻量型文本生成模型)
            prompt,  # 用户输入的提示词
            system_prompt=system_prompt,  # 系统提示词(可选,定义模型行为)
            history_messages=history_messages,  # 对话历史(可选,支持多轮对话)
            api_key=api_key,  # 传入API密钥
            base_url=base_url,  # 传入API基础地址
            **kwargs,  # 其他可选参数(如温度系数、最大生成长度)
        )

    # 定义视觉模型调用函数(用于处理图像等多模态内容)
    def vision_model_func(prompt, system_prompt=None, history_messages=[], image_data=None, messages=None, **kwargs):
        # 若提供messages格式(多模态VLM增强查询专用),直接使用该格式调用模型
        if messages:
            return openai_complete_if_cache(
                "gpt-4o",  # 使用支持图像的模型:gpt-4o(视觉-语言模型)
                "",  # 提示词为空(完整内容已包含在messages中)
                system_prompt=None,
                history_messages=[],
                messages=messages,  # 多模态消息结构(含文本、图像等信息)
                api_key=api_key,
                base_url=base_url,** kwargs,
            )
        # 传统单图像格式处理(当存在图像数据时)
        elif image_data:
            return openai_complete_if_cache(
                "gpt-4o",  # 用gpt-4o解析图像内容
                "",  # 提示词为空(内容在messages中定义)
                system_prompt=None,
                history_messages=[],
                # 构造符合OpenAI多模态API格式的消息
                messages=[
                    # 可选:添加系统提示词(若存在)
                    {"role": "system", "content": system_prompt} if system_prompt else None,
                    # 用户消息:包含文本和base64编码的图像
                    {
                        "role": "user",
                        "content": [
                            {"type": "text", "text": prompt},  # 文本指令部分
                            # 图像部分(base64格式URL,供模型识别)
                            {"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{image_data}"}}
                        ],
                    } if image_data else {"role": "user", "content": prompt},  # 无图像时仅传文本
                ],
                api_key=api_key,
                base_url=base_url,
                **kwargs,
            )
        # 纯文本格式:复用LLM模型函数
        else:
            return llm_model_func(prompt, system_prompt, history_messages, **kwargs)

    # 定义嵌入函数(将文本转换为向量,支持语义检索)
    embedding_func = EmbeddingFunc(
        embedding_dim=3072,  # 嵌入向量维度(需与模型匹配,text-embedding-3-large对应3072维)
        max_token_size=8192,  # 模型支持的最大令牌(token)长度
        # 嵌入生成逻辑:调用OpenAI的文本嵌入接口
        func=lambda texts: openai_embed(
            texts,  # 待转换为向量的文本列表
            model="text-embedding-3-large",  # 使用的嵌入模型
            api_key=api_key,  # 传入API密钥
            base_url=base_url,  # 传入API基础地址
        ),
    )

    # 初始化RAGAnything实例(整合配置、模型和嵌入功能)
    rag = RAGAnything(
        config=config,  # 配置对象
        llm_model_func=llm_model_func,  # LLM文本生成函数
        vision_model_func=vision_model_func,  # 视觉模型处理函数
        embedding_func=embedding_func,  # 嵌入生成函数
    )

    # 示例:来自外部源的预先解析好的内容列表(无需再解析文档)
    content_list = [
        # 文本类型内容
        {
            "type": "text",  # 内容类型:文本
            "text": "这是我们研究论文的引言部分。",  # 文本内容
            "page_idx": 0  # 该内容所在的页码
        },
        # 图像类型内容
        {
            "type": "image",  # 内容类型:图像
            "img_path": "/absolute/path/to/figure1.jpg",  # 图像绝对路径(重要:必须用绝对路径)
            "image_caption": ["图1:系统架构"],  # 图像标题
            "image_footnote": ["来源:作者原创设计"],  # 图像脚注(补充信息)
            "page_idx": 1  # 图像所在页码
        },
        # 表格类型内容
        {
            "type": "table",  # 内容类型:表格
            "table_body": "| 方法   | 准确率  | F1分数  |\n|--------|----------|----------|\n| 我们的方法 | 95.2%   | 0.94    |\n| 基准方法 | 87.3%   | 0.85    |",  # Markdown格式表格
            "table_caption": ["表1:性能对比"],  # 表格标题
            "table_footnote": ["测试数据集上的结果"],  # 表格脚注
            "page_idx": 2  # 表格所在页码
        },
        # 公式类型内容
        {
            "type": "equation",  # 内容类型:公式
            "latex": "P(d|q) = \\frac{P(q|d) \\cdot P(d)}{P(q)}",  # 公式的LaTeX格式(贝叶斯定理)
            "text": "文档相关性概率公式",  # 公式的文本说明
            "page_idx": 3  # 公式所在页码
        },
        # 另一部分文本内容
        {
            "type": "text",
            "text": "总之,我们的方法在所有指标上都表现出更优的性能。",
            "page_idx": 4  # 文本所在页码
        }
    ]

    # 直接插入内容列表(无需解析文档)
    await rag.insert_content_list(
        content_list=content_list,  # 传入预先解析好的内容列表
        file_path="research_paper.pdf",  # 参考文件名(用于引用该内容所属的文档)
        split_by_character=None,  # 可选:按字符拆分文本的长度(None表示不手动拆分)
        split_by_character_only=False,  # 可选:是否仅按字符拆分(False表示结合语义拆分)
        doc_id=None,  # 可选:自定义文档ID(未提供则自动生成)
        display_stats=True  # 显示内容插入后的统计信息(如插入的内容数量)
    )

    # 查询已插入的内容
    result = await rag.aquery(
        "研究中提到的关键发现和性能指标是什么?",  # 查询问题(针对插入的内容)
        mode="hybrid"  # 检索模式:混合模式(结合关键词和语义检索)
    )
    print("查询结果:", result)

    # 也可以插入多个内容列表(为不同文档指定不同ID)
    another_content_list = [
        # 另一文档的文本内容
        {
            "type": "text",
            "text": "这是另一篇文档的内容。",
            "page_idx": 0  # 内容所在页码
        },
        # 另一文档的表格内容
        {
            "type": "table",
            "table_body": "| 特征   | 数值   |\n|---------|-------|\n| 速度   | 快    |\n| 准确率 | 高    |",  # Markdown表格
            "table_caption": ["特征对比"],  # 表格标题
            "page_idx": 1  # 表格所在页码
        }
    ]

    # 插入第二个内容列表(指定自定义文档ID)
    await rag.insert_content_list(
        content_list=another_content_list,
        file_path="another_document.pdf",  # 第二个文档的参考文件名
        doc_id="custom-doc-id-123"  # 自定义文档ID(便于后续识别该文档)
    )


# 程序入口:运行异步函数
if __name__ == "__main__":
    asyncio.run(insert_content_list_example())

内容列表格式:

content_list 需遵循标准格式,其中每个元素为一个字典,包含以下内容:

  • 文本内容:{"type": "text", "text": "内容文本", "page_idx": 0}
  • 图像内容:{"type": "image", "img_path": "/ 绝对路径 / 至 / 图像.jpg", "image_caption": ["标题"], "image_footnote": ["注释"], "page_idx": 1}
  • 表格内容:{"type": "table", "table_body": "Markdown 格式表格", "table_caption": ["标题"], "table_footnote": ["注释"], "page_idx": 2}
  • 公式内容:{"type": "equation", "latex": "LaTeX 格式公式", "text": "描述说明", "page_idx": 3}
  • 通用内容:{"type": "自定义类型", "content": "任意内容", "page_idx": 4}

重要说明:

  • img_path(图像路径):必须是图像文件的绝对路径(例如:/home/user/images/chart.jpg 或 C:\Users\user\images\chart.jpg)

  • page_idx(页码索引):表示该内容在原始文档中所在的页码(采用 0 开始的索引方式,即首页页码为 0)

  • 内容顺序:列表中的内容项将按照其在列表中出现的顺序进行处理

以下场景使用此方法尤为适用:

  1. 您拥有来自外部解析器(非 MinerU/Docling 解析器)的内容

  2. 您需要处理通过编程方式生成的内容

  3. 您需要将来自多个来源的内容插入到同一个知识库中

  4. 您拥有缓存的解析结果,希望重复利用这些结果

8.实际应用演示

examples/ 目录包含完整的使用示例:

  • raganything_example.py:使用 MinerU 进行端到端文档处理
  • modalprocessors_example.py:直接多模态内容处理
  • office_document_test.py:使用 MinerU 进行办公文档解析测试(无需 API 密钥)
  • image_format_test.py:使用 MinerU 进行图像格式解析测试(无需 API 密钥)
  • text_format_test.py:使用 MinerU 进行文本格式解析测试(无需 API 密钥)

运行例子:

# End-to-end processing with parser selection
python examples/raganything_example.py path/to/document.pdf --api-key YOUR_API_KEY --parser mineru

# Direct modal processing
python examples/modalprocessors_example.py --api-key YOUR_API_KEY

# Office document parsing test (MinerU only)
python examples/office_document_test.py --file path/to/document.docx

# Image format parsing test (MinerU only)
python examples/image_format_test.py --file path/to/image.bmp

# Text format parsing test (MinerU only)
python examples/text_format_test.py --file path/to/document.md

# Check LibreOffice installation
python examples/office_document_test.py --check-libreoffice --file dummy

# Check PIL/Pillow installation
python examples/image_format_test.py --check-pillow --file dummy

# Check ReportLab installation
python examples/text_format_test.py --check-reportlab --file dummy

注意:为保证向后兼容性,仍支持旧版环境变量名称:

  • MINERU_PARSE_METHOD 已废弃,请使用 PARSE_METHOD

注意:仅在结合 LLM 进行完整 RAG 处理时,才需要 API 密钥。解析测试文件(office_document_test.py 和 image_format_test.py)仅用于测试解析器功能,无需 API 密钥。

解析器配置

RAGAnything 目前支持多种解析器,每种解析器均具备特定优势:

MinerU 解析器

  • 支持 PDF、图像、办公文档等多种格式
  • 具备强大的光学字符识别(OCR)与表格提取能力
  • 支持 GPU 加速

Docling 解析器

  • 针对办公文档与 HTML 文件优化
  • 能更好地保留文档结构
  • 原生支持多种办公文档格式

MinerU 设置

# MinerU 2.0 uses command-line parameters instead of config files
# Check available options:
mineru --help

# Common configurations:
mineru -p input.pdf -o output_dir -m auto    # Automatic parsing mode
mineru -p input.pdf -o output_dir -m ocr     # OCR-focused parsing
mineru -p input.pdf -o output_dir -b pipeline --device cuda  # GPU acceleration

你也可以通过 RAGAnything 的参数来配置解析(过程):

# 带解析器选择的基础解析配置
await rag.process_document_complete(
    file_path="document.pdf",  # 待处理文档的路径(示例为PDF文件,需替换为实际文件路径)
    output_dir="./output/",    # 解析结果的输出目录(结构化内容、中间文件等将保存至此)
    parse_method="auto",       # 解析方式:可选"auto"(自动判断文档类型选择最优方式)、"ocr"(光学字符识别,适用于图片/扫描件)、"txt"(纯文本提取,适用于可直接读取的文本类文档)
    parser="mineru"            # 可选解析器:支持"mineru"或"docling",不指定时使用默认解析器
)

# 带特殊参数的高级解析配置
await rag.process_document_complete(
    file_path="document.pdf",  # 待处理文档路径(支持多格式,此处以PDF为例)
    output_dir="./output/",    # 解析结果输出目录
    parse_method="auto",       # 解析方式:"auto"(自动)、"ocr"(光学字符识别)、"txt"(纯文本)
    parser="mineru",           # 解析器选择:"mineru"或"docling"

    # MinerU专属参数 —— 支持以下所有关键字参数(kwargs):
    lang="ch",                 # OCR优化的文档语言(例如"ch"中文、"en"英文、"ja"日文等,提升识别精度)
    device="cuda:0",           # 推理设备:可选"cpu"(中央处理器)、"cuda"(英伟达GPU通用标识)、"cuda:0"(指定第1块GPU)、"npu"(昇腾NPU)、"mps"(苹果Metal加速)
    start_page=0,              # 起始页码(PDF专用,0为起始索引,即从第1页开始解析)
    end_page=10,               # 结束页码(PDF专用,0为起始索引,即解析到第11页结束)
    formula=True,              # 是否启用公式解析(True为启用,可提取文档中的公式内容)
    table=True,                # 是否启用表格解析(True为启用,可提取文档中的表格并转为结构化数据)
    backend="pipeline",        # 解析后端:可选pipeline(默认流水线模式)、vlm-transformers(VLM transformer框架)、vlm-sglang-engine(SGLang本地引擎)、vlm-sglang-client(SGLang客户端)
    source="huggingface",      # 模型来源:可选"huggingface"(Hugging Face平台)、"modelscope"(ModelScope平台)、"local"(本地模型文件)
    # vlm_url="http://127.0.0.1:3000"  # 当使用backend=vlm-sglang-client(SGLang客户端)时,需指定服务地址(示例为本地地址,需根据实际服务调整)

    # RAGAnything标准参数
    display_stats=True,        # 是否显示内容统计信息(True为显示,如解析的内容数量、类型分布等)
    split_by_character=None,   # 可选文本拆分字符(None表示不按特定字符拆分,默认按语义拆分文本)
    doc_id=None                # 可选文档ID(不指定时自动生成唯一ID,用于标识该文档在知识库中的身份)
)

说明:

MinerU 2.0 不再使用 magic-pdf.json 配置文件。所有设置现在均通过命令行参数或函数参数传递。RAG-Anything 目前支持多种文档解析器 —— 您可根据需求在 MinerU 和 Docling 之间进行选择。

数据处理要求

不同内容类型需依赖特定的可选组件:

  • 办公文档(.doc、.docx、.ppt、.pptx、.xls、.xlsx):需安装 LibreOffice
  • 扩展图像格式(.bmp、.tiff、.gif、.webp):通过 pip install raganything[image] 命令安装
  • 文本文件(.txt、.md):通过 pip install raganything[text] 命令安装

📋 快速安装:执行 pip install raganything[all] 可启用所有格式支持(仅包含 Python 依赖项 ——LibreOffice 仍需单独安装)

支持输入数据内容类型

文档格式

  • PDF 文件:研究论文、报告、演示文稿
  • 办公文档:DOC、DOCX、PPT、PPTX、XLS、XLSX
  • 图像文件:JPG、PNG、BMP、TIFF、GIF、WebP
  • 文本文件:TXT、MD(Markdown 格式)

多模态元素

  • 图像:照片、示意图、图表、截图
  • 表格:数据表格、对比图表、统计摘要
  • 公式:LaTeX 格式的数学公式
  • 通用内容:通过可扩展处理器支持的自定义内容类型

参考文献

[1] HKUDS/RAG-Anything: "RAG-Anything: All-in-One RAG Framework"

[2]RAGAnything架构炸裂!私有化知识库终极方案,企业级部署一篇封神_rag anything-CSDN博客

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐