注意:这篇博客已重新修订,并更新了自首次发布以来 Elastic 发布的新功能。请点击此处查看新的博客!
将 Elasticsearch 的搜索相关性与 OpenAI 的 ChatGPT 的问答能力相结合,以查询您的数据。在本博客中,您将学习如何使用 Elasticsearch 将 ChatGPT 连接到专有数据存储,并为您的数据构建问答功能。
什么是 ChatGPT?
近几个月来,围绕 OpenAI 创建的突破性 AI 模型 ChatGPT 的热情激增。但 ChatGPT 究竟是什么?
ChatGPT 基于强大的 GPT 架构,旨在理解和生成对文本输入类似人类的响应。GPT 代表“生成式预训练转换器”。转换器是一种尖端的模型架构,彻底改变了自然语言处理 (NLP) 领域。这些模型经过海量数据的预训练,能够理解上下文、生成相关的响应,甚至进行对话。要了解有关转换器模型的历史以及 Elastic Stack 中的一些 NLP 基础知识,请务必查看 Elastic ML 工程师 Josh Devins 的精彩演讲。
ChatGPT 的主要目标是促进人机之间有意义且引人入胜的互动。通过利用 NLP 的最新进展,ChatGPT 模型可以提供广泛的应用,从聊天机器人和虚拟助手到内容生成、代码补全等等。这些 AI 驱动的工具已迅速成为无数行业中宝贵的资源,帮助企业简化流程并增强服务。
ChatGPT 的局限性以及如何减少这些局限性
尽管 ChatGPT 具有令人难以置信的潜力,但用户应该了解某些局限性。一个值得注意的限制是知识截止日期。目前,ChatGPT 接受的训练数据截止日期为 2021 年 9 月,这意味着它不知道此后发生的事件、发展或变化。因此,用户在依赖 ChatGPT 获取最新信息时应牢记此限制。在讨论软件增强和功能甚至世界事件等快速变化的知识领域时,这可能导致过时或不正确的响应。
ChatGPT 虽然是一个令人印象深刻的 AI 语言模型,但在其响应中偶尔会出现幻觉,当它缺乏相关信息时,这种情况往往会加剧。这种过度自信可能导致向用户提供不正确的答案或误导性信息。务必了解此限制,并以一定程度的怀疑态度对待 ChatGPT 生成的响应,必要时交叉检查和验证信息,以确保准确性和可靠性。
ChatGPT 的另一个局限性是它缺乏关于特定领域内容的知识。虽然它可以根据其接受训练的信息生成连贯且与上下文相关的响应,但它无法访问特定领域的数据或提供依赖于用户独特知识库的个性化答案。例如,它可能无法提供对组织专有软件或内部文档的见解。因此,用户在直接向 ChatGPT 寻求此类主题的建议或答案时应谨慎。
减少这些限制的一种方法是为 ChatGPT 提供与您的领域和问题相关的特定文档,并启用 ChatGPT 的语言理解能力以生成定制的响应。
这可以通过将 ChatGPT 连接到 Elasticsearch 等搜索引擎来实现。
Elasticsearch——您知道的,用于搜索!
Elasticsearch 是一个可扩展的数据存储和向量数据库,旨在提供相关的文档检索,确保用户能够快速准确地访问所需的信息。Elasticsearch 的主要关注点是向用户提供最相关的结果,简化搜索过程并增强用户体验。
Elasticsearch 拥有无数功能以确保一流的搜索性能,包括对传统关键字和基于文本的搜索 (BM25) 的支持,以及具有精确匹配和近似 kNN (k 近邻) 搜索功能的 AI 就绪向量搜索。这些高级功能允许 Elasticsearch 检索不仅相关而且对于使用自然语言表达的查询的结果。通过利用传统、向量或混合搜索 (BM25 + kNN),Elasticsearch 可以以前所未有的精度提供结果,帮助用户轻松找到所需的信息。
Elasticsearch 的关键优势之一是其强大的 API,它能够与其他服务无缝集成以扩展和增强其功能。通过将 Elasticsearch 与各种第三方工具和平台集成,用户可以创建强大的自定义搜索解决方案,以满足其特定需求。这种灵活性和可扩展性使 Elasticsearch 成为寻求改进搜索能力并在竞争激烈的数字领域保持领先地位的企业的理想选择。
通过与 ChatGPT 等高级 AI 模型协同工作,Elasticsearch 可以为 ChatGPT 提供其响应中最相关的文档。Elasticsearch 和 ChatGPT 之间的这种协同作用确保用户能够收到对其查询的事实性、与上下文相关的和最新的答案。本质上,Elasticsearch 的检索能力和 ChatGPT 的自然语言理解能力的结合提供了无与伦比的用户体验,为信息检索和 AI 驱动的辅助设定了新的标准。
如何将 ChatGPT 与 Elasticsearch 一起使用
- Python 接口接受用户问题。
为 Elasticsearch 生成混合搜索请求
- 在标题字段上进行 BM25 匹配
- 在标题向量字段上进行 kNN 搜索
- 提升 kNN 搜索结果以对齐分数
- 将 size=1 设置为仅返回得分最高的文档
- 搜索请求发送到 Elasticsearch。
- 文档正文和原始 URL 返回到 Python。
- 对 OpenAI ChatCompletion 进行 API 调用。
- 提示:“仅使用此文档 <来自顶级搜索结果的正文内容> 回答此问题 <问题> ”
- 生成的响应返回到 Python。
- Python 将原始文档源 URL 添加到生成的响应中,并将其打印到屏幕上供用户查看。
ElasticDoc ChatGPT 流程利用 Python 接口接受用户问题并为 Elasticsearch 生成混合搜索请求,结合 BM25 和 kNN 搜索方法从 Elasticsearch Docs 网站(现已编入 Elasticsearch 索引)中查找最相关的文档。但是,您不必使用混合搜索甚至向量搜索。Elasticsearch 提供了灵活性,您可以使用最适合您需求并为您的特定数据集提供最相关结果的任何搜索模式。
检索到顶级结果后,程序会为 OpenAI 的 ChatCompletion API 创建一个提示,指示它仅使用所选文档中的信息来回答用户的问题。此提示对于确保 ChatGPT 模型仅使用来自官方文档的信息至关重要,从而减少幻觉的可能性。
最后,程序向用户展示 API 生成的响应和指向源文档的链接,提供了一种无缝且用户友好的体验,该体验集成了前端交互、Elasticsearch 查询和 OpenAI API 使用,从而实现高效的问答。
请注意,为了简单起见,我们只返回得分最高的文档,最佳实践是返回多个文档以向 ChatGPT 提供更多上下文。正确的答案可能不止在一个文档页面中找到,或者如果我们为全文生成向量,则可能需要将这些较大的文本块分割并存储在多个 Elasticsearch 文档中。通过利用 Elasticsearch 并行搜索多个向量字段以及传统搜索方法的能力,您可以显著提高顶级文档的召回率。
技术设置
技术要求相当低,但需要一些步骤才能将所有部分组合在一起。在此示例中,我们将配置Elasticsearch 网络爬虫以摄取 Elastic 文档并在摄取时生成标题向量。您可以按照以下步骤复制此设置或使用您自己的数据。要继续操作,我们需要
- Elasticsearch 集群
- Eland Python 库
- OpenAI API 帐户
- 运行我们的 Python 前端和 API 后端的位置
Elastic Cloud 设置
本节中的步骤假设您目前没有在 Elastic Cloud 中运行的 Elasticsearch 集群。如果您有,可以跳到下一节。
注册如果您还没有 Elasticsearch 集群,您可以使用Elastic Cloud注册免费试用。
创建部署注册后,系统将提示您创建您的第一个部署。
- 为您的部署创建一个名称。
- 您可以接受默认的云提供商和区域,也可以单击“编辑设置”并选择另一个位置。
- 点击“创建部署”。稍后将为您配置一个新的部署,您将登录到 Kibana。返回云控制台 在继续之前,我们需要在云控制台中执行几个操作:点击左上角的导航图标,然后选择“管理此部署”。
添加一个机器学习节点。
- 返回云控制台,点击左侧导航栏中部署名称下的“编辑”。
- 向下滚动到“机器学习实例”框,然后点击“+添加容量”。
- 在“每个区域的大小”下,点击并选择“2 GB RAM”。
- 向下滚动并点击“保存”。
- 在总结架构更改的弹出窗口中,点击“确认”。
- 几分钟后,您的部署将能够运行机器学习模型!
重置 Elasticsearch 部署用户名和密码
- 点击部署名称下左侧导航栏中的“安全”。
- 点击“重置密码”,然后点击“重置”确认。(注意:由于这是一个新的集群,因此没有任何内容应该使用此 Elastic 密码。)
- 下载为“elastic”用户新创建的密码。(我们将使用它从 Hugging Face 加载我们的模型并在我们的 Python 程序中使用它。)
复制 Elasticsearch 部署云 ID。
- 点击您的部署名称以转到概述页面。
- 在右侧点击复制图标以复制您的云 ID。(保存此 ID 以便稍后连接到部署。)
Eland
接下来,我们需要将嵌入模型加载到 Elasticsearch 中,以便为我们的博客标题以及以后用户的搜索问题生成向量。我们将使用 SentenceTransformers 训练并在 Hugging Face 模型中心托管的 all-distilroberta-v1 模型。此特定模型不是此设置正常工作所必需的。它适用于一般用途,因为它是在涵盖广泛主题的大型数据集上训练的。但是,对于向量搜索用例,使用针对您的特定数据集微调的模型通常会提供最佳的相关性。
为此,我们将使用 Elastic 创建的 Eland Python 库。该库提供了广泛的数据科学功能,但我们将把它用作桥梁,从 Hugging Face 模型中心将模型加载到 Elasticsearch 中,以便可以在机器学习节点上进行推理使用。
Eland 可以作为 Python 脚本的一部分运行,也可以在命令行上运行。该代码库还为希望采用这种方式的用户提供了 Docker 容器。今天,我们将在 一个小型的 Python 笔记本 中运行 Eland,该笔记本可以在 Google 的 Colab 中免费在 Web 浏览器中运行。
打开 程序链接,然后点击顶部的“在 Colab 中打开”按钮以在 colab 中启动笔记本。
将变量 hf_model_id 设置为模型名称。此模型已在示例代码中设置,但如果您想使用其他模型或只是为了将来参考。
- hf_model_id='sentence-transformers/all-distilroberta-v1'
- 从 Hugging Face 复制模型名称。最简单的方法是点击模型名称右侧的复制图标。
运行云身份验证部分,系统将提示您输入
- 云 ID(您可以在 Elastic Cloud 控制台中找到它)
- Elasticsearch 用户名(最简单的方法是使用创建部署时创建的“Elastic”用户)
- Elasticsearch 用户密码
运行其余步骤。
- 这将从 Hugging Face 下载模型,将其分割,然后将其加载到 Elasticsearch 中。
- 将模型部署(启动)到机器学习节点上。
Elasticsearch 索引和网络爬虫
接下来,我们将创建一个新的 Elasticsearch 索引来存储我们的 Elastic 文档,配置网络爬虫来自动爬取和索引这些文档,并使用摄取管道为文档标题生成向量。
请注意,您可以使用您的专有数据来完成此步骤,以创建适合您领域的问答体验。
- 如果尚未打开,请从云控制台打开 Kibana。
- 在 Kibana 中,导航到企业搜索 -> 概述。点击“创建 Elasticsearch 索引”。
- 使用网络爬虫作为摄取方法,输入 elastic-docs 作为索引名称。然后,点击“创建索引”。
- 点击“管道”选项卡。
- 在“摄取管道”框中点击“复制并自定义”。
- 在“机器学习推理管道”框中点击“添加推理管道”。
- 为新管道输入名称 elastic-docs_title-vector。
- 选择您在上述 Eland 步骤中加载的已训练 ML 模型。
- 选择 title 作为源字段。
- 点击“继续”,然后在测试阶段再次点击“继续”。
- 在“审核”阶段点击“创建管道”。
更新 dense_vector 字段的映射。(注意:对于 Elasticsearch 8.8+ 版本,此步骤应该是自动的。)
- 在导航菜单中,点击“开发工具”。如果这是您第一次打开“开发工具”,则可能需要点击弹出窗口中的“关闭”以关闭文档。
- 在“开发工具”的“控制台”选项卡中,使用以下代码更新我们的密集向量目标字段的映射。您只需将其粘贴到代码框中,然后点击第 1 行右侧的小箭头。
POST search-elastic-docs/_mapping
{
"properties": {
"title-vector": {
"type": "dense_vector",
"dims": 768,
"index": true,
"similarity": "dot_product"
}
}
}
- 您应该在屏幕的右侧看到以下响应
{
"acknowledged": true
}
- 这将允许我们稍后对标题字段向量运行 kNN 搜索。
配置网络爬虫以爬取 Elastic 文档站点
- 再次点击导航菜单,然后点击企业搜索 -> 概述。
- 在“内容”下,点击“索引”。
- 点击“可用索引”下的 search-elastic-docs。
- 点击“管理域”选项卡。
- 点击“添加域”。
- 输入 https://elastic.ac.cn/guide/en,然后点击“验证域”。
- 检查运行完毕后,点击“添加域”。然后点击“爬取规则”。
- 一次添加以下爬取规则。从底部开始向上工作。根据首次匹配来评估规则。
禁止 | 包含 | release-notes |
允许 | 正则表达式 | /guide/en/.*/current/.* |
禁止 | 正则表达式 | .* |
- 所有规则都到位后,点击页面顶部的“爬取”。然后,点击“爬取此索引上的所有域”。
Elasticsearch 的网络爬虫现在将开始爬取文档站点,为标题字段生成向量,并索引文档和向量。
第一次爬取将需要一些时间才能完成。在此期间,我们可以设置 OpenAI API 凭据和 Python 后端。
连接 OpenAI API
要将文档和问题发送到 ChatGPT,我们需要一个 OpenAI API 帐户和密钥。如果您还没有帐户,可以创建一个免费帐户,您将获得一定数量的免费积分。
- 访问 https://platform.openai.com 并点击“注册”。您可以通过使用电子邮件地址和密码或使用 Google 或 Microsoft 登录来完成此过程。
创建帐户后,您需要创建一个 API 密钥
- 点击 API 密钥。
- 点击“创建新的密钥”。
- 复制新密钥并将其保存在安全的地方,因为您将无法再次查看该密钥。
Python 后端设置
克隆或下载 Python 程序
- 安装所需的 Python 库。我们正在 Replit 中运行示例程序,它具有隔离的环境。如果您在笔记本电脑或虚拟机上运行此程序,最佳实践是 设置 Python 的虚拟环境。
- 运行 pip install -r requirements.txt
- 设置身份验证和连接环境变量(例如,如果在命令行上运行:export openai_api=”123456abcdefg789”)
- openai_api - OpenAI API 密钥
- cloud_id - Elastic Cloud 部署 ID
- cloud_user - Elasticsearch 集群用户
- cloud_pass - Elasticsearch 用户密码
- 运行 streamlit 程序。更多关于 streamlit 的信息可以在其文档中找到。
- Streamlit 有自己的启动命令:streamlit run elasticdocs_gpt.py
- 这将启动一个 Web 浏览器,并且 URL 将打印到命令行。
示例聊天回复
所有内容都已摄取并且前端已启动并运行后,您可以开始询问有关 Elastic 文档的问题。
询问“显示推理处理器的 API 调用”现在将返回一个示例 API 调用和一些关于配置设置的信息。
询问添加新集成到 Elastic Agent 的步骤将返回
如前所述,允许 ChatGPT 仅基于其已接受训练的数据来回答问题的一大风险是它倾向于产生不正确的答案。本项目的目标之一是为 ChatGPT 提供包含正确信息的数据,并让它来撰写答案。
那么,当我们向 ChatGPT 提供一份不包含正确信息的文件时会发生什么?例如,要求它告诉您如何造船(Elastic 的文档目前未涵盖此内容)
当 ChatGPT 无法在我们提供的文档中找到问题的答案时,它会回到我们的提示说明,只需告诉用户它无法回答该问题。
Elasticsearch 的强大检索 + ChatGPT 的强大功能
在这个示例中,我们演示了如何将 Elasticsearch 强大的搜索检索功能与 GPT 模型生成的尖端 AI 回复相集成,可以将用户体验提升到一个全新的水平。
各个组件可以根据您的具体要求进行调整,并进行调整以提供最佳结果。虽然我们使用 Elastic 网络爬虫来摄取公共数据,但您并不限于这种方法。您可以随意尝试其他嵌入模型,尤其是针对您特定领域的数据进行微调的模型。
您可以尝试今天这篇博文中讨论的所有功能!要构建您自己的 ElasticDocs GPT 体验,请注册一个 Elastic 试用帐户,然后查看此 示例代码库 以开始使用。
如果您想尝试搜索相关性的想法,这里有两个:
在这篇博文中,我们可能使用了第三方生成式 AI 工具,这些工具由其各自的所有者拥有和运营。Elastic 对第三方工具没有任何控制权,我们对它们的内容、操作或使用,以及因您使用此类工具而可能造成的任何损失或损害不承担任何责任。使用 AI 工具处理个人、敏感或机密信息时,请务必谨慎。您提交的任何数据都可能用于 AI 训练或其他用途。我们无法保证您提供的信息将被安全或保密地保存。在使用任何生成式 AI 工具之前,您应该熟悉其隐私惯例和使用条款。
Elastic、Elasticsearch 及相关标志是 Elasticsearch N.V. 在美国及其他国家/地区的商标、标识或注册商标。所有其他公司和产品名称是其各自所有者的商标、标识或注册商标。
Elasticsearch 与行业领先的生成式 AI 工具和提供商具有原生集成。查看我们关于超越 RAG 基础知识的网络研讨会 超越 RAG 基础知识,或关于构建可用于生产环境的应用程序的网络研讨会 Elastic 向量数据库。