首页 > 数据库 >跟着 8.6k Star 的开源数据库,搞 RAG!

跟着 8.6k Star 的开源数据库,搞 RAG!

时间:2024-12-26 12:08:27浏览次数:3  
标签:RAG Star name 8.6 OceanBase 数据库 文档 HelloGitHub

https://www.cnblogs.com/xueweihan/p/18629166

 

过去 9 年里,HelloGitHub 月刊累计收录了 3000 多个开源项目。然而,随着项目数量的增加,不少用户反馈:“搜索功能不好用,找不到想要的项目!” 这让我意识到,仅仅收录项目是不够的,还需要通过更智能的方式,帮助用户找到心仪的开源项目。于是,我开始探索如何通过 RAG 技术解决这个问题

检索增强生成(RAG),是赋予生成式人工智能模型信息检索能力的技术。

RAG 技术我早有耳闻,但却一直不知道该从哪里入手。虽然现在有不少容易上手的 RAG 低代码平台,但我不想只停留在“会用”的层面,更希望了解它的实现细节,否则不敢在生产环境中用。不过,要让我直接用 LangChain 和 Ollama 从零搭建一个 RAG 系统,还真有点心里没底。

还好最近 OceanBase 搞事情,在 4.3.3 版本里支持了向量检索功能,更贴心的是,还专门为像我这样对 RAG 感兴趣的新手,准备了一个用 Python 搭建 RAG 聊天机器人的实战教程

GitHub 地址:github.com/oceanbase/oceanbase

光看永远只是纸上谈兵,所以我干脆上手把玩了一番。

接下来,我将分享如何基于该项目,打造一款 HelloGitHub 开源社区的聊天机器人,内容包括实现过程、细节优化,以及对 RAG 技术的理解与未来展望。

一、介绍

OceanBase 开源的 RAG 聊天机器人,能够通过自然对话更精准地回答与 OceanBase 文档相关的问题。

该项目是基于 langchain、langchain-oceanbase 和 streamlit 构建,处理流程是先将 OceanBase 数据库的文档,通过 Embedding 模型转化为向量数据,并存储在 OceanBase 数据库中。当用户提问时,系统会用相同的模型将问题转化为向量,然后通过向量检索找到相关的文档内容,再将这些文档作为上下文提交给大语言模型,从而生成更精准的回答。

在线体验:oceanbase.com/obi

体验后,我感觉效果还不错,于是就萌生了一个想法:能不能把 OceanBase 的文档,换成 HelloGitHub 月刊的 Markdown 文件,灌进系统里,这样不就摇身一变,成为 HelloGitHub 专属的聊天机器人了吗? 说干就干!

二、安装运行

在开始改造之前,首先需要把项目跑起来。安装运行的步骤在 OceanBase 提供的实战教程中已经很详细了,这里不再过多介绍。运行步骤如下:

  1. 执行 embed_docs.py 脚本,将文档内容向量化后存储到 OB
  2. 启动项目 streamlit run --server.runOnSave false chat_ui.py

启动成功将自动跳转至此界面:

建议

  1. Python 版本管理:运行需要 Python 3.9+,建议使用 pyenv 管理项目的 Python 版本。
  2. 查看数据库:不论是通过 Docker 部署 OceanBase 还是使用 OB Cloud,都建议在本地通过 GUI 工具查看数据库,有助于开发和调试。

运行 embed_docs.py 脚本后,查看数据库中的表,你会发现这些字段:

  • document:存储原始的文档内容
  • embedding:存储文档向量化后的数据
  • metadata:记录文档的名称、路径以及切分后的标题等信息

其中 embedding 列是一个类似数组形式的数据,这个就是通过 Embedding 模型将文档片段转化为向量数据的结果。这些向量数据能够捕捉文本的语义信息,使计算机能够更好地理解文本的含义,从而实现类似语义搜索的功能(计算距离),为后续问题与文档内容的匹配提供基础。

三、动手改造

这个项目除了支持 LLMs API,还可以切换为本地的 Ollama API 使用,只需修改 .env 配置文件即可完成调整:

# 使用支持 embed API 的模型
OLLAMA_URL=localhost:11434/api/embed
OLLAMA_TOKEN=
OLLAMA_MODEL=all-minilm

注意:在调用第三方付费 API 时,一定要注意使用量,建议仅导入部分文档用于测试,或用本地 LLM 调试逻辑,避免不必要的花费。

3.1 导入 HelloGitHub 月刊

通过 embed_docs.py 脚本,将 HelloGitHub 月刊内容向量化并导入到 OceanBase 数据库,命令如下:

python embed_docs.py --doc_base /HelloGitHub/content --table_name hg

参数说明:

  • doc_base:HelloGitHub 内容目录
  • table_name:脚本会自动创建该表,并将数据存储到表中。

但是运行后,我查看数据库时发现 document 字段中包含了许多无意义的内容,例如格式符号或无关信息:

面对这些噪声数据,我编写了一个脚本,清洗 HelloGitHub 月刊文件中无关的格式符号和冗余内容,并重新导入数据库。

3.2 启动服务

在启动服务时,需要通过环境变量 TABLE_NAME 指定要使用的表。命令如下:

TABLE_NAME=hg2 streamlit run --server.runOnSave false chat_ui.py

我试了一下,回答的效果并不理想:

经过测试,我分析问答效果欠佳的原因,可能包括以下几点:

  1. 向量化效果:所选用的模型 all-minilm 仅有 384 维度,可以尝试更大的 Embedding 模型;
  2. 数据清理:虽然清理了一部分无用内容,但可能还有一些噪声数据未处理完全;
  3. 文档完整性:HelloGitHub 的内容结构是否适合问答模型需要进一步分析;
  4. 提示词:需要完善提示词设计,补充更多上下文;

四、优化问答效果

我开始对 RAG 有些感觉了,所以准备切换到付费但效果更好的通义千问 text-embedding-v3 模型(1024 维度),进行调试。

4.1 数据优化

为提升问答效果,我决定进一步优化 document 的构造方式。具体思路是:将 HelloGitHub 网站中的表导入至 OceanBase 数据库,并基于这些表的数据,构建更干净和精准的内容。这样可以最大程度地确保项目数据的全面性,同时减少无关内容的干扰,提升向量检索相关性。

导入表到 OceanBase

OceanBase 和 MySQL 高度兼容,因此,我直接用 Navicat 将 HelloGitHub 的数据表结构和内容,从 MySQL 无缝迁移到了 OceanBase。然后我写了一个 embed_sql.py 脚本,通过直接查询相关表的数据,进而生成更精简的内容(document),同时补充元数据(metadata),并存储到数据库。核心代码如下:

# 构建内容(document)
content = f"""{row.get('name', '未知')}:{row.get('title', '未知标题')}。{row.get('summary', '暂无概要')}"""

# 构建元数据(metadata)
metadata = {
    "repository_name": row.get("name", "N/A"),  # 仓库名称
    "repository_url": row.get("url", "N/A"),  # 仓库链接
    "description": row.get("summary", "N/A"),  # 项目描述
    "category_name": row.get("category_name", "N/A"),  # 类别名称
    "language": row.get("primary_lang", "N/A"),  # 主要编程语言
    "chunk_title": row.get("name", "N/A"), 
    "enhanced_title": f'内容 -> {row.get("category_name", "N/A")} -> {row.get("name", "N/A")}'
    ...
}

# 将内容和元数据添加到文档对象
docs.append(Document(page_content=content.strip(), metadata=metadata))
# 存储到数据库
vs.add_documents(
    docs,
    ids=[str(uuid.uuid4()) for _ in range(len(docs))],
)

经过多轮调试和对比,我发现 document 数据越精简,向量检索效果越好,随后将完整的数据集存入 OceanBase 数据库的 hg5 表。

python embed_sql.py --table_name hg5 --limit=4000              
args Namespace(table_name='hg5', batch_size=4, limit=4000, echo=False)
Using RemoteOpenAI
Processing: 100%|███████████████████████████████████████████████████████████████████████▉| 3356/3357 [09:33<00:00,  5.85row/s]

至此,基于数据库表构造的 document 数据,已经非常干净了。

4.2 提示词优化

在优化完数据后,我开始思考如何优化提示词,并对 LLM 的回答进行引导和强化。以下是针对 LLM 提示词优化的方向:

  1. 明确背景和任务:在提示词中设定问答的背景并限制问题的范围,例如,确保问题只涉及开源项目或 HelloGitHub 的内容。
  2. 丰富上下文:将 metadata(元数据) 和 document(项目描述)同时提供给大模型,让 LLM 有更多上下文来生成精确回答。
  3. 高质量示例:提供高质量的回答示例,统一输出格式。
  4. 约束逻辑:明确要求 LLM 不得虚构答案。如无法回答问题,需清楚指出知识盲点,并合理提供方向性建议。

4.3 处理流程优化

