Elasticsearch:使用 Elasticsearch 向量搜索及 RAG 来实现 Chatbot

Elasticsearch 的向量搜索为我们的语义搜索提供了可能。而在人工智能的动态格局中,检索增强生成(Retrieval Augmented Generation - RAG)已经成为游戏规则的改变者,彻底改变了我们生成文本和与文本交互的方式。 RAG 使用大型语言模型 (LLMs) 等工具将信息检索的能力与自然语言生成无缝结合起来,为内容创建提供了一种变革性的方法。在本文中,我们将使用 Elasticsearch 的向量搜索并结合 OpenAI 大模型来实现 RAG。有关更多关于 RAG 的描述,请参阅文章 "Elasticsearch:什么是检索增强生成 - RAG?"。

安装 Elasticsearch 及 Kibana

如果你还没有安装好自己的 Elasticsearch 及 Kibana,那么请参考一下的文章来进行安装:

在安装的时候,请选择 Elastic Stack 8.11 进行安装。这个也是在 Github 中代码的要求。你可以在如下的地址下载源码:

复制代码
git clone https://github.com/liu-xiao-guo/elasticsearch-labs

运行应用

在进行之前,我们选择 OpenAI 来进行展示。本演示的代码是下面的这个项目:

复制代码
$ pwd
/Users/liuxg/python/elasticsearch-labs/example-apps
$ ls 
README.md                 openai-embeddings         workplace-search
chatbot-rag-app           relevance-workbench
internal-knowledge-search search-tutorial

如上所示,chatbot-rag-app 目录含有我们所需要运行的代码。在运行代码之前,我们需要在 terminal 中打入如下的命令:

复制代码
export ELASTICSEARCH_URL=https://elastic:o6G_pvRL=8P*7on+o6XH@192.168.0.3:9200
export ES_INDEX=workplace-app-docs
export ES_INDEX_CHAT_HISTORY=workplace-app-docs-chat-history
export LLM_TYPE=openai
export OPENAI_API_KEY=YourOpenAiKey

在我的设置中,我使用自签名证书的 Elasticsearch 集群。在上面,你需要根据自己的 Elasticsearch 超级用户及密码进行配置。你也需要在 OpenAI 的网站中申请开发者 key。你可以在地址 https://platform.openai.com/api-keys 进行申请。

构建 docker 镜像

我们使用如下的命令来构建镜像:

复制代码
docker run --rm --env-file .env chatbot-rag-app flask create-index

摄入数据

我们把 Elasticsearch 的证书拷贝到 chatbot-rag-app 的根目录下:

复制代码
$ pwd
/Users/liuxg/python/elasticsearch-labs/example-apps/chatbot-rag-app
$ cp ~/elastic/elasticsearch-8.11.0/config/certs/http_ca.crt .

我们在当前的目录下创建 .env 文件,它的内容如下:

.env

复制代码
ELASTICSEARCH_URL=https://elastic:o6G_pvRL=8P*7on+o6XH@192.168.0.3:9200
ES_INDEX=workplace-app-docs
ES_INDEX_CHAT_HISTORY=workplace-app-docs-chat-history
LLM_TYPE=openai
OPENAI_API_KEY=YourOpenAiKey

$ pwd
/Users/liuxg/python/elasticsearch-labs/example-apps/chatbot-rag-app
$ ls -al
total 960
drwxr-xr-x  17 liuxg  staff     544 Dec 11 21:43 .
drwxr-xr-x  10 liuxg  staff     320 Dec 11 21:42 ..
-rw-r--r--@  1 liuxg  staff    8196 Dec 11 21:44 .DS_Store
-rw-r--r--   1 liuxg  staff     237 Dec 11 21:10 .env
-rw-r--r--   1 liuxg  staff      55 Dec  8 17:09 .flaskenv
-rw-r--r--   1 liuxg  staff      82 Dec  8 17:09 .gitignore
-rw-r--r--   1 liuxg  staff     807 Dec  8 17:09 Dockerfile
-rw-r--r--   1 liuxg  staff    6085 Dec  8 17:09 README.md
drwxr-xr-x   7 liuxg  staff     224 Dec  8 17:09 api
-rw-r--r--   1 liuxg  staff  430277 Dec  8 17:09 app-demo.gif
drwxr-xr-x   4 liuxg  staff     128 Dec  8 17:09 data
-rw-r--r--   1 liuxg  staff     860 Dec  8 17:09 env.example
drwxr-xr-x   2 liuxg  staff      64 Dec 11 21:38 filebeat.yml
drwxr-xr-x   9 liuxg  staff     288 Dec  8 17:09 frontend
-rw-r-----   1 liuxg  staff    1915 Dec 11 21:47 http_ca.crt
-rw-r--r--   1 liuxg  staff     315 Dec  8 17:09 requirements.in
-rw-r--r--   1 liuxg  staff    5259 Dec  8 17:09 requirements.txt

我们使用如下的命令来摄入数据:

复制代码
docker run \
  --volume="$PWD/http_ca.crt:/usr/share/certs/http_ca.crt:ro" \
  --rm --env-file .env chatbot-rag-app flask create-index

