RAG、Reranker、embedding

  • ❓ RAG 是什么
  • ❓ Reranker 是什么
  • ❓ embedding 是什么
  • ❓ chunk分块 是什么


    h7.png

业务场景

这里要说明的是,大模型本身不会联网、知识有限的,例如:"娱乐圈今天xxx出轨了"大模型是不知道的,你数据库里有一些资料文件大模型也是不知道的!

A 股现在上市有五六千家,每个季度都会公布一份pdf文件财报,一份财报文件少说有十几页,多的有上百页,现在我们要做一个AI搜索功能

按照2年的数据量,5000 X 4 X 2 = 40000 份文件要存入数据库中

这个量已经非常的大了,现在要做一个大模型搜索功能,比如你询问 茅台2025年第一季度净利润多少?

在以前大模型没有诞生的年代,通常的做法是

  1. 将这4W份pdf解析成文字,存入数据库或者elasticsearch
  2. 将问题 茅台2025年第一季度净利润多少?进行分词拆分
    2.1 例如es的ik分词器拆分为茅台 2025 第一季度 净利润 多少?
    2.2 进行es的打分搜索,取出来分值靠前的几个pdf文件
  3. 如果使用mysql的话,也可以将整句话进行全文/like搜索(没几个人这么干)

这种方式会将与关键词有关联的原始文章搜索出来

现在有了大模型,要对大模型进行数据交互,发送大模型的提示词可以写

请读取是我的资料库,回答我的问题 "茅台2025年第一季度净利润多少?"

4万份pdf文件解析的财报文本……
……
……

然后你就会发现,4W份pdf文件解析的文本一并发送给了大模型,token直接干了上千万。。。。

但即使你使用上面的步骤搜索出来的有关联原始文章发给大模型,也会有两个问题

  1. 即使是几篇pdf,token也是非常之大
  2. 由于全靠词的相似度进行搜索,里面没有自然语言的理解成分在内,例如中石化的财报里提到了2025年茅台第一季度与我公司合作这几个字,也会被搜出来,其实与我们要问的问题八杆子打不着

下面,我们以一种高效的、自然语言方式的存储搜索方法来实现

检索增强生成(RAG)

步骤一:原始数据解析

例如,我们的4万份A股财报,我们对其预处理,其中可能会有html、pdf、word、text格式文件,我们在程序上进行适配解析,确保能够解析成为文本,这里面有几个技术点需要自己慢慢磨、调试,这是一个很折磨的过程!

  • 文件中有图片的,如果也要解析,就要引入ocr识别
  • 有一些文件内容有大范围的空格,例如pdf换页的时候,段落会有数行的空格,看是否需要保留
  • 表格、目录、标题、图表等,这类内容解析成文本时格式异常的错乱无序
  • ……

LangChain 提供了很多种文件解析方案,但如果要做到精益求精,也得需要对解析结果格式不断的测试

步骤二:解析分块chunk

❓ 4万份 pdf 文件解析成文本后,存入数据库中的数据是4万表记录么?
❓ 茅台的财报pdf文件85页,讲 净利润 的只有短短两句话,你要把整个pdf文件发给大模型么?

我们有提到过,有些单个文件里面的内容非常之大,例如 中石化1个季度的财报pdf文件有80多页,这种内容是很多的,我们应当对单个 pdf 文件或其他类型的文件,再进行拆分分割,例如有这么几种方式

  • 直接按照pdf页码拆分,一页到了强制分割(这会出现一段话跨页时被分成了2块)
  • 按照内容的token数量,例如 800 个token切割一次(token是干嘛的自行gg)
  • 按照自然语言进行拆分,例如 一段 或者 两段 完整的段落切块一次

这里和步骤一一样,是一个技术打磨的过程,这里不在细讲

LangChain 是个伟大解决方案框架,也为文件内容分块做了很多基础方法封装,上面列的几种情况都有现成的方法可供调用

这样,一个原始文件就被拆分成了>=1个字文件内容

步骤三:向量化

将自然语言文本(如单词、句子或段落)转换为数值向量(即一串数字)的过程。

例如,有一段很长的内容

