Dify 集成-文档处理

1. 集成概述

Dify 集成多种文档处理和网页爬取服务,用于从各类文档和网页中提取文本内容,构建知识库。

核心价值

  • 多格式支持: PDF、Word、Excel、HTML、Markdown 等
  • 网页爬取: 支持 Firecrawl、Jina Reader、WaterCrawl 等服务
  • 文档解析: 本地解析和第三方服务解析
  • 内容清洗: 提取主要内容,去除噪音

2. 支持的服务/产品

2.1 文档格式支持

格式 状态 解析方式 说明
PDF ✅ 支持 pypdfium2 本地 PDF 解析
Word (docx) ✅ 支持 python-docx Word 文档解析
Excel (xlsx) ✅ 支持 openpyxl Excel 表格解析
CSV ✅ 支持 csv module CSV 文件解析
Markdown ✅ 支持 markdown-it-py Markdown 解析
HTML ✅ 支持 BeautifulSoup HTML 解析
Text ✅ 支持 Native 纯文本文件
Notion ✅ 支持 Notion API Notion 页面导入

2.2 网页爬取服务

服务名称 状态 说明
Firecrawl ✅ 支持 高质量网页爬取和转换为 Markdown
Jina Reader ✅ 支持 LLM 友好的网页内容提取
WaterCrawl ✅ 支持 网页爬取服务
内置爬虫 ✅ 支持 基于 BeautifulSoup 的简单爬虫

2.3 文档处理服务

服务名称 状态 说明
Unstructured.io ✅ 支持 企业级文档解析服务
Azure Blob Extractor ✅ 支持 Azure 文档智能服务
本地处理 ✅ 支持 基于 Python 库的本地处理

3. 集成方式

3.1 架构设计

复制代码
┌─────────────────────────────────────────────────────┐
│             Document Processing                      │
├─────────────────────────────────────────────────────┤
│          Extract Processor                           │
│  ┌───────────────────────────────────────────────┐  │
│  │  - 选择合适的提取器                           │  │
│  │  - 协调提取流程                               │  │
│  │  - 内容后处理                                 │  │
│  └───────────────────────────────────────────────┘  │
├─────────────────────────────────────────────────────┤
│             Extractor Layer                          │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐            │
│  │   PDF    │ │  Word    │ │  Excel   │            │
│  │Extractor │ │Extractor │ │Extractor │  ...       │
│  └──────────┘ └──────────┘ └──────────┘            │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐            │
│  │Firecrawl │ │   Jina   │ │   HTML   │            │
│  │Extractor │ │Extractor │ │Extractor │  ...       │
│  └──────────┘ └──────────┘ └──────────┘            │
├─────────────────────────────────────────────────────┤
│        External Services (Optional)                  │
│  ┌──────────────┐ ┌──────────────┐                 │
│  │ Unstructured │ │  Firecrawl   │                 │
│  │   Service    │ │   Service    │    ...          │
│  └──────────────┘ └──────────────┘                 │
└─────────────────────────────────────────────────────┘

3.2 配置方式

bash 复制代码
# Unstructured.io 配置
RAG_ETL_TYPE=Unstructured
UNSTRUCTURED_API_URL=https://api.unstructured.io/general/v0/general
UNSTRUCTURED_API_KEY=your_api_key

# Firecrawl 配置
FIRECRAWL_API_KEY=your_api_key
FIRECRAWL_API_URL=https://api.firecrawl.dev

# Jina Reader 配置
JINA_READER_API_KEY=your_api_key

4. 代码实现

4.1 核心代码路径

📌 以下路径均为项目实际文件结构

