过去 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

五、最后

在构建 HelloGitHub 的 RAG 聊天机器人过程中,回答效果一直不好,让我一度产生了放弃的念头。但当我通过查询表里的数据构造 document,并使用维度更大的 Embeding 模型后,回答效果直线提升,才让我重新看到了希望。

这段经历也让我开始认真思考:优化 RAG 的关键是什么?我的答案是 数据+检索。如今,许多企业希望借助 AI 技术赋能已有服务,RAG 则是一种门槛较低的通用解决方案。在这一过程中,数据质量决定了基础,高质量数据往往是从海量数据提纯而来。检索则是确保内容能够被快速且准确提取的关键。否则不管提示词再怎么优化,也无法检索到有价值的内容,就无法实现增强的效果。

另外,我认为在未来的 RAG 应用中,除了向量数据,数据库还需要具备一些关键能力来确保检索和生成的高效性。例如,支持关系型数据和向量数据的混合搜索,不仅能处理结构化和非结构化数据,还能有效减少 RAG 模型中的“幻觉”问题,从而让生成的答案更准确、更有根据。图搜索(知识图谱)同样很重要,它为 RAG 提供复杂推理所需的背景信息,提升生成质量。此外,RAG 应用在许多场景中需要频繁更新和同步数据,因此数据库还需支持实时查询、低延迟响应、事务处理和高可用性,这些是确保 RAG 高效运行的基础。

OceanBase 的分布式架构优势,让它在面对海量数据时依然游刃有余。而新引入的向量存储和检索能力,使得我们能够通过 SQL 轻松获取最“干净”的数据,并在同一个数据库内完成向量化操作。OceanBase 未来可期!

GitHub 地址:github.com/oceanbase/oceanbase

虽然 RAG 技术目前还不像 Web 开发那么成熟,但作为一个潜力巨大的技术方向,值得我们持续关注和学习。作为一名刚刚踏上 RAG 探索之旅的小白,我还有很多需要学习的地方。如果你也对 RAG 充满兴趣,欢迎结伴而行、共同成长!

