查看原文
其他

如何使用Jina 和 JCloud 打造基于知识库的分类搜索?

Jina AI 2023-03-21

本文我们将利用聊天机器人构建更强大的、云上的知识库搜索引擎。

不久前,我们使用Jina的神经搜索框架构建了一个简单的聊天机器人:

仔细想想,一个聊天机器人基本就是一个精简的搜索引擎。

·  聊天机器人:输入单个查询,获取单个结果。接口是简单的。

·  搜索引擎:输入单个查询,获取多个结果。接口可能包含过滤器或元数据。

聊天机器人有构建大型项目的良好基础,在这种情况下,它是给定知识库的搜索引擎。本文我们将采用代码并将其构建为更好,更快,更强大的知识库搜索引擎。

完整代码如下:

https://github.com/alexcg1/example-knowledge-base-search

立即开始

1、git clone

https://github.com/alexcg1/example-chatbot

2、cd example-chatbot

3、创建虚拟环境

4、pip install -r requirements.txt

5、pip install -U jina jcloud(让我们确保我们使用的是最新版本的 Jina 和 JCloud)

数据集使用

我们将再次使用 COVID-QA 数据集。

具体链接如下:

https://www.kaggle.com/xhlulu/covidqa/

对于这些元数据,可以通过分面搜索来显示和过滤我们的结果。我们保持了数据集与聊天机器人完全相同,因此可以重用现有的代码,将CSV加载到 DocumentArray 中:

docs = DocumentArray.from_csv( "data/community.csv", field_resolver={"question": "text"})

Flow 简介

我们将 DocumentArray 传递到 Flow 中,该流程会生成用于搜索索引。由于我们的用例与简单的聊天机器人不同,因此需要调整聊天机器人的流程以适应我们的新用例:

我们应该使用哪种型号/编码器?我们之前的模型专门用于回答问题,我们希望执行更直接的搜索操作。

我们应该使用哪个索引器?聊天机器人的 SimpleIndexer 比较简单。它不支持元数据筛选。