在优化向量检索和回答的流程方面,我做了以下改进:

  1. 扩大检索范围:向量检索默认只返回前 10 条最高相似度的内容。我将其扩展至 20 条,为 LLM 提供更多上下文选择。
  2. 判断相关性:使用提示词指导 LLM 在输出答案前,先判断问题是否与 HelloGitHub 或开源项目相关,避免生成无关回答。
  3. 提炼回答:基于用户输入分析意图后,选出最相关的 5 个项目,并结合元数据生成更贴合用户需求的回答。

4.4 效果展示

除了上面的优化,我还进一步简化了页面、删除用不到的代码,最终呈现效果如下:

回答效果对比:

通过切换至通义千问 text-embedding-v3 模型,同时优化数据、提示词策略和问答流程,让这套 RAG 系统的回答质量有了明显提升,我打算自己盘一盘再上线。所以先放出源码,感兴趣的小伙伴可以作为参考:

GitHub 地址:github.com/521xueweihan/ai-workshop-2024

标签:RAG,Star,name,8.6,OceanBase,数据库,文档,HelloGitHub
From: https://www.cnblogs.com/chinasoft/p/18632472

相关文章

  • Chapter 8, 9 B-CIDS: 5 pillars of AI preparation → Jumpstart Approach
    B-CIDSAI-Readiness:AcompanyisAI-readywhenitcansmoothlyprogressfromAIconcepttoimplementationandbenefitrealization,anddosoconsistently.Preparation:AchievingAI-readinessisacomprehensiveprocessinvolvingcompanyculture,talent,......
  • SpringBoot自定义starter
    一.命名推荐以xxx-spring-boot-starter命名二.原理引入spring-boot-starter-jdbc后可直接使用DataSource1.加载自动配置类通过SPI(ServiceProviderInterface,Java提供的服务发现机制,用于框架拓展和组件替换)原理(1)@SpringBootApplication->@EnableAutoConfiguration->@Imp......
  • [转]使用matplotlib绘图,报错“This application failed to start because no Qt platf
    问题使用matplotlib绘图时,报错:ThisapplicationfailedtostartbecausenoQtplatformplugincouldbeinitialized.Reinstallingtheapplicationmayfixthisproblem.Availableplatformpluginsare:minimal,offscreen,webgl,windows.如图  解决方法:impor......
  • StartAI图生图局部重绘,让画面细节焕发新生!!
    在设计的世界里,每一个细节都承载着我们的创意与心血。然而,有时我们总会遇到一些不尽如人意的画面细节,它们如同瑕疵般破坏了整体的和谐与美感。今天,我要向大家推荐一款强大的工具——StartAI的局部重绘功能,它正是我们修图师的得力助手,能够帮助我们轻松解决这一问题!一、 问题初......
  • linux系统load average表示什么
    把loadaverage理解为CPU核心数是错误的,网上以讹传讹.manuptime可见:loadaverage指的是处于task_running或task_uninterruptible状态的进程(或线程)数的平均值.处于task_running状态的进程(或线程),可能正在使用CPU或排队等待使用CPU.处于task_uninterruptible状态的进程(或线......
  • vue3 使用拖动插件vuedraggable@next
    下面是一个使用VueDraggableNext的Vue3组件示例。这个示例展示了一个可拖动的列表。安装依赖首先,确保安装了VueDraggableNext:npminstallvuedraggable@next示例组件<template><div><h2>可拖动列表</h2><draggablev-model="items":animation="200&q......
  • 解决 高版本SpringBoot整合Swagger 启动报错Failed to start bean ‘documentationPlu
    解决高版本SpringBoot整合Swagger启动报错Failedtostartbean‘documentationPluginsBootstrapper‘问题|Id|Title|DateAdded|SourceUrl|PostType|Body|BlogId|Description|DateUpdated|IsMarkdown|EntryName|CreatedTime|IsActive|AutoDesc|A......
  • Camstar禁用SSL,使用Http替代Https登录Portal
    前提:1.Camstar安装正常并正常可以通过浏览器打开登录2.适用Camstar版本:8.3/8.5/8.9(问就是别的版本没用过)默认安装完成的地址:https://localhost/CamstarPortal/default.htm#/loginStep1:进入系统注册表修改相关信息CamstarInSiteServer进入注册表:regedit找到路......
  • 微软 GraphRAG 构建武松打虎的知识图谱 - 超简单教程,小学生都能学会!
    微软GraphRAG构建武松打虎的知识图谱-超简单教程,小学生都能学会!0.引言1.创建组2.读取文件3.创建组和文件的关联4.选择语言和设置实体类型5.设置LLM6.设置Langfuse7.创建基础文本单元8.创建最终文档9.抽取实体和关系10.社区检测11.创建最终实体12.创建......
  • WPF LinearGradientBrush StartPoint EndPoint
    <Windowx:Class="WpfApp92.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.......