Haystack WebSearch 组件详解:用 SerperDevWebSearch 与 SearchApiWebSearch 为 LLM 应用接入实时联网检索
【免费下载链接】haystackOpen-source AI orchestration framework for building context-engineered, production-ready LLM applications. Design modular pipelines and agent workflows with explicit control over retrieval, routing, memory, and generation. Built for scalable agents, RAG, multimodal applications, semantic search, and conversational systems.项目地址: https://gitcode.com/GitHub_Trending/ha/haystack
Haystack 的websearch组件族为 RAG、Agent 与对话系统提供了"搜索网页 → 抽取链接 → 获取正文 → 生成回答"的完整链路入口。本文以 version-2.19 的 API 参考文档为核心,系统讲解SerperDevWebSearch(基于 Serper)与SearchApiWebSearch(基于 SearchApi)两个联网搜索组件的初始化参数、run接口、域名过滤、序列化机制与 Pipeline 集成方式,并结合仓库源码与版本演进说明给出可直接运行的实战示例。
WebSearch 组件概览:把"实时信息"注入 LLM 应用
大语言模型的训练数据存在截止时间,无法回答"今天的热点事件"或需要实时验证的查询。Haystack 的 WebSearch 组件正是为此设计的:给定一个查询字符串,组件调用外部搜索引擎 API,返回相关文档列表(内容为搜索结果的页面摘要 snippets)和链接列表(URL 字符串),供下游组件进一步抓取正文或直接用于构建提示词。
在 version-2.19 中,haystack.components.websearch模块下包含两个组件(见 WebSearch 组件索引):
| 组件 | 后端搜索引擎 | 默认环境变量 |
|---|---|---|
SerperDevWebSearch | Serper(Google 搜索 API) | SERPERDEV_API_KEY |
SearchApiWebSearch | SearchApi(默认 Google,可切换引擎) | SEARCHAPI_API_KEY |
两个组件的接口高度一致:初始化时传入 API Key 与检索参数,运行时接收query字符串,输出documents(list[Document])与links(list[str])。它们在 Pipeline 中的典型位置是LinkContentFetcher之前(用于把摘要级的结果扩展为完整网页正文),也可以直接接在 Converters 之前。由于返回的是搜索摘要而非整页内容,若需要全文检索,应当串联LinkContentFetcher组件继续抓取页面。
SerperDevWebSearch:基于 Serper 的网页搜索组件
SerperDevWebSearch使用 Serper 服务在网络上检索与查询相关的文档。Serper 返回的搜索结果中包含页面标题下方的摘要文本(snippet),组件会将每个结果封装为Document,同时单独返回所有结果的 URL。
初始化参数
根据 version-2.19 API 参考(websearch_api.md),构造函数签名为:
def __init__(api_key: Secret = Secret.from_env_var("SERPERDEV_API_KEY"), top_k: Optional[int] = 10, allowed_domains: Optional[list[str]] = None, search_params: Optional[dict[str, Any]] = None, *, exclude_subdomains: bool = False)各参数含义如下:
api_key(Secret):Serper API 密钥。默认从环境变量SERPERDEV_API_KEY读取;也可以在初始化时通过Secret.from_token("<your-api-key>")显式传入。使用Secret类型可以避免密钥以明文形式出现在序列化后的 YAML/JSON 中。top_k(int,默认 10):返回的文档数量上限。allowed_domains(list[str],默认None):将搜索结果限定在指定域名内。例如["example.com"]。exclude_subdomains(bool,默认False,仅限关键字参数):配合allowed_domains使用。为True时只返回精确匹配allowed_domains中域名的结果,子域名(如blog.example.com、shop.example.com)会被过滤;为False时子域名结果也会被包含。默认False以保持向后兼容(见 serperdev-add-exclude-subdomains-param release note)。search_params(dict[str, Any],默认None):透传给 Serper API 的附加参数。例如设置"num": 20可以提高搜索引擎内部返回的结果数量上限。
独立使用示例
from haystack.components.websearch import SerperDevWebSearch from haystack.utils import Secret websearch = SerperDevWebSearch(top_k=10, api_key=Secret.from_token("test-api-key")) results = websearch.run(query="Who is the boyfriend of Olivia Wilde?") assert results["documents"] assert results["links"]带域名过滤的用法(排除子域名):
# Example with domain filtering - exclude subdomains websearch_filtered = SerperDevWebSearch( top_k=10, allowed_domains=["example.com"], exclude_subdomains=True, # Only results from example.com, not blog.example.com api_key=Secret.from_token("test-api-key") ) results_filtered = websearch_filtered.run(query="search query")run 方法与返回结构
@component.output_types(documents=list[Document], links=list[str]) def run(query: str) -> dict[str, Union[list[Document], list[str]]]run接收唯一的必填参数query(搜索查询字符串),返回一个包含两个键的字典:
"documents":搜索引擎返回的文档列表,每个Document的内容来自搜索结果摘要(snippet);"links":搜索引擎返回的链接字符串列表。
序列化:to_dict / from_dict
def to_dict() -> dict[str, Any] @classmethod def from_dict(cls, data: dict[str, Any]) -> "SerperDevWebSearch"to_dict将组件序列化为字典(可用于 Pipeline 的 YAML/JSON 导出),from_dict从字典反序列化重建组件实例。密钥以Secret形式保存,序列化时引用环境变量名而非明文密钥,从而保证配置文件可以安全地提交到版本库。
错误处理
run可能抛出的异常:
SerperDevError:查询 SerperDev API 过程中发生错误;TimeoutError:请求 SerperDev API 超时。
SearchApiWebSearch:基于 SearchApi 的多引擎搜索组件
SearchApiWebSearch使用 SearchApi 服务检索网络文档,接口与SerperDevWebSearch基本对称,可视为后者的直接替代方案(详见 searchapiwebsearch.mdx)。
初始化参数
def __init__(api_key: Secret = Secret.from_env_var("SEARCHAPI_API_KEY"), top_k: Optional[int] = 10, allowed_domains: Optional[list[str]] = None, search_params: Optional[dict[str, Any]] = None)api_key(Secret):SearchApi API 密钥,默认从环境变量SEARCHAPI_API_KEY读取。top_k(int,默认 10):返回的文档数量上限。allowed_domains(list[str],默认None):限定搜索的域名列表。search_params(dict[str, Any],默认None):透传给 SearchApi API 的附加参数。例如设置"num": 100可提高搜索引擎返回的结果数量上限。
引擎切换:SearchApi 默认使用 Google 作为搜索引擎,用户可以在search_params中设置engine参数切换为其他引擎(如 Bing、Brave 等 SearchApi 支持的引擎)。
独立使用示例
from haystack.components.websearch import SearchApiWebSearch from haystack.utils import Secret websearch = SearchApiWebSearch(top_k=10, api_key=Secret.from_token("test-api-key")) results = websearch.run(query="Who is the boyfriend of Olivia Wilde?") assert results["documents"] assert results["links"]run 方法与返回结构
@component.output_types(documents=list[Document], links=list[str]) def run(query: str) -> dict[str, Union[list[Document], list[str]]]与SerperDevWebSearch.run一致:接收query,返回"documents"(搜索结果文档列表)与"links"(链接列表)。
可能的异常:
TimeoutError:请求 SearchApi API 超时;SearchApiError:查询 SearchApi API 时发生错误。
序列化:to_dict / from_dict
SearchApiWebSearch同样实现了to_dict/from_dict对,to_dict输出序列化字典,from_dict(类方法)从字典恢复组件实例,用于 Pipeline 的持久化与反序列化。
在 RAG Pipeline 中组合使用:Web Search → 全文抓取 → 生成
单独调用搜索组件只能拿到摘要级信息。完整的联网 RAG 流水线通常由四段组成:WebSearch 组件检索 URL →LinkContentFetcher抓取页面 →HTMLToDocument转换正文 → 提示词构建器 + LLM 生成回答。version-2.19 官方文档(serperdevwebsearch.mdx)给出的完整示例:
from haystack import Pipeline from haystack.utils import Secret from haystack.components.builders.chat_prompt_builder import ChatPromptBuilder from haystack.components.fetchers import LinkContentFetcher from haystack.components.converters import HTMLToDocument from haystack.components.generators.chat import OpenAIChatGenerator from haystack.components.websearch import SerperDevWebSearch from haystack.dataclasses import ChatMessage from haystack.utils import Secret web_search = SerperDevWebSearch(api_key=Secret.from_token("<your-api-key>"), top_k=2) link_content = LinkContentFetcher() html_converter = HTMLToDocument() prompt_template = [ ChatMessage.from_system("You are a helpful assistant."), ChatMessage.from_user( "Given the information below:\n" "{% for document in documents %}{{ document.content }}{% endfor %}\n" "Answer question: {{ query }}.\nAnswer:", ), ] prompt_builder = ChatPromptBuilder( template=prompt_template, required_variables={"query", "documents"}, ) llm = OpenAIChatGenerator( api_key=Secret.from_token("<your-api-key>"), model="gpt-3.5-turbo", ) pipe = Pipeline() pipe.add_component("search", web_search) pipe.add_component("fetcher", link_content) pipe.add_component("converter", html_converter) pipe.add_component("prompt_builder", prompt_builder) pipe.add_component("llm", llm) pipe.connect("search.links", "fetcher.urls") pipe.connect("fetcher.streams", "converter.sources") pipe.connect("converter.documents", "prompt_builder.documents") pipe.connect("prompt_builder.messages", "llm.messages") query = "What is the most famous landmark in Berlin?" pipe.run(data={"search": {"query": query}, "prompt_builder": {"query": query}})数据流的关键连接一目了然:
search.links → fetcher.urls:把搜索结果中的 URL 交给LinkContentFetcher抓取网页;fetcher.streams → converter.sources:抓取到的字节流交给HTMLToDocument解析为文本;converter.documents → prompt_builder.documents:转换后的文档注入提示词模板;prompt_builder.messages → llm.messages:构建好的消息交给聊天生成器产出最终答案。
将上述示例中的组件替换为SearchApiWebSearch(导入语句改为from haystack.components.websearch import SearchApiWebSearch)即可得到完全等价的 SearchApi 版本流水线,两种后端可以在不同 Pipeline 中互为备选。
底层实现与调用链
虽然 version-2.19 的这两个组件实现在后续版本中被移出核心库(见下文"版本演进"),但它们在代码库中的调用方式仍可从当前仓库中交叉印证:
- 在 component_tool.py 中,
SerperDevWebSearch与SearchApiWebSearch被用作@component组件"从组件自动生成 Tool(工具)"的典型示例,说明这类搜索组件常被包装为 Agent 可调用的工具; - 在 test_run.py 的功能测试中同样引用了这两个组件,用于验证 Pipeline 运行机制。
从实现结构看,两个组件都遵循 Haystack 的标准组件协议:用@component.output_types(...)声明输出类型,run方法内部调用对应搜索引擎的 REST API,将 JSON 响应解析为Document与链接列表,并对异常(网络错误、超时)做统一封装后抛出。
版本演进与迁移提示
需要特别说明的是,SerperDevWebSearch与SearchApiWebSearch在后续版本中经历了"核心库 → 独立集成包"的演进,理解这一点有助于避免在新旧版本之间踩坑:
- version-2.19 及之前:两个组件位于核心库
haystack.components.websearch,即本文 API 参考所对应的导入路径; - 后续版本:两个组件被弃用并从核心库移除,迁移到独立的集成包。根据仓库中的 release note(remove-serperdev-websearch-7c7f3caa702bfb03.yaml、remove-searchapi-websearch-238622d2b7667236.yaml),迁移方式为:
pip install serperdev-haystack # SerperDevWebSearch pip install searchapi-haystack # SearchApiWebSearch导入路径相应变为:
# 迁移前(version-2.19) from haystack.components.websearch import SerperDevWebSearch from haystack.components.websearch import SearchApiWebSearch # 迁移后(集成包) from haystack_integrations.components.websearch.serperdev import SerperDevWebSearch from haystack_integrations.components.websearch.searchapi import SearchApiWebSearch此外,这两个组件后来还新增了异步方法run_async(见 add-run_async-websearch release note),签名与run一致,适合在异步 Pipeline 或高并发场景下使用。当前仓库主线的 WebSearch 组件索引 中,二者已与 Brave、DDGS、Tavily 等更多搜索后端并列,说明 Haystack 的联网检索能力仍在持续扩展。
小结
SerperDevWebSearch与SearchApiWebSearch是 Haystack 中接口统一、可直接互换的两个联网检索组件:初始化参数覆盖 API 密钥、返回条数、域名白名单与引擎级透传参数;run方法统一输出documents与links;两者都支持to_dict/from_dict序列化以嵌入 Pipeline 配置。把它们放在LinkContentFetcher之前,即可搭建"搜索 → 抓取 → 转换 → 生成"的实时 RAG 流水线;若部署新版本,请记得改用serperdev-haystack/searchapi-haystack集成包的导入路径。
【免费下载链接】haystackOpen-source AI orchestration framework for building context-engineered, production-ready LLM applications. Design modular pipelines and agent workflows with explicit control over retrieval, routing, memory, and generation. Built for scalable agents, RAG, multimodal applications, semantic search, and conversational systems.项目地址: https://gitcode.com/GitHub_Trending/ha/haystack
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考