收到问题后,应用程序首先搜索Elasticsearch索引中相关的文档。这是通过为问题生成稀疏向量嵌入,然后在索引中搜索与其最接近的嵌入来实现的,每个嵌入都与文档的一部分关联。
与摄取阶段一样,Elasticsearch索引是通过与Langchain集成的ElasticsearchStore
来管理的。
store = ElasticsearchStore(
es_connection=elasticsearch_client,
index_name=INDEX,
strategy=ElasticsearchStore.SparseVectorRetrievalStrategy(model_id=ELSER_MODEL),
)
为问题生成嵌入,然后搜索它,所有这些都被Langchain的检索器接口的invoke()
方法很好地抽象掉了,该方法执行所有这些任务并返回找到的最相关文档列表。
docs = store.as_retriever().invoke(question)
for doc in docs:
doc_source = {**doc.metadata, 'page_content': doc.page_content}
yield f'data: {SOURCE_TAG} {json.dumps(doc_source)}\n\n'
您可以在这里看到返回的部分是如何作为来源发送给客户端的。React应用程序将在答案下方将其显示为“搜索结果”。
需要注意的是,在ElasticsearchStore
类中使用的strategy
参数必须与摄取过程中使用的策略匹配。在这个例子中,SparseVectorRetrievalStrategy
创建并搜索来自Elastic的ELSER模型的稀疏向量。另一个您可以评估的有趣选项是使用ApproxRetrievalStrategy
,它使用密集向量嵌入。