检索增强生成(RAG)¶
课程大作业:RAG系统开发与应用¶
一、任务说明¶
1.1 核心目标¶
开发一个 端到端RAG系统,实现以下功能:
- 知识库构建:从文本数据中提取信息并构建索引,。
- 检索与生成:结合检索结果与LLM生成回答。
- 动态更新:支持知识库实时更新(如新增文档)。
- 评估与优化:通过实验对比不同检索策略的效果。
1.2 简化场景示例¶
可选医疗问答、电商客服、法律顾问、科学探究等系统,可自行搜索数据集。
场景1:医疗问答系统¶
- 用户输入:
- 系统流程:
- 检索模块:从医学指南中检索相关段落。
- 生成模块:结合检索结果,LLM生成药物列表(如氨氯地平、缬沙坦)。
场景2:电商客服系统¶
- 用户输入:
- 系统流程:
- 检索模块:从产品说明书检索该手机的参数。
- 生成模块:生成回答(如“4500mAh”)。
二、框架设计要求¶
2.1 核心组件¶
模块 | 基础功能要求 | 实现建议 |
---|---|---|
知识库管理 | 存储文档、构建向量索引、支持动态更新。 | 使用 FAISS/Milvus 等存储向量,SQLite 记录文档元数据。 |
检索模块 | 根据用户查询检索相关文档片段。 | 实现 BM25 或 稠密向量检索(如 Sentence-BERT)。 |
生成模块 | 结合检索结果生成自然语言回答。 | 使用 LLM(如 LLaMA3、Qwen),可通过 API 调用。 |
用户接口 | 接收用户输入并返回结果,支持命令行或Web界面。 | 使用 FastAPI 构建REST API,或 Flask 实现Web界面。 |
日志记录器 | 记录查询、检索结果、生成内容及耗时。 | 使用 Python logging 等模块输出到文件或控制台。 |
2.2 必选实现要求¶
- 知识库构建:
- 包含必要的文档(如医学指南、产品说明书)。
- 支持 PDF/Markdown/文本 格式解析。
- 检索与生成:
- 实现 稠密向量检索(如 Sentence-BERT)。
- 支持 生成模型微调(可选)。
- 动态更新:
- 新增文档时自动更新索引。
三、实验实施要求¶
3.1 必做实验¶
1. 基础功能验证¶
- 自主构建测试用例示例:
- 检索结果是否相关。
- 生成回答是否准确。
2. 检索策略对比实验¶
- 对比BM25与向量检索:
- 场景:同一查询下,统计两种方法的 Top-5检索结果相关性。
- 输出对比表格(如准确率、耗时)。
3. 知识库更新实验¶
- 模拟场景:
- 新增一篇文档后,验证系统能否检索到新内容。
3.2 可选优化方向¶
- 多模态支持:
- 添加图像检索(如分析CT影像,需调用 CLIP 模型)。
- 索引优化:
- 实现增量更新(无需重新构建整个索引)。
- 生成质量提升:
- 对LLM进行微调(如医疗领域指令微调)。
四、提交要求¶
4.1 目录结构¶
├── core/ # 核心模块
│ ├── rag_engine.py # RAG核心逻辑(检索+生成)
│ ├── knowledge_base.py # 知识库管理与索引构建
│ └── utils.py # 辅助工具(如文档解析、日志)
├── data/ # 知识库文件夹
│ ├── medical_guidelines/ # 医学指南
│ └── product_manuals/ # 产品说明书
├── demo/
│ ├── demo.mp4 # 系统演示视频(3分钟内)
│ └── test_cases.md # 测试用例与结果
├── logs/ # 运行日志文件夹
└── report.pdf # 报告(含架构图、实验数据、代码说明)
4.2 性能指标¶
指标 | 合格标准 |
---|---|
知识库检索准确率 | ≥85%(测试用例命中相关文档) |
任务完成率 | ≥90%(测试用例通过率) |
平均响应时间 | ≤60秒(端到端任务) |
五、评分标准¶
维度 | 细则说明 | 占比 |
---|---|---|
功能完整性 | 知识库构建、检索与生成、动态更新等核心功能实现。 | 40% |
代码可读性 | 模块划分清晰、注释规范、遵循PEP8规范。 | 30% |
实验完成度 | 基础测试、检索策略对比实验、知识库更新实验的完整性和数据合理性。 | 20% |
报告质量 | 架构图清晰、实验分析逻辑严谨、演示视频完整。 | 10% |
六、实现支持¶
实现步骤(医疗问答系统示例)¶
-
知识库构建:
-
收集医学指南(如《WHO糖尿病诊疗规范》),使用 PyPDF2 解析PDF。
- 使用 Sentence-BERT 构建向量索引并存储到 FAISS。
- RAG流程:
class RAGSystem: def __init__(self): self.kb = KnowledgeBase() self.llm = LLMClient() # LLM API客户端 def query(self, user_input): # 检索 docs = self.kb.retrieve(user_input, top_k=5) # 生成 context = "\n".join([doc.text for doc in docs]) prompt = f"根据以下信息回答问题:\n{context}\n\n问题:{user_input}" response = self.llm.generate(prompt) return response
- 动态更新: