Haystack SerperDevWebSearch 组件实战:用 Serper 为 RAG 与 Agent 注入实时网页搜索能力
【免费下载链接】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 2.23 版本的SerperDevWebSearch网页搜索组件展开。它调用 Serper(SerperDev)API 返回与查询最相关的网页 URL 列表,并将其封装为Document与链接字符串,常用于在 RAG 管道、Agent 工作流中补充实时外部知识。读完本文,你将掌握该组件的初始化参数、同步/异步调用方式、域过滤技巧、在 Pipeline 中的接线方式,以及其序列化与弃用迁移等关键细节。
组件定位:Pipeline 中的网页搜索入口
SerperDevWebSearch是 Haystack 生态中的搜索引擎组件,核心作用是根据给定的查询词(query)从互联网检索相关网页。在docs-website/versioned_docs/version-2.23/pipeline-components/websearch/serperdevwebsearch.mdx中,官方明确了它的典型位置与输入输出契约:
| 项目 | 说明 |
|---|---|
| 最常见的管道位置 | 位于LinkContentFetcher或 Converters 转换器 之前 |
| 必填初始化变量 | api_key:Serper API 密钥,可通过SERPERDEV_API_KEY环境变量设置 |
| 必填运行变量 | query:字符串类型的搜索查询 |
| 输出变量 | documents:搜索结果构成的文档列表;links:结果链接字符串列表 |
需要注意一个关键设计:该组件返回的是搜索结果的页面摘要(snippet),也就是搜索结果页中标题下方那段文本片段,而不是整页内容。官方文档明确指出:"It uses page snippets (pieces of text displayed under the page title in search results) to find the answers, not the whole pages."因此,如果要获取网页正文,需要再接上LinkContentFetcher组件去抓取链接对应的完整页面内容。
从仓库的 release notes(add-serper-dev-8c582749728e3699.yaml)可以看到,该组件最初以preview(预览)状态加入 Haystack,功能定位就是 "retrieve URLs from the web"(从网络检索 URL)。
快速上手:单独使用组件
SerperDevWebSearch的独立使用方式非常简单,只需提供 API 密钥与查询词即可:
from haystack.components.websearch import SerperDevWebSearch from haystack.utils import Secret web_search = SerperDevWebSearch(api_key=Secret.from_token("<your-api-key>")) query = "What is the capital of Germany?" response = web_search.run(query)这里有两个值得注意的点:
- API 密钥的来源:组件默认从
SERPERDEV_API_KEY环境变量读取密钥,也可以通过Secret.from_token()显式传入。使用Secret包装器而不是明文字符串,是 Haystack 组件的最佳实践,可以避免密钥硬编码进代码或序列化文件。 - 返回值结构:
run()返回一个字典,包含documents(由搜索结果构造的Document列表)和links(URL 字符串列表)两个键。组件在内部将 Serper API 返回的结果转换为标准的 HaystackDocument对象,便于后续组件直接消费。
关于Secret的细节可参考 Haystack 官方 API 文档 与核心库的 Secret 实现。
构造函数参数详解
SerperDevWebSearch的构造函数签名如下:
__init__( api_key: Secret = Secret.from_env_var("SERPERDEV_API_KEY"), top_k: int | None = 10, allowed_domains: list[str] | None = None, search_params: dict[str, Any] | None = None, *, exclude_subdomains: bool = False ) -> None各参数的作用与默认值如下:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
api_key | Secret | Secret.from_env_var("SERPERDEV_API_KEY") | Serper API 密钥,默认从SERPERDEV_API_KEY环境变量读取 |
top_k | int \| None | 10 | 返回的文档数量 |
allowed_domains | list[str] \| None | None | 限制搜索范围的域名列表 |
exclude_subdomains | bool | False | 使用allowed_domains过滤时是否排除子域名 |
search_params | dict[str, Any] \| None | None | 传递给 Serper API 的附加参数 |
域过滤与exclude_subdomains
allowed_domains用于将搜索限定在指定域名范围内;exclude_subdomains则进一步控制匹配精度:
- 当
exclude_subdomains=True时,只返回与allowed_domains完全一致域名的结果; - 当
exclude_subdomains=False(默认)时,子域名结果也会被包含。
官方 API 参考(serperdev.md)给出了典型用法:
from haystack.utils import Secret from haystack_integrations.components.websearch.serperdev import SerperDevWebSearch serper_dev_api = Secret.from_env_var("SERPERDEV_API_KEY") websearch = SerperDevWebSearch(top_k=10, api_key=serper_dev_api) 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=serper_dev_api, ) results_filtered = websearch_filtered.run(query="search query")该参数由 release note(serperdev-add-exclude-subdomains-param-932b8fe4a001f378.yaml)引入,其中明确说明:当allowed_domains=["example.com"]且exclude_subdomains=True时,来自blog.example.com或shop.example.com的结果会被过滤掉,只保留example.com本身的结果;参数默认值为False,以保证向后兼容。
search_params 透传
search_params允许将任意附加参数透传给 Serper API。官方示例是设置'num'来增加单次返回的搜索结果数量:
websearch = SerperDevWebSearch( top_k=10, search_params={"num": 20}, # 让 Serper API 返回更多候选结果 api_key=serper_dev_api, )该字段的取值与行为以 Serper 官方 API 文档为准,适合需要精细控制搜索行为(如语言、地区、结果数量等)的场景。
run 与 run_async:同步与异步执行
组件同时提供同步与异步两种执行入口,签名完全一致:
run(query: str) -> dict[str, list[Document] | list[str]] run_async(query: str) -> dict[str, list[Document] | list[str]]run(同步)
- 参数:
query(str)——搜索查询词。 - 返回值:字典,包含两个键:
documents:搜索引擎返回的文档列表;links:搜索引擎返回的链接列表。
- 异常:
SerperDevError——查询 SerperDev API 时发生错误;TimeoutError——请求 SerperDev API 超时。
run_async(异步)
run_async是run的异步版本,参数与返回值完全一致,适用于需要并发执行多个搜索请求的高吞吐场景(例如 Agent 并行工具调用)。该能力由 release note(add-run_async-websearch-8507b8c02a5346e6.yaml)引入,与SearchApiWebSearch的异步方法一并加入。
健壮性细节
release note(serperdev-more-robust-229ba25c8fc9306d.yaml)显示,组件针对 Serper API 响应中缺少snippet字段的情况做了健壮性处理,避免因个别结果没有摘要文本而导致整个请求失败。这也再次印证:组件输出的Document内容以 snippet 为主,实际开发时应对"摘要缺失"的文档内容有心理预期。
在 Pipeline 中构建 RAG 管道
SerperDevWebSearch最常见的应用场景是作为 RAG 管道的搜索入口。官方在 serperdevwebsearch.mdx 中给出了完整的可运行示例,整体数据流为:
SerperDevWebSearch(搜索链接)→ LinkContentFetcher(抓取正文)→ HTMLToDocument(转文档)→ ChatPromptBuilder(拼提示词)→ OpenAIChatGenerator(生成答案)
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,即把搜索结果链接交给LinkContentFetcher抓取页面内容;fetcher.streams输出的字节流交给HTMLToDocument转换成Document;- 转换后的文档进入
ChatPromptBuilder,与查询词一起渲染为模板消息; - 最后由
OpenAIChatGenerator基于检索到的网页内容生成答案。
这正是"搜索摘要 → 抓取正文 → 生成回答"的经典实时 RAG 数据流,可有效缓解 LLM 知识截止时间导致的时效性问题。
与其他搜索组件的选择
在 2.23 版本中,Haystack 提供了两个网页搜索组件(参见 websearch.mdx):
| 组件 | 说明 |
|---|---|
| SearchApiWebSearch | 使用 Search API 的搜索引擎 |
| SerperDevWebSearch | 使用 SerperDev API 的搜索引擎 |
官方文档建议,如果希望使用 Search API 作为备选方案,可以参考其独立文档页面。两者接口形态一致(都输出documents与links),在管道中可以相互替换。
序列化支持:to_dict 与 from_dict
作为标准 Haystack 组件,SerperDevWebSearch支持序列化与反序列化,便于将管道配置保存为 YAML/JSON 或在服务间传递:
to_dict() -> dict[str, Any]to_dict()将组件序列化为字典;from_dict(data: dict[str, Any]) -> SerperDevWebSearch从字典还原组件实例。
序列化时组件会记录api_key、top_k、allowed_domains、exclude_subdomains、search_params等配置。需要特别说明的是,仓库中另有 release note(remove-api-key-from-serialization-2474a1539b86e233.yaml)涉及从序列化结果中移除 API 密钥的安全加固方向,因此在生产环境中建议始终通过SERPERDEV_API_KEY环境变量注入密钥,而不要将密钥以明文写入序列化后的管道配置。
版本演进与迁移注意
该组件在 Haystack 中的生命周期值得注意,涉及后续版本的迁移路径:
- 引入:以 preview 状态加入 Haystack(
add-serper-dev-8c582749728e3699.yaml); - 增强:新增
exclude_subdomains参数、异步run_async方法,并加强了对缺失snippet的容错; - 弃用:官方在 release note(
deprecate-serperdev-websearch-9de15a703cba06cc.yaml)中宣布SerperDevWebSearch将弃用并在 3.0 中移除,迁移到独立的serperdev-haystack集成包:- 安装方式:
pip install serperdev-haystack - 新的导入路径:
from haystack_integrations.components.websearch.serperdev import SerperDevWebSearch
- 安装方式:
- 移除:在 3.0 中正式移出 Haystack 核心库(
remove-serperdev-websearch-7c7f3caa702bfb03.yaml),旧导入from haystack.components.websearch import SerperDevWebSearch需改为上述新路径。
因此,如果你当前基于 2.23 版本开发,可以放心使用核心库内置的SerperDevWebSearch;如果面向更高版本或准备长期维护,建议直接采用haystack_integrations.components.websearch.serperdev的导入方式。
小结
SerperDevWebSearch是 Haystack 中接入 Serper 网页搜索能力的最快捷方式:它把"搜索查询 → 结果链接 + 摘要文档"的转换封装成一个标准组件,可与LinkContentFetcher、转换器、PromptBuilder 和 LLM 无缝串联,构建带实时信息的 RAG 管道;其exclude_subdomains域过滤、search_params透传、同步/异步双接口与序列化支持,也让它能灵活适配从简单搜索到复杂 Agent 工作流的多种场景。使用时牢记两点:一是它返回的是搜索摘要而非整页正文,需配合抓取组件;二是密钥优先通过SERPERDEV_API_KEY环境变量注入,并留意后续版本的包迁移路径。
相关资源:
- 组件 API 参考:docs-website/reference_versioned_docs/version-2.23/integrations-api/serperdev.md
- 组件使用指南:docs-website/versioned_docs/version-2.23/pipeline-components/websearch/serperdevwebsearch.mdx
- 搜索组件索引:docs-website/versioned_docs/version-2.23/pipeline-components/websearch.mdx
【免费下载链接】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),仅供参考