资讯动态

大模型幻觉抑制实战:基于Spring AI与pgvector的RAG工程落地指南

发布时间:2026/9/21 20:27:25 来源:尧图企业网站定制
1. 大模型幻觉到底是什么为什么每个做AI应用的人都绕不开它第一次被大模型幻觉坑到是我拿它做一个内部知识问答的原型。问它我们公司年假制度里入职满三年有多少天它一本正经地回了一段格式工整、语气笃定的答案连根据员工手册第X条都编出来了。我去翻真实的手册根本没有那一条天数也是错的。那一刻我才真正理解大模型幻觉AI Hallucination不是模型偶尔抽风而是它工作机制里自带的一种副作用。说白了大模型本质上是一个下一个词预测器。它读过海量文本学到的是词与词之间的概率分布而不是一个可查询的事实数据库。当你问它问题它做的事情是根据上下文一个词一个词地往外续写最像人话的内容。至于这段内容是不是真的它自己并不知道也没有一个内置的真值校验器来拦它。所以当它遇到知识盲区、或者上下文里没有足够信息时它不会说我不知道而是倾向于编一个看起来最合理的答案——这就是幻觉。这件事对做应用的人意味着什么意味着你只要把大模型直接怼到用户面前尤其是怼到企业知识库、客服、医疗、法律、金融这类对准确性要求极高的场景里翻车是迟早的。热搜里那一堆词——RAG、rag知识库、企业知识库 rag、rag检索增强生成、spring ai实战、java rag问答——本质上都是同一件事的不同侧面大家都在想办法把幻觉压下去让模型说的话有据可查。这篇内容我打算按一个真实项目落地的思路来写。先讲清楚幻觉的成因和分类再讲主流的抑制手段重点是RAG这条主线然后落到工程实现上把Spring AI、pgvector、切块、Prompt工程这些热搜词串起来讲透最后给一份排查手册。适合正在做AI应用、被幻觉折磨过的开发者也适合刚接触RAG、想知道为什么我的知识库答不准的朋友。不管你是用Java栈还是Python栈思路是通用的。2. 幻觉的成因拆解与分类先搞清楚敌人长什么样2.1 从下一个词预测看幻觉的必然性要抑制幻觉得先接受一个前提幻觉不是bug是feature的阴暗面。模型的训练目标是最大化下一个词的条件概率它优化的是像不像真的不是是不是真的。这两者在绝大多数情况下重合但在边缘情况下会分叉。我打个比方。你让一个博览群书但从没查过证的人凭记忆回答一个冷门问题他大概率会给你一个听起来很对的答案因为他读过的书里类似的表述太多了他的大脑会自动补全。大模型干的就是这件事而且它补全得比人还流畅所以更有欺骗性。具体到成因我一般分成四类来看知识缺失型训练数据里压根没有这个知识或者知识太新超出训练截止时间。模型不知道但它不会承认于是编。知识冲突型训练数据里同一个问题有多个矛盾的说法模型把它们混在一起输出一个缝合怪。上下文误导型你给的Prompt或者检索回来的资料本身有错、有歧义模型顺着错误信息往下编。解码随机型采样温度temperature太高模型在多个候选词里随机挑挑着挑着就偏离了事实轨道。这四类里第一类和第三类是工程上最常遇到的也是RAG主要要解决的。第二类靠数据清洗第四类靠参数调优。2.2 幻觉的几种典型表现别只盯着编事实很多人以为幻觉就是编造不存在的事实其实它的表现形式比这丰富得多识别不出来就容易误判。幻觉类型典型表现常见场景事实性幻觉编造不存在的人名、条款、数据、引用知识问答、法律咨询引用性幻觉编造参考文献、链接、文档编号学术助手、报告生成逻辑性幻觉推理步骤自相矛盾前后打架数学解题、多步推理指令性幻觉无视你的格式要求自作主张Prompt工程、结构化输出时效性幻觉用旧知识回答新问题还说得斩钉截铁新闻、股价、政策查询我踩过最隐蔽的一个坑是引用性幻觉。做企业知识库时模型回答完还贴心地附上来源XX制度文档第3.2节看起来特别可信结果那个文档根本没有3.2节。这种幻觉最危险因为它自带可信度伪装。后来我在系统里强制要求来源必须由检索层给出模型不许自己编来源这才堵住。2.3 为什么直接问大模型这条路走不通有人会想那我Prompt写得好一点让它不要编造不就行了实测下来效果有限。原因有三第一模型对我不知道这件事没有内在驱动力。你让它别编它表面上答应遇到盲区还是会编因为编一个流畅答案的概率收益比说我不知道高。第二Prompt的约束力会随着上下文变长而衰减。热搜里那个prompt is too long和invalid prompt: your prompt was flagged其实都指向同一个问题Prompt不是越长越好也不是越强硬越好它有边界。第三模型没有外部事实的锚点。它所有的判断都来自参数里的记忆而记忆是会模糊、会混淆的。你不给它一个可查证的外部来源它就只能靠记忆硬撑。所以结论很明确要压幻觉必须给模型外挂一个可靠的知识来源让它在回答前先去查查到什么说什么查不到就说不知道。这就是RAG检索增强生成的核心思想也是热搜里rag、rag知识库、rag检索增强生成、rag实战这些词反复出现的原因。3. RAG这条主线把幻觉从编变成查3.1 RAG到底解决了什么一句话讲透RAG的全称是Retrieval-Augmented Generation检索增强生成。拆开看就三步检索Retrieve→ 增强Augment→ 生成Generate。用户提问后系统先去知识库里检索出最相关的几段资料把这些资料塞进Prompt里作为参考资料然后让模型基于这些资料来回答。模型的任务从凭记忆回答变成了阅读理解后回答幻觉空间一下子被压缩了。我常跟团队说RAG的本质是给模型开卷考试。闭卷考试它只能靠记忆容易瞎蒙开卷考试它手边有资料照着资料答准确率立刻上一个台阶。当然开卷也有开卷的问题——资料找错了、资料太长模型看漏了、资料本身有错都会导致答错。所以RAG不是银弹是一整套需要调优的工程。3.2 RAG的完整链路每个环节都是幻觉的潜在来源一个标准的RAG链路我习惯拆成六个环节每个环节没做好幻觉都会从那里钻出来文档加载与解析把PDF、Word、网页、数据库记录读进来。解析错了后面全错。切块Chunking把长文档切成小块。热搜里的rag切块就是这个。切得不好检索出来的片段是残缺的模型读不懂。向量化Embedding把每个块转成向量存进向量数据库比如pgvector。检索Retrieval用户提问也转成向量去库里找最相似的Top-K个块。重排Rerank对检索结果再排一次序把最相关的顶上来。这一步很多简易实现会省掉但它是提准确率的关键。生成Generation把重排后的资料和问题一起塞给模型让它基于资料回答。这六步里第2步和第4步是幻觉的高发区。切块切碎了检索就找不准检索找不准模型拿到的资料就是错的它再忠实地基于错误资料回答输出就是错的。这种错误比模型自己编还难发现因为它看起来有据可查。3.3 RAG和微调、和MCP的区别别选错工具热搜里有个词叫rag和mcp区别说明很多人在这几个概念之间犯迷糊。我简单理一下RAG不改模型参数靠外部检索给模型喂资料。适合知识频繁更新、要求可溯源、成本敏感的场景。企业知识库首选。微调Fine-tuning改模型参数把知识焊进模型里。适合风格迁移、固定领域术语、对延迟极敏感的场景。但知识更新要重新训练成本高且依然会有幻觉。MCP可以理解为一种让模型调用外部工具/数据源的协议标准。它解决的是模型怎么连上外部能力的问题RAG可以是它连接的一种能力。我的经验是知识类问答优先RAG风格和格式类需求考虑微调两者可以叠加。绝大多数企业知识库场景RAG就够了别一上来就想着微调那是杀鸡用牛刀还费钱。4. 工程落地用Spring AI pgvector搭一套抗幻觉的RAG4.1 技术选型背后的考量热搜里spring ai实战spring ai 2.0java rag问答spring ai alibabaspring ai对接本地部署的deepseekspring ai连接千问平台这些词扎堆出现说明Java栈的开发者对RAG落地需求很旺。我这边主力也是Java栈选型逻辑分享一下。为什么用Spring AI而不是自己撸HTTP调用因为Spring AI把模型调用、Embedding、向量库、Prompt模板这些抽象成了统一的接口换模型比如从千问换到本地部署的DeepSeek基本只改配置。热搜里spring ai连接千问平台需要引哪个jar包这种问题本质就是依赖管理Spring AI的starter帮你屏蔽了大部分差异。为什么用pgvector而不是专用向量库因为大多数企业已经有PostgreSQL了pgvector是它的一个扩展不用额外维护一套数据库。数据量在百万级以下pgvector的性能完全够用运维成本还低。热搜里基于 fastapilangchainlanggraphragpgvector 的 ai agentic rag也是这个思路pgvector是跨语言栈的通用选择。为什么强调抗幻觉而不是高准确率因为准确率是个综合指标而幻觉是其中最要命的一环。我的做法是宁可让模型说资料里没有也不让它编。这个原则要贯穿整个设计。4.2 依赖配置与模型接入先看Maven依赖。以Spring AI对接国内模型平台为例核心依赖大致是这样具体版本以官方文档为准热搜里spring ai 2.0文档就是查这个的dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-model-openai/artifactId /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-vector-store-pgvector/artifactId /dependency dependency groupIdorg.postgresql/groupId artifactIdpostgresql/artifactId /dependency配置文件里把模型地址、密钥、向量库连接配好spring: ai: openai: base-url: https://你的模型平台地址 api-key: ${API_KEY} chat: options: model: 你的对话模型名 temperature: 0.1 embedding: options: model: 你的向量模型名 datasource: url: jdbc:postgresql://localhost:5432/ragdb username: rag password: rag这里有个关键点temperature一定要调低。对话场景我一般设0.1到0.3知识问答场景直接0.1甚至0。温度越低模型越保守越倾向于选概率最高的词幻觉概率显著下降。热搜里prompt闪退prompt is too long这类问题很多时候不是Prompt本身的问题是参数和上下文长度没控制好。4.3 文档切块RAG里最容易被低估的一步切块Chunking这件事我见过太多人随便按固定字数切然后抱怨检索不准。切块是RAG的地基地基歪了上面全歪。我的切块策略分三层第一层按语义结构切。优先按标题、段落、列表项这些自然边界切而不是硬按字符数。一篇制度文档按章-节-条切每个条是一个块语义完整。第二层控制块大小。块太小语义不完整检索出来是碎片块太大噪声多还会挤占上下文窗口。我的经验值是300到800个token中文大概200到500字。具体看文档密度技术文档可以小一点叙述性文档可以大一点。第三层加重叠Overlap。相邻块之间保留10%到20%的重叠防止一个完整意思被切断在两块之间。比如块大小500字重叠50到100字。// 伪代码示意实际用Spring AI的TokenTextSplitter TokenTextSplitter splitter new TokenTextSplitter( 500, // 目标块大小 100, // 最小块大小 50, // 重叠大小 10000, // 最大块数 true // 保留分隔符 );注意切块参数没有万能值必须拿你自己的文档做实验。我的做法是准备20个典型问题用不同切块参数跑检索看Top-3里有没有正确答案选命中率最高的那组。4.4 检索与重排把最相关的资料顶上来检索默认是向量相似度Top-K。K取多少我一般取5到10。取太少可能漏掉关键资料取太多会引入噪声还会让Prompt变长热搜里prompt is too long就是这么来的。但纯向量检索有个问题它擅长语义相似不擅长精确匹配。比如用户问第3.2条怎么规定的向量检索可能找不回精确的第3.2条。所以我会加一路关键词检索BM25和向量检索做混合Hybrid Search两路结果融合后再重排。重排Rerank这一步简易实现可以省但想提准确率强烈建议加上。原理是用一个专门的重排模型对问题-候选块对做精细打分比向量相似度准得多。热搜里rag检索增强生成rag实战讲得好的文章基本都会提重排。// 混合检索 重排的思路示意 ListDocument vectorResults vectorStore.similaritySearch(query, 10); ListDocument keywordResults keywordSearch(query, 10); ListDocument merged mergeAndDedup(vectorResults, keywordResults); ListDocument reranked rerankModel.rerank(query, merged, 5);4.5 Prompt工程让模型照着资料说检索回来的资料怎么用全看Prompt怎么写。这是抑制幻觉的最后一道闸门也是最考验功夫的地方。热搜里prompt engineeringprompt提示词优化prompt提示词这些词热度高就是因为大家发现Prompt写得好不好直接决定输出质量。我的抗幻觉Prompt模板核心是四条铁律你是一个严谨的知识问答助手。请严格基于下面提供的【参考资料】回答问题。 规则 1. 只使用【参考资料】中的信息回答不要使用你自己的知识补充。 2. 如果【参考资料】中没有足够信息回答直接回复根据现有资料无法回答该问题不要编造。 3. 回答时标注信息来源资料编号不要编造来源。 4. 不要对资料内容做过度推断资料说什么就说什么。 【参考资料】 {context} 【问题】 {question}这个模板的关键在于给了模型一条退路——明确告诉它不知道是被允许的、正确的。很多幻觉是因为模型觉得必须给个答案你给它台阶下它就老实了。实操心得规则不要写太多条超过5条模型就开始选择性遵守。把最关键的2到3条放前面用加粗或编号强化。另外规则里不要编造来源这条一定要有我吃过亏。5. 常见问题与排查技巧实录5.1 检索到了正确资料模型还是答错这是最让人抓狂的情况。资料明明在上下文里模型却视而不见或者答成别的。排查思路资料被淹没了上下文里塞了太多无关块正确的那块被稀释。解决减少Top-K加强重排。资料位置太靠后模型对上下文中间部分注意力弱lost in the middle现象。解决把最相关的块放最前面或最后面。Prompt指令不够强模型没意识到必须用资料。解决强化指令甚至用few-shot给个例子。模型能力不足小模型处理长上下文能力弱。解决换更强的模型或减少上下文长度。5.2 模型总说无法回答明明资料里有这是矫枉过正。规则写太死模型变得过度保守。解决把无法回答的条件放宽一点比如如果资料部分相关可以基于相关部分回答并说明哪些部分资料未覆盖。另外检查检索是不是真的召回了正确资料很多时候是检索没召回模型巧妇难为无米之炊。5.3 多轮对话里幻觉变多热搜里rag多轮对话怎么设计是个好问题。多轮对话的坑在于历史对话会污染上下文。用户前面说错了一个前提模型后面顺着错前提一路编。我的做法是每轮都重新检索不要复用上一轮的检索结果历史对话只保留最近2到3轮且做摘要压缩关键事实以本轮检索结果为准历史对话只用于理解指代比如它那个指什么。5.4 常见问题速查表现象可能原因排查方向答非所问检索召回错误检查切块、Embedding模型、Top-K编造来源Prompt未约束加来源由系统提供规则答无法回答规则过严或检索失败放宽规则、验证召回多轮后跑偏历史污染每轮重检索、压缩历史输出格式乱指令不明确用结构化输出、给示例响应超时上下文过长减Top-K、压缩资料5.5 几个我踩过的坑坑一Embedding模型和对话模型不匹配。检索用的向量模型和生成用的对话模型是两回事别混。向量模型选中文效果好的对话模型选指令遵循强的。坑二知识库更新后没重建索引。文档改了向量库还是旧的检索出来是过期内容。一定要有增量更新机制。坑三忽略元数据过滤。企业知识库往往有权限和分类检索时要带上过滤条件比如只搜用户有权限的部门文档否则会召回不该看的内容还会引入噪声。坑四把RAG当万能药。有些问题比如需要复杂推理、多跳查询RAG解决不了得上Agentic RAG让模型自己决定检索几次、检索什么。热搜里agentic rag基于 fastapilangchainlanggraphragpgvector 的 ai agentic rag就是这个方向适合复杂场景但复杂度也高别一上来就上。6. 从RAG到Agentic RAG幻觉治理的下一步单轮RAG能解决大部分知识查询类幻觉但遇到需要多步推理的问题就力不从心。比如对比A制度和B制度在年假上的差异单轮检索可能只召回一个制度的资料模型就得靠记忆补另一个幻觉又来了。Agentic RAG的思路是让模型自己规划检索策略。它可以先检索A制度再检索B制度然后对比。LangGraph这类框架就是干这个的把检索、推理、再检索串成一个可控的流程。热搜里基于 fastapilangchainlanggraphragpgvector 的 ai agentic rag描述的就是这套组合。但我要泼盆冷水Agentic RAG的复杂度和调试成本比单轮RAG高一个数量级。我的建议是先用单轮RAG把80%的常见问题解决掉剩下20%的复杂问题再考虑Agentic。别为了炫技把简单问题复杂化。另外无论哪种RAG评估体系都是必须的。我一般建一个几十到上百条的问题-标准答案集每次改动换模型、调切块、改Prompt都跑一遍看准确率和幻觉率的变化。没有评估调优就是盲人摸象。热搜里rag历史用例检索与实例化适配其实也指向这个——用历史问答对来评估和优化检索。最后分享一个我个人的判断标准一个RAG系统好不好不看它答对了多少看它答错的时候是不是诚实地错。如果它答错时说的是资料里没有那这个系统是可控的如果它答错时还在编那这个系统就是定时炸弹。抗幻觉的核心从来不是让模型变聪明而是让模型学会在该闭嘴的时候闭嘴。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价