【AI】五.AI大模型必备之RAG和智能医生实战 小滴课堂讲师 2025年09月18日 ai大模型, aigc 预计阅读 17 分钟 #### 什么是大模型的幻觉输出 ##### “幻觉输出”(Hallucination) * 是大语言模型(如GPT、Llama、DeepSeek等)生成内容时的一种常见问题 * 指模型输出看似合理但实际错误、虚构或脱离事实的信息。 * 这种现象类似于人类的“臆想”——模型基于不完整或错误的知识,生成逻辑通顺但内容失实的回答 ##### 表现形式 * 虚构事实 * 例1:生成不存在的书籍(如称《时间简史》是鲁迅所写)。 * 例2:编造错误的历史事件(如“秦始皇于公元前200年统一六国”)。 * 错误推理 * 例:回答数学问题时,步骤正确但结果错误(如“2+3=6”)。 * 过度泛化 * 例:将特定领域的知识错误迁移到其他领域(如用医学术语解释物理现象)。 * 矛盾内容 * 例:同一段回答中前后逻辑冲突(如先说“地球是平的”,后又说“地球绕太阳公转”) ##### 幻觉产生的根本原因 * **训练数据的局限性** - **数据噪声**:模型训练数据可能包含错误、过时或偏见信息(如互联网上的谣言)。 - **知识截止**:模型训练后无法获取新知识(如GPT-3的数据截止到2021年)。 * **模型生成机制** - **概率驱动**:模型通过预测“最可能的下一词”生成文本,而非验证事实。 - **缺乏常识判断**:无法区分“合理表达”与“真实事实”。 * **模型策略的副作用** - **创造性模式**:模型在开放生成任务中更易“放飞自我”(如写小说时虚构细节) ##### 典型案例分析 - **案例1:医疗问答** - **问题**:用户问“新冠疫苗会导致自闭症吗?” - **幻觉输出**:模型可能生成“有研究表明两者存在相关性”(错误)。 - **解决方案**:RAG检索WHO官方声明,生成“无科学证据支持此说法”。 - **案例2:金融咨询** - **问题**:“2024年比特币会涨到10万美元吗?” - **幻觉输出**:模型虚构专家预测或历史数据。 - **解决方案**:限定回答范围(如“截至2023年,比特币最高价格为…”) ##### 产生的影响 * **误导用户**:在医疗、法律等专业领域可能引发严重后果。 * **信任危机**:用户对模型输出的可靠性产生质疑。 * **技术瓶颈**:暴露大模型在事实性、可解释性上的不足。 ##### 如何缓解幻觉输出(注意:不是解决) * **技术改进方案** - **检索增强生成(RAG)**:通过实时检索外部知识库(如维基百科、专业数据库),为生成提供事实依据。 - **微调对齐**:用高质量数据(如标注正确的问答对)调整模型输出偏好。 - **强化学习(RLHF)**:通过人类反馈惩罚错误生成,奖励准确回答。 * **生成策略优化** - **温度参数调整**:降低随机性(`temperature=0`),减少“胡编乱造”。 - **后处理校验**:添加事实核查模块(如调用知识图谱API验证答案)。 * **用户侧应对** - **提示词设计**:明确要求模型标注不确定性(如“回答需基于2023年数据”)。 - **多源验证**:对关键信息人工交叉核对(如学术论文、权威网站)。 #### 带你走进RAG检索增强生成和应用场景 ##### 什么是RAG技术 * RAG(Retrieval-Augmented Generation)检索增强生成,是结合信息检索与文本生成的AI技术架构。 * 核心思想: * 先通过检索系统找到与问题相关的知识片段 * 再将检索结果与问题共同输入生成模型得到最终答案 * 类比人类解答问题的过程:遇到问题时先查资料(检索),再结合资料组织回答(生成)  * 用Java伪代码描述RAG工作流程: ```java public class JavaRAG { public static void main(String[] args) { // 1. 加载文档 List docs = FileLoader.load("data/"); // 2. 创建向量库(类似建立索引) VectorDB vectorDB = new FAISSIndex(docs); // 3. 处理用户问题 String question = "如何申请报销?"; List results = vectorDB.search(question, 3); // 4. 生成回答 String context = String.join("\n", results.stream() .map(Document::content) .collect(Collectors.toList())); String answer = LLM.generate(context + "\n问题:" + question); System.out.println(answer); } } ``` ##### 需求背景:为什么需要RAG * 传统生成模型的局限性 * 知识过时:大模型(如GPT-3)训练数据截止于特定时间,无法覆盖实时信息。 * 幻觉问题:生成内容可能包含不准确或虚构的信息。 * 领域局限性:通用模型缺乏垂直领域的专业知识(如法律、医疗),企业私有数据无法写入公开模型 | 题类型 | 示例 | 传统模型表现 | | :----------------: | :------------------------: | :----------------------------------: | | 时效性问题 | "2027年诺贝尔奖得主是谁?" | 无法回答(训练数据截止到当时的数据) | | 领域专业问题 | "如何配置Hadoop集群参数?" | 回答模糊或错误 | | 需要引用来源的问题 | "不睡觉有哪些副作用?" | 无法提供可信出处 | * 检索与生成的互补性 * 检索系统:擅长从海量数据中快速找到相关文档(实时、精准),实时从外部知识库检索信息 * 生成模型:擅长语言理解和流畅输出。 * 结合优势:RAG通过检索外部知识库增强生成结果,提高准确性和可信度 * 降低训练成本:无需重新训练模型即可更新知识 * 生成可验证性:每句回答都可追溯来源文档 ##### 技术架构 * **涉及的技术链路环节: 文档加载器->文档转换器->文本嵌入模型->向量存储->检索器** * 关键技术组件 | 组件 | 常用工具 | Java类比 | | :--------: | :-----------------------: | :------------------: | | 文档加载器 | PyPDFLoader, Unstructured | FileInputStream | | 文本分块器 | RecursiveTextSplitter | String.split()增强版 | | 元数据处理 | LangChain Document类 | DTO对象封装 | | 向量存储 | FAISS, Pinecone | 数据库索引 | ##### 典型应用场景 * 案例1:智能客服系统 * 传统问题:客服知识库更新频繁,模型无法实时同步。 * RAG方案: * 实时检索最新的产品文档、FAQ。 * 生成个性化回答(如退货政策、故障排查)。 ```python 用户问:"这个小滴手机支持老人家使用不?" 系统检索:产品适合人群相关词条 生成回答:"我们这个产品适合18岁以上的成人使用,包括中老年人等" ``` * 效果:减少人工干预,回答准确率提升30%+。 * 案例2:医疗问答助手 * 传统问题:通用模型缺乏专业医学知识,可能给出危险建议。 * RAG方案: * 检索权威医学数据库(如PubMed、临床指南)。 * 生成基于循证医学的答案,标注参考文献来源。 ```python 用户问:"二甲双胍的禁忌症有哪些?" 系统检索:最新《临床用药指南》第5.3节 生成回答:"根据2023版用药指南,二甲双胍禁用于以下情况:1)严重肾功能不全..." ``` * 效果:合规性提升,避免法律风险。 * 案例3:金融研究报告生成 * 传统问题:市场数据动态变化,模型无法实时分析。 * RAG方案: * 检索实时财报、新闻、行业数据 → 输入生成模型。 * 自动生成带有数据支撑的投资建议。 ```python 用户问:"XXX公司财报如何" 系统检索:某某公司财报 生成回答:"根据公司的财报和解读,利润和负债..." ``` * 效果:析师效率提升,报告更新频率加快 #### LLM智能AI医生+RAG系统案例实战 ##### 需求 * 快速搭建智能医生客服案例,基于LLM大模型+RAG技术 * 方便大家可以直观的看相关效果,并方便后续拆解每个步骤 * 效果:可以根据用户的提问,检索相关私有数据,整合大模型,最终生成返回给用户 案例实战 * 创建项目和安装相关环境 ```python # 创建并激活虚拟环境 python -m venv .venv source .venv/bin/activate # 安装依赖 pip install -r requirements.txt pip install chromadb # 安装本地向量数据库 ``` * 查看训练的文档数据qa.txt ``` 99. 患者:换季就鼻炎发作怎么缓解? 智能医生:使用生理盐水洗鼻,出门戴口罩。床单每周高温清洗,必要时使用鼻用激素喷雾(需医生指导)。 100. 患者:突然头晕目眩是什么原因? 智能医生:可能原因包括低血糖、体位性低血压或耳石症。请立即坐下休息,测量血压血糖。如伴呕吐、言语不清请立即就医 101. 患者:饭后经常打嗝是什么原因? 智能医生:可能与进食过快、摄入碳酸饮料有关。建议小口进食,吞咽时闭气5秒。若持续超过48小时,需排查胃部疾病。 102. 患者:运动后肌肉酸痛怎么缓解? 智能医生:48小时内冷敷,之后热敷。轻度拉伸+补充电解质。若疼痛集中在某一肌肉且无法活动,需排除拉伤可能。 103. 患者:头皮屑多怎么办? 智能医生:使用含吡硫翁锌的洗发水(每周2-3次),避免过度烫染。若头皮发红瘙痒,可能为脂溢性皮炎需就医。 ``` * 项目部署运行 ```python from langchain_core.output_parsers import StrOutputParser from langchain_core.prompts import ChatPromptTemplate from langchain_core.runnables import RunnablePassthrough from langchain_community.document_loaders import WebBaseLoader from langchain_community.document_loaders import TextLoader from langchain_community.vectorstores import Chroma from langchain_openai import ChatOpenAI from langchain_text_splitters import RecursiveCharacterTextSplitter from langchain_community.embeddings import DashScopeEmbeddings import secret import os os.environ["USER_AGENT"] = "D:/PycharmProjects/AI_Pan_Projects/xd-rag" os.environ["DASHSCOPE_API_KEY"] = secret.api_key # 只在这里写一次 # 1. 加载文档 # loader = WebBaseLoader(["xdclass.net"]) # 示例网页 # docs = loader.load() # 1. 文本加载 loader = TextLoader("./data/qa.txt", encoding="utf-8") docs = loader.load() # 2. 分割文档 text_splitter = RecursiveCharacterTextSplitter( chunk_size=1000, chunk_overlap=200 ) splits = text_splitter.split_documents(docs) # 初始化模型 embedding_model = DashScopeEmbeddings( model="text-embedding-v2", # 第二代通用模型 max_retries=3 ) # 3. 创建向量存储 vectorstore = Chroma.from_documents( documents=splits, embedding=embedding_model, persist_directory="./rag_chroma_db" ) retriever = vectorstore.as_retriever(search_kwargs={"k": 3}) # 检索前3个相关片段 # 定义模型 model = ChatOpenAI( model_name="qwen-plus", base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", api_key=secret.api_key, temperature=0.7 ) # 5. 创建提示模板 template = """[INST] <> 你是一个有用的AI助手,请根据以下上下文回答问题: {context} <> 问题:{question} [/INST]""" rag_prompt = ChatPromptTemplate.from_template(template) # 6. 构建RAG链 rag_chain = ( {"context": retriever, "question": RunnablePassthrough()} | rag_prompt | model | StrOutputParser() ) # 执行查询 question = "饭后经常打嗝原因是?" response = rag_chain.invoke(question) print(f"问题:{question}") print(f"回答:{response}") ``` 疑问 * **为啥可以根据我们的提问,进行检索到对应的词条?而且还可以正确检索?** * **为啥要加载文件?然后切割?什么是向量数据库?** * **为啥检索到词条后,还可以用调整输出内容,更加友好?** * **什么是嵌入大模型?和前面学的LLM大模型有啥区别?**
评论区