复制代码
api/core/rag/extractor/
├── extractor_base.py           # 提取器基类
├── extract_processor.py        # 提取处理器
├── pdf_extractor.py           # PDF 提取器
├── word_extractor.py          # Word 提取器
├── excel_extractor.py         # Excel 提取器
├── csv_extractor.py           # CSV 提取器
├── markdown_extractor.py      # Markdown 提取器
├── html_extractor.py          # HTML 提取器
├── text_extractor.py          # 文本提取器
├── notion_extractor.py        # Notion 提取器
├── jina_reader_extractor.py   # Jina Reader 提取器
├── firecrawl/                 # Firecrawl 提取器
│   ├── firecrawl_app.py       # Firecrawl API 客户端
│   └── firecrawl_web_extractor.py  # Firecrawl 网页提取器
├── watercrawl/                # WaterCrawl 提取器
│   └── extractor.py           # WaterCrawl 网页提取器
├── unstructured/              # Unstructured 提取器
│   ├── unstructured_doc_extractor.py    # Word 文档提取
│   ├── unstructured_eml_extractor.py    # EML 邮件提取
│   ├── unstructured_epub_extractor.py   # EPUB 提取
│   ├── unstructured_markdown_extractor.py  # Markdown 提取
│   ├── unstructured_msg_extractor.py    # MSG 邮件提取
│   ├── unstructured_pptx_extractor.py   # PPTX 提取
│   ├── unstructured_ppt_extractor.py    # PPT 提取
│   └── unstructured_xml_extractor.py    # XML 提取
├── blob/                      # Blob 处理
│   └── blob.py
└── entity/                    # 实体定义
    └── extract_setting.py

4.2 提取器基类

📌 源代码引用 : api/core/rag/extractor/extractor_base.py

python 复制代码
# api/core/rag/extractor/extractor_base.py - 源代码引用
class BaseExtractor(ABC):
    """Interface for extract files."""

    @abstractmethod
    def extract(self):
        raise NotImplementedError

5. 使用示例

5.1 PDF 提取

⚠️ 概念性示例 : 以下代码为演示 PDF 提取的概念性示例,可参考源代码 api/core/rag/extractor/pdf_extractor.py

python 复制代码
from core.rag.extractor.pdf_extractor import PdfExtractor

# 提取 PDF 内容
extractor = PdfExtractor(
    file_path="/path/to/document.pdf",
    file_cache_key="cache_key"  # 可选,用于缓存
)

documents = extractor.extract()

for doc in documents:
    print(f"Page {doc.metadata['page']}: {doc.page_content}")

5.2 Word 提取

⚠️ 概念性示例 : 以下代码为演示 Word 提取的概念性示例,可参考源代码 api/core/rag/extractor/word_extractor.py

python 复制代码
from core.rag.extractor.word_extractor import WordExtractor

# 注意:WordExtractor 需要 tenant_id 和 user_id 参数
extractor = WordExtractor(
    file_path="/path/to/document.docx",
    tenant_id="your_tenant_id",
    user_id="your_user_id"
)
documents = extractor.extract()

5.3 Excel 提取

⚠️ 概念性示例 : 以下代码为演示 Excel 提取的概念性示例,可参考源代码 api/core/rag/extractor/excel_extractor.py

python 复制代码
from core.rag.extractor.excel_extractor import ExcelExtractor

extractor = ExcelExtractor(file_path="/path/to/spreadsheet.xlsx")
documents = extractor.extract()

# Excel 每行会成为一个 document
for doc in documents:
    print(f"Content: {doc.page_content}")
    print(f"Source: {doc.metadata['source']}")

5.4 Firecrawl 网页爬取

⚠️ 概念性示例 : 以下代码为演示 Firecrawl 使用的概念性示例,可参考源代码 api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py

python 复制代码
from core.rag.extractor.firecrawl.firecrawl_web_extractor import FirecrawlWebExtractor

# 爬取单个页面
extractor = FirecrawlWebExtractor(
    url="https://example.com",
    job_id="job_123",
    tenant_id="tenant_id",
    mode="scrape",  # 或 "crawl"
    only_main_content=True
)

documents = extractor.extract()

5.5 Jina Reader 网页提取

⚠️ 概念性示例 : 以下代码为演示 Jina Reader 使用的概念性示例,可参考源代码 api/core/rag/extractor/jina_reader_extractor.py

python 复制代码
from core.rag.extractor.jina_reader_extractor import JinaReaderWebExtractor

extractor = JinaReaderWebExtractor(
    url="https://example.com",
    job_id="job_123",
    tenant_id="tenant_id",
    mode="crawl"
)

documents = extractor.extract()

