找回密码
 立即注册

QQ登录

只需一步,快速开始

nimotea

超级版主

29

主题

105

帖子

614

积分

超级版主

Rank: 8Rank: 8

积分
614
nimotea
超级版主   /  发表于:2024-7-15 11:37  /   查看:763  /  回复:7
本帖最后由 nimotea 于 2024-7-15 11:42 编辑

什么是RAG
        一家软件公司,希望能推出一个学习助手的功能,当用户在官网咨询关于软件产品的使用方式时,希望能由 AI 助手来解读用户的问题,并从软件的帮助文档信息中,找到正确的答案并回答用户,而且在这个过程中还希望能保证数据隐私和数据安全性,这都是 RAG 技术面对的场景问题。
RAG (Retrieval-augmented Generation) 一般指检索增强生成。通常来说,当模型需要生成文本或者回答问题时,他会从一个庞大的文档集合中检索出相关的信息,然后利用检索到的信息来指导文本的生成,从而提高预测的质量和准确性。
RAG 理解
        知识库管理是语义大模型横空出世后,最先进入工程师视野中,也是最快被实际应用的场景之一。一般来说,个人认为语义模型具备如下一些典型能力,比如内容梗概, 信息提取,模式拓展 等能力。但是需要注意的是,对于语义模型来说,"知识的范畴"本身是确定的,尝试通过 "告知"模型一些相关信息,而让模型"知道"相关的知识,本质上是做不到的。比如说当我们在某一次对话中,告知语义模型一些产品信息,切换到另一个对话进程中,你会发现模型对该产品的概念又变得一无所知,就是这个道理。引用之前看到的一句话。
"无论提示工程或者微调模型,基本上都是在告诉语义模型一种新的任务处理方式,而不是告知模型一些新的知识,模型会通过迁移学习的方式来处理新的任务。"
        语义模型提供的是对信息处理的模式服务,所以我们如果想要让语义模型掌握一定的 "私有知识",合理的做法是,将相关知识作为 prompt (提示词)中关于问题背景的描述(context),在提供的背景信息之下,语义模型会尝试提取出问题的答案,并按照自然语义的形式返回给提问者。那紧接着,自然而然的问题是,我们怎样提供,提供多少context信息呢?
ALL IN
       以活字格帮助文档为例,导出 word 版总页数按 6000页计算,我们需要将 3000000 字符的背景知识作为信息上下文传递给语义模型,按照 0.008元/千tokens 的价格计算,简单的咨询一次 设置单元格命令的相关知识,我们就需要支付 24 元的成本,这个成本会非常夸张。除了成本,还需要注意到如此庞大 context 信息带来的后续一系列性能、准确度问题,语义模型本身也会消化不良。在实际工程当中,基本没有人会采取这种检索方式。
相关性检索
       在和语义模型沟通之前,我们可以通过一种相关性规则来处理全量的资料信息,从中找到和问题最相关的那一部分文档,并使用这一部分文档作为 context 来和语义模型进行后续对话。通过这种预处理方式,可以将提问者所需的知识信息极大缩减,从成本和模型对背景信息的消化效率上都更符合生产环境需求,本文提到的 rag 就是基于这种思路来构建的。

RAG 检索架构
       一般来说,一个标准的 LLM APP 架构由如下
LLM App Stack.png45559996.png
【图片来源】https://thedataplatform.substack ... or-llm-applications
当然在我们的 RAG 应用中可能不需要上面的所有组件,我们再简化一部分
RAG 架构.png427716674.png
大致可以从以下几个流程来介绍
原始资料向量化
       在 RAG 理解这节中,我们大致描述了 RAG 检索的思路。需要在原有的资料集上选择一部分和提问相关的文档作为背景信息提供给语义模型,所以第一步我们需要解决原有资料数字化的问题,即 将我们的 pdf、word、txt 等资料文本转化为向量数据存储在向量数据库中。单纯将资料切割已经有了很多解决方案,可以 google 下相关 python 库,文本切割后,我们需要将文本数据向量化。这里需要注意一个新概念 "嵌入(embedding)",嵌入简单理解就是从字符文本到数字向量的转化过程,但需要注意,不一样的向量化方式对后续的向量相关性准确性影响还是比较大的,我们可以使用一些在线的服务,比如 千帆大模型的 bge_large_zh 文本模型,或者本地部署的嵌入模型。通过嵌入模型的帮助,我们就可以将大量的原始资料转化为 向量数据并存储在我们的向量数据库中。这里又有一个新概念,向量数据库,顾名思义,向量数据库存储的主要是向量数据,而且提供了一些通用的向量运算来满足相关场景,如果没有使用过相关数据库经验的同学可以尝试一下 pg_vector,作为 postgres 数据库的一个插件,在性能上 pgvector 已经可以打败很多商业向量数据库了。

