大家好,我是Edison。

上一篇,我们了解了什么如何让一些开源小参数量模型具有函数调用的能力。这一篇,我们来快速了解下RAG(检索增强生成)并通过一个简单的DEMO来直观感受一下它的作用。

RAG是什么?

检索增强生成(Retrieval Augmented Generation),简称 RAG,它是根据用户输入的提示词,通过自有垂域数据库检索相关信息,然后合并成为一个新的“完备的“提示词,最后再给大模型生成较为准确的回答

例如,假设你正在构建问答聊天机器人,以帮助员工回答有关公司专有文档的问题。如果没有专门的培训,独立的 LLM 将无法准确回答有关这些文档的内容的问题,因为这些 LLM 都是基于互联网上公开的数据训练的。LLM 可能会因为缺乏信息而拒绝回答,或者更糟的是,它可能会生成不正确的响应。

为了解决这个问题,RAG 首先根据用户的查询从公司文档检索相关信息,然后将检索到的信息作为额外的上下文提供给 LLM。这样,LLM 就可以根据在相关文档中找到的特定详细信息生成更准确的响应。从本质上讲,RAG 使 LLM 能够“咨询”检索到的信息来表述其答案。

一般的RAG工作流程如下图所示,它实现了 非参数事实知识 和 逻辑推理能力 的解耦或分离,这些事实知识存储在外部知识库中独立管理和更新,确保LLM能够访问到就行。

综上所述,RAG其实类似于大学期末的开卷考试,反正知识点都在书里,你平时都没学过,得先找一找,找到了就把相关答案写在试卷上,考完了还是忘得一干二净,但是你的目标达到了:考试及格60分万岁!对于LLM来说,它完成了任务,给你了一个至少可以有60分的回答。下面总结下:

  • 检索(Retrieve):根据用户提示词从知识库中获取相关知识上下文。
  • 增强(Augment):将用户的原始提示词 和 获取到的知识 进行合并,形成一个新的提示词。
  • 生成(Generate):将增强后的新提示词发给LLM进行输出。

直观感受RAG

这里我们就不深究RAG的更多细节内容了,先来通过一个DEMO直观感受下RAG到底有什么作用。至于那些更多的细节内容,留到后续学习实践后,再总结分享。

这仍然是一个WindowsForm的DEMO应用,界面如下:

(1)在没有使用RAG时的查询

(2)使用RAG:导入内部知

(3)使用RAG:检索增强查询

可以看到,基于导入的内部知识,LLM能够基于RAG获得这些知识片段,然后结合用户的问题 和 知识片段 来生成较为准确的答案。

DEMO要点

(1)配置文件

DEMO中LLM使用的是Qwen2-7B-Instruct的模型,Embedding使用的是bge-m3模型,具体的配置如下:

{
"OpenAI": {
"API_PROVIDER": "SiliconCloud",
"API_CHATTING_MODEL": "Qwen/Qwen2-7B-Instruct",
"API_EMBEDDING_MODEL": "BAAI/bge-m3",
"API_BASE_URL": "https://api.siliconflow.cn",
"API_KEY": "**********************" // Update this value to yours
},
"TextChunker": {
"LinesToken": 100,
"ParagraphsToken": 1000
}
}

(2)使用组件

使用到的组件包主要有两个:

  • Microsoft.SemanticKernel 1.19.0

  • Microsoft.SemanticKernel.Connectors.OpenAI 1.19.0

  • Microsoft.SemanticKernel.Connectors.Sqlite 1.19.0-alpha

可以看到这里使用的是一个本地数据Sqlilte来作为向量数据库存储,因为我们这个仅仅是个快速的DEMO,实际中可能会考虑选择更为适合的DB。需要注意的是,这里Sqlite这个包是个预览版,你在Nuget管理器中需要注意下勾选包含预览版才能搜索得到。

也正因为这个预览版,很多用法都有警告提示,所以最好在代码中加上下面这些将其禁用掉:

#pragma warning disable SKEXP0050
#pragma warning disable SKEXP0001
#pragma warning disable SKEXP0020
#pragma warning disable SKEXP0010
public partial class ChatForm : Form
{
......
}

(3)Embedding