5.6 HTML 提取

⚠️ 概念性示例 : 以下代码为演示 HTML 提取的概念性示例,可参考源代码 api/core/rag/extractor/html_extractor.py

python 复制代码
from core.rag.extractor.html_extractor import HtmlExtractor

extractor = HtmlExtractor(file_path="/path/to/page.html")
documents = extractor.extract()

5.7 Notion 导入

⚠️ 概念性示例 : 以下代码为演示 Notion 导入的概念性示例,可参考源代码 api/core/rag/extractor/notion_extractor.py

python 复制代码
from core.rag.extractor.notion_extractor import NotionExtractor

extractor = NotionExtractor(
    notion_workspace_id="workspace_id",
    notion_obj_id="page_id",
    notion_page_type="page",  # 或 "database"
    tenant_id="tenant_id",
    # 可选参数:
    # document_model=document_model,
    # notion_access_token="token",
    # credential_id="credential_id"
)

documents = extractor.extract()

5.8 使用 Unstructured 服务

⚠️ 概念性示例 : 以下代码为演示 Unstructured 服务使用的概念性示例,可参考源代码 api/core/rag/extractor/unstructured/

python 复制代码
# Unstructured 提取器示例(使用 Word 文档)
from core.rag.extractor.unstructured.unstructured_doc_extractor import UnstructuredWordExtractor

extractor = UnstructuredWordExtractor(
    file_path="/path/to/document.docx",
    api_url="https://api.unstructured.io/general/v0/general",
    api_key="your_api_key"
)

documents = extractor.extract()

6. 错误处理

⚠️ 概念性示例: 本节所有代码为演示错误处理模式的概念性示例,非项目源代码

6.1 文件格式错误

python 复制代码
try:
    extractor = PdfExtractor(file_path=file_path)
    documents = extractor.extract()
except UnsupportedFileTypeError as e:
    logger.error(f"Unsupported file type: {e}")
except FileNotFoundError as e:
    logger.error(f"File not found: {e}")

6.2 网页爬取错误

python 复制代码
try:
    extractor = FirecrawlWebExtractor(url=url, ...)
    documents = extractor.extract()
except requests.exceptions.Timeout:
    logger.error("Firecrawl request timeout")
except requests.exceptions.RequestException as e:
    logger.error(f"Firecrawl error: {e}")

7. 性能优化

⚠️ 概念性示例: 本节所有代码为演示性能优化模式的概念性示例,非项目源代码

7.1 文件缓存

python 复制代码
from extensions.ext_storage import storage

# 缓存提取的文本
def extract_with_cache(file_path: str, cache_key: str):
    # 检查缓存
    try:
        cached_text = storage.load(cache_key).decode('utf-8')
        return [Document(page_content=cached_text)]
    except FileNotFoundError:
        pass
    
    # 提取
    extractor = PdfExtractor(file_path=file_path)
    documents = extractor.extract()
    
    # 保存缓存
    text = "\n\n".join([doc.page_content for doc in documents])
    storage.save(cache_key, text.encode('utf-8'))
    
    return documents

7.2 批量处理

python 复制代码
from concurrent.futures import ThreadPoolExecutor

def batch_extract(file_paths: list[str], max_workers: int = 5):
    """批量提取文档"""
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        futures = []
        for file_path in file_paths:
            extractor = get_extractor_for_file(file_path)
            future = executor.submit(extractor.extract)
            futures.append(future)
        
        results = [future.result() for future in futures]
    return results

7.3 流式处理大文件

python 复制代码
def extract_large_pdf_stream(file_path: str):
    """流式处理大型 PDF"""
    extractor = PdfExtractor(file_path=file_path)
    
    # 逐页处理
    for document in extractor.load():
        yield document
        # 可以在这里进行后处理或存储

8. 监控与日志

⚠️ 概念性示例: 本节所有代码为演示监控与日志模式的概念性示例,非项目源代码

python 复制代码
import time
import logging

logger = logging.getLogger(__name__)

