一、前言:
实验环境
- 系统版本:Centos 7.9
- 内存:8G
- 存储:70G
- docker版本:26.1.4
上次广州ai搭建时部署过 AI 实践营实验,会有以下问题:
1.权限不足
Database migration skipped
None of PyTorch, TensorFlow >= 2.0, or Flax have been found. Models won't be available and only tokenizers, configuration and file/data utilities can be used.
/app/api/.venv/lib/python3.12/site-packages/celery/platforms.py:829: SecurityWarning: You're running the worker with superuser privileges: this is
absolutely not recommended!
2.表结构已存在
sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (1050, "Table 'account_integrates' already exists")
解决方案:
- 创建一个新的超级用户,新的用户将具备
REFERENCES
权限 - 删除当前创建部分表的数据库,创建一个新的数据库用以连接
二、平台搭建步骤
1. 获取 OceanBase 数据库
进行实验之前,我们需要先获取 OceanBase 数据库,目前可行的方式有两种:使用 OBCloud 实例或者使用 Docker 本地部署单机版 OceanBase 数据库。我们在此推荐 OBCloud 实例,因为它部署和管理都更加简单,且不需要本地环境支持。
1.1 注册并开通 OBCloud 实例
进入OB Cloud 云数据库 365 天免费试用页面,点击“立即试用”按钮,注册并登录账号,填写相关信息,开通实例,等待创建完成。
1.2 获取数据库实例连接串
进入实例详情页的“实例工作台”,点击“连接”-“获取连接串”按钮来获取数据库连接串,将其中的连接信息填入后续步骤中创建的 .env 文件内。
1.3 创建多个数据库
为了分别存放结构化数据(满足 alembic 的数据库结构迁移方案要求)和向量数据,我们需要至少创建两个数据库。可在实例详情页面中的“数据库管理”功能中创建数据库。
2.安装docker
2.1安装依赖包
yum install -y yum-utils device-mapper-persistent-data lvm2
2.2docker-ce安装
sudo yum install -y docker-ce
2.3启动docker并设置开机自启
#启动docker命令
systemctl start docker
#设置开机自启命令
systemctl enable docker
#查看docker版本命令
docker version
2.4我的报错调整
我这里sudo 启动sudo sh scripts/setup-env.sh 一直报错,调整了权限(自己虚拟机给了777,大家别模仿)
[root@localhost ~]# ls -al /var/run/docker.sock
srw-rw----. 1 root docker 0 12月 9 17:09 /var/run/docker.sock
[root@localhost ~]#
[root@localhost ~]#
[root@localhost ~]#
[root@localhost ~]#
[root@localhost ~]# chmod 777 /var/run/docker.sock
[root@localhost ~]#
检测数据库连接:
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 2005 (HY000): Unknown MySQL server host 'obmt69g97qs7kio0-mi.aliyun-cn-hangzhou-internet.oceanbase.cloud' (-2)
test1 数据库连接失败!
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 2005 (HY000): Unknown MySQL server host 'obmt69g97qs7kio0-mi.aliyun-cn-hangzhou-internet.oceanbase.cloud' (-2)
vectors 数据库连接失败!
3. 克隆项目
我们针对 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
4. 拉取 Docker 镜像(有点慢)
root@localhost data]# cd dify/docker
[root@localhost docker]#
[root@localhost docker]#
[root@localhost docker]# docker compose --profile workshop pull
WARN[0000] The "CERTBOT_EMAIL" variable is not set. Defaulting to a blank string.
WARN[0000] The "CERTBOT_DOMAIN" variable is not set. Defaulting to a blank string.
[+] Pulling 27/30
✔ worker Skipped - Image is already being pulled by api 0.0s
⠏ web [⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀] Pulling 122.1s
⠏ api [⣿⣿⣿⣿⣿⣿⣿⣿⣀⣿⣿⣿⣿] 481.5MB / 953.3MB Pulling 122.1s
✔ redis Pulled 103.8s
✔ ssrf_proxy Pulled 35.5s
⠏ nginx [⠀⠀⠀⠀⠀⠀⠀] Pulling 122.1s
⠏ sandbox [⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀] Pulling 122.1s
5. 修改环境变量
在docker
目录下存放着一个.env.example
文件,其中包含了若干 Dify 运行所需的环境变量,我们需要把其中几个重要的配置项填写上。
我们在 docker/scripts
目录下提供了一个脚本 setup-env.sh
用来交互式地获取数据库连接信息,填入 .env
文件中并且完成数据库连接校验。你只需要执行:
[root@localhost docker]#sh scripts/setup-env.sh
请输入数据库配置信息:
数据库主机地址 [当前值: ob云连接ip]:
数据库端口 [当前值: 3306]:
数据库用户名 [当前值: xxx]:
数据库密码 [当前值: 密码]:
数据库名称 [当前值: test1]: #自己创建的库
向量数据库名称 [当前值: vectors]: #自己创建的库
数据库配置已更新到 .env 文件中
检测数据库连接:
mysql: [Warning] Using a password on the command line interface can be insecure.
Tables_in_test
call_center
catalog_page
catalog_returns
catalog_sales
corpus
customer
customer_address
customer_demographics
date_dim
household_demographics
income_band
inventory
item
promotion
reason
ship_mode
store
store_returns
store_sales
time_dim
warehouse
web_page
web_returns
web_sales
web_site
test 数据库连接成功~
mysql: [Warning] Using a password on the command line interface can be insecure.
vectors 数据库连接成功~
[root@localhost docker]#
[admin@localhost docker]$ sudo bash ./scripts/setup-env.sh -t
mysql: [Warning] Using a password on the command line interface can be insecure.
test1 数据库连接成功~
mysql: [Warning] Using a password on the command line interface can be insecure.
vectors 数据库连接成功~
6. 启动 Dify 容器组
[admin@localhost docker]$ sudo docker compose --profile workshop up -d
[+] Running 9/9
✔ Network docker_ssrf_proxy_network Created 0.0s
✔ Network docker_default Created 0.1s
✔ Container docker-ssrf_proxy-1 Started 1.1s
✔ Container docker-sandbox-1 Started 1.1s
✔ Container docker-redis-1 Started 1.2s
✔ Container docker-web-1 Started 1.2s
✔ Container docker-worker-1 Started 1.7s
✔ Container docker-api-1 Started 1.8s
✔ Container docker-nginx-1 Started 2.2s
[admin@localhost docker]$
# 关闭
sudo docker compose stop
7. 查看 Dify 后端服务日志
docker logs -f docker-api-1
docker logs -f docker-worker-1
7.1日志信息
正确的迁移:正常情况下会创建 72 张表,迁移完成的时候可能会有 Redis 相关的报错,这是 Redis 加锁超时的问题
[root@localhost docker]# docker logs -f docker-api-1
[root@localhost ~]# docker logs -f docker-api-1
Running migrations
.................................................................
fontManager
Preparing database migration...
Starting database migration.
INFO [alembic.runtime.migration] Context impl MySQLImpl.
INFO [alembic.runtime.migration] Will assume non-transactional DDL.
INFO [alembic.runtime.migration] Running upgrade -> 01d6889832f7, snapshot
Database migration successful! # 成功,完美
Traceback (most recent call last):
File "/app/api/.venv/bin/flask", line 8, in <module>
sys.exit(main())
................................................................
# 有 Redis 相关的报错,这是 Redis 加锁超时的问题
File "/app/api/commands.py", line 595, in upgrade_db
lock.release()
File "/app/api/.venv/lib/python3.12/site-packages/redis/lock.py", line 256, in release
self.do_release(expected_token)
File "/app/api/.venv/lib/python3.12/site-packages/redis/lock.py", line 262, in do_release
raise LockNotOwnedError(
redis.exceptions.LockNotOwnedError: Cannot release a lock that's no longer owned
如果在其中任意一个容器的日志中看到了Database migration successful!
这一条信息,则说明数据库结构升级完成(另一个容器中可能会有Database migration skipped
表示在该容器中跳过了数据库结构迁移),如果没有其他ERROR
信息,则说明可以正常打开 Dify 界面了。
7.2云上mysql创建 72 张表
mysql> show tables;
+-----------------------------------+
| Tables_in_test1 |
+-----------------------------------+
| account_integrates |
| accounts |
| alembic_version |
| api_based_extensions |
| api_requests |
| api_tokens |
| app_annotation_hit_histories |
| app_annotation_settings |
| app_dataset_joins |
| app_model_configs |
| apps |
| celery_taskmeta |
| celery_tasksetmeta |
| conversations |
| data_source_api_key_auth_bindings |
| data_source_oauth_bindings |
| dataset_collection_bindings |
| dataset_keyword_tables |
| dataset_permissions |
| dataset_process_rules |
| dataset_queries |
| dataset_retriever_resources |
| datasets |
| dify_setups |
| document_segments |
| documents |
| embeddings |
| end_users |
| external_knowledge_apis |
| external_knowledge_bindings |
| installed_apps |
| invitation_codes |
| load_balancing_model_configs |
| message_agent_thoughts |
| message_annotations |
| message_chains |
| message_feedbacks |
| message_files |
| messages |
| operation_logs |
| pinned_conversations |
| provider_model_settings |
| provider_models |
| provider_orders |
| providers |
| recommended_apps |
| saved_messages |
| sites |
| tag_bindings |
| tags |
| tenant_account_joins |
| tenant_default_models |
| tenant_preferred_model_providers |
| tenants |
| tidb_auth_bindings |
| tool_api_providers |
| tool_builtin_providers |
| tool_conversation_variables |
| tool_files |
| tool_label_bindings |
| tool_model_invokes |
| tool_providers |
| tool_published_apps |
| tool_workflow_providers |
| trace_app_config |
| upload_files |
| whitelists |
| workflow_app_logs |
| workflow_conversation_variables |
| workflow_node_executions |
| workflow_runs |
| workflows |
+-----------------------------------+
72 rows in set (0.05 sec)
8. 访问 Dify 应用
默认情况下,Dify 的前端页面会启动在本机的80
端口上,也就是说可以通过访问当前机器的 IP 来访问 Dify 的界面。也就是说如果我在笔记本上运行的话,我在浏览器上访问localhost
即可(或者是内网 IP);如果在服务器上部署 Dify,则需要访问服务器的公网 IP。初次访问 Dify 应用会进入“设置管理员账户”的页面,设置完成后即可使用该账号登录。
三、应用开发步骤
在该步骤当中我们将使用阿里云百炼的模型服务,通过 Dify 搭建一个文档 RAG 问答助手。
1. 开通阿里云百炼模型调用服务并获取 API KEY
首先,我们需要注册阿里云百炼账号,开通模型调用服务并获取 API Key
参考文档:docs/dify@oceanbase-workshop.md · oceanbase-devhub/dify - Gitee.com
2. 设置模型供应商和系统模型
填写API KEY 和模型名称qwen-turbo-2024-11-01
完成系统模型设置,将系统推理模型设置为qwen-turbo-2024-11-01
,Embedding 模型设置为text-embedding-v3
3. 创建知识库并上传文档
3.1 克隆文档仓库
我们将 OceanBase 数据库的开源文档仓库克隆下来,作为数据来源。
[admin@localhost docker]$ git clone --single-branch --branch V4.3.4 https://gitee.com/oceanbase-devhub/oceanbase-doc.git ~/oceanbase-doc
正克隆到 '/home/admin/oceanbase-doc'...
remote: Enumerating objects: 126520, done.
remote: Counting objects: 100% (126520/126520), done.
remote: Compressing objects: 100% (70851/70851), done.
remote: Total 126520 (delta 55338), reused 126520 (delta 55338), pack-reused 0
接收对象中: 100% (126520/126520), 69.60 MiB | 5.72 MiB/s, done.
处理 delta 中: 100% (55338/55338), done.
[admin@localhost docker]$
3.2 将指定文档上传到知识库中
回到首页,顶端中部的“知识库”标签页,进入知识库管理界面,点击创建知识库。
为了节省时间和模型服务调用量,我们仅处理 OceanBase 向量检索有关的几篇文档,这些文档相对于oceanbase-doc
目录的相对路径是zh-CN/640.ob-vector-search
,我们需要将这个目录下面所有的文档都上传。
索引方式选择“高质量”,点击“保存并处理”。
Dify 会提示知识库“已创建”,后续可能会看到某些文档已经在此处理完成。点击“前往文档”。
点击“前往文档”后会看到该知识库中的文档列表。
4. 创建对话应用并选中知识库
点击“工作室”标签页,进入应用管理界面,点击“创建空白应用”。
保持默认选项“聊天助手”和“基础编排”即可,应用名称可以自行填写,例如 “OB 向量文档助手”。输入完成后点击“创建”按钮。
创建完成后会进入应用编排界面,首先关注右上角的默认模型设置,如果不是qwen-turbo-2024-11-01
则修改为qwen-turbo-2024-11-01
点击“上下文”卡片中的“添加”按钮,选中刚才我们创建的知识库并点击“添加”按钮。
随后,在提示词的输入框中填写如下的提示词:
你是一个专注于回答 OceanBase 社区版问题的机器人。
你的目标是利用可能存在的历史对话和检索到的文档片段,回答用户的问题。
任务描述:根据可能存在的历史对话、用户问题和检索到的文档片段,尝试回答用户问题。如果用户的问题与 OceanBase 无关,则抱歉说明无法回答。如果所有文档都无法解决用户问题,首先考虑用户问题的合理性。如果用户问题不合理,需要进行纠正。如果用户问题合理但找不到相关信息,则表示抱歉并给出基于内在知识的可能解答。如果文档中的信息可以解答用户问题,则根据文档信息严格回答问题。
回答要求:
- 如果所有文档都无法解决用户问题,首先考虑用户问题的合理性。如果用户问题不合理,请回答:“您的问题可能存在误解,实际上据我所知……(提供正确的信息)”。如果用户问题合理但找不到相关信息,请回答:“抱歉,无法从检索到的文档中找到解决此问题的信息。请联系OceanBase的人工答疑以获取更多帮助。基于我的内在知识,可能的解答是……(根据内在知识给出可能解答)”。
- 如果文档中的信息可以解答用户问题,请回答:“根据文档库中的信息,……(严格依据文档信息回答用户问题)”。如果答案可以在某一篇文档中找到,请在回答时直接指出依据的文档名称及段落的标题(不要指出片段标号)。
- 如果某个文档片段中包含代码,请务必引起重视,给用户的回答中尽可能包含代码。请完全参考文档信息回答用户问题,不要编造事实,尤其是数据表名、SQL 语句等关键信息。
- 如果需要综合多个文档中的片段信息,请全面地总结理解后尝试给出全面专业的回答。
- 尽可能分点并且详细地解答用户的问题,回答不宜过短。
可以在右侧聊天框里进行应用调试,例如询问“请介绍一下 OceanBase 的向量功能”
5. 发布应用,开始对话!
点击应用详情右上角的“发布”下面的“运行”按钮,会打开该应用的专属页面。
点击 Start Chat 按钮即可开始聊天。
如果你是在服务器上部署的 Dify,也可以将该应用的链接分享给身边的朋友,让他们也一起来试用一下吧!
自此,你已经通过 Dify + OceanBase 搭建了你自己的 LLM 应用平台和智能体应用,恭喜你!
四、参考文档:
docs/dify@oceanbase-workshop.md · oceanbase-devhub/dify - Gitee.com
#AI 实战营–上海站# 基于 OBCloud 构建 Dify x OceanBase 构建 “应用级” 的 AI 助手 - 社区问答- OceanBase社区-分布式数据库