private void btnEmbedding_Click(object sender, EventArgs e)
{
var query = new QueryModel(tbxIndex.Text, tbxPrompt.Text);
_textMemory = this.GetTextMemory().GetAwaiter().GetResult();
var lines = TextChunker.SplitPlainTextLines(query.Text, _textChunkerLinesToken);
var paragraphs = TextChunker.SplitPlainTextParagraphs(lines, _textChunkerParagraphsToken); foreach (var para in paragraphs)
{
Task.Run(() =>
{
ShowProcessMessage("AI is embedding your content now...");
_textMemory.SaveInformationAsync(
query.Index,
id: Guid.NewGuid().ToString(),
text: para)
.GetAwaiter()
.GetResult();
ShowProcessMessage("Embedding success!");
MessageBox.Show("Embedding success!", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
});
}
} private async Task<ISemanticTextMemory> GetTextMemory()
{
var memoryBuilder = new MemoryBuilder();
var embeddingApiClient = new HttpClient(new OpenAiHttpHandler(_embeddingApiConfiguration.Provider, _embeddingApiConfiguration.EndPoint));
memoryBuilder.WithOpenAITextEmbeddingGeneration(
_embeddingApiConfiguration.ModelId,
_embeddingApiConfiguration.ApiKey,
httpClient: embeddingApiClient);
var memoryStore = await SqliteMemoryStore.ConnectAsync("memstore.db");
memoryBuilder.WithMemoryStore(memoryStore);
var textMemory = memoryBuilder.Build(); return textMemory;
}

在Click事件中,调用GetTextMemory方法进行真正的Embedding操作,然后进行数据持久化到本地的Sqlite数据库。在GetTextMemory这个方法中,实现了调用Embedding模型API进行词嵌入。

数据写入Sqlite后打开表后的效果如下图所示。至于这个collection字段,是对应界面中的Index字段,这里我们暂时不用管它。

(4)Generation

private void btnGetRagResponse_Click(object sender, EventArgs e)
{
if (_textMemory == null)
_textMemory = this.GetTextMemory().GetAwaiter().GetResult(); var query = new QueryModel(tbxIndex.Text, tbxPrompt.Text);
var memoryResults = _textMemory.SearchAsync(query.Index, query.Text, limit: 3, minRelevanceScore: 0.3); Task.Run(() =>
{
var existingKnowledge = this.BuildPromptInformation(memoryResults).GetAwaiter().GetResult();
var integratedPrompt = @"
获取到的相关信息:[{0}]。
根据获取到的信息回答问题:[{1}]。
如果没有获取到相关信息,请直接回答 Sorry不知道。
";
ShowProcessMessage("AI is handling your request now...");
var response = _kernel.InvokePromptAsync(string.Format(integratedPrompt, existingKnowledge, query.Text))
.GetAwaiter()
.GetResult();
UpdateResponseContent(response.ToString());
ShowProcessMessage("AI Response:");
});
} private async Task<string> BuildPromptInformation(IAsyncEnumerable<MemoryQueryResult> memoryResults)
{
var information = string.Empty;
await foreach (MemoryQueryResult memoryResult in memoryResults)
{
information += memoryResult.Metadata.Text;
} return information;
}

在Click事件中,将用户的原始提示词 和 从知识库中获取的知识片段 通过一个提示词模板 组成另一个增强版的 提示词,最后将这个新的提示词发给LLM进行处理回答。

小结

本文简单介绍了一下RAG(检索增强生成)的基本概念 和 工作流程,然后通过一个简单的DEMO快速直观感受了一下RAG的作用。后续,我们会持续关注RAG的更多细节内容 和 落地实践。

参考内容

mingupupu大佬的文章:https://www.cnblogs.com/mingupupu/p/18367726

示例源码

GitHub:https://github.com/Coder-EdisonZhou/EDT.Agent.Demos

推荐学习

Microsoft Learn, 《Semantic Kernel 学习之路》,点击查看原文按钮即可直达

作者:周旭龙

出处:https://edisonchou.cnblogs.com

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

大模型应用开发初探 : 快速直观感受RAG的更多相关文章

  1. Unity3D游戏开发初探—2.初步了解3D模型基础

    一.什么是3D模型? 1.1 3D模型概述 简而言之,3D模型就是三维的.立体的模型,D是英文Dimensions的缩写. 3D模型也可以说是用3Ds MAX建造的立体模型,包括各种建筑.人物.植被. ...

  2. 无插件的大模型浏览器Autodesk Viewer开发培训-武汉-2014年8月28日 9:00 – 12:00

    武汉附近的同学们有福了,这是全球第一次关于Autodesk viewer的教室培训. :) 你可能已经在各种场合听过或看过Autodesk最新推出的大模型浏览器,这是无需插件的浏览器模型,支持几十种数 ...

  3. Web开发初探之JavaScript 快速入门

    本文改编和学习自 A JavaScript Primer For Meteor 和 MDN Web教程 前文 Web开发初探 概述 本文以介绍 JavaScript 为主,初学者掌握本文的内容后,将能 ...

  4. Web开发初探(系统理解Web知识点)

    一.Web开发介绍 我们看到的网页通过代码来实现的 ,这些代码由浏览器解释并渲染成你看到的丰富多彩的页面效果. 这个浏览器就相当于Python的解释器,专门负责解释和执行(渲染)网页代码. 写网页的代 ...

  5. [web建站] 极客WEB大前端专家级开发工程师培训视频教程

    极客WEB大前端专家级开发工程师培训视频教程  教程下载地址: http://www.fu83.cn/thread-355-1-1.html 课程目录:1.走进前端工程师的世界HTML51.HTML5 ...

  6. 基于Unity的AR开发初探:第一个AR应用程序

    记得2014年曾经写过一个Unity3D的游戏开发初探系列,收获了很多好评和鼓励,不过自那之后再也没有用过Unity,因为没有相关的需求让我能用到.目前公司有一个App开发的需求,想要融合一下AR到A ...

  7. PowerDesigner 学习:十大模型及五大分类

    个人认为PowerDesigner 最大的特点和优势就是1)提供了一整套的解决方案,面向了不同的人员提供不同的模型工具,比如有针对企业架构师的模型,有针对需求分析师的模型,有针对系统分析师和软件架构师 ...

  8. PowerDesigner 15学习笔记:十大模型及五大分类

    个人认为PowerDesigner 最大的特点和优势就是1)提供了一整套的解决方案,面向了不同的人员提供不同的模型工具,比如有针对企业架构师的模型,有针对需求分析师的模型,有针对系统分析师和软件架构师 ...

  9. 未来一年的13大手机APP开发趋势

    无论是欢呼出租车,保存票据,订购披萨还是在线购物,您可以立即联系到什么设备?你的智能手机 这是您需要的朋友,在如何查找信息和简化日常任务方面发挥着不可或缺的作用. 移动技术以光速增长; 我们不能否认手 ...

  10. 华为高级研究员谢凌曦:下一代AI将走向何方?盘古大模型探路之旅

    摘要:为了更深入理解千亿参数的盘古大模型,华为云社区采访到了华为云EI盘古团队高级研究员谢凌曦.谢博士以非常通俗的方式为我们娓娓道来了盘古大模型研发的"前世今生",以及它背后的艰难 ...

