首页
看点啥
插画图片
首页 看点啥 从大模型“幻觉”到RAG实战:我借7个故事片段搭了个语义搜索引擎

从大模型“幻觉”到RAG实战:我借7个故事片段搭了个语义搜索引擎

2026-07-14 0

你有没有遇到过这样的情况——问大模型一个关于你公司内部文档的问题,它给你回答得头头是道,但仔细一看全是胡编乱造?

从大模型“幻觉”到RAG实战:我用7个故事片段搭了个语义搜索引擎

这不是大模型在故意骗你,而是它真的不知道。它只知道训练时喂给它的那些数据,对于你企业私有的文档、最新的资讯,它一概不知。但它又不会承认自己不知道,于是就开始“一本正经地胡说八道”——这就是所谓的大模型幻觉

怎么解决这个头疼的问题?

最直接的想法是微调(Finetune) 。但这条路走不通——成本太高了,需要大量的算力和专业的数据,一般公司根本玩不转。

那换个思路:既然大模型不知道,那我们告诉它不就行了?

这就是RAG(检索增强生成)的核心思想:

这样一来,大模型就有了“参考资料”,回答自然就靠谱多了。

但问题来了:怎么检索?

最朴素的想法是关键词搜索。但这种方法太粗糙了——用户可能问“怎么请假”,文档里写的是“休假申请流程”,关键词根本匹配不上。

于是就有了向量化(Vectorization) 的方案。

简单来说,就是把文本转换成一组数字(向量),通过计算向量之间的“距离”来判断语义上的相似度。比如:

苹果和香蕉的向量更接近,说明它们在语义上是相关的;苹果和石头则离得很远。

这就是嵌入模型(Embedding Model) 做的事。它能把文本、图片、PDF、语音等各种内容都转成向量,实现真正的语义搜索。而且嵌入模型比生成式大模型便宜得多,简直是小团队福音。

动手搭一个RAG Demo

光说不练假把式,我决定用LangChain搭一个简单的RAG Demo。

先准备数据——我写了一个关于“光光和东东”的小故事,分成7个片段,每个片段都带上元数据(章节、角色、类型、情绪):

javascript

 复制代码import { Document } from '@langchain/core/documents';const documents = [
  new Document({
    pageContent: '光光是一个活泼开朗的小男孩,他有一双明亮的大眼睛,总是带着灿烂的笑容。光光最喜欢的事情就是和朋友们一起玩耍,他特别擅长踢足球...',
    metadata: {
      chapter: 1,
      character: '光光',
      type: '角色介绍',
      mood: '活泼'
    }
  }),
  // ... 更多文档片段
];

然后初始化生成模型嵌入模型

javascript

 复制代码import 'dotenv/config';
import { ChatOpenAI, OpenAIEmbeddings } from 'langchain/openai';// 生成模型 - 用来回答问题
const model = new ChatOpenAI({
  temperature: 0,
  model: process.env.MODEL_NAME,
  apiKey: process.env.OPENAI_API_KEY,
  configuration: {
    baseURL: process.env.OPENAI_API_BASE_URL,
  }
});// 嵌入模型 - 用来做语义检索
const embeddings = new OpenAIEmbeddings({
  model: process.env.EMBEDDING_MODEL_NAME,
  apiKey: process.env.OPENAI_API_KEY,
  configuration: {
    baseURL: process.env.OPENAI_API_BASE_URL,
  }
});

这里要注意两个模型的区别:

向量数据库:存什么?怎么查?

有了文档和嵌入模型,下一步就是把这些文档向量化并存起来。

传统的MySQL等关系型数据库做不了这件事,因为向量之间的相似度计算(比如余弦相似度)需要专门的索引和查询能力。这时候就要用到向量数据库

常见的向量数据库有:

流程是这样的:

text

 复制代码1. 把文档切成段落(按章节、按页、按语义段落)
2. 用嵌入模型把每个段落转成向量
3. 把向量存到向量数据库
4. 用户提问时,也把问题转成向量
5. 在向量数据库中搜索最相似的文档片段
6. 把检索到的片段作为上下文,让大模型生成回答

实战效果

我拿着准备好的7个故事片段,问了一个问题:

如果用关键词搜索,可能只能匹配到“朋友”、“东东”、“光光”这些词,但具体的情节可能匹配不准。

但用向量检索,它能理解“成为朋友”这个语义,找到相关的片段——比如光光邀请东东踢球、光光教东东踢球、东东画画回报光光这些情节。

然后把检索到的内容放到Prompt里:

text

 复制代码背景知识:
光光看出了东东的担忧,他拍着东东的肩膀说:“没关系,我们一起练习,我相信你一定能行的!”
接下来的日子里,光光每天放学后都会教东东踢足球...
东东也用自己的方式回报光光,他画了一幅画送给光光...问题:东东和光光怎么成为朋友的?

这样大模型就能基于真实的上下文来回答,而不是瞎编。

两个关键突破

在做RAG的过程中,有两个核心问题需要解决:

1. 文档怎么切分?

切分太粗,检索到的片段可能包含太多无关信息;切分太细,可能丢失上下文。一般会按章节、按页、按语义段落来切,保证每个片段有完整的语义。

2. 向量怎么把相关的文档查出来?

这就靠向量数据库的相似度检索了。用余弦相似度计算问题向量和文档向量的夹角,夹角越小越相似。

小结

RAG不是什么高深莫测的技术,它的核心就三件事:

  1. 检索:用嵌入模型把文档向量化,存到向量数据库
  2. 增强:用户提问时,从向量数据库中检索相关文档,塞进Prompt
  3. 生成:大模型基于增强后的Prompt生成回答

这套方案比微调便宜得多,比关键词搜索准确得多,而且支持文本、图片、PDF、语音等多种格式。如果你也在被大模型幻觉困扰,不妨试试RAG。

喜欢(0)

上一篇

短剧《青染录》剧情概要

短剧《青染录》剧情概要

下一篇

从零打造LLM流式输出:让你的AI聊天像打字机一样丝滑

从零打造LLM流式输出:让你的AI聊天像打字机一样丝滑
猜你喜欢