数据库运维工作量直接减少 50%,基于大模型构建智能问答系统的技术分享

news2024/11/15 11:47:42

本文源自百度智能云数据库运维团队的实践,深入探讨了基于大模型构建「知识库智能问答系统」的设计过程和应用。

全文包括了总体的技术方案选型、各个模块的设计实现、重点难点问题的突破、以及目前的落地场景应用等。

该系统自从内部上线以来,整体的回答准确率达到 80% 以上,数据库运维工作量直接减少 50%:包括 80% 咨询量,以及 20% 工单处理工作。


1    背景

随着大模型的飞速发展, AI 技术开始在更多场景中普及。在数据库运维领域,我们的目标是将专家系统和 AI 原生技术相融合,帮助数据库运维工程师高效获取数据库知识,并做出快速准确的运维决策。

传统的运维知识库系统主要采用固化的规则和策略来记录管理操作和维护的知识,这些系统的知识检索方式主要基于关键字搜索和预定义的标签或分类,用户需要具备一定的专业知识才能有效地利用这些系统。

这已不足以满足现在复杂多变的运维环境。因此,借助大模型来提供运维知识并协助决策成为趋势。这将在运维能力、成本控制、效率提升和安全性等方面带来深刻的变革。

在数据库领域,AI 技术应用可以划分为不同场景,例如知识库学习(包括知识问答和知识管理)、诊断与推理(包括日志分析和故障诊断)、工作辅助(包括 SQL 生成和 SQL 优化)等。本文将主要着重介绍「知识库智能问答系统」的设计与实现,旨在为读者提供深入了解该领域应用的思路。

2    架构设计和实现

2.1    技术方案选型

目前,大模型已经可以通过对自然语言的理解揣摩用户意图,并对原始知识进行汇总、整合,进而生成更具逻辑和完整性的答案。然而,仍存在以下几个问题,导致我们不能直接使用这些模型来对特定领域知识进行问答。

  • 专业性不足:作为通用大模型,对专业领域知识的训练不足,可能会产生虚假陈述、准确性不足以及信息丰富度不足的问题。
  • 时效性问题:模型的训练数据基于某个时间之前的数据,缺乏最新的信息,每次添加新数据都会导致高昂的训练成本。
  • 安全性问题:模型无法访问企业内部私密文档,且这些文档不能直接用于 Fine-Tuning。

为了解决这些问题,业界采用了如下几种技术手段来为大型模型提供额外知识。

  • Fine-Tuning(微调):使用特定领域的知识对基础大模型进行微调,以改变神经网络参数的权重。虽然适用于特定任务或风格,但需要大量资源和高质量的训练数据。
  • Prompt 工程:将行业领域的知识作为输入消息提供给模型,让模型对消息中的知识进行分析和处理。这种方法在正确性和精度上表现良好,但有文本长度限制,对于大规模数据不够高效。
  • 与传统搜索结合:使用传统搜索技术构建基础知识库,然后使用大语言模型处理用户请求,对召回结果进行二次加工。这种方法具有更高的可控性和效率,并适用于大规模数据。

为了确保准确性和效率,我们选择了第 2 种和第 3 种方式相结合的方案,通过向量数据库将知识外挂作为大模型记忆体,使用 LangChain 作为基础开发框架来构建知识库问答系统,最终依靠 Prompt 工程和大模型进行交互。

2.2    分模块设计实现

数据库运维知识库的整体设计流程如下图所示,包括文档加载、文档分割、文本/问题向量化、问答缓存、大模型生成答案等流程。

图片