2月3日,媒体报道称从权威渠道获悉,浙江天台夫妻食用网购娃娃菜后被诊断出老鼠药中毒一案,警方进一步侦查发现,下毒者系杨女士的丈夫,目前涉事男子已被警方采取刑事强制措施,案件还在进一步调查之中。
3日,红星新闻记者联系当地官方人士,对方表示上述报道“部分不属实”“警方还在进一步调查”。红星新闻了解到,杨女士丈夫系陈某波,二人已结婚十几年。二人家乡的村支书表示,夫妻二人平时关系很好,村民均反映没有什么矛盾。
3日下午,红星新闻从浙江台州天台县相关官方人士处进一步了解到,警方在进一步侦查过程中发现,丈夫的下毒行为系夫妻双方共谋,两人试图通过网购娃娃菜食用后制造中毒迹象,以此要挟,向平台或商家骗取巨额赔偿。但最终被警方侦查识破。
该人士指出,“他其实不是给他老婆下毒”,夫妻二人为了骗取钱财“自己给自己下毒”。目前,杨女士、陈某波均已被刑拘。
对此,红星新闻记者也询问了夫妻二人家乡的村支书。村支书告诉红星新闻,1月31日,他和另一名村干部出于对村民的关爱,去县医院探望杨女士、陈某波,夫妻二人均尚在病房治疗,“杨女士血液里的老鼠药毒素还没清除干净”。2月3日看到新闻后,村支书多次拨打二人电话,希望了解真实情况,但已无人接听

将其转化为完整的转换成向量,例如阿里云提供了 1024 纬度的文本向量转换API,这个转化过程就称为 embedding

大致长这样 [0.23232323, 0.2389273923,0.237943934,0.984973924..............] 类似一个1024个元素的数组

截至2024年3月份是这么用的,现在是2026年,据说一些云数据库pgsql内部自带embedding方法了

步骤四:存储

id aid(源文件) chunk_id(分块id) content(内容) embedding(向量值)
1 1 1 2月3日,媒体报道称从权威渠道获悉,浙江天台夫妻食用网购娃娃菜后被诊断出老鼠药中毒一案,警方进一步侦查发现,下毒者系杨女士的丈夫,目前涉事男子已被警方采取刑事强制措施,案件还在进一步调查之中。 [0.23232323, 0.2389273923,0.237943934,0.984973924..............]
2 1 2 3日,红星新闻记者联系当地官方人士,对方表示上述报道“部分不属实”“警方还在进一步调查”。红星新闻了解到,杨女士丈夫系陈某波,二人已结婚十几年。二人家乡的村支书表示,夫妻二人平时关系很好,村民均反映没有什么矛盾。 [0.23232323, 0.2389273923,0.237943934,0.984973924..............]
3 1 3 3日下午,红星新闻从浙江台州天台县相关官方人士处进一步了解到,警方在进一步侦查过程中发现,丈夫的下毒行为系夫妻双方共谋,两人试图通过网购娃娃菜食用后制造中毒迹象,以此要挟,向平台或商家骗取巨额赔偿。但最终被警方侦查识破。 [0.23232323, 0.2389273923,0.237943934,0.984973924..............]
4 1 4 对此,红星新闻记者也询问了夫妻二人家乡的村支书。村支书告诉红星新闻,1月31日,他和另一名村干部出于对村民的关爱,去县医院探望杨女士、陈某波,夫妻二人均尚在病房治疗,“杨女士血液里的老鼠药毒素还没清除干净”。2月3日看到新闻后,村支书多次拨打二人电话,希望了解真实情况,但已无人接听 [0.23232323, 0.2389273923,0.237943934,0.984973924..............]

这是一个表结构,我们将一个文件内容,分成了4块,并分别进行了向量化存储

目前,postgresql数据库的Vector,是用的多的向量存储数据类型(这里要测试一下,Vector字段是否能够有效命中索引)

步骤五:搜索

queryDb.Raw("select id, aid, page_index, chunk_index, doc, 1-(embedding <=> ?) as score from reportify_chunk_embedding_test where article_category=? and 1-(embedding <=> ?) > ? order by score desc limit ?", sliceStr, base.Category, sliceStr, threshold, limit).Scan(&result)

上面是一个真实的向量字段搜索sql

postgresql 提供了向量字段,也提供了对应的 sql 搜索方式,例如余弦搜索

例如你询问,茅台有多少位股东,我们将这句话转化为向量值,然后通过余弦搜索sql去表里面搜全表,取出来前10条记录拿去使用

注意,文本=>embedding 的过程,结果值是非幂等的,且不能混用的

  • 有1000份文本需要向量化入库,
  • 前500条使用阿里云的 embedding api 入库
  • 后500条使用百度的 embedding api 入库

这时去通过 sql 去查库,查出来的肯定是不精准的

检索增强生成(Reranker)

向量搜索有个非常鸡肋的缺点,幻听严重

例如,你询问 茅台董事长叫什么? 向量搜索的10条记录,排名第一的可能是包含 茅台的股东是谁、茅台的老板是谁之类的原文所在段落,包含茅台的董事长的段落可能在地第5条

这时候需要重新拍一下序,来更一步精确打分与问题解决的记录

这个就叫做 Reranker(重排序器),也是很多的商业API可供调用

这个过程属于精确优化内容,例如你通过向量搜索从海量数据表中取出来10条记录,再通过 Reranker 排个序,获取前 3 条记录,扔给大模型,从而提高内容仅准率,也节省了token

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容