随机推荐

  1. linux date格式化获取时间

    转载请注明出处: 在编写shell脚本时,需要在shell脚本中格式化时间,特此整理下date命令相关参数的应用 root@controller1:~# date --help 用法:date [选项 ...

  2. Windows下UI自动化工具Inspect

    windows系统下的UI自动化工具Inspect是包含在WindowsSDK包里的,所以需要先下载SDK包,然后在SDK包路径下找到Inspect工具并打开使用就可以了. 官网下载链接:https: ...

  3. 搭建lnmp环境-mysql(第五步)

    版本mysql 5.7 先删除系统自带的db 新建文件夹/data/download 进入后下载 wget http://repo.mysql.com/mysql57-community-releas ...

  4. 使用ventoy安装windows10

    使用ventoy安装windows10 在ventoy中选择windows10镜像 进入Windows安装界面 下一步,选择现在安装 稍等片刻 选择我没有产品密钥 根据需求选择对应版本 下一步,接受许 ...

  5. vue pinia sessionstorage 数据存储不上的原因

    vue pinia sessionstorage 的坑 默认的配置是开始 localStorage 如果用 sessionstorage 则发现数据存储不上 ,是因为缺少了序列化和反序列化 impor ...

  6. 【爬虫】Java爬取省市县行政区域统计数据

    前言 网上看了好几个Python爬虫来爬取省市县行政区域统计 官网除了省市县以外,还有区,街道,居委村委层级 https://zhuanlan.zhihu.com/p/512852193 所以自己用J ...

  7. 【Excel】Poi + Hutool Springboot 读写Excel案例

    Excel处理需要的依赖: <!-- https://mvnrepository.com/artifact/org.apache.poi/poi --> <dependency> ...

  8. pygame游戏:python版本的贪吃蛇游戏 —— Python 贪吃蛇魔改大赛

    在网上找python版本的贪吃蛇游戏,看到一个Gitee Community / Python 贪吃蛇魔改大赛,感觉还不错,这里收藏下. 一等奖 1名 Snake Quest 蛇蛇闯关: jeffya ...

  9. pytorch不像TensorFlow那样有专用的文件存储格式真的是不足吗?pytorch该如何处理大量小文件的读取呢?

    偶然发现前文: [转载] PyTorch下训练数据小文件转大文件读写(附有各种存储格式对比) 在谈论pytorch的文件读取问题,因为以前是搞TensorFlow的,后来由于编写效率和生态环境问题转为 ...

  10. Auto.js 入门教程(二)

    来了来了 ~ 下面开始学习auto.js 了! 准备材料 : android7.0及以上版本的手机一部(需要开启 '无障碍服务') auto.js软件 vscode (安装配套插件Auto.js-VS ...