2.2.1    知识入库

  • 数据源加载和解析:主要使用 LangChain 支持的文档加载方法,对 PDF、CSV、Markdown 等格式的文档类型进行加载和采集。此外,考虑到很多企业的文档来源是内网网页,因此也支持 Selenium 和 BeautifulSoup 来爬取网页内容,最后再应用 LangChain 中的 Markdown 加载器进行格式解析。
  • 文本分片:原始知识库应当被拆分成独立、较短的文本块,每个文本块将作为问答的最小记录,与问题进行匹配。文本的切分质量直接关系到 Embedding 和召回的质量。切分块不能太大或者太小,也不能超过 Embedding 和大模型的 token 限制。在很多内部网页文档中,由于多级标题和段落间是有上下文关联的,所以我们采用 Markdown 或者 HTML 方式进行切分,进而大大提高了对文档内容的感知能力。在文本切分器的选择上,我们主要采用 LangChain 中的 RecursiveCharacterTextSplitter 和 SpacyTextSplitter这两种分词器。它们能够在保持知识点完整性的基础上,对中文句子、段落、章节等进行良好的切分。需要注意的是,由于算法有 token 数量的限制,选择好的分词器能够为切片提供很好的切分单位和依据。目前我们选择的是 tiktoken 和 Spacy 中的 Tokenizer,但有时候并不理想,需要根据大模型采用的 token 计算方法进行适配。
  • 文本向量化:在项目初期 Embedding 模型选择了 Hugging Face 上开源的 Embedding模型,例如 GanymedeNil/text2vec-large-chinese和 moka-ai/m3e-large,但实际测试效果并不理想。最终我们选择了文心的 Embeddings 模型,效果有质的飞跃,虽然支持的 token 和向量维度低,但整体效果很好。LangChain 中对于千帆接口进行了封装,可以直接通过百度智能云千帆大模型平台调用文心 Embedding。关于文本向量化、存储和检索的详细信息,请参考下图:

图片

  • 存储:将生成的Embeddings(向量)与原始分片(知识点)进行存储,同时考虑存储一些关键的元信息,如链接地址和分片大小,以用于检索时作为过滤条件。专业的解决方案是使用向量数据库,但也可以考虑传统数据库或存储中间件,如RedisSearch 或 pgvector,它们都支持向量字段和向量相似性查询,可提供实时向量索引和查询功能。在向量数据库选型上我们对 ElasticSearch、Baidu ElasticSearch(BES)、Milvus 和 PGVector分别做了测试,在查询性能方面,PostgreSQL 性能较差不可用,而 BES、ES、milvus 性能在一个层级,BES采用自研的插件实现了 HNSW 算法,召回效果表现更好。在资源消耗方面,它们都较为耗费内存,其中 BES 和 ES 相对来说消耗较小。BES 是百度智能云自研的分布式、开源搜索与分析引擎,在百度内部多模态和大模型基础平台有多年积累和应用,在性能、分布式和易用性方面表现良好,LangChain 也对其进行了集成,最终我们选择了 BES 作为向量数据库。

2.2.2    数据检索

  • 用户问题向量化:对用户的问题进行向量化计算。如果结果在缓存中命中,将从缓存中获取已经缓存的答案,以减少文心大模型 API 费用和提高响应速度,可使用 GPTCache 等库来实现。
  • 向量检索:使用 Embeddings 模型在向量数据库中进行相似性计算,召回相似度最高的 n 个分片。目前设置的召回策略是默认选择前 10 个评分最高的分片。

2.2.3    结果整合

将向量数据库检索召回的文本进行二次加工后,利用 LLM 总结概括和分析推理能力,完成最终答案的生成。

  • Prompt 生成:将 n 个切片和用户原始 Question 组装成 Prompt。需要注意的是,Prompt 不能超出 Token 限制,超出限制则需要进行优化,例如淘汰或多次迭代调用等。我们在 Prompt 中除了原始问题和内容,还对大模型加入了回答内容的限制,如「不允许在答案中添加编造成分」、「请用中文回答」等。此外,我们还提供记忆功能,将历史会话信息传入 Prompt,一并发送给大模型。
  • 大模型响应:将 Prompt 发送给大模型,获取最终的结果。同时,将对话信息和结果追加存储到 MySQL 中,以保存会话历史,这有助于会话重启和历史信息接入大模型。

3    技术难点和解决方案

3.1    难点一:向量数据库召回率低

