人人都会AI编程

6.1 数据源接入

更新时间:2026-07-12

RAG 系统的知识库不是凭空产生的,它需要从各类数据源中提取文档。数据源接入是整个流水线的起点,接入的质量和覆盖面直接决定了后续检索和生成的上限。本节介绍常见的数据源类型、接入方式以及实践中需要注意的要点。

6.1.1 常见数据源类型

企业内部的知识通常散落在不同系统中,RAG 系统需要能够对接这些异构来源。最常见的包括:

  • 本地文件:PDF、Word、Excel、PPT、TXT、Markdown 等。这类文件通常存储在文件服务器、NAS 或云盘上,是最基础的数据源。
  • 网页与内部站点:公司内部 Wiki(如 Confluence)、公告门户、产品帮助中心。通常以 HTML 页面形式存在。
  • 数据库中的结构化文本:虽然 RAG 主要用于非结构化文本,但很多知识以文本字段形式存储在关系型数据库中,例如产品描述、FAQ 列表、政策条款等。
  • 实时 API 输出:部分信息是动态生成的,比如从 CRM 查询的客户服务记录、从 ERP 获取的物料说明,可以通过 API 拉取后再转化为文本切片。
  • 聊天记录与工单:历史客服对话、技术支持工单中沉淀了大量经验,经过脱敏和整理后也是高价值知识。

真实场景举例:某制造企业要构建设备维修知识库,数据源包括设备手册(PDF)、维修经验库(Excel 汇总表)、内部技术论坛帖子(HTML)、以及 ERP 系统中备件描述(数据库)。这些都需要统一接入。

6.1.2 接入方式与工具选择

根据数据源类型不同,接入方式可以灵活选择,但一般遵循“抽取文本 → 清洗 → 结构化(可选)→ 写入文件或直接索引”的路径。

  • 文档解析库
  • PDF:PyMuPDF(fitz)、pdfplumber、Unstructured.io(支持多种格式)
  • Word/PPT/Excel:python-docx、openpyxl、unstructured
  • HTML/网页:BeautifulSoup、trafilatura
  • 通用:Apache Tika(多格式支持,适合批处理)
  • 连接器与集成框架
  • LlamaIndex 的 Reader 模块提供了大量现成的数据加载器:DatabaseReader、NotionPageReader、DiscordReader 等,可减少重复开发。
  • LangChain 的 Document Loaders 也覆盖了主流平台,如 ConfluenceLoader、GitHubLoader。
  • API 抓取
  • 对于有 API 的系统(如 Confluence、Notion),优先使用官方 API 获取结构化内容,避免依赖页面抓取导致格式丢失。
  • 对于静态网页,可使用 requests + 解析器定时抓取,但要注意网站的 robots.txt 和频率限制。
  • 数据库直接读取
  • 使用 Python 标准数据库驱动(psycopg2、pymysql)查询文本字段,将结果构造为文档对象。注意处理大字段和分页。

6.1.3 接入过程中的实际考量

1. 文本提取的完整性

很多 PDF 有扫描件、图表、跨栏排版,直接提取可能得到乱码或信息丢失。在选型时需要验证解析器对实际文档的支持程度。对于图片型 PDF,可能需要集成 OCR(如 Tesseract、AWS Textract)先进行识别。表格内容如果直接展开会失去结构,可以考虑用专门的表格解析工具(如 camelot、tabula)提取后转为 Markdown 表格以保留语义。

2. 元数据的保留

在接入阶段,一定要为每个文档片段保留足够的元数据,否则溯源能力大打折扣。关键元数据包括:

  • 源文件名(如 产品手册_v3.2.pdf
  • 文档内的章节标题或页码(如果可解析)
  • 最后修改时间(用于判断时效性)
  • 数据来源分类(如“内部 Wiki”、“产品库”)
  • 文档语言、作者等(可选)

这些元数据会在索引时一起存入库中,后续检索时可作为过滤条件或用于回答附注来源。

3. 增量同步与去重

知识库并非一次性导入就完结,数据源会持续更新。需要设计增量同步机制:记录每次同步的时间戳或文件哈希,只处理新增或修改过的文档。同时需要处理重复文档——同名文件更新时,要能识别并替换旧版本,避免知识库中出现多个版本冲突的回答。

4. 权限与安全

接入数据源时必须遵守原有的权限规则。例如,一些内部 Wiki 页面仅对特定部门可见,如果 RAG 系统不加区分地公开检索,就会导致越权。一种实践是:在索引阶段为每个文档片段标记可见性标签(如“全员”、“研发部”、“高管”),并在检索时根据用户身份过滤。更严格的做法是在 API 实时查询数据源,而非全量导入,确保权限实时生效。

6.1.4 一个轻量级接入示例

假设需要接入 Confluence 上指定空间的页面,可以这样操作:

from langchain_community.document_loaders import ConfluenceLoader

loader = ConfluenceLoader(
    url="https://confluence.company.com",
    username="bot@company.com",
    api_key="xxxxx"
)

# 加载指定空间的所有页面
documents = loader.load(
    space_key="SUPPORT",
    include_attachments=False,
    limit=50
)

for doc in documents:
    # 清理多余空白
    doc.page_content = doc.page_content.strip()
    # 保留元数据
    print(doc.metadata["title"], len(doc.page_content))

这些 documents 对象可以直接进入后续的切片和向量化步骤。如果要支持增量,可以在每次运行前查询 Confluence 的最近更新 API,只导入变化页面。

6.1.5 小结

数据源接入看似技术难度不高,却是决定知识库质量的根基。投入时间做好内容解析、元数据标注和增量同步机制,能在后续避免大量“回答正确但源文档找不到”或“引用了过期政策”的问题。记住一个原则:接入不是目的,让正确的内容以合适的粒度进入知识库才是。在下一节中,我们将进入如何处理这些文本,以使其更适合检索和生成。