$ pwd
/Users/liuxg/python/elasticsearch-labs/example-apps/chatbot-rag-app
$ docker run \
>   --volume="$PWD/http_ca.crt:/usr/share/certs/http_ca.crt:ro" \
>   --rm --env-file .env chatbot-rag-app flask create-index
".elser_model_2" model is available
Loading data from $/app/api/../data/data.json
Loaded 15 documents
Split 15 documents into 26 chunks
Creating Elasticsearch sparse vector store in Elastic Cloud: None

从上面的显示中,我们可以看出来,我们已经写入了15个文档。这些文档的内容,你可以在 data 目录下的 data.json 中看到。我们在 Kibana 中可以使用如下的命令来进行查看:

从上面的输出中,我们可以看到它使用了 ELSER 来实现向量搜索。这个在代码中我们可以查看到。

在代码中,它是通过程序来进行安装的,所以我们不必要使用手动来安装 ELSER 模型。如果你之前没有安装过,那么第一次运行时速度会比较慢,因为有个安装的过程。另外,安装 ELSER 需要你具有白金版的授权,你需要启动试用:

更多关于 ELSER 的部署,请参阅文章 "Elasticsearch:部署 ELSER - Elastic Learned Sparse EncoderR"。

启动 API 前端

我们可以使用如下的命令来启动前端应用。请注意在启动之前,我们设置好 .env。有关 .env 的写法,请参考 env.example 文件。我们使用如下的命令来进行启动:

复制代码
docker run \
  --volume="$PWD/http_ca.crt:/usr/share/certs/http_ca.crt:ro" \
  --rm -p 4000:4000 --env-file .env -d chatbot-rag-app

$ pwd
/Users/liuxg/python/elasticsearch-labs/example-apps/chatbot-rag-app
$ docker run \
>   --volume="$PWD/http_ca.crt:/usr/share/certs/http_ca.crt:ro" \
>   --rm -p 4000:4000 --env-file .env -d chatbot-rag-app
5955d1ec4b931f4a562330b682367b2c9a511bad20dd4a4033c7c3cac2c505f7

如上所示,我们在端口 4000 启动一个 web 应用:

太好了,我们成功地启动了这个 chatbot 应用。

查询展示

在下面,我们来针对我们的数据进行一些查询:

复制代码
What is our work from home policy?

从上面的结果中,我们可以看出来:我们首先使用想要查询的问题让 Elasticsearch 在自己的向量数据库中(稀疏向量)进行搜索,并查到如上所示的几个最相近的文档。很显然查询到的结果非常冗长,而且不易被我们所理解。当然这些结果是从我们的私有数据里查询到的,也是和我们的公司的制度最相关的结果。为了得到更为简洁而精确的回答,我们可以把得到的结果变成为提示,再把原来的问题提交给 OpenAI 大模型,并进行总结。最终我们得到了如上所示的结果。

我们再做一个练习:

复制代码
What's the NASA sales team?

同样地,我们得到三个相关的文档。我们知道 NASA 的真正意思是:

如上所示,在互联网上的 NASA 定义式美国航空航天局。如果我们想搜索和我们自己公司相关的关于 NASA 的内容,那么它就是如上所示的答案:

复制代码
The NASA sales team is the North America South America region sales team. It is divided into two areas, with Laura Martinez as the Area Vice-President of North America and Gary Johnson as the Area Vice-President of South America.

它是指的一个北美南美的销售团队代名词。很显然它和互联网上的数据是不一样的。如果我们只是简单地从 Elasticsearch 来展示结果,那么我们的几个文档堆积在一起,需要更多地阅读。很显然,我们使用 OpenAI 的总结,我们得到一个更为简单明了的结果。

在我们的实例中,有更多的例子。请大家自己尝试。

相关推荐
新智元1 分钟前
Meta没做的,英伟达做了!全新架构吞吐量狂飙6倍,20万亿Token训练
人工智能·openai
新智元1 分钟前
Hinton 预言成真!AI 接管美国一半白领,牛津哈佛扎堆转行做技工
人工智能·openai
aneasystone本尊13 分钟前
学习 Coze Studio 的知识库入库逻辑
人工智能
然我14 分钟前
从 “只会聊天” 到 “能办实事”:OpenAI Function Call 彻底重构 AI 交互逻辑(附完整接入指南)
前端·javascript·人工智能
岁月宁静21 分钟前
软件开发核心流程全景解析 —— 基于 AI 多模态项目实践
前端·人工智能·后端
wangjiaocheng22 分钟前
软件功能分解输入处理输出递归嵌套模型
人工智能
G等你下课22 分钟前
Function call
前端·人工智能
岁月宁静23 分钟前
MCP 协议应用场景 —— Cursor 连接 Master Go AI
前端·vue.js·人工智能
柠檬味拥抱25 分钟前
融合NLU与NLG的AI Agent语言交互机制研究
人工智能
wydaicls29 分钟前
用函数实现方程函数解题
人工智能·算法·机器学习