既然如此,让我们在 YAML 中重新做整个 Flow ,这样就可以更容易地在云上托管(很快就会有更多内容!

我们的变化

我们会保持大多数东西的稳定性,但会把一些执行器换成更合适的执行器(可以直接从Jina Hub获得)。由于 Hub 为所有机器学习组件提供了统一的接口,这意味着我们只需要更改 Flow 中的几行(而不会陷入手动集成内容的困境)。

1、模型/编码器:我们使用 SpacyTextEncoder 和模型。我发现 spaCy 的产品获得更快。en_web_core_md

2、索引器:AnnLite 支持对元数据进行筛选,所以可以继续使用它。

3、YAML:我们将一直迁移改变。

之前的 Flow

flow = (    Flow(protocol="http", port=PORT)    .add(        name="encoder",        uses="jinahub+docker://TransformerTorchEncoder",        uses_with={            "pretrained_model_name_or_path": "sentence-transformers/paraphrase-mpnet-base-v2"        },    )    .add(name="indexer", uses="jinahub://SimpleIndexer", install_requirements=True))

调整后的 Flow

jtype: Flowwith: protocol: http port: 23456executors: - name: encoder uses: jinahub+://SpacyTextEncoder/v0.4 uses_with: model_name: 'en_core_web_md' install_requirements: true - name: indexer uses: jinahub://AnnLiteIndexer/0.3.0 uses_with: dim: 300 # the model has 300 dimensions columns: ... # We'll fill this in soon install_requirements: true uses_metas: workspace: workspace

因为我们使用的是 AnnLiteIndexer ,它需要一些额外的参数,即我们模型嵌入的维度。我们的列是我们将用于筛选搜索结果的字段。

使用此命令:dimcolumnsdata.csv

head -n data/community.csv

给我们:

question_id,title,question,answer_id,answer,answer_type,wrong_answer,wrong_answer_type,url,source

对于要用作元数据的每个字段,我们需要提供:

1、字段名称

2、字段类型(例如 、 、 等)strintbool

在您自己的数据集中,您可能拥有有用的元数据

例如:日期、质量评级、回复数、作者、类别

但在我们的例子中,只有“ and ”字段为筛选提供了任何有意义的数据。所以现在我们的 YAML 将看起来像这样:answer_typesource

jtype: Flowwith:  protocol: http  port: 23456executors:  - name: encoder    uses: jinahub+docker://SpacyTextEncoder/v0.4    uses_with:      model_name: 'en_core_web_md'    install_requirements: true  - name: indexer    uses: jinahub+docker://AnnLiteIndexer/0.3.0    uses_with:      dim: 300  # the model has 300 dimensions      columns:        - ['answer_type', 'str']        - ['source', 'str']    install_requirements: true    uses_metas:      workspace: workspace

调整我们的应用程序

我们需要确保应用程序从 YAML 加载 Flow,而不是直接从 Python 加载 Flow。因此,我们可以删除之前的 Flow:

flow = (    Flow(protocol="http", port=PORT)    .add(        name="encoder",        uses="jinahub+docker://TransformerTorchEncoder",        uses_with={            "pretrained_model_name_or_path": "sentence-transformers/paraphrase-mpnet-base-v2"        },    )    .add(name="indexer", uses="jinahub://SimpleIndexer", install_requirements=True))

并替换为以下内容:

flow = Flow.load_config("flow.yml")

运行应用程序

我们可以使用以下方式对数据进行索引:

python app.py -t index

并通过以下方式打开 RESTful 界面进行搜索:

python app.py -t search

搜索知识库

基本搜索(查找相似文本字符串)

from jina import Clientfrom docarray import Document
client = Client(host='localhost', port=23456)
query = Document(text="Can I catch COVID from my pet armadillo?")
results = client.search(query)
for result in results:    print(result.text)

分面搜索

from jina import Clientfrom docarray import Document
client = Client(host='localhost', port=23456)
query = Document(text="Can I catch COVID from my pet armadillo?")
search_filter = {"source": {"$eq": "biomedical"}}
results = client.search(query, parameters={"filter": search_filter})
for result in results: print(result.text)

如果我们想要按照元数据筛选,那么答案是:biomedicalsource。你可以在  AnnLiteIndexer Hub 页面上找到有关创建搜索筛选器的详细信息。

云上托管

在本机部署托管是很好的,但是 Jina 支持你在 JCoud 上做到云上部署搜索。

https://github.com/jina-ai/jcloud/

我们需要对 Flow 做些更改,这样我们就得到了如下的 YAML 。

jtype: Flowwith:  protocol: http  # remove the portexecutors:  - name: encoder    uses: jinahub+docker://SpacyTextEncoder/v0.4  # run everything in docker    uses_with:      model_name: 'en_core_web_md'    replicas: 2  # 2 replicas for faster encoding    resources:      memory:        8G  # give our encoder more memory to work with    #  No need to install requirements since we run in docker  - name: indexer    uses: jinahub+docker://AnnLiteIndexer/0.3.0    uses_with:      dim: 300      columns:        - ['answer_type', 'str']        - ['source', 'str']    uses_metas:      workspace: workspace

我们可以通过以下方式部署 Flow :

jc deploy flow.yml  # make a note of the URL that comes up!

由于我们只在自己的计算机上索引了数据,所以需要在云上重新索引数据。

client = Client(host=<Flow URL>)client.index(docs)

在云上搜索知识库

使用 cURL:

curl -X POST https://8bae9ebaf9.wolf.jina.ai/search -H 'Content-Type: application/json' -d '{"data":[{"text": "will my teacher give me covid"}], "execEndpoint":"/"}'

使用Jina Client

from jina import Clientfrom docarray import Document
client = Client("https://8bae9ebaf9.wolf.jina.ai")
query = Document(text="Can I catch COVID from my pet armadillo?")
search_filter = {"source": {"$eq": "biomedical"}}
results = client.search(query, parameters={"filter": search_filter})
for result in results:    print(result.text)

你也可以使用我为快速流量测试创建的:jfc

jfc search "can I catch COVID from my pet tardigrade?" -h https://8bae9ebaf9.wolf.jina.ai

今后的步骤

发现错误或收到功能请求?

在我们的存储库中留下问题

有其他问题?

加入我们的 Slack ,并在 Jina 的#support频道中提问

神经搜索、深度学习、推荐系统


教程、Demo、干货分享


扫码备注加入讨论组

更多精彩内容(点击图片阅读)

系列教程 | 用Jina搭建PDF搜索引擎Part 3

系列教程 | 用Jina搭建PDF搜索引擎Part 2

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存