尽管通过将知识嵌入(Embedding)与大型语言模型相结合已经成为一种高效的实现路径,但向量数据库在向量化、存储和检索等多个阶段都可能存在问题,进而导致检索结果的召回率不尽如人意。在实际测试中,我们在未经优化的情况下,召回率仅达到了 70% 左右。而一个相对可靠的系统,召回率至少需要达到 85% 或甚至 90% 以上。以下是我们在应用中采取的优化措施。

3.1.1    精确切分文本

  • 分割模型:由于训练的文档主要是中文文档,因此切片工具必须具备对中文的良好支持。为此,我们首选 Spacy 作为分割工具,并采用 zh_core_web_sm 模型作为标记器(tokenizer)。
  • 分割条件:一般情况下,大部分系统会使用 LangChain 定长切分,但这样会丢失大部分上下文关联,知识点也是割裂的。在实践中,我们没有仅仅依赖 chunk size 作为唯一的切割条件,而是对那些具有明显段落或章节结构的文本格式(如 Markdown 或 HTML)进行了格式化分割,以确保文本的连续性、相关性和完整性。当段落超过 Embedding token 数限制时,我们会使用 RecursiveCharacterTextSplitter 对段落继续进行切分,切分条件除了设置换行符外,还加入了中文常见的断句符号,比如分号、叹号等。
  • 标题补偿:当某段文字的大小超过了 chunk size 时,我们会针对没有标题的 chunk 补充标题,以确保整体切分的完整性。

图片

3.1.2    优化文本向量化

  • 标题向量化:在进行精细化切分之后,标题的重要性显现出来。因此,我们在这一阶段对标题进行向量化处理。这一方法适用于帮助手册、 HTML 和 Markdown 等文本格式。
  • 内容关键字向量化:如果仅对标题进行向量化,对于那些标题概括性较差或段落内容丰富的情况,精召率提升仍然有限。因此,我们还尝试了了另一种方法,即首先利用大型模型或关键字模型提取关键字,数量通常限制在 10 左右,然后对这些关键字进行向量化处理。由于多轮次调用的耗时和关键字提取的可靠性问题,最终该方案被放弃。
  • 标题 + 内容同时向量化:在文本分割时,我们强行对每个分片加入了标题。在向量化时,会将标题 + 内容打包一并进行向量化。我们将用户提问向量化后,和向量化后的切片进行检索匹配,选择与问题最相关的 topN 切片,这样可以显著提高精召率,这也是我们最终的方案。

3.1.3    Embeddings 和向量检索调优

对于 Embeddings 的选择和调优,上文已经介绍过,我们最终选择了效果更好的文心 Embedding。对于向量数据库检索性能,这里优化空间并不大,调整 HNSW 算法的参数,对最后召回结果影响不大。

3.2    难点二:Token 数量限制

在应用大型语言模型时,我们面临的主要限制之一就是输入文本的上下文长度。开源模型和商业模型的上下文长度限制范围从 2K 到 100K 不等。上下文长度对于应用大型语言模型具有关键影响,包括知识增强、记忆等方面的工作,都是为了解决上下文长度限制而设计的。以下是我们采取的策略:

  • 取舍:如果选择的 10 个文本组合成的 Prompt 超出了模型的 Token 限制,我们采取逐一舍弃相似度较低的片段的策略。如果减少到召回文档为 6 个时还是超限制,则会选择 token 数支持更多的模型。
  • 模型选择:ERNIE-Bot-turbo 模型支持 10200 个Token,ERNIE-Bot 支持 2000 个 Token 的 ERNIE-Bot 模型,以扩大上下文长度。但是 ERNIE-Bot-turbo 在问答领域的效果并不如 ERNIE-Bot,此时,我们的策略是在不超过 2000 个 token 的情况下优先选择 ERNIE-Bot,极大地提升了系统对复杂问题的处理能力。
  • 压缩 Prompt:我们尝试对多个切片拼接后的文本进行压缩,以提取主要内容,去除无用且重复的词组。然而,这种方法的效果有限,甚至可能导致文本失真,且对中文支持较差,因此无法从根本上解决问题。压缩效果如下图:

图片

  • 多轮次迭代调用 LLM:面对超长文本超出大模型 token 限制的情况,我们采用了 MapReduce 的方式来突破 Token 限制。该方式将文本拆分成多个部分,并多次调用 LLM 以解决文本长度问题。具体流程包括将多个分段分别请求 LLM,获取各自的局部答案。然后将这些局部答案拼接成新的 Prompt,再次请求 LLM 以获取最终答案。这一流程有效地扩展了上下文长度,但是实际应用效果并不理想,表现为最终结果失真,尤其是在回答流程类问题场景下。主要原因是汇聚后丢失了很多原始文本细节。

图片

3.3    难点三:知识陈旧和虚构答案

在商业大型模型的大多数应用场景下,模型能够为 MySQL、Oracle 等数据库的相关问题提供令人满意的答案。然而,不可避免地,这些大型模型有时会出现知识陈旧和答案虚构的问题。为了提供更加丰富和准确的答案,我们采用了一种搜索和推荐系统的方法,并结合了大型模型的推理和总结能力。以下是我们的主要方案和流程:

  • 提取问题关键字:首先从客户问题中提取关键字,以确保这些关键字能够准确地用于搜索引擎检索。为此,我们探索了两种不同的方法:
    • 大模型:大型模型本身具备一定的关键字提取能力,但实际测试表明,这种方法的稳定性有待提高,可能会导致调用链出现异常。因此,我们需要对这种方式进行 Prompt 的调优,以提高其性能和可靠性。
    • NLP 算法:另一种思路是利用 NLP 模型来进行关键字提取。然而,我们曾尝试使用 Hugging Face 的一些模型,但效果并不十分理想。
  • 搜索引擎检索和文档解析:为了获得与数据库问题相关的准确答案,我们评估了以下两种不同的策略:
    • 接入百度搜索引擎:我们曾尝试使用百度搜索 API 来根据提取的关键字进行检索。然而,这一方法的答案质量较差,而且可能包含过时的信息,这可能会对最终答案造成负面影响。因此,我们最终放弃了这一方案。
    • 接入官方文档搜索:对于 MySQL 等数据库,官方文档提供了用于客户搜索的 API。我们只需传入关键字即可获取与之匹配的搜索结果。然后,我们可以选择最相关的前 N 个结果,并对这些结果的链接内容进行爬取和解析。这一流程类似于之前描述的领域知识入库和知识检索流程,但具体细节不再赘述。

图片

  • 调用大模型:将多个 chunk 拼接和问题一起生成 prompt,调用大模型获取答案。

可以看到文档解析和大模型调用其实就是在重复我们前边介绍的领域知识入库和结果的二次整合过程,唯一不同的地方就是我们使用搜索引擎去代替了向量检索。以 MySQL 为例子,具体流程如下:

图片

4    应用场景接入

该系统自从内部上线以来,整体的回答准确率达到 80% 以上,数据库运维工作量直接减少 50%,包括 80% 咨询量,以及 20% 工单处理工作。

目前「知识库智能问答系统」主要通过两种方式接入和应用:Database Chat 和 IM 机器人。

  • Database Chat:除了类似于 ChatGPT 问答界面外,还具备知识管理、用户管理等功能。(该功能已经集成数据库智能驾驶舱 DBSC 中,将于 3 月底正式开放上线)

图片

  • IM 机器人:IM 工具做为工作协同中最重要的软件,使用频率非常高。我们提供了 IM 接入接口,客户可以开发 IM 软件(微信、飞书、如流等)机器人,在聊天群中实现快速高效获取信息和知识。

图片

5    总结

从技术工程角度来看,利用向量数据库结合大型 AI 模型来构建领域知识库系统的实现并不复杂,然而,这一领域仍然面临着不少挑战和潜在的改进空间。在本文中,我们已经讨论了一些解决方案和技术,但仍然有许多可能的改进和未来发展方向值得深入研究。

首先我们认为关键点还是解决向量检索的召回准确性和超长文本处理能力是两个难点,这些方面可能还有更好的方式。此外,大模型本身的能力和文档质量是系统性能的关键因素,因此需要不断升级和维护模型,同时确保文档的及时性和准确性。

