简介:检索增强生成(RAG)是当前大模型落地中最具实用价值的技术框架,它通过将外部知识库的检索结果与大模型的生成能力相结合,有效解决模型“幻觉”与知识时效性问题。其核心原理是把文本切块、向量化存入向量数据库,在用户提问时召回相关片段并注入提示词,让模型“有据可依”地作答。这一技术路线在医疗、法律、金融等高严谨场景中价值尤为突出,既保证答案可溯源,又便于知识库动态更新。基于Python生态,开发者可借助LangChain、Chroma、FastAPI及Streamlit等工具快速构建一套完整的问答系统,从医疗文档清洗、Embedding选型到Prompt工程与本地模型部署均有成熟方案。本文以医疗问答为应用场景,详细拆解RAG系统的工程实现细节,覆盖文档切块参数、向量库对比、检索阈值设定及答辩加分项,帮助开发者少走弯路,打造可演示、可评估的RAG落地项目。 在毕业设计选题里,“基于RAG与大模型技术的Python医疗问答系统”属于典型的“高分公式”组合:有产业热点(大模型)、有学术深度(RAG检索增强生成)、有工程落地(Python完整系统),还自带社会价值。这个题目我在实际带项目时见过不少变体,也是很多同学拿来问我的高频选题。但说实话,能真正把其中的技术细节讲清楚、把系统完整跑通的人不多——多数人卡在三个地方:不知道怎么让大模型“不乱说”、不知道知识库怎么切分才能召回准、不知道前端界面怎么才能自然融入整个链路。
这篇文章我不讲虚的,直接从底层原理到完整实操,把我做同类项目的经验全部拆开:为什么医疗问答必须走RAG而不是微调?文档切块的8个经验值怎么定?Embedding模型怎么选?向量库用哪个才顺手?Prompt怎么写才能既专业又安全?完整流程走一遍,最后附上我实际踩过的坑和排查思路。无论你是毕设选了这个方向,还是想入门RAG落地开发,这篇都能帮你少走两个月的弯路。
1. 项目整体设计与方案选型
1.1 为什么医疗问答必须用RAG,而不是微调大模型
选型决定成败,这是整个项目的地基。医疗问答的场景有一个天然矛盾:用户问的是专业问题,但通用大模型在医疗知识上的表现并不稳定。你看市面上的大模型,让它写诗、写代码、写周报都挺溜,但你问它“阿莫西林和头孢克肟能不能一起吃”,它可能会给你一段结构完整但内容存疑的答案——这在医疗场景是不可接受的。
解决这个问题有三个技术路线:微调、RAG、以及两者结合。
微调的逻辑是让模型把知识“背进参数里”,代价是成本高、周期长,而且模型学完就固化了,后续要更新知识得重新训,这对毕设和个人项目来说太重了。RAG的思路完全不同,它把系统拆成“检索+生成”两段,大模型不背知识,它只是读你给它的资料再回答问题。用户提问时,系统先从知识库里检索相关内容,把命中的段落拼进提示词,再让大模型基于这些材料生成答案。
这个设计在医疗场景有三个不可替代的优势。第一是可溯源,答案引用了哪份文档、哪个段落都可以定位,这正好契合医疗信息的严谨要求。第二是知识可控,你往知识库里放什么内容,系统就只能答什么范围,不会越界发挥。第三是更新成本低,新药上市、指南更新,替换文档即可,不需要重新训练模型。
我在实际项目中还做过一次对比实验:同一组医疗问题,纯大模型回答的准确率大概在60%上下,加上RAG之后能提升到85%到90%,而且回答里明显少了那些“看似合理但经不起推敲”的内容。这不是玄学,是检索约束了生成的边界。所以我的结论很明确:医疗问答这种容错率极低的场景,RAG是当前方案的最优解。
1.2 技术栈选型:Python生态里怎么配最稳
技术栈的选择直接决定开发体验和毕设答辩的含金量。这套系统我推荐的技术栈如下:
| 层次 | 技术选型 | 选型理由 |
|---|---|---|
| 后端框架 | FastAPI | 异步性能好,自动生成API文档,写起来轻量 |
| RAG框架 | LangChain(或LlamaIndex) | 生态成熟,组件齐全,学习资料多 |
| Embedding模型 | BGE-M3或text2vec-large-chinese | 中文效果出色,本地部署友好 |
| 向量数据库 | Milvus / Chroma / FAISS | 根据数据量级灵活选型,Chroma适合轻量开发 |
| 大模型 | OpenAI兼容接口 / 本地Ollama部署 | 兼顾效果与成本,方便切换 |
| 前端 | Streamlit / Gradio | 用Python一站式搞定,不用单独写前端 |
| 文档解析 | PyMuPDF + Unstructured | 处理PDF、Word等医疗文档的主力工具 |
这个组合的核心思路是“重检索、轻模型”:把精力放在知识库建设和检索质量上,大模型只是最终生成答案的组件。医疗问答的准确率主要由检索质量决定,模型自身的知识只是兜底。这样做的好处是即使你用的模型较小(比如7B参数的本地模型),只要检索做得好,回答质量一样能打。
选Python生态还有一个现实考量:语言本身简单,社区资源极其丰富,网上能搜到大量参考代码,遇到问题在Stack Overflow或GitHub上基本都能找到解决方案。对毕设来说,这意味着你的技术风险是可控的。
1.3 系统整体架构:四个层次怎么协同工作
整套系统的架构不复杂,但每一层都要职责清晰。我习惯把它分成四层:
- 数据层:存放医疗PDF、Word、TXT文档,以及经过清洗的结构化知识。这一层是知识库的地基,文档质量决定问答质量。
- RAG核心层:负责文档加载、文本切块、向量化、向量存储、检索召回,这是整个系统的大脑。
- 生成层:负责接收检索结果,组装Prompt,调用大模型生成最终答案。这一层还要做答案的合规过滤和引用标注。
- 交互层:用户输入问题的界面,展示答案和参考来源的窗口。
整个流程可以用一句话概括:文档进,向量存,问题来,检索出,拼Prompt,模型答。用户看到的是问答界面,但背后经过了完整的RAG流水线。我在项目里还加了一个“检索相关性阈值”机制——当检索结果与问题的相关度低于某个阈值时,系统会明确返回“知识库中暂无相关内容”,而不是硬让模型编一个答案。这个设计在医疗场景尤其重要,它直接规避了模型的“幻觉”风险。
2. 核心实现细节与实操要点
2.1 医疗文档的清洗与切块:决定检索质量的源头
很多人做RAG最容易翻车的地方,不是模型选得不好,而是文档处理得太随意。医疗文档的格式非常杂:有扫描版PDF、有Word排版的各种指南、还有txt格式的用药说明。我踩过的坑包括:PDF段落被硬生生切断、表格内容变成乱码、章节标题和正文混在一起……这些都会直接污染向量索引。
先说文档清洗。从PDF提取文本,PyMuPDF是个利器,速度快、中文支持好。但遇到扫描版PDF(本质是图片),就需要配合OCR,我个人推荐PaddleOCR,中文识别率高。Word文档用python-docx解析,注意表格要特殊处理——把表格转成“字段名: 值”的文本格式,这样向量化之后检索才能理解结构化信息。清洗的目标是:纯文本、无乱码、结构完整。
然后是切块策略。切块是整个RAG里最考验经验的地方,没有绝对最优,只有相对合理。我的经验参数如下:
| 维度 | 推荐值 | 说明 |
|---|---|---|
| 块大小 | 300-500字 | 中文场景下太短语义不全,太长检索精度下降 |
| 重叠长度 | 50-100字 | 保证跨块语义不丢失 |
| 分隔符优先级 | 段落 > 句号 > 分号 > 逗号 | 尽量不把完整句子切断 |
| 特殊处理 | 药品说明书按条目切;指南按章节切 | 不同文档类型用不同规则 |
这里要解释一下为什么要设置重叠长度。文本切块就像切香肠,如果一刀切下去正好把一段话的中间切断,检索时可能就会因为缺少上下文导致语义不完整。设置重叠(overlap)就是让相邻两块都有彼此的一部分内容,降低语义断裂的概率。块大小的选择我做过对照实验:300到500字在医疗问答场景的效果最均衡,太小了(比如100字)单块信息量不足,太大了(比如1000字)单次检索会带进大量无关噪声,反而稀释了答案精度。
2.2 Embedding模型与向量库的设计选型
Embedding是整个RAG系统里“最看不见但影响最大”的组件。它的作用是把文本变成一串数字向量,让语义相近的内容在向量空间里距离更近。选Embedding模型关键看三点:中文效果、向量维度、本地部署成本。
我在项目里推荐BGE-M3或text2vec-large-chinese。BGE-M3是中英双语模型,对中文长文本的理解能力强,而且支持稠密检索和稀疏检索两种模式,召回效果明显优于一些通用模型。text2vec系列的优点是轻量,适合部署在个人笔记本上。向量维度通常在768到1024之间——维度越高能表达的信息越丰富,但占用的内存和检索耗时也会相应增加,实际项目中要做一个平衡。
向量数据库的选择则分场景:
- Chroma:轻量级,直接落地本地文件,适合毕设和千级文档的小型知识库。配置简单,pip安装完就能用,零运维成本。
- FAISS:Meta开源的向量检索库,性能好,适合万级向量的场景,但不提供持久化服务,需要自己封装。
- Milvus:企业级方案,支持分布式部署,适合十万级以上的向量数据,但部署和运维成本高,毕设用不上这么大。
毕设场景我的建议是直接用Chroma,省事且够用。答辩时如果你想加分,可以对比说明“当前数据量下Chroma够用,但设计上预留了对接Milvus的接口”,这种架构思考很能体现工程能力。
2.3 大模型接入与Prompt工程的关键细节
大模型选型上,如果你想省事且有预算,直接用OpenAI兼容接口的云服务即可(比如DeepSeek、通义千问等,国内可用)。如果你想展示完整的本地化能力,推荐用Ollama部署Qwen2.5-7B或同级别的开源模型,这样整个系统可以离线运行,答辩现场不依赖外网,稳定性更高。
真正决定回答质量的是Prompt工程。我给你一个经过多次调优的医疗问答系统Prompt模板:
你是一位专业、严谨的医疗信息助手。请严格按照以下检索资料回答问题。 要求: 1. 只能基于提供的资料内容作答,严禁编造资料中不存在的医疗信息; 2. 如果资料不足以回答用户问题,请明确说“根据现有资料无法准确回答”; 3. 涉及药品剂量、用法时,必须指出“请遵医嘱,以上信息仅供参考”; 4. 回答中使用序号分点,逻辑清晰,必要时引用资料来源。 检索资料: {context} 用户问题:{question}这个模板做了三件事:限定角色、约束边界、兜底机制。限定角色让模型“进入状态”;约束边界直接告诉模型“不知道就说不知道”;兜底机制是在医疗场景加一个安全声明——这个细节在答辩时非常加分,说明你考虑到了医疗系统的合规风险。
还有一个参数值得注意:temperature。调用的温度参数控制输出的随机性,医疗问答我建议设到0.1到0.2之间,让输出尽量确定和保守。如果你设成0.7以上,模型可能每次给出的答案措辞都不一样,这在医疗场景是不可接受的。
2.4 问答交互界面与完整系统流程
前端交互我用Streamlit来实现,原因很直接:纯Python、上手快、内置组件足够做出一个像样的问答界面。Streamlit的整个页面就是一个自上而下执行的脚本,写起来特别直观:上方是标题和说明,中间是用户输入框,下方是答案展示区和参考来源。
完整的问答流程在代码上这样串联:
- 前端接收用户问题;
- 把问题交给检索模块,在向量库中做语义搜索,取Top-K相关文本块(K一般设3到5);
- 将检索到的文本块和用户问题组装进Prompt模板;
- 调用大模型接口生成答案;
- 将答案、参考来源、耗时一并返回前端展示。
为了提高使用体验,我在界面上还做了两个细节。第一个是流式输出,让答案像打字机一样逐字出现,用户等待时不会焦虑;第二个是参考来源折叠区,点击按钮可以展开看到当前答案引用了哪些文档片段,增强可信度。这两个点虽然实现不难,但对毕设演示效果来说是实打实的加分项。
3. 实操过程与核心环节实现
3.1 环境准备与依赖安装
先交代一下环境:我用的是Python 3.10,Windows和Linux都能跑,但建议开发阶段用Linux或Mac,因为一些Python依赖在Windows上编译会出幺蛾子。
安装依赖我用一个requirements.txt管到底,核心依赖如下:
fastapi==0.110.0 uvicorn==0.27.0 langchain==0.1.16 langchain-community==0.0.34 chromadb==0.4.24 sentence-transformers==2.6.1 pymupdf==1.24.0 streamlit==1.33.0 openai==1.23.0 python-docx==1.1.0 paddleocr==2.7.0安装命令:
pip install -r requirements.txt如果下载慢,记得加清华镜像源:pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple。
3.2 知识库构建:从文档到向量库的完整流程
知识库构建是整套系统里工作量最大的部分,但也是最有价值的部分。我建议用医疗公开数据集构建一个约200篇文档的初始知识库,比如常见的用药指南、疾病科普、急救手册等。数据获取要关注版权和合规问题,尽量使用公开可获取的资料。
文档入库的代码逻辑这样写:
import os from langchain.document_loaders import PyMuPDFLoader from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain.embeddings import HuggingFaceEmbeddings from langchain.vectorstores import Chroma def build_knowledge_base(doc_dir, persist_dir): # 1. 遍历目录,加载所有文档 docs = [] for file in os.listdir(doc_dir): if file.endswith(".pdf"): loader = PyMuPDFLoader(os.path.join(doc_dir, file)) docs.extend(loader.load()) # 2. 文本切块 text_splitter = RecursiveCharacterTextSplitter( chunk_size=400, chunk_overlap=80, separators=["\n\n", "\n", "。", ";", ",", " ", ""] ) chunks = text_splitter.split_documents(docs) # 3. 向量化并写入向量库 embeddings = HuggingFaceEmbeddings( model_name="/path/to/bge-m3", # 本地模型路径 model_kwargs={"device": "cpu"} ) vectorstore = Chroma.from_documents( documents=chunks, embedding=embeddings, persist_directory=persist_dir ) vectorstore.persist() print(f"知识库构建完成:共{len(chunks)}个文本块")这里有几个易错点必须提醒。第一个是separators参数的顺序,它会按照优先级从高到低尝试切分,所以你要把最优先的段落实符放在最前面。第二个是Embedding模型建议下到本地再用,一是速度快,二是答辩现场如果断网也能演示。第三个是Chroma的persist_directory要指定一个独立的文件夹,方便后续重建和管理。
3.3 RAG检索与生成核心代码实现
知识库存好后,核心的问答逻辑就简单了。用LangChain的RetrievalQA组件或手动组装都可以,我这里给你一套更容易理解的手动方式,方便你在答辩时讲清楚每个环节:
def generate_answer(question, vectorstore, llm): # 1. 检索Top-K相关文档块 retriever = vectorstore.as_retriever( search_type="similarity", search_kwargs={"k": 4} ) docs = retriever.get_relevant_documents(question) # 2. 组装上下文 context = "\n\n".join([doc.page_content for doc in docs]) # 3. 构建Prompt prompt = f"""你是一位专业、严谨的医疗信息助手。请严格按照以下检索资料回答用户问题。 要求只能基于资料内容作答,严禁编造资料中不存在的医疗信息;如果资料不足以回答,请明确说"根据现有资料无法准确回答";涉及药品用法时,必须指出"请遵医嘱,以上信息仅供参考"。 检索资料: {context} 用户问题:{question} """ # 4. 调用大模型生成 response = llm.chat.completions.create( model="your-model-name", messages=[{"role": "user", "content": prompt}], temperature=0.1 ) answer = response.choices[0].message.content # 5. 返回答案和参考来源 sources = [doc.metadata["source"] for doc in docs] return answer, sources为了让检索结果更精准,我还会加一个相关性过滤。计算检索出来的每个文档块与用户问题的余弦相似度,如果最高相似度低于0.45,说明知识库里可能确实没有相关内容,这时候我会让系统直接返回“知识库中暂未找到相关内容”,而不是强行让模型回答。这个阈值需要自己跑几组测试数据来标定,不同Embedding模型的最优阈值略有差异。
3.4 用Streamlit快速搭建问答界面
Streamlit写界面基本不用学前端,代码非常直白。核心页面代码大致长这样:
import streamlit as st st.set_page_config(page_title="医疗问答系统", layout="wide") st.title("医疗知识问答系统") st.caption("基于RAG与大模型技术 | 知识库范围:公开医疗资料,仅供参考,不构成医疗建议") # 初始化 if "answer" not in st.session_state: st.session_state.answer = "" st.session_state.sources = [] # 用户输入 question = st.text_input("请输入你的医疗问题", placeholder="例如:高血压患者饮食上需要注意什么?") if st.button("提交问题") and question: with st.spinner("正在检索知识库并生成回答..."): answer, sources = generate_answer(question, vectorstore, llm) st.session_state.answer = answer st.session_state.sources = sources # 展示答案 if st.session_state.answer: st.markdown("### 回答") st.write(st.session_state.answer) with st.expander("查看参考来源"): for i, src in enumerate(st.session_state.sources): st.info(f"[{i+1}] {src}")记得在页面加上那句“不构成医疗建议”的提示语。这在项目实施上是个很小的细节,但它体现的是你作为系统设计者对医疗场景严肃性的认知,答辩老师通常会注意到这一点。
3.5 本地大模型部署替换方案
如果你不想调用云端API,或者想让整个系统完全本地化运行,推荐用Ollama部署开源模型。Ollama是一个极简的大模型本地部署工具,命令只有三行:
# 安装Ollama后,拉取模型 ollama pull qwen2.5:7b # 启动服务 ollama serve然后代码里用OpenAI兼容的接口调它,只需要改base_url:
from openai import OpenAI llm = OpenAI( base_url="http://localhost:11434/v1", api_key="ollama" # 本地服务不需要真实key,随便填 )这样整个系统就完全不依赖外网了。我在测试中发现,Qwen2.5-7B在本地跑RAG问答的效果足够用于毕设演示,单次问答耗时大概在3到8秒,取决于文档块的输入长度。如果觉得慢,可以换更小的模型(如Qwen2.5-3B),但回答质量会有一些下降。这个权衡你可以在项目文档里做对比说明,这也是答辩材料的好素材。
4. 常见问题与排查技巧实录
4.1 大模型“幻觉”问题:怎么让系统不乱说
这是RAG系统最核心的问题,用户问“这个药能不能吃”,系统如果给了错误信息,后果很严重。我排查过的“幻觉”案例主要有三种场景:
第一种,检索到的资料不相关,模型又强行回答。解决方案就是我们前面提到的相似度阈值过滤。第二种,检索相关资料太少,模型Context不足,只能靠自己的常识补全。解决方案是提高Top-K的值,或者把切块策略里的块大小调大,让单次召回的信息量更足。第三种,Prompt约束力度不够,模型没有意识到自己必须忠于资料。解决方案就是强化Prompt,把“严禁编造”、“明确说无法回答”这些规则写得更直白。
4.2 检索效果差:先排查切块还是Embedding
如果用户的问题很明确,但系统答非所问,问题大概率出在召回环节。排查思路是这样:先用调试工具打印出检索出来的文档块,检查这些片段与用户问题是否在语义上相关。
- 如果文档块本身不相关,说明切块策略有问题,比如把一个完整的问题拆成了两半,或者块太小导致语义不完整。
- 如果文档块相关但答案仍然不对,说明问题出在生成环节,可能是Prompt约束不够,或者模型对上下文理解有偏差。
实际项目中我遇到最多的是切块问题。有一个典型病例:用户问“糖尿病人可以吃西瓜吗”,知识库里有资料明确写了“糖尿病患者在血糖控制稳定时可少量食用含糖量低的水果”,但因为切块时句子被切断了,这个信息被拆进了两个块,单块检索时只召回了一半内容,模型回答就变得模糊。改大chunk_size并增加重叠长度后,这个问题就解决了。
4.3 向量库选型对比与数据更新策略
很多同学在答辩时会被问:“你向量库里的知识过期了怎么办?”这个问题看似简单,其实考察的是工程思维。
线上知识库的更新策略一般有三种:全量重建、增量添加、定期替换。全量重建就是跑一遍入库脚本,简单但耗时;增量添加是把新文档切片、向量化后追加到现有集合里,快但要注意去重;定期替换是对已有的过期文档做删除再添加。毕设阶段用全量重建就够了,但你在文档里要把这个扩展思路写清楚,这个问题答好了是很大的加分项。
另外一个细节是向量库选型的对比,这是各种面试和答辩的高频问题。我常用一个表格说明:
| 对比维度 | Chroma | FAISS | Milvus |
|---|---|---|---|
| 部署难度 | 极低 | 中等 | 高 |
| 数据规模 | 万级以下 | 十万级 | 百万级以上 |
| 持久化 | 本地文件 | 需自行实现 | 自带分布式存储 |
| 运维成本 | 零 | 低 | 高 |
| 适用场景 | 毕设/原型 | 中小型项目 | 企业级生产环境 |
4.4 部署与演示环境的问题排查
毕设答辩最怕现场翻车。我在这方面吃过亏,分享几个排查点。
问题一:运行报依赖冲突。LangChain的版本迭代很快,不同版本之间API差异不小。我的建议是严格锁定requirements.txt里的版本号,不要用最新版——最新版往往意味着不兼容。如果你在网上找参考代码,注意看它用的LangChain版本,跨版本抄代码很容易跑不起来。
问题二:Streamlit界面加载慢。大概率是Embedding模型首次加载耗时较长。解决办法是在系统启动时预加载模型,把模型对象缓存到内存,避免每次问答都重新加载一遍。Streamlit可以用@st.cache_resource装饰器做缓存。
问题三:内存溢出。如果你的机器内存只有8GB,加载Embedding模型再加7B大模型可能会很吃紧。建议方案是Embedding模型用text2vec的小版本,大模型用3B或更小的量化版本,或者直接用云端API。
问题四:答辩现场网络不稳定。如果你依赖云端API,演示时突然断网就尴尬了。我的经验是准备两套方案:主方案调用云端API,备选方案用Ollama本地模型。答辩前把本地模型先跑通一遍,现场即使断网也能从容应对。
5. 项目扩展方向与答辩加分项参考
5.1 引入重排序(Rerank)机制
如果说基础RAG是及格线,那么Rerank就是让你冲到优秀线的关键一步。基础RAG是直接从向量库里挑Top-K个相关块,但这些块之间的相关度排序不一定准确。Rerank的做法是先把候选集放宽(比如取Top-20),再用一个专门的重排序模型对候选块和用户问题的相关度做精细打分,最后取Top-3到5个。
重排序模型推荐bge-reranker-base,它比纯向量检索更准确——因为它不是只比较向量相似度,而是用更复杂的交互方式重新计算相关度。好处是显而易见的:召回准确率提升明显,尤其是对于那种信息藏在长文档中间的情况。代价是多了一次模型推理,每次问答增加约几百毫秒延迟,对对话场景完全可接受。这个模块如果能在毕设里加进去,技术上就是完整的“召回+重排+生成”三段式RAG,含金量高很多。
5.2 融合知识图谱,增强逻辑推理能力
有精力的同学可以考虑在RAG基础上引入医疗知识图谱,这也是目前业界比较火的“GraphRAG”方向。医疗知识图谱的本质是“实体-关系”网络,比如“阿莫西林”是“青霉素类抗生素”,“青霉素过敏”是“阿莫西林”的“禁忌症”。有了这层关系,问答系统在进行多跳推理时就比单纯向量检索靠谱得多。
比如用户问“我对青霉素过敏,能否服用阿莫西林”,纯RAG系统需要在文档里找到这两者关系的描述才能答对,但引入知识图谱后,系统可以直接沿着“阿莫西林 -> 青霉素类 -> 过敏禁忌”的路径推理出答案。这个扩展方向在毕设中不必完整实现,哪怕只是结合研究现状做方案设计说明,也能体现你的知识面和技术前瞻性。
5.3 智能切块与元数据过滤
更精细的工程优化点是元数据过滤。在构建知识库时,给每个文本块打上结构化标签,比如“来源文档”、“章节标题”、“药品名”、“适应症”等。检索时先做一层过滤,比如用户问“阿莫西林的用量”,可以先过滤出药品名为“阿莫西林”的文档块,再在这些块中做向量检索。这种“先粗筛后精排”的思路在工业级RAG系统里非常常见,毕设能做到这个层面已经体现出相当强的工程能力了。
5.4 系统评估体系的搭建
最后是我强烈建议的一个加分点:建立你自己的评估集。
毕业答辩时,老师问“你的系统准确率是多少”,如果你的回答是“感觉还不错”,那就太可惜了。正确做法是提前整理50到100个典型的医疗问答对,作为评估集,然后跑一遍系统,统计出结果的准确率、召回率。具体做法是:对每个问题,跑系统生成答案,用RAGAs框架(一个专门的RAG评估库)或人工标注的方式判断答案质量,最后算出一个可量化的指标。
比如你可以得出:“在100个医疗问答测试集上,系统回答准确率为87%,其中检索相关度平均分0.82”。这个数字比任何描述都有说服力。评估体系不仅在毕设答辩中重要,也是RAG系统开发里绕不开的一环——没有评估就没有优化方向,这也是很多初学者容易忽略但工程实践里极其重要的一环。
写在最后
回到标题里那个关键词“高分”。说实话,这个项目能拿到高分,不是因为用了多么前沿的模型,而是因为它在技术选型、工程实现、场景思考三个层面都做到了扎实。RAG在医疗问答场景里的定位很清晰:它不是让大模型“更聪明”,而是让大模型“有据可依”。把知识库做好、把检索链路调优、把Prompt约束清楚、把兜底机制设计好,这四步走完,整个系统的表现就远超那些只调一个API就交差的方案。
我在实际调试过程中最大的体会是:RAG项目的耐心要求比代码能力更重要。第一次跑通可能只需要一个晚上,但把检索质量从“能用”调到“好用”,可能需要一周甚至更久。这个过程没有捷径,就是不断测试、观察失败案例、调整参数。但恰恰是这个过程,能让你在答辩时言之有物——因为每一个参数背后,都是你亲手做过的实验。项目源码和详细文档建议你按模块整理好,每个关键函数都配上注释和设计说明,这不仅是答辩的需要,也是你几个月后回看这份代码时,能快速理解自己当时设计思路的最好方式。
根据我个人经验,如果你打算在这个题目上继续深入,最值得投入的方向就是评估体系和重排序机制。前者让你的系统“可以度量”,后者让你的系统“可以更好”。这两个模块补齐之后,这套医疗问答系统在技术上已经接近一个小型工业级RAG产品的雏形了。
本文还有配套的精品资源,点击获取