语义查询
       对于最终用户来说肯定使用的是自然语义来提问,在 RAG 工程中,我们获取到用户提交的问题等相关信息,接着就可以根据我们前文提到的,使用用户查询和我们的资料文档库进行相关性运算,拿到最符合用户查询问题的相关文档。大致流程可以分为如下环节:
  • 将用户查询转化为向量信息 (使用嵌入模型将查询对话转为向量数据)
  • 使用查询向量在向量数据库查询固定数量的相关文档 (获取和查询向量最接近的5处文档信息)
  • 获取到相关文档信息后,填充到预先设定好的 提示模板中,例如
    1. 作为一名活字格低代码产品的技术专家,你需要回答用户提出的相关产品问题,已知用户想要了解活字格产品的 {{cagtegory}} 模块信息,活字格的 {{category}} 模块有以下相关功能{{context-info}},已经沟通历史信息为 {{chat_history}}请回答如下相关问题 {{query}}注意: 如果查询问题不涉及到活字格产品的相关问题或者和已有文档的内容相关性过低,优先回答:很抱歉,您提出的问题超出了我的知识盲区,请在论坛提交相关帖子或者咨询相关技术顾问!注意: 如果查询问题和活字格的文档相关性非常高,在回答问题时,要标注相关文档的在线访问地址
    复制代码

提示工程也有非常多的技巧点,本文不过多涉及
  • 获取到语义模型返回的结果并返回给我们的 RAG 应用
以上就是关于 RAG 增强检索的大致流程,当然有很多功能细节在一些现有开发框架上已经提供了对应方法,不至于我们需要从头实现。

结束
本文是个人学习了部分关于 AI 应用的场景后,总结的部分内容,希望对各位读者能有帮助,以后也会就一些典型 AI 应用分享更多相关知识。





7 个回复

倒序浏览
jinxinwork
初级会员   /  发表于:2024-7-16 14:34:24
沙发
AI 应用的场景,AI 应用的场景
回复 使用道具 举报
137294886
金牌服务用户   /  发表于:2024-7-16 18:13:00
板凳
谢谢分享
回复 使用道具 举报
Aa金砂
高级会员   /  发表于:2024-8-2 08:53:22
地板
作为一名活字格低代码产品的技术专家,你需要回答用户提出的相关产品问题,已知用户想要了解活字格产品的 {{cagtegory}} 模块信息,活字格的 {{category}} 模块有以下相关功能{{context-info}},已经沟通历史信息为 {{chat_history}}请回答如下相关问题 {{query}}注意: 如果查询问题不涉及到活字格产品的相关问题或者和已有文档的内容相关性过低,优先回答:很抱歉,您提出的问题超出了我的知识盲区,请在论坛提交相关帖子或者咨询相关技术顾问!注意: 如果查询问题和活字格的文档相关性非常高,在回答问题时,要标注相关文档的在线访问地址
回复 使用道具 举报
chengj
中级会员   /  发表于:2024-8-4 19:57:03
5#
<script>标记 HTML 嵌入
将工作区嵌入为聊天小部件的主要方法是通过简单的方法<script>

<!--
An example of a script tag embed
REQUIRED data attributes:
  data-embed-id // The unique id of your embed with its default settings
  data-base-api-url // The URL of your anythingLLM instance backend
-->
<script
  data-embed-id="5fc05aaf-2f2c-4c84-87a3-367a4692c1ee"
  data-base-api-url="http://localhost:3001/api/embed"
  src="http://localhost:3000/embed/anythingllm-chat-widget.min.js"
></script>

这种小部件要嵌入活字格应该怎么做?
回复 使用道具 举报
nimotea
超级版主   /  发表于:2024-8-4 23:22:37
6#
本帖最后由 nimotea 于 2024-8-5 13:51 编辑

如果只是要嵌入这个组件,可以通过 前端命令 调用 js 脚本实现
  1. let body = document.getElementsByTagName("body")[0];
  2.     let script = document.createElement("script");
  3.     script.setAttribute("data-embed-id","1473fd1e-b42d-46cc-9cf8-311a4a9505fc");
  4.     script.setAttribute("data-base-api-url","http://localhost:3001/api/embed");
  5.     script.setAttribute("src","http://localhost:3001/embed/anythingllm-chat-widget.min.js");
  6. body.appendChild(script);
复制代码
image.png375267943.png
image.png422308654.png

不过我调查了下这个 anythingllm 组件,目前嵌入交互对话框功能还是beta 版本,功能还不太全,学习可以,生产要用还得再考虑考虑。
回复 使用道具 举报
chengj
中级会员   /  发表于:2024-8-6 11:21:59
7#
nimotea 发表于 2024-8-4 23:22
如果只是要嵌入这个组件,可以通过 前端命令 调用 js 脚本实现

谢谢大佬,目前一直在研究LLM本地部署应用,主要就RAG,有可能的话还想对接活字格api,苦于能力不够
回复 使用道具 举报
nimotea
超级版主   /  发表于:2024-8-6 11:34:22
8#
chengj 发表于 2024-8-6 11:21
谢谢大佬,目前一直在研究LLM本地部署应用,主要就RAG,有可能的话还想对接活字格api,苦于能力不够

Rag 实现起来复杂度不是很高,但是要想有好的效果,还是比较难的,后面打算写一篇 rankRag 和 graphRag 这些 优化 rag 的帖子
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 立即注册
返回顶部