我们希望更多的研究者和工程师积极贡献更多的创新思路和技术,推动大模型在数据库运维领域落地,期待未来能有更多的可能性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1424649.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Vue】vue项目中使用tinymce富文本组件(@tinymce/tinymce-vue)

【Vue】vue项目中使用tinymce富文本组件(tinymce/tinymce-vue) 一、安装二、前期准备工作1、去[官网](https://www.tiny.cloud/get-tiny/language-packages/)下载语言包;2、将下载的语言包复制到项目中的assets(存放路径您随意&am…

SAP的FAGLGVTR执行出现视图名称FGLV_BCF_ALLB不存在

这个问题找了很久没有找到问题所在,查阅了很多资料也没有 执行完FAGLGVTR出现视图dump,原因是CB的增强字段不知道什么原因在视图没有保持一致 往前面溯源的时候 FGLV_BCF_ALLB10 FGLV_BCF_PER0B FGLV_BCF_PER0B10 FGLV_BCF_PER0 前面FGLV_BCF_…

三子棋游戏小课堂

🪐🪐🪐欢迎来到程序员餐厅💫💫💫 今天的主菜是,C语言实现的三子棋小游戏, 所属专栏: C语言知识点 主厨的主页:Chef‘s blog 前言&…

SpringBoot集成H2数据库

1&#xff09;添加H2的依赖 <dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId><scope>compile</scope> </dependency>2&#xff09;添加连接配置&#xff0c;启用web控制台 spring:datasource:url…

短信验证码接口被恶意攻击了该怎么办?

在企业运行的时候&#xff0c;安全意识和风险防范机制一定要做好。在2019年SUBMAIL短信平台就有几个客户的短信验证码接口遭到了恶意攻击&#xff0c;如果没有做好防范就会造成一定程度的损失。 那么&#xff0c;当短信验证码接口被恶意攻击的时候&#xff0c;该怎么办呢&#…

【OCR软件进化史】文字、表格、公式图片识别并与ChatGPT交互

第1年 由于日常工作需要大量的文本处理&#xff0c;身为一个全栈pythoner是绝不允许手动复制粘贴。 于是&#xff0c;在2021年&#xff0c;封装了第1版的文字、表格、公式图片识别工具&#xff08;第1版&#xff09;&#xff1a; 第1版做的比较粗糙&#xff0c;就是封装了百度…

STC8G1K17A点灯

目录 1设计目的 2STC8G1K17A介绍 3代码实现 4效果测试 1设计目的 通用的STC89C52单片机由于封装太大&#xff0c;而且还需要外加晶振才能工作&#xff0c;对于一些要求不高的场合&#xff0c;就显得很笨重&#xff0c;所以&#xff0c;此次设计就是寻找一个代替产品&#x…

Kotlin 协程:用源码来理解 ‘viewModelScope‘

Kotlin 协程&#xff1a;用源码来理解 ‘viewModelScope’ Kotlin 协程是 Kotlin 语言的一大特色&#xff0c;它让异步编程变得更简单。在 Android 开发中&#xff0c;我们经常需要在后台线程执行耗时操作&#xff0c;例如网络请求或数据库查询&#xff0c;然后在主线程更新 UI…

PHP的线程安全与非线程安全模式选哪个

曾经初学PHP的时候也很困惑对线程安全与非线程安全模式这块环境的选择&#xff0c;也未能理解其中意。近来无意中看到一个教程对线程安全&#xff08;饿汉式&#xff09;&#xff0c;非线程安全&#xff08;懒汉式&#xff09;的描述&#xff0c;虽然觉得现在已经能够很明了透彻…

Python算法题集_最大子数组和

本文为Python算法题集之一的代码示例 题目53&#xff1a;最大子数组和 说明&#xff1a;给你一个整数数组 nums &#xff0c;请你找出一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&#xff0c;返回其最大和。 子数组 是数组中的一个连续部分。…

RS485自动收发电路震荡的问题

电路 设计初衷 电源5V 选择5V的原因&#xff0c;差分2.5V比1.5V可以提高传输能力 TTL输入 3.3V电平满足需求 TTL输出 4.5V了&#xff0c;MCU是3.3V平台 这样就分为两种情况 MCU接收端可以容忍5V输入 MCU接收端不可以容忍5V输入&#xff0c;就要进行电压转换&#xff0c;我这里使…

【C++】STL优先级队列(priority_queue)

priority_queue 基本介绍 priority_queue就是优先级队列。其头文件就是queue&#xff0c;但是队列和优先级队列关系不大&#xff0c;两个是不同的数据结构。但二者都是适配器&#xff0c;容器适配器。 优先级队列中存放的数据是有优先级的。 其内部有以下成员方法&#xff0c…

跟着cherno手搓游戏引擎【17】整理代码、timestep和transform

这里就不分部走了&#xff0c;直接上代码。 全局&#xff1a; YOTO.h:添加renderer的头文件&#xff1a; #pragma once//用于YOTO APP#include "YOTO/Application.h" #include"YOTO/Layer.h" #include "YOTO/Log.h"#include"YOTO/Core/T…

V2X,启动高增长引擎

车载通讯的下一个新周期&#xff0c;毋庸置疑是V2X。从4G、5G再到C-V2X&#xff0c;是车载通讯逐步从信息娱乐、行车数据监控到万物互联的关键。 去年5月&#xff0c;全球车载通讯芯片巨头—高通公司宣布&#xff0c;与以色列车联网&#xff08;V2X&#xff09;芯片设计公司Aut…

DevOps落地笔记-05|非功能需求:如何有效关注非功能需求

上一讲主要介绍了看板方法以及如何使用看板方法来解决软件研发过程中出现的团队过载、工作不均、任务延期等问题。通过学习前面几个课时介绍的知识&#xff0c;你的团队开始源源不断地交付用户价值。用户对交付的功能非常满意&#xff0c;但等到系统上线后经常出现服务不可用的…

扣库的函数经验

有的库确实可以提出来的 比如这个库 GitHub - intel/x86-simd-sort: C template library for high performance SIMD based sorting algorithms 根据自己的需要是可以&#xff0c;把内容抠出来的&#xff0c;重新build的。 我就自己新建了一个vs的工程&#xff0c;然后把源…

将java对象转换为json字符串的几种常用方法

目录 1.关于json 2.实现方式 1.Gson 2.jackson 3.fastjson 3.与前端的联系 1.关于json JSON是一种轻量级的数据交换格式。它由Douglas Crockford在2001年创造。JSON的全称是JavaScript Object Notation&#xff0c;它是一种文本格式&#xff0c;可以轻松地在各种平台之间传…

【GEE】基于GEE可视化和下载Landsat8 L2A数据(镶嵌、裁剪)

之前发过一篇使用GEE下载Landsat8的文章&#xff0c;然后有很多小伙伴私信我各种问题&#xff0c;如L1C、L2数据代码怎么修改&#xff0c;如何镶嵌&#xff0c;如何去云、 如何裁剪等一系列问题。正好快过年了&#xff0c;手头的事也没有多少了&#xff0c;所以这两天整理了一下…

考研高数(数列极限之f(xn)和{xn}的关系)

说白了&#xff0c;f(xn)是复合函数&#xff0c;是f(x)与{xn}的复合函数。&#xff08;复合函数的单调性有同增异减的原则&#xff09; 例题1&#xff1a;【可以用同增异减的原则&#xff0c;迅速解答&#xff08;有不合理的地方&#xff0c;请各位大佬指正&#xff01;&#…

【操作系统】FileOutputStream的flush操作有时不生效

按照我们的理解&#xff1a;FileOutputStream的flush()方法的作用就是将缓冲区中的数据立即写入到文件中&#xff0c;即使缓冲区没有填满。这样可以确保数据的及时写入&#xff0c;而不需要等待缓冲区填满或者调用 close() 方法关闭流时才写入。真的是这样吗&#xff1f;&#…