RAG工厂制度问答 - 框架结构
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() 过滤 |