def extract_with_logging(extractor, file_path: str):
    """带日志的提取"""
    start_time = time.time()
    
    try:
        logger.info(f"Starting extraction: {file_path}")
        documents = extractor.extract()
        
        end_time = time.time()
        logger.info(
            f"Extraction completed: {file_path}, "
            f"documents: {len(documents)}, "
            f"time: {end_time - start_time:.2f}s"
        )
        
        return documents
    except Exception as e:
        logger.error(f"Extraction failed: {file_path}, error: {e}")
        raise

9. 测试

⚠️ 概念性示例: 本节所有代码为演示测试模式的概念性示例,非项目源代码

python 复制代码
import pytest
from core.rag.extractor.pdf_extractor import PdfExtractor

def test_pdf_extraction():
    """测试 PDF 提取"""
    extractor = PdfExtractor(file_path="test.pdf")
    documents = extractor.extract()
    
    assert len(documents) > 0
    assert documents[0].page_content
    assert 'page' in documents[0].metadata

10. 扩展新提取器

⚠️ 概念性示例: 本节所有代码为演示如何扩展新提取器的概念性示例,非项目源代码

10.1 实现提取器类

python 复制代码
from core.rag.extractor.extractor_base import BaseExtractor
from core.rag.models.document import Document

class MyExtractor(BaseExtractor):
    """自定义提取器"""
    
    def __init__(self, file_path: str, **kwargs):
        self.file_path = file_path
    
    def extract(self) -> list[Document]:
        """实现提取逻辑"""
        # 读取文件
        with open(self.file_path, 'r') as f:
            content = f.read()
        
        # 处理内容
        processed_content = self.process(content)
        
        # 返回文档
        return [Document(
            page_content=processed_content,
            metadata={'source': self.file_path}
        )]
    
    def process(self, content: str) -> str:
        """内容处理逻辑"""
        # 实现特定的处理逻辑
        return content

10.2 注册提取器

python 复制代码
# 在 extract_processor.py 中注册
EXTRACTOR_MAP = {
    '.pdf': PdfExtractor,
    '.docx': WordExtractor,
    '.xlsx': ExcelExtractor,
    '.my': MyExtractor,  # 添加新提取器
}

11. 最佳实践

11.1 文件类型检测

  • 使用 MIME 类型检测而非文件扩展名
  • 验证文件大小限制
  • 检查文件内容完整性

11.2 内容清洗

  • 去除多余空白字符
  • 统一换行符
  • 移除不可见字符
  • 提取主要内容区域(网页)

11.3 错误处理

  • 捕获并记录所有异常
  • 提供降级方案
  • 返回有意义的错误信息

11.4 性能考虑

  • 大文件分块处理
  • 使用缓存减少重复解析
  • 异步处理多个文件
  • 限制并发数量
相关推荐
Aliex_git3 小时前
大模型相关概念 - LLM对话
人工智能·笔记·prompt·ai编程
福大大架构师每日一题3 小时前
dify 1.11.4 正式发布:全面强化安全性、修复多项关键问题,Node.js 升级至 24.13.0!附详细升级指南
node.js·dify
人工智能培训4 小时前
如何持续、安全地向大模型注入新知识?
人工智能·python·算法·大模型·大模型学习·大模型应用工程师·大模型工程师证书
audyxiao0015 小时前
AAAI 2025论文分享|Agent4Edu:基于大语言模型生成式智能体的个性化学习模拟器
llm·aaai·智能体·智慧教育·个性化学习
全干engineer5 小时前
一篇文章看懂AI名词-Prompt,Agent,MCP,FunctionCalling是什么
人工智能·ai·prompt·agent
唐钰小球5 小时前
layer.prompt文本框为空时也能提交的方法
javascript·prompt·layui
程序员老周6666 小时前
10.一文学会GPU与cuda原理,并从其原理来理解FlashAttention
人工智能·深度学习·语言模型·大模型·transformer·gpu算力·cuda
红尘炼丹客7 小时前
DeepSeek 新作 mHC 解读:用流形约束(Manifold Constraints)重构大模型残差连接
人工智能·深度学习·大模型·mhc
CoderJia程序员甲21 小时前
GitHub 热榜项目 - 日榜(2026-01-19)
git·ai·开源·llm·github