← 项目主页
过程

RAG工厂制度问答 - 框架结构

发布于 2026/10/23

RAG工厂制度问答 - 代码框架整理

一、整体架构概览

本项目是一个基于 RAG(检索增强生成) 技术的问答系统,核心流程为:

PDF文档 → 文本提取 → 滑窗切分 → 向量化 → 存入向量数据库 → 用户提问 → 向量检索 → 拼接Prompt → 大模型生成回答

整体分为四大模块:

模块 职责 对应代码
文档解析层 从PDF中提取文字并切分 extract_text_from_pdf() / sliding_window_chunks()
向量数据库层 向量化、存储、检索 MyVectorDBConnector 类
大模型交互层 调用千问API生成回答 RAG_Bot.get_completion()
业务流程层 串联检索+生成,完成问答 RAG_Bot.chat() / __main__ 入口

二、模块详细拆解

2.1 文档解析层

作用: 把PDF文档变成可供向量化的文本片段(chunk)

PDF文件
  │
  ▼
extract_text_from_pdf()        ← 入口函数
  │
  ├─ extract_pages()            ← pdfminer 逐页解析PDF布局
  │
  ├─ 遍历 LTTextContainer       ← 提取文本元素
  │
  ├─ 清理空白字符               ← replace("\n","").replace(" ","")
  │
  ▼
sliding_window_chunks()         ← 滑窗切分
  │
  ├─ chunk_size=250             ← 每个片段250字符
  ├─ stride=100                  ← 滑动步长100字符(有重叠)
  │
  ▼
返回 text_chunks 列表

关键函数:

函数名 参数 返回值 说明
sliding_window_chunks text, chunk_size, stride list 固定字符数滑窗切分
extract_text_from_pdf filename, page_numbers list PDF文本提取+切分

2.2 向量数据库层(MyVectorDBConnector)

作用: 封装 ChromaDB 操作,负责向量化、入库、检索

MyVectorDBConnector
  │
  ├─ __init__(collection_name)
  │   └─ 创建/获取 collection,设置余弦相似度
  │
  ├─ get_embeddings(texts, model, batch_size)
  │   └─ 调用千问 Embedding API(支持分批)
  │
  ├─ add_documents(instructions)
  │   ├─ 向量化
  │   └─ collection.add() 存入向量+原文
  │
  └─ search(query, n_results)
      ├─ 问题向量化
      └─ collection.query() 返回topk结果

关键函数:

函数名 参数 返回值 说明
__init__ collection_name - 初始化ChromaDB集合
get_embeddings texts, model, batch_size list[vec] 批量向量化(内部自动分批)
add_documents instructions - 向量化后存入数据库
search query, n_results dict 向量检索返回相似度最高的文档

2.3 大模型交互层(RAG_Bot)

作用: 封装千问对话API,提供问答能力

RAG_Bot
  │
  ├─ __init__(vector_db, n_results)
  │   └─ 注入向量数据库实例和检索数量
  │
  ├─ get_completion(prompt, model)
  │   └─ 调用千问 chat.completions.create() 生成文本
  │
  └─ chat(user_query)
      ├─ vector_db.search()      ← 向量检索相关知识
      ├─ 拼接 prompt_template    ← 注入检索结果+用户问题
      └─ get_completion()        ← 大模型生成回答

关键函数:

函数名 参数 返回值 说明
__init__ vector_db, n_results - 注入依赖
get_completion prompt, model str 调用大模型生成回复
chat user_query - 完整RAG流程:检索→拼接→生成

2.4 主流程入口(main)

作用: 编排完整业务流程

__main__
  │
  ├─ 1. 环境加载
  │   └─ load_dotenv() + 初始化 OpenAI client
  │
  ├─ 2. Prompt模板定义
  │   └─ prompt_template(含 __INFO__ / __QUERY__ 占位符)
  │
  ├─ 3. 索引创建(一次性)
  │   ├─ 读取PDF文本
  │   ├─ 创建向量数据库实例
  │   └─ 入库向量化
  │
  └─ 4. 检索问答(循环)
      ├─ 创建 RAG_Bot 实例
      ├─ 接收用户问题
      └─ bot.chat() → 输出回答

三、数据流转图

┌──────────────┐     ┌──────────────┐     ┌──────────────┐
│  PDF文档      │────▶│  文本切分     │────▶│  向量化       │
│  工厂员工手册  │     │  chunk_size   │     │  千问Embedding │
└──────────────┘     └──────────────┘     └──────┬───────┘
                                                  │
                                                  ▼
┌──────────────┐     ┌──────────────┐     ┌──────────────┐
│  用户提问     │◀────│  大模型生成   │◀────│  ChromaDB    │
│  录用员工...  │     │  千问Chat     │     │  向量检索     │
└──────────────┘     └──────────────┘     └──────▲───────┘
                                                  │
                                                  ▼
                                           ┌──────────────┐
                                           │  Prompt拼接   │
                                           │  检索结果+问题  │
                                           └──────────────┘

四、依赖关系总览

库/包 用途 调用位置
dotenv 环境变量加载 __main__
openai 千问API客户端 MyVectorDBConnector.get_embeddings() / RAG_Bot.get_completion()
pdfminer PDF文本提取 extract_text_from_pdf()
chromadb 向量数据库 MyVectorDBConnector
os 系统操作 __main__ 读取环境变量

五、类依赖关系

RAG_Bot
  │
  └─ 依赖 ──▶ MyVectorDBConnector
                 │
                 └─ 依赖 ──▶ chromadb.Client()

__main__
  │
  ├─ 依赖 ──▶ RAG_Bot
  ├─ 依赖 ──▶ MyVectorDBConnector
  ├─ 依赖 ──▶ extract_text_from_pdf()
  └─ 依赖 ──▶ OpenAI client

六、待优化项(代码注释中标注的问题)

序号 问题 位置 建议
1 client 是全局变量,类内直接引用 get_embeddings / get_completion 通过构造函数注入
2 prompt_template 定义在 __main__ 内 RAG_Bot.chat 中直接引用 构造函数传入或抽为配置常量
3 ID 使用 id0~idN 简单递增 add_documents 改用内容哈希防重复
4 add 而非 upsert add_documents 改用 upsert 避免重复入库报错
5 检索结果用逗号拼接 chat 中 ','.join(...) 改用换行分隔更清晰
6 未过滤空字符串chunk extract_text_from_pdf 返回值 入库前加 if p.strip() 过滤