# 使用 OpenAI 部署您自己的知识库聊天机器人

## 概述

[AutoFlow](https://github.com/pingcap/autoflow) 是一个基于图形 RAG 的对话式知识库聊天助手，使用 TiDB 向量存储和 LlamaIndex 构建，开源且免费使用。

+ 在本实验中，您将学习如何：
  + 将您自己的知识（Word/PDF/TXT/Markdown 等）导入到知识库中。
  + 使用聊天机器人在知识库中搜索信息。
  + 连接并在为您提供的 TiDB Cloud Serverless 集群上运行查询。该集群同时作为向量存储和图形数据库。
  + 部署您自己的知识库聊天机器人，类似于 [这个](https://tidb.ai)：

  ![70%](https://lab-static.pingcap.com/quick-demo/taa-example-does-tidb-support-fk.jpeg)

### 实验时长

+ 本实验大约需要 30 分钟完成。

### 任务

+ 使用 [pingcap/autoflow](https://github.com/pingcap/autoflow) 仓库部署知识库应用程序。
+ 配置您的知识库应用程序。
+ 与 AI 聊天机器人进行随机聊天，看看它是否能使用知识库中的信息回答您的问题。

### 先决条件

+ 本次实验将依赖您自己的 OpenAI API Key。

> [!TIP]
> 点击 **开始** 启动实验环境。
> 环境准备就绪后，点击底部工具栏中的 **前进** 进入 **模块 1**。
> 然后，按照实验指南的步骤连接到实践环境并开始你的任务。

## 模块 1：准备运行环境并初始化 AutoFlow 服务

### 步骤 1. 登录应用服务器虚拟机

+ 点击这里 - [终端 1](ssh://monitor1-ssh#1) 打开一个新的终端，连接到为你的实践实验分配的虚拟机。

+ 登录后显示的信息如下：

  ```output
  ubuntu@ip-10-90-1-154:~$ 
  ```

### 步骤 2. 安装必要的软件包，如 Docker、Docker Compose、MySQL 客户端

+ 卸载旧版本的 Docker 和 Docker Compose。

   ```bash
   for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done
   ```

   ```output
   Reading package lists... Done
   Building dependency tree... Done
   Reading state information... Done
   .
   .
   .
   Reading state information... Done
   Package 'runc' is not installed, so not removed
   0 upgraded, 0 newly installed, 0 to remove and 30 not upgraded.
   ```

+ 添加 Docker 的官方 GPG 密钥。

   ```bash
   sudo apt-get update -y
   sudo apt-get install ca-certificates curl -y
   sudo install -m 0755 -d /etc/apt/keyrings
   sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
   sudo chmod a+r /etc/apt/keyrings/docker.asc
   ```

   ```output
   Hit:1 http://us-west-2.ec2.archive.ubuntu.com/ubuntu noble InRelease
   Get:2 http://us-west-2.ec2.archive.ubuntu.com/ubuntu noble-updates InRelease [126 kB]
   .
   .
   .
   Get:15 http://us-west-2.ec2.archive.ubuntu.com/ubuntu noble-updates/main Translation-en [151 kB]
   Fetched 30.6 MB in 5s (6133 kB/s)               
   Reading package lists... Done
   Reading package lists... Done
   Building dependency tree... Done
   Reading state information... Done
   ca-certificates is already the newest version (20240203).
   ca-certificates set to manually installed.
   curl is already the newest version (8.5.0-2ubuntu10.4).
   curl set to manually installed.
   0 upgraded, 0 newly installed, 0 to remove and 33 not upgraded.
   ```

+ 将仓库添加到 `apt` 源。

   ```bash
   echo \
     "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
     $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
     sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
   sudo apt-get update -y
   ```

   ```output
   Reading package lists... Done
   .
   .
   .                      
   Get:6 https://download.docker.com/linux/ubuntu noble/stable amd64 Packages [15.3 kB]
   Fetched 64.2 kB in 1s (79.9 kB/s)   
   Reading package lists... Done
   ```
  
+ 安装 Docker 软件包。

   ```bash
   sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
   ```

   ```output
   Reading package lists... Done
   Building dependency tree... Done
   Reading state information... Done
   .
   .
   .
   No VM guests are running outdated hypervisor (qemu) binaries on this host.
   ```

+ 通过运行 `hello-world` 镜像验证 Docker 是否正确安装。

   ```bash
   sudo docker run hello-world
   ```

   ```output
   Unable to find image 'hello-world:latest' locally
   latest: Pulling from library/hello-world
   c1ec31eb5944: Pull complete 
   Digest: sha256:d211f485f2dd1dee407a80973c8f129f00d54604d2c90732e8e320e5038a0348
   Status: Downloaded newer image for hello-world:latest

   Hello from Docker!
   .
   .
   .
   To try something more ambitious, you can run an Ubuntu container with:
    $ docker run -it ubuntu bash

   Share images, automate workflows, and more with a free Docker ID:
    https://hub.docker.com/

   For more examples and ideas, visit:
    https://docs.docker.com/get-started/
   ```

+ 安装 MySQL 客户端。

   ```bash
   sudo apt-get install -y mysql-client-core-8.0
   ```

   ```output
   Reading package lists... Done
   Building dependency tree... Done
   Reading state information... Done
   The following NEW packages will be installed:
     mysql-client-core-8.0
   0 upgraded, 1 newly installed, 0 to remove and 33 not upgraded.
   Need to get 2794 kB of archives.
   After this operation, 61.6 MB of additional disk space will be used.
   Get:1 http://us-west-2.ec2.archive.ubuntu.com/ubuntu noble-updates/main amd64 mysql-client-core-8.0 amd64 8.0.39-0ubuntu0.24.04.2 [2794 kB]
   Fetched 2794 kB in 0s (34.7 MB/s)
   Selecting previously unselected package mysql-client-core-8.0.
   (Reading database ... 68102 files and directories currently installed.)
   Preparing to unpack .../mysql-client-core-8.0_8.0.39-0ubuntu0.24.04.2_amd64.deb ...
   Unpacking mysql-client-core-8.0 (8.0.39-0ubuntu0.24.04.2) ...
   Setting up mysql-client-core-8.0 (8.0.39-0ubuntu0.24.04.2) ...
   Processing triggers for man-db (2.12.0-4build2) ...
   Scanning processes...
   Scanning linux images...

   Running kernel seems to be up-to-date.

   No services need to be restarted.

   No containers need to be restarted.

   No user sessions are running outdated binaries.

   No VM guests are running outdated hypervisor (qemu) binaries on this host.
   ```

### 步骤 3. 克隆并配置 AutoFlow

+ 克隆 pingcap/autoflow 仓库并导航到 `autoflow` 目录。

   ```bash
   git clone https://github.com/pingcap/autoflow;
   cd autoflow;
   git switch --detach adb5f5483b83c5af98868b8a5f080b3a6f4f4116;
   ```

   ```output
   Cloning into 'autoflow'...
   remote: Enumerating objects: 12041, done.
   remote: Counting objects: 100% (538/538), done.
   remote: Compressing objects: 100% (264/264), done.
   remote: Total 12041 (delta 312), reused 446 (delta 268), pack-reused 11503 (from 1)
   Receiving objects: 100% (12041/12041), 4.33 MiB | 22.07 MiB/s, done.
   Resolving deltas: 100% (7431/7431), done.
   ```

+ 使用以下值更新 `.env` 文件：

   ```bash
   cat > .env <<'EOF'
   ENVIRONMENT=production

   SECRET_KEY="some_secret_key_that_is_at_least_32_characters_long"

   TIDB_HOST=serverless_host
   TIDB_PORT=serverless_port
   TIDB_USER='serverless_username'
   TIDB_PASSWORD='serverless_password'
   TIDB_DATABASE=tidbai_test
   TIDB_SSL=true

   EMBEDDING_DIMS=1536
   EMBEDDING_MAX_TOKENS=8191
   EOF
   cat .env
   ```

   ```output
   ENVIRONMENT=production

   SECRET_KEY="some_secret_key_that_is_at_least_32_characters_long"

   TIDB_HOST=serverless_host
   TIDB_PORT=serverless_port
   TIDB_USER='serverless_username'
   TIDB_PASSWORD='serverless_password'
   TIDB_DATABASE=tidbai_test
   TIDB_SSL=true

   EMBEDDING_DIMS=1536
   EMBEDDING_MAX_TOKENS=8191
   ```

### 步骤 4. 确保您的数据库干净并准备好进行下一步

+ 使用以下命令连接到 TiDB Cloud Serverless 集群。

   ```bash
   mysql \
      --comments -u 'serverless_username' -p'serverless_password' \
      -h serverless_host -P serverless_port \
      --ssl-mode=VERIFY_IDENTITY --ssl-ca=/etc/ssl/certs/ca-certificates.crt
   ```

   ```output
   mysql: [Warning] Using a password on the command line interface can be insecure.
   Welcome to the MySQL monitor.  Commands end with ; or \g.
   Your MySQL connection id is 2168969
   Server version: 5.7.28-TiDB-Serverless TiDB Server (Apache License 2.0) Community Edition, MySQL 5.7 compatible

   Copyright (c) 2000, 2024, Oracle and/or its affiliates.

   Oracle is a registered trademark of Oracle Corporation and/or its
   affiliates. Other names may be trademarks of their respective
   owners.

   Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

   mysql>
   ```

+ 删除现有数据库并创建一个新的。

   ```bash
   DROP DATABASE IF EXISTS tidbai_test;
   CREATE DATABASE tidbai_test;
   EXIT;
   ```

   ```output
   mysql> DROP DATABASE IF EXISTS tidbai_test;
   Query OK, 0 rows affected (0.00 sec)

   mysql> CREATE DATABASE tidbai_test;
   Query OK, 0 rows affected (0.12 sec)

   mysql> EXIT;
   Bye
   ```

### 步骤 5. 创建架构

+ 运行数据迁移以创建表架构并设置初始管理员用户。<span style="color: Red">请注意输出中红色行中生成的管理员密码。</span>

   ```bash
   sudo docker compose run backend /bin/sh -c "alembic upgrade head";
   sudo docker compose run backend /bin/sh -c "python bootstrap.py";
   ```

   ```output
   [+] Creating 1/0
   ✔ Container tidb-ai-redis-1  Running                                                                                                                                   0.0s
   INFO  [alembic.runtime.migration] Context impl MySQLImpl.
   INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
   INFO  [alembic.runtime.migration] Running upgrade  -> 2fc10c21bf88, empty message
   INFO  [alembic.runtime.migration] Running upgrade 2fc10c21bf88 -> 94b198e20946, empty message
   INFO  [alembic.runtime.migration] Running upgrade 94b198e20946 -> 04d4f05116ed, empty message
   INFO  [alembic.runtime.migration] Running upgrade 04d4f05116ed -> 197bc8be72d1, empty message
   INFO  [alembic.runtime.migration] Running upgrade 197bc8be72d1 -> ac6e4d58580d, empty message
   INFO  [alembic.runtime.migration] Running upgrade ac6e4d58580d -> a8c79553c9f6, empty message
   INFO  [alembic.runtime.migration] Running upgrade a8c79553c9f6 -> bd17a4ebccc5, empty message
   INFO  [alembic.runtime.migration] Running upgrade bd17a4ebccc5 -> e32f1e546eec, empty message
   INFO  [alembic.runtime.migration] Running upgrade e32f1e546eec -> 04d81be446c3, empty message
   INFO  [alembic.runtime.migration] Running upgrade 04d81be446c3 -> 041fbef26e3a, empty message
   INFO  [alembic.runtime.migration] Running upgrade 041fbef26e3a -> 10f36e8a25c4, empty message
   INFO  [alembic.runtime.migration] Running upgrade 10f36e8a25c4 -> 00534dc350db, empty message
   INFO  [alembic.runtime.migration] Running upgrade 00534dc350db -> eb0b85608c0a, empty message
   INFO  [alembic.runtime.migration] Running upgrade eb0b85608c0a -> dfee070b8abd, empty message
   WARN[0000] Found orphan containers ([tidb-ai-backend-run-d4d35b6b5909]) for this project. If you removed or renamed this service in your compose file, you can run this command with the --remove-orphans flag to clean it up.
   [+] Creating 1/0
   ✔ Container tidb-ai-redis-1  Running                                                                                                                                   0.0s
   Bootstrapping the application...
   /usr/local/lib/python3.11/site-packages/pydantic/_internal/_config.py:341: UserWarning: Valid config keys have changed in V2:
   * 'orm_mode' has been renamed to 'from_attributes'
    warnings.warn(message, UserWarning)
   User 019309f5-2a8f-7e9d-b848-cc81312e598a has registered.

   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
   [IMPORTANT] Admin user created with email: admin@example.com and password: <your admin password will be displayed here>
   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

   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.
   Default chat engine created.
   Bootstrapping completed.
   ```

### 步骤 6. 启动知识库应用程序

+ 通过运行以下 `docker compose` 命令启动应用程序。

   ```bash
   sudo docker compose up -d
   ```

   ```output
   [+] Running 43/33
   ✔ backend Pulled                    51.9s
   ✔ background Pulled                 51.9s
   ✔ redis Pulled                       6.5s
   ✔ frontend Pulled                   36.8s

   [+] Running 5/5
   ✔ Network tidb-ai_default         Created              0.3s
   ✔ Container tidb-ai-redis-1       Started             35.0s
   ✔ Container tidb-ai-backend-1     Started              0.7s
   ✔ Container tidb-ai-background-1  Started              0.7s
   ✔ Container tidb-ai-frontend-1    Started              0.9s
   ```

## 模块 2：配置 OpenAI 服务

### 步骤 1. 访问应用程序

+ 通过在浏览器中访问 [http://monitor1_address:3000](http://monitor1_address:3000) 来访问和配置知识库应用程序。
+ 使用默认管理员用户 `admin@example.com` 和您在 <span style="color: Red">模块 1，步骤 5</span> 中收到的密码登录。

  ![60%](https://lab-static.pingcap.com/quick-demo/taa-app-credentials.jpeg)

### 步骤 2. 配置 LLM

+ 点击 <kbd>Models</kbd> 然后点击 <kbd>LLMs</kbd> 标签，然后点击 <kbd>New LLM</kbd> 按钮。
+ 输入以下信息，然后点击 <kbd>Create LLM</kbd> 按钮：

  + 名称：my-openai-llm
  + 提供商：OpenAI
  + 模型：gpt-4o
  + OpenAI API 密钥：${YOUR_OPENAI_API_KEY}
  + 是否为默认 LLM：是

  ![60%](https://lab-static.pingcap.com/quick-demo/taa-default-llm.jpeg)

  ![60%](https://lab-static.pingcap.com/quick-demo/taa-setup-progress.jpeg)

### 步骤 3. 配置嵌入模型

+ 点击 <kbd>Models</kbd> 然后点击 <kbd>Embedding Models</kbd> 标签，然后点击 <kbd>New Embedding Model</kbd> 按钮。
+ 输入以下信息，然后点击 <kbd>Create Embedding Model</kbd> 按钮：

  + 名称：my-openai-embedding
  + 提供商：OpenAI
  + 模型：text-embedding-3-small
  + OpenAI API 密钥：${YOUR_OPENAI_API_KEY}
  + 向量维度：1536

  ![60%](https://lab-static.pingcap.com/quick-demo/setup-embedding-model-start.jpeg)

  ![60%](https://lab-static.pingcap.com/quick-demo/setup-embedding-model-done.png)

### 步骤 4. 创建知识库

+ 点击 <kbd>Knowledge Base</kbd> 标签，然后点击 <kbd>New Knowledge Base</kbd> 按钮。
+ 输入以下信息，然后点击 <kbd>Create</kbd> 按钮：

  + 名称：tidb overview
  + 描述：tidb overview
  + LLM：my-openai-llm
  + 嵌入模型：my-openai-embedding
  + 知识图谱索引：是

### 步骤 5. 创建数据源

+ 在知识库页面，点击 <kbd>Data Sources</kbd> 标签，然后点击 <kbd>Web Pages</kbd> 按钮。
+ 在页面 URL 部分下点击 <kbd>New Item</kbd> 按钮，并输入以下信息，然后点击 <kbd>Create</kbd> 按钮：

  + 页面 URL：https://docs.pingcap.com/tidb/stable/overview
  + 数据源名称：tidb overview

  ![60%](https://lab-static.pingcap.com/quick-demo/setup-datasource-start.jpeg)

  ![60%](https://lab-static.pingcap.com/quick-demo/setup-datasource-done.jpeg)

### 步骤 6. 观察索引进度

+ 点击 <kbd>Index Progress</kbd> 标签导航到索引进度状态页面，检查索引任务的进度。
+ 您即将完成！现在应用程序正在运行后台任务下载您提供的 URL 中的内容。
    + 如果圆圈颜色为蓝色，表示正在下载内容。
    + 如果圆圈颜色为绿色，表示内容已成功下载并导入（已建立索引），这意味着您可以开始与 AI 聊天机器人聊天了。

  ![60%](https://lab-static.pingcap.com/quick-demo/build-index-done.jpeg)

### 步骤 7. 配置默认聊天引擎

+ 点击 <kbd>Chat Engines</kbd> 标签，然后点击 <kbd>default</kbd> 聊天引擎。
+ 点击 <kbd>Retrieval</kbd> 标签，然后选择您刚刚创建的知识库，然后点击 <kbd>Save</kbd> 按钮。

### 步骤 8. 使用您刚刚构建的聊天机器人

+ 在浏览器中打开 [http://monitor1_address:3000](http://monitor1_address:3000) 或点击 <kbd>Home</kbd> 开始与 AI 聊天机器人聊天！只需问："什么是 TiDB？"
+ 享受与您自己的 AI 聊天机器人聊天的乐趣！

  ![60%](https://lab-static.pingcap.com/quick-demo/chat-start.jpeg)

  ![60%](https://lab-static.pingcap.com/quick-demo/chat-done.jpeg)

## 结论

在本实验中，您学习了如何部署自己的知识库聊天机器人，类似于 [https://tidb.ai](https://tidb.ai)，您可以将自己的知识导入到知识库中，并使用聊天机器人在知识库中搜索信息。

但我们必须提醒您，此实验环境中存储的数据不能保证持久性。它将在实验会话结束后被释放。

如果您想在工作环境中使用这个 AI 聊天机器人，您需要在自己的服务器上部署它，您需要：

+ 在 [pingcap/autoflow](https://github.com/pingcap/autoflow) 获取源代码。
+ 在 [https://tidbcloud.com](https://tidbcloud.com) 获取您自己的 TiDB Cloud Serverless 集群。
+ 在 [https://platform.openai.com](https://platform.openai.com) 获取您自己的 OpenAI API 密钥。