Dify 是一个开源的 LLM 应用开发平台。其直观的界面结合了 AI 工作流、RAG 管道、Agent、模型管理、可观测性功能等,让您可以快速从原型到生产。OceanBase 从 4.3.3 版本开始支持了向量数据类型的存储和检索,在 Dify 0.11.0 中开始支持使用 OceanBase 作为其向量数据库。通过我们在 Fork 出来的 Dify 代码仓库 oceanbase-devhub/dify 中进行相应的修改之后,Dify 支持使用 MySQL 协议的数据库存储结构化数据。自此,OceanBase 作为一款多模数据库,可以很好地支持 Dify 对结构化数据和向量数据的存取需求,有力地支撑其上 LLM 应用的开发和落地。
进行实验之前,我们需要先获取 OceanBase 数据库,目前可行的方式有两种:使用 OBCloud 实例或者使用 Docker 本地部署单机版 OceanBase 数据库。我们在此推荐 OBCloud 实例,因为它部署和管理都更加简单,且不需要本地环境支持。
进入OB Cloud 云数据库 365 天免费试用页面,点击“立即试用”按钮,注册并登录账号,填写相关信息,开通实例,等待创建完成。
进入实例详情页的“实例工作台”,点击“连接”-“获取连接串”按钮来获取数据库连接信息。在“安全设置”中,将放通的 IP 地址设置为 0.0.0.0/0
。最后把密码和生成的形如mysql -h obmtxxxxxx.xxxxxx.oceanbase.cloud -P 3306 -u super -D dify -p
的连接命令记下来,后续步骤中需要把这些信息填写到创建的 .env 文件内。其中, obmtxxxxxx.xxxxxx.oceanbase.cloud
是数据库实例的连接主机地址,3306
是数据库连接端口,super
是数据库的用户名,dify
是数据库的名称。
为了分别存放结构化数据(满足 alembic 的数据库结构迁移方案要求)和向量数据,我们需要至少创建两个数据库。可在实例详情页面中的“数据库管理”功能中创建数据库。
我们针对 Dify 的 0.12.1 版本进行了 MySQL 协议兼容的修改,并且上传到了我们 fork 的代码仓库中。大家网络条件好的话推荐克隆 Github 上的版本,否则克隆 Gitee 上的版本。
git clone https://github.com/oceanbase-devhub/dify.git
# 如果网络条件差
git clone https://gitee.com/oceanbase-devhub/dify.git
为保证 dify 目录的代码是最新的状态,需要执行 git pull
命令,拉取最新的代码。
cd dify
git pull
进入到 dify 的工作目录中的docker
目录下,执行docker compose --profile workshop pull
,拉取所需要的镜像,这些镜像不一定都能够顺利拉取,请大家先自行寻求解决方案。
参考命令
cd docker
docker compose --profile workshop pull
在docker
目录下存放着一个.env.example
文件,其中包含了若干 Dify 运行所需的环境变量,我们需要把其中几个重要的配置项填写上。
我们在 docker/scripts
目录下提供了一个脚本 setup-env.sh
用来交互式地获取数据库连接信息,填入 .env
文件中并且完成数据库连接校验。你只需要执行:
bash ./scripts/setup-env.sh
然后按照提示输入数据库连接信息即可,大致形式如下:
如果在检测数据库连接步骤中,两个数据库都连接成功,则说明数据库连接信息填写正确,可以继续进行下一步。
启动之前先看看第 2 步开始拉取的镜像是否就绪,如果已经完成,可以使用下列命令启动 Dify 的容器组。
docker compose --profile workshop up -d
docker logs -f docker-api-1
docker logs -f docker-worker-1
如果在其中任意一个容器的日志中看到了Database migration successful!
这一条信息,则说明数据库结构升级完成(另一个容器中可能会有Database migration skipped
表示在该容器中跳过了数据库结构迁移),如果没有其他ERROR
信息,则说明可以正常打开 Dify 界面了。
默认情况下,Dify 的前端页面会启动在本机的80
端口上,也就是说可以通过访问当前机器的 IP 来访问 Dify 的界面。也就是说如果我在笔记本上运行的话,我在浏览器上访问localhost
即可(或者是内网 IP);如果在服务器上部署 Dify,则需要访问服务器的公网 IP。初次访问 Dify 应用会进入“设置管理员账户”的页面,设置完成后即可使用该账号登录。
在该步骤当中我们将使用阿里云百炼的模型服务,通过 Dify 搭建一个文档 RAG 问答助手。
首先,我们需要注册阿里云百炼账号,开通模型调用服务并获取 API Key
设置完成模型供应商之后刷新网页,再向通义千问模型供应商中添加模型qwen-turbo-2024-11-01
完成系统模型设置,将系统推理模型设置为qwen-turbo-2024-11-01
,Embedding 模型设置为text-embedding-v3
我们将 OceanBase 数据库的开源文档仓库克隆下来,作为数据来源。
git clone --single-branch --branch V4.3.4 https://github.com/oceanbase/oceanbase-doc.git ~/oceanbase-doc
# 如果您访问 Github 仓库速度较慢,可以使用以下命令克隆 Gitee 的镜像版本
git clone --single-branch --branch V4.3.4 https://gitee.com/oceanbase-devhub/oceanbase-doc.git ~/oceanbase-doc
回到首页,顶端中部的“知识库”标签页,进入知识库管理界面,点击创建知识库。
为了节省时间和模型服务调用量,我们仅处理 OceanBase 向量检索有关的几篇文档,这些文档相对于oceanbase-doc
目录的相对路径是zh-CN/640.ob-vector-search
,我们需要将这个目录下面所有的文档都上传。
索引方式选择“高质量”,点击“保存并处理”。
Dify 会提示知识库“已创建”,后续可能会看到某些文档已经在此处理完成。点击“前往文档”。
点击“前往文档”后会看到该知识库中的文档列表。
点击“工作室”标签页,进入应用管理界面,点击“创建空白应用”。
保持默认选项“聊天助手”和“基础编排”即可,应用名称可以自行填写,例如 “OB 向量文档助手”。输入完成后点击“创建”按钮。
创建完成后会进入应用编排界面,首先关注右上角的默认模型设置,如果不是qwen-turbo-2024-11-01
则修改为qwen-turbo-2024-11-01
点击“上下文”卡片中的“添加”按钮,选中刚才我们创建的知识库并点击“添加”按钮。
随后,在提示词的输入框中填写如下的提示词:
你是一个专注于回答 OceanBase 社区版问题的机器人。
你的目标是利用可能存在的历史对话和检索到的文档片段,回答用户的问题。
任务描述:根据可能存在的历史对话、用户问题和检索到的文档片段,尝试回答用户问题。如果用户的问题与 OceanBase 无关,则抱歉说明无法回答。如果所有文档都无法解决用户问题,首先考虑用户问题的合理性。如果用户问题不合理,需要进行纠正。如果用户问题合理但找不到相关信息,则表示抱歉并给出基于内在知识的可能解答。如果文档中的信息可以解答用户问题,则根据文档信息严格回答问题。
回答要求:
- 如果所有文档都无法解决用户问题,首先考虑用户问题的合理性。如果用户问题不合理,请回答:“您的问题可能存在误解,实际上据我所知……(提供正确的信息)”。如果用户问题合理但找不到相关信息,请回答:“抱歉,无法从检索到的文档中找到解决此问题的信息。请联系OceanBase的人工答疑以获取更多帮助。基于我的内在知识,可能的解答是……(根据内在知识给出可能解答)”。
- 如果文档中的信息可以解答用户问题,请回答:“根据文档库中的信息,……(严格依据文档信息回答用户问题)”。如果答案可以在某一篇文档中找到,请在回答时直接指出依据的文档名称及段落的标题(不要指出片段标号)。
- 如果某个文档片段中包含代码,请务必引起重视,给用户的回答中尽可能包含代码。请完全参考文档信息回答用户问题,不要编造事实,尤其是数据表名、SQL 语句等关键信息。
- 如果需要综合多个文档中的片段信息,请全面地总结理解后尝试给出全面专业的回答。
- 尽可能分点并且详细地解答用户的问题,回答不宜过短。
可以在右侧聊天框里进行应用调试,例如询问“请介绍一下 OceanBase 的向量功能”
点击应用详情右上角的“发布”下面的“运行”按钮,会打开该应用的专属页面。
点击 Start Chat 按钮即可开始聊天。
如果你是在服务器上部署的 Dify,也可以将该应用的链接分享给身边的朋友,让他们也一起来试用一下吧!
自此,你已经通过 Dify + OceanBase 搭建了你自己的 LLM 应用平台和智能体应用,恭喜你!🎉
您可以使用以下命令启动一个 OceanBase docker 容器:
docker run --name=ob433 -e MODE=mini -e OB_MEMORY_LIMIT=8G -e OB_DATAFILE_SIZE=10G -e OB_CLUSTER_NAME=ailab2024_dify -e OB_SERVER_IP=127.0.0.1 -p 2881:2881 -d quay.io/oceanbase/oceanbase-ce:4.3.3.1-101000012024102216
如果上述命令执行成功,将会打印容器 ID,如下所示:
af5b32e79dc2a862b5574d05a18c1b240dc5923f04435a0e0ec41d70d91a20ee
容器启动后,您可以使用以下命令检查 OceanBase 数据库初始化状态:
docker logs -f ob433
初始化过程大约需要 2 ~ 3 分钟。当您看到以下消息(底部的 boot success!
是必须的)时,说明 OceanBase 数据库初始化完成:
cluster scenario: express_oltp
Start observer ok
observer program health check ok
Connect to observer ok
Initialize oceanbase-ce ok
Wait for observer init ok
+----------------------------------------------+
| oceanbase-ce |
+------------+---------+------+-------+--------+
| ip | version | port | zone | status |
+------------+---------+------+-------+--------+
| 172.17.0.2 | 4.3.3.1 | 2881 | zone1 | ACTIVE |
+------------+---------+------+-------+--------+
obclient -h172.17.0.2 -P2881 -uroot -Doceanbase -A
cluster unique id: c17ea619-5a3e-5656-be07-00022aa5b154-19298807cfb-00030304
obcluster running
...
check tenant connectable
tenant is connectable
boot success!
使用 Ctrl + C
退出日志查看界面。
可以使用 mysql 客户端连接到 OceanBase 集群,检查数据库部署情况。
mysql -h127.0.0.1 -P2881 -uroot@test -A -e "show databases"
如果部署成功,您将看到以下输出:
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| oceanbase |
| test |
+--------------------+
可通过下面的命令将test
租户下的ob_vector_memory_limit_percentage
参数设置为非零值,以开启 OceanBase 的向量功能模块。
mysql -h127.0.0.1 -P2881 -uroot@test -A -e "alter system set ob_vector_memory_limit_percentage = 30"
OceanBase 数据库初始化之后默认只会创建一个名为test
的空数据库,为了分别存放结构化数据(满足 alembic 的数据库结构迁移方案要求)和向量数据,我们需要再创建一个数据库。例如可通过下面的命令创建一个新的数据库,名为dify
。
mysql -h127.0.0.1 -P2881 -uroot@test -A -e "create database dify"
setup-env.sh 脚本文件先把示例文件复制成为正式的版本。
cp .env.example .env
这部分配置项是关系型数据库的配置项,.env.example
中的171-189
行是这样的,
# ------------------------------
# Database Configuration
# The database uses PostgreSQL. Please use the public schema.
# It is consistent with the configuration in the 'db' service below.
# ------------------------------
DB_PASSWORD=******
DB_DATABASE=dify
# For MySQL Database
# SQLALCHEMY_DATABASE_URI_SCHEME=mysql+pymysql
# DB_USERNAME=root
# DB_HOST=mysql-db
# DB_PORT=3306
# For PostgresQL (By default)
DB_USERNAME=postgres
DB_HOST=db
DB_PORT=5432
需要改成如下所示的样子,也就是改成用MySQL
而不是 PG 作为 Dify 的元数据库。需要注意的是,如果使用的是在本地机器上部署的 OceanBase 数据库,xxx_HOST
需要填写172.17.0.1
。(如果是在 macOS 上,则填写 host.docker.internal
)
# ------------------------------
# Database Configuration
# The database uses PostgreSQL. Please use the public schema.
# It is consistent with the configuration in the 'db' service below.
# ------------------------------
DB_PASSWORD=****** # 更新了密码
DB_DATABASE=****** # 更新了数据库名
# For MySQL Database
SQLALCHEMY_DATABASE_URI_SCHEME=mysql+pymysql # 取消了这一行的注释,很关键!
DB_USERNAME=**** # 更新了用户名
DB_HOST=******** # 更新了 Host
DB_PORT=**** # 更新了端口
# For PostgresQL (By default)
# DB_USERNAME=postgres
# DB_HOST=db
# DB_PORT=5432
这部分是将 OceanBase 作为 Dify 的向量数据库的配置,这里需要注意的是OCEANBASE_VECTOR_DATABASE
变量不能和步骤1
中填写的DB_DATABASE
一致,因为元数据库是需要做数据库结构升级的,每次都需要比对库中所有表的结构来生成结构升级脚本,如果有向量表在其中会影响数据库结构升级工具(alembic)的正常工作。
这五个变量需要修改成你的 OceanBase 数据库的连接信息。但需要注意的是,如果使用的是在本地机器上部署的 OceanBase 数据库,xxx_HOST
需要填写172.17.0.1
。(如果是在 macOS 上,则填写 host.docker.internal
)
# OceanBase Vector configuration, only available when VECTOR_STORE is `oceanbase`
OCEANBASE_VECTOR_HOST=***
OCEANBASE_VECTOR_PORT=***
OCEANBASE_VECTOR_USER=***
OCEANBASE_VECTOR_PASSWORD=***
OCEANBASE_VECTOR_DATABASE=***
将 .env 中的VECTOR_STORE
变量的值改为了oceanbase
,选用 oceanbase 作为 Dify 的向量数据库。
在修改完.env
文件之后,setup-env.sh 脚本通过下面的命令检验数据库连接是否正常。
mysql -h1.2.3.4 -P3306 -uroot -pxxxx -Doceanbase -e "SHOW TABLES"