RAG
什么是RAG
RAG(Retrieval-Augmented Generation)检索增强生成 RAG 的核心思想是在LLM生成回复之前,先去外部数据源中查找相关信息,然后将这些信息作为额外上下文提供给LLM,引导其生成更准确的回答。
在我看来,RAG就是ai应用开发的核心,对于ai的基础应用来说是地基,因为如果要投入使用或者加入到生产阶段,高可用是必要的,一定要做到稳定、准确才能实际使用。
为什么需要RAG?
- 减少大模型幻觉现象,提高回答的准确性和相关度
- 构建专门领域的回答资料库
RAG三步走
- 数据准备(索引)
- 收集和处理外部数据(提前搜集): 将各种形式的外部数据(如文档、数据库、网页、API等)收集起来。这些数据可以是企业的内部知识库,也可以是互联网上的公开信息。
- 切分和嵌入(Transformer): 将这些数据切分成小块(称为“chunk”),并使用嵌入模型将每个小块转换为高维度的数字向量(称为“嵌入”)。这些嵌入能够捕捉文本的语义信息。
- 存储到向量数据库(Embedding&indexer): 将这些向量存储在专门的向量数据库(如Milvus)中,以便后续进行高效的相似性搜索。
- 检索(Reteriever)
- 用户查询: 当用户提出问题或输入查询时,RAG系统会首先将这个查询也转换为一个向量。
- 相似性搜索: 然后,系统会在向量数据库中进行相似性搜索,找到与用户查询最相关的文档块(或片段)。这个过程就像在海量信息中找到最相关的“证据”。
- 增强生成
- 构建增强提示: 将用户原始的查询和从向量数据库中检索到的相关信息(作为上下文)一起发送给大型语言模型。
- LLM 生成回答: LLM在接收到这个“增强”后的提示后,会根据其自身的训练知识和提供的外部上下文来生成最终的回答。这样,LLM不再仅仅依赖于其训练时的数据,而是有了“实时”的参考资料。
利用Eino简易介绍
Eino是什么
Eino[‘aino] (近似音: i know,希望框架能达到 “i know” 的愿景) 旨在提供基于 Golang 语言的终极大模型应用开发框架。 它从开源社区中的诸多优秀 LLM 应用开发框架,如 LangChain 和 LlamaIndex 等获取灵感,同时借鉴前沿研究成果与实际应用,提供了一个强调简洁性、可扩展性、可靠性与有效性,且更符合 Go 语言编程惯例的 LLM 应用开发框架。
Eino核心组件
文本向量化: Embedding
Embedding 组件是一个用于将文本转换为向量表示的组件。它的主要作用是将文本内容映射到向量空间,使得语义相似的文本在向量空间中的距离较近。这个组件在以下场景中发挥重要作用:
- 文本相似度计算
- 语义搜索
- 文本聚类分析
做小抄:Indexer组件
Indexer 组件是一个用于存储和索引文档的组件。它的主要作用是将文档及其向量表示存储到后端存储系统中,并提供高效的检索能力。这个组件在以下场景中发挥重要作用:
- 构建向量数据库,以用于语义关联搜索
翻小抄:Retriever组件
Retriever 组件是一个用于从各种数据源检索文档的组件。它的主要作用是根据用户的查询(query)从文档库中检索出最相关的文档。这个组件在以下场景中特别有用:
- 基于向量相似度的文档检索
- 基于关键词的文档搜索
- 知识库问答系统 (rag)
细细切作臊子:Transformer组件
Document Transformer 是一个用于文档转换和处理的组件。它的主要作用是对输入的文档进行各种转换操作,如分割、过滤、合并等,从而得到满足特定需求的文档。这个组件可用于以下场景中:
- 将长文档分割成小段落以便于处理
- 根据特定规则过滤文档内容
- 对文档内容进行结构化转换
- 提取文档中的特定部分
Eino实现构建RAG
参考代码:https://github.com/ZenKaiii/eino-demo 这里讲一下代码流程 首先我们需要先创建一个embedder,因为后续的indexer和retriever组件都依赖embedder; 在建立indexer之前,首先需要构建向量数据库,这里选择milvus,基于docker-compose.yml构建,并初始化milvus.Cli; 随后是indexer的创建,并将想上传的文件(如markdown)利用对应的transformer做转换,并上传至向量数据库; 随后retriever取出对应的doc,并作为prompt传递给LLM;