跟着 8.6k Star 的开源数据库,搞 RAG!的更多相关文章

  1. 云栖PPT下载 | 开源界大咖集体现身,开源数据库专场重点再回眸!

    阿里云开源数据库项目最新发布 阿里巴巴集团副总裁.阿里云智能数据库事业部总裁.高级研究员李飞飞(飞刀).阿里云数据库资深技术专家楼方鑫(黄忠)以及阿里云数据库技术专家傅宇(齐木)三位阿里云技术专家为大 ...

  2. 【转】 MySQL与PostgreSQL:该选择哪个开源数据库?哪一个更好?

    转载地址:http://www.infoq.com/cn/news/2013/12/mysql-vs-postgresql 如果打算为项目选择一款免费.开源的数据库,那么你可能会在MySQL与Post ...

  3. MySQL、PostgreSQL、Ingres r3、MaxDB等开源数据库的详细比较

    1.MySQL 5 作为当今最流行的开放源码数据库之一,MySQL数据库为用户提供了一个相对简单的 解决方案,适用于广泛的应用程序部署,能够降低用户的TCO.MySQL是一个多线程.结构化查询语言(S ...

  4. MySQL全世界最流行的开源数据库软件

    誉天全国首推全球市场占有率第二的数据库——MySQL培训课程,阿里巴巴.新浪等知名企业正在使用MySQL数据库系统,而这方面的人才需求也是供不应求,誉天作为国内2014年首批ORACLE官方授权MyS ...

  5. Java免费开源数据库、Java嵌入式数据库、Java内存数据库

    Java免费开源数据库.Java嵌入式数据库.Java内存数据库 http://blog.csdn.net/leiyinsu/article/details/8597680

  6. Android开发——使用LitePal开源数据库

    前言:之前使用Android内置的数据库,感觉一大堆SQL语句,一不小心就错了,很难受,学习了这个LItePal的开源数据库,瞬间觉得Android内置的数据库简直是垃圾般的存在 LitePal Gi ...

  7. LitepalNewDemo【开源数据库ORM框架-LitePal2.0.0版本的使用】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 本Demo使用的是LitePal2.0.0版本,对于旧项目如何升级到2.0.0版本,请阅读<赶快使用LitePal 2.0版本 ...

  8. Android开发——使用LitePal开源数据库框架

    前言:之前使用Android内置的数据库,感觉一大堆SQL语句,一不小心就错了,很难受,学习了这个LItePal的开源数据库框架,瞬间觉得Android内置的数据库简直是垃圾般的存在 LitePal ...

  9. 我发起了一个 .Net 开源 数据库 项目 SqlNet

    大家好 , 我发起了一个 .Net 开源 数据库 项目 SqlNet . 项目计划 是 用 C# 写一个 关系数据库 . 可以先参考我之前写的 2 篇文章 : 谈谈数据库原理    https://w ...

  10. MySQL VS PostgreSQL:该选择哪个开源数据库?

    Naresh Kumar 是一位软件工程师与热情的博主,对编程与新事物充满了激情和兴趣.近日,Naresh撰写了一篇博文,对开源世界最常见的两种数据库 MySQL 与 PostgreSQL 的特点进行 ...

随机推荐

  1. ios中文件夹文件的创建和删除

    //1.文件夹.文件的创建和删除 NSFileManager *fileManager=[NSFileManager defaultManager]; NSString *filePath=@&quo ...

  2. 云原生爱好者周刊:寻找 Netlify 开源替代品

    开源项目推荐 Coolify Coolify 是一个开源自托管的 Heroku/Netlify 替代品,颜值还不错. Podman Desktop Podman Desktop 是针对 Podman ...

  3. 在centos7系统上安装docker环境

    基于 CentOS 7 安装 官网安装参考手册:https://docs.docker.com/install/linux/docker-ce/centos/ 确定你是CentOS7及以上版本 [ro ...

  4. 强化学习环境gym/gymnasium下的atari环境的v0、v4、v5的说明

    声明: 本文是最新版gym-0.26.2下Atari环境的安装以及环境版本v0,v4,v5的说明的部分更新和汇总,可以看作是更新和延续版本. 由于gym已经由openai公司独立出来,虽然开发团队和投 ...

  5. 基于Java+SpringBoot+Mysql实现的快递柜寄取快递系统功能实现一

    一.前言介绍: 1.1 项目摘要 随着电子商务的迅猛发展和城市化进程的加快,快递业务量呈现出爆炸式增长的趋势.传统的快递寄取方式,如人工配送和定点领取,已经无法满足现代社会的快速.便捷需求.这些问题不 ...

  6. 新手入门Java自动化测试的利器:Selenium WebDriver

    今天我们将深入探讨一款强大的Java自动化测试工具--Selenium WebDriver.在正式介绍Selenium WebDriver之前,让我们首先对Selenium本身进行简要概述,以便更好地 ...

  7. 780E开发板之errDump错误日志上报,操作方法解析

    ​ 一.errDump功能 LuatOS-Air错误日志上报功能模块名叫:errDump,errDump对"量产投放市场的设备,远程调试初步定位问题"至关重要,强烈建议客户一定要使 ...

  8. 网站统计代码v1.0

    var m = {}; var p ={}; var gifUrl = 'http://hm.iwgame.test/v.gif'; (function() { //参数组合类 m = { ck : ...

  9. MMORPG技能管线设计经验总结

    导语: 表现丰富.机制多变的技能作为MMORPG游戏战斗体验的核心组成部分,是吸引玩家的一大亮点,本文总结了在MMORPG技能系统设计上的一些经验,供大家参考. 1.设计思路 早期的MMORPG手游中 ...

  10. JDBC中驱动加载的过程分析

    江苏 无锡 缪小东 本篇从java.sql.Driver接口.java.sql.DriveManager类以及其它开源数据库的驱动类讨论JDBC中驱动加载的全过程以及JDBC的Framework如何做 ...