如何使用Jina 和 JCloud 打造基于知识库的分类搜索?
本文我们将利用聊天机器人构建更强大的、云上的知识库搜索引擎。
不久前,我们使用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: Flow
with:
protocol: http
port: 23456
executors:
- 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: Flow
with:
protocol: http
port: 23456
executors:
- 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 Client
from 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 Client
from 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: Flow
with:
protocol: http # remove the port
executors:
- 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 Client
from 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、干货分享
扫码备注加入讨论组
更多精彩内容(点击图片阅读)