与 Haystack 文档对话:使用 WebRetriever 创建面向特定领域的问答 RAG 管道
如何使用 Haystack 的 WebRetriever 和 RAG 管道创建面向特定领域的问答 (Q&A) 系统
2023年9月4日自推出以来,WebRetriever 一直在 Haystack 生态系统中发挥着重要作用。顾名思义,WebRetriever 允许从互联网获取文档并将其传入 Haystack 管道。
在底层,WebRetriever 使用搜索引擎查找要从网上检索的相关文档。尽管用户(使用“site:” AND/OR 语法与实际查询混合)甚至在此之前就可以自定义搜索查询的域范围,但这通常感觉像是一种变通方法,而不是一项功能。更糟糕的是——它为用户充分利用 WebRetriever 功能设置了障碍。我们需要使其更直观,不那么“hacky”。
随着 Haystack 1.20 的发布,WebRetriever 现在可以限制搜索到特定域,而不是搜索整个互联网。在本文中,我们将演示这一细微调整如何能够轻松创建专门的问答系统,该系统仅使用特定域(在本例中是 Haystack 文档)中的文档来回答问题。
尽管我们在本文中将 Haystack 文档作为用例,但我们可以轻松设想许多其他用例。企业可以创建 RAG 管道,将 WebRetriever 指向产品特定 FAQ 或产品官方网站上的故障排除指南,从而有效地创建人工智能驱动的助手来回答客户查询。学生和研究人员可以将 WebRetriever 范围限定在学术期刊、arXiv 或 PubMed,以回答与其学习领域相关的问题。用户可以在购买产品时将 WebRetriever 设置为从可信赖的网站收集产品评论或规格。要穷尽所有潜在用例,需要付出相当大的努力。
WebRetriever 的强大功能
WebRetriever 是一个 Haystack 组件,用于从网上提取相关文档。它利用 WebSearch 实例来获取搜索结果链接;然后,它从链接中获取内容,并将原始文本内容提取为 Document 列表。
WebRetriever 支持三种不同的操作模式
Snippets 模式:在此模式下,WebRetriever 会生成一个 Document 实例列表,其中每个 Document 代表网页结果中的一个片段或部分。需要注意的是,此模式不涉及实际的网页检索。
Raw Documents 模式:在此模式下,WebRetriever 会生成一个 Document 实例列表,其中每个 Document 代表从搜索结果链接检索到的整个网页(去除任何 HTML,仅包含原始文本内容)。
Preprocessed Documents 模式:此模式与 Raw Documents 模式类似,但增加了一个额外步骤——使用指定的 PreProcessor 将从每个检索到的网页中提取的原始文本分成更短的 Document 实例。
尽管知识渊博的用户可以使用 Google 的“site:”搜索语法手动 hack 查询,但新的“allowed_domains” WebRetriever init 参数使用户能够轻松地将搜索限制在特定网站,从而使他们的问答更加专注和可靠。
RAG 管道设置
为了更好地理解“与网站对话”用例的构建块,让我们回顾一下管道示例 [1] 的每个代码部分。在组装 RAG 管道之前,我们必须设置 https://serper.dev API 密钥并选择一个 LLM 来使用。它可以是任何 LLM,但我们将选择限制在 Anthropic Claude、OpenAI GPT 模型以及 Hugging Face Inference API 免费层级上可用的开源模型。
import os
from typing import Dict, Any
search_key = os.environ.get("SERPERDEV_API_KEY")
if not search_key:
raise ValueError("Please set the SERPERDEV_API_KEY environment variable")
models_config: Dict[str, Any] = {
"openai": {"api_key": os.environ.get("OPENAI_API_KEY"), "model_name": "gpt-3.5-turbo"},
"anthropic": {"api_key": os.environ.get("ANTHROPIC_API_KEY"), "model_name": "claude-instant-1"},
"hf": {"api_key": os.environ.get("HF_API_KEY"), "model_name": "tiiuae/falcon-7b-instruct"},
}
接下来,我们定义一个简单的提示模板来指导 LLM 如何构造答案。使用定义的 PromptTemplate,我们还使用 API 密钥、最大回答长度、流设置等附加参数初始化 PromptNode。
from haystack.nodes import PromptNode, PromptTemplate
prompt_text = """
Synthesize a comprehensive answer from the provided paragraphs and the given question.\n
Focus on the question and avoid unnecessary information in your answer.\n
\n\n Paragraphs: {join(documents)} \n\n Question: {query} \n\n Answer:
"""
prompt_node = PromptNode(
model["model_name"],
default_prompt_template=PromptTemplate(prompt_text),
api_key=model["api_key"],
max_length=768,
model_kwargs={"stream": stream},
)
我们使用特定参数初始化 WebRetriever 组件,例如搜索引擎 API 密钥、用于获取文档的允许域以及文档缓存。现在,WebRetriever 已设置为仅从“haystack.deepset.ai”域检索文档。
from haystack.document_stores import InMemoryDocumentStore
from haystack.nodes.retriever import WebRetriever
web_retriever = WebRetriever(
api_key=search_key,
allowed_domains=["haystack.deepset.ai"],
top_search_results=10,
mode="preprocessed_documents",
top_k=50,
cache_document_store=InMemoryDocumentStore(),
)
接下来,我们创建 Haystack RAG 管道。我们逐一添加组件:WebRetriever、sampler、ranker,最后是 PromptNode 用于生成答案。我们按顺序添加管道节点,定义数据在管道中的流向。
from haystack import Pipeline
from haystack.nodes.sampler import TopPSampler
from haystack.nodes.ranker import LostInTheMiddleRanker
pipeline = Pipeline()
pipeline.add_node(component=web_retriever, name="Retriever", inputs=["Query"])
pipeline.add_node(component=TopPSampler(top_p=0.90), name="Sampler", inputs=["Retriever"])
pipeline.add_node(component=LostInTheMiddleRanker(1024), name="LostInTheMiddleRanker", inputs=["Sampler"])
pipeline.add_node(component=prompt_node, name="PromptNode", inputs=["LostInTheMiddleRanker"])
最后,我们进入一个允许用户输入查询的循环。我们的示例代码将这些问题通过管道运行以产生答案,然后将这些答案打印到控制台。超级简单!
while True:
user_input = input("\nAsk question (type 'exit' or 'quit' to quit): ")
if user_input.lower() == "exit" or user_input.lower() == "quit":
break
if stream:
print("Answer:")
response = pipeline.run(query=user_input)
if not stream:
print(f"Answer: {response['results'][0]}")
结论
Haystack 的 WebRetriever 使用户能够快速轻松地设置一个高度专业化的问答系统,直接从指定域绘制内容。无论您是为您的网站设置人工智能驱动的问答助手,还是工程师正在浏览 arXiv 出版物列表,Haystack 的模块化架构都可以让您快速设置适合您特定用例的 RAG 管道。
我们仅通过这个简单的例子触及了表面,但希望它能鼓励您进一步探索 Haystack RAG 管道和组件,让您可以根据您的特定场景定制 Haystack。我们期待看到社区如何利用 WebRetriever 和其他 Haystack 组件来解决当今复杂的检索挑战。
参考文献
[1] https://github.com/deepset-ai/haystack/blob/main/examples/talk_to_website.py
