亚马逊AWS官方博客
Bedrock Claude + LiteLLM WebSearch Interception 配置指南
摘要:WebSearch Interception 是 LiteLLM 的一个功能,允许不原生支持 web search 的 LLM provider(如 AWS Bedrock、Azure、Vertex AI)通过 LiteLLM 代理自动执行网页搜索并返回带有实时信息的回答。
目录
一、概述
WebSearch Interception 是 LiteLLM 的一个功能,允许不原生支持 web search 的 LLM provider(如 AWS Bedrock、Azure、Vertex AI)通过 LiteLLM 代理自动执行网页搜索并返回带有实时信息的回答。
1.1 工作原理
[图1:WebSearchInterception] |
二、环境要求
| 组件 | 版本/要求 |
| LiteLLM Docker 镜像 | ghcr.io/berriai/litellm:1.84.0-dev.2(v1.84.0+) |
| SearXNG | 自部署实例,需启用 JSON 格式输出 |
| 调用端点 | /v1/messages(Anthropic 格式,不是 /chat/completions) |
三、配置步骤
3.1 部署 SearXNG
searxng-settings.yml 中必须启用 JSON 格式:
验证 SearXNG 是否正常:
3.2 配置 LiteLLM(litellm_config.yaml)
3.3 启动 LiteLLM Docker
3.4 验证搜索端点
四、调用方式
4.1 正确方式:通过 /v1/messages(Anthropic 格式)
4.2 用 Claude Code 连接
Claude Code 会自动通过 /v1/messages 调用,web search 自动生效。
4.3 ❌ 不支持的方式
通过 /chat/completions(OpenAI 格式)调用 Bedrock 不会触发 agentic loop:
五、功能支持情况
| 功能 | 状态 | 说明 |
| /v1/messages + Bedrock + web search | ✅ | 完整支持 |
| /chat/completions + Bedrock | ❌ | Bedrock Converse 路径无 agentic loop |
| Stream 模式 | ⚠️ | 内部强制转为非流式,最终一次性返回完整结果 |
| Citation(来源引用) | ❌ | 搜索结果作为纯文本传给模型,无结构化引用 |
| 多次搜索(max_uses > 1) | ✅ | 最多 3 次 agentic loop |
| SearXNG 免费搜索 | ✅ | 无 API 费用 |
| Perplexity/Tavily 搜索 | ✅ | 需要 API Key |
六、踩坑记录
6.1 启动报错:’dict’ object has no attribute ‘startswith’
原因: 文档中的 config 格式(dict 嵌套在 callbacks 里)与源码实际实现不一致。
错误写法(文档中的):
正确写法:
6.2 回调注册了但不生效
原因: 用了 success_callback 而不是 callbacks。
- success_callback → 只把字符串加到列表,不实例化 handler
- callbacks → 触发 initialize_callbacks_on_proxy,正确实例化 WebSearchInterceptionLogger
6.3 Agentic loop 不触发(/chat/completions)
原因: Bedrock 走 BedrockConverseLLM(继承 BaseAWSLLM),不经过 BaseLLMHTTPHandler,后者才有 _call_agentic_chat_completion_hooks。
解决: 改用 /v1/messages 端点。
6.4 搜索失败:SEARXNG_API_BASE is not set
原因: WebSearch Interception handler 内部调用 litellm.asearch() 时不传递 config 中的 api_base,只读环境变量 SEARXNG_API_BASE。
解决: Docker 启动时加 -e SEARXNG_API_BASE=http://host.docker.internal:8888。
6.5 v1.83.x 版本不支持,需要v1.84.x
原因: v1.83.14 的 BedrockConverseLLM 没有 agentic loop 集成。
解决: 升级到 ghcr.io/berriai/litellm:1.84.0-dev.2。
七、Citation(引用)实现方案
虽然 LiteLLM WebSearch Interception 不支持 Anthropic 原生的结构化 citations 字段,但可以通过提示词工程让模型在回答中生成格式化的引用。
7.1 带 Citation 的请求示例
7.2 返回结果示例
模型会返回带有完整引用的回答:
7.3 原理说明
SearXNG 返回的搜索结果包含 Title 和 URL,LiteLLM 将其格式化为:
模型基于这些信息,按照提示词中的格式要求,自动将 URL 映射为引用编号。
八、Stream 模式说明
8.1 测试 Stream 请求
8.2 实际行为
即使传入 “stream”: true,WebSearch Interception 内部会强制转为非流式,最终一次性返回完整 JSON 结果(不是 SSE 事件流)。
原因: Agentic loop 需要拿到模型的完整响应才能判断是否有 tool_call 需要拦截执行搜索。源码中的处理逻辑:
8.3 影响
- 响应时间较长(需要等待:LLM 调用 → 搜索执行 → 再次 LLM 调用 全部完成)
- 客户端不会收到中间的 SSE 事件
- 最终返回的是完整的 JSON response,格式与非 stream 请求一致
8.4 如果需要 Stream
当前版本不支持 WebSearch Interception + Stream 同时工作。如果必须要流式输出,可以: 1. 不使用 WebSearch Interception,在客户端自己实现 tool loop 2. 等待 LiteLLM 后续版本支持(可能会在搜索完成后对 follow-up 请求启用 stream)
九、为什么请求中的 tool 是 web_search_20250305 而不是 searxng-search?
这是一个常见疑问。请求中的 tools 和 config 中的 search_tools 是两个不同层面的概念:
9.1 两层架构
9.2 对照表
| 请求中的 tools | Config 中的 search_tools | |
| 作用 | 定义模型可用的工具接口 | 定义实际搜索引擎实现 |
| 谁看 | LLM 模型 | LiteLLM handler |
| 格式 | Anthropic 原生协议 | LiteLLM 内部配置 |
| 值 | web_search_20250305 | searxng-search |
| 可替换 | 固定(协议标准) | 可换为 perplexity/tavily 等 |
9.3 为什么这样设计
1. 客户端无需修改 — Claude Code 等工具以为在用 Anthropic 原生 web search,实际上 LiteLLM 在背后用 SearXNG 替代
2. 搜索引擎可插拔 — 只需改 config 中的 search_provider,不影响客户端代码
3. 协议兼容 — 保持与 Anthropic API 的完全兼容
简单说:web_search_20250305 是接口协议(给模型看的),searxng-search 是实现引擎(给 LiteLLM 用的)。
十、参考链接
十一、结语
➡️ 下一步行动:
相关产品:
- Amazon Bedrock — 用于构建生成式人工智能应用程序和代理的端到端平台
相关文章:
- 使用Logstash在线迁移 Amazon OpenSearch Service
- 基于Amazon Bedrock 上实现 Dynamic Filtering Web Search 与 Web Fetch
- AWS Security Agent 渗透测试实操
- CloudHSM的Java SDK使用及IoT场景加密体系设计最佳实践(上)
- 用 Strands Agents SDK 构建确定性数据分析:语义层 + VQR 在 Amazon Bedrock 上的实践
*前述特定亚马逊云科技生成式人工智能相关的服务目前在亚马逊云科技海外区域可用。亚马逊云科技中国区域相关云服务由西云数据和光环新网运营,具体信息以中国区域官网为准。


