2026-06-09 23:15:17 +08:00
|
|
|
|
---
|
|
|
|
|
|
tags: [web-search, bing, brave, 适配器模式, claude-code]
|
|
|
|
|
|
create time: 2026-06-09 22:30
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-06-08 23:08:57 +08:00
|
|
|
|
# WEB_SEARCH_TOOL — 网页搜索工具
|
|
|
|
|
|
|
2026-06-09 23:15:17 +08:00
|
|
|
|
## 概述
|
2026-06-08 23:08:57 +08:00
|
|
|
|
|
2026-06-09 23:15:17 +08:00
|
|
|
|
WebSearchTool 让模型可以搜索互联网获取最新信息。原始实现仅支持 Anthropic API 服务端搜索,现已重构为适配器架构,支持 API / Bing / Brave 三种后端,确保任何 API 端点都能使用搜索功能。
|
2026-06-08 23:08:57 +08:00
|
|
|
|
|
2026-06-09 23:15:17 +08:00
|
|
|
|
> [!info]
|
|
|
|
|
|
> 实现状态:适配器架构完成,支持 API / Bing / Brave 三种后端
|
|
|
|
|
|
> 核心工具,无 feature flag 门控(始终启用)
|
2026-06-08 23:08:57 +08:00
|
|
|
|
|
2026-06-09 23:15:17 +08:00
|
|
|
|
## 正文
|
2026-06-08 23:08:57 +08:00
|
|
|
|
|
2026-06-09 23:15:17 +08:00
|
|
|
|
### 实现架构
|
2026-06-08 23:08:57 +08:00
|
|
|
|
|
2026-06-09 23:15:17 +08:00
|
|
|
|
#### 适配器模式
|
|
|
|
|
|
|
|
|
|
|
|
```mermaid
|
|
|
|
|
|
graph TD
|
|
|
|
|
|
A["WebSearchTool.call()"] --> B["createAdapter() 适配器工厂"]
|
|
|
|
|
|
B --> C["ApiSearchAdapter: Anthropic 官方 API 服务端搜索"]
|
|
|
|
|
|
B --> D["BingSearchAdapter: Bing HTML 抓取 + 正则提取"]
|
|
|
|
|
|
B --> E["BraveSearchAdapter: Brave LLM Context API"]
|
|
|
|
|
|
C --> F["使用 web_search_20250305 server tool"]
|
|
|
|
|
|
D --> G["直接抓取 Bing 搜索页 HTML"]
|
|
|
|
|
|
E --> H["调用 Brave HTTPS GET 接口"]
|
2026-06-08 23:08:57 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-06-09 23:15:17 +08:00
|
|
|
|
#### 模块结构
|
2026-06-08 23:08:57 +08:00
|
|
|
|
|
|
|
|
|
|
| 模块 | 文件 | 说明 |
|
|
|
|
|
|
|------|------|------|
|
|
|
|
|
|
| 工具入口 | `packages/builtin-tools/src/tools/WebSearchTool/WebSearchTool.ts` | `buildTool()` 定义:schema、权限、执行、输出格式化 |
|
|
|
|
|
|
| 工具 prompt | `packages/builtin-tools/src/tools/WebSearchTool/prompt.ts` | 搜索工具的系统提示词 |
|
|
|
|
|
|
| UI 渲染 | `packages/builtin-tools/src/tools/WebSearchTool/UI.tsx` | 搜索结果的终端渲染组件 |
|
2026-06-09 23:15:17 +08:00
|
|
|
|
| 适配器接口 | `packages/builtin-tools/src/tools/WebSearchTool/adapters/types.ts` | `WebSearchAdapter` 接口定义 |
|
|
|
|
|
|
| 适配器工厂 | `packages/builtin-tools/src/tools/WebSearchTool/adapters/index.ts` | `createAdapter()` 工厂函数 |
|
|
|
|
|
|
| API 适配器 | `packages/builtin-tools/src/tools/WebSearchTool/adapters/apiAdapter.ts` | 封装 `queryModelWithStreaming` 逻辑 |
|
2026-06-08 23:08:57 +08:00
|
|
|
|
| Bing 适配器 | `packages/builtin-tools/src/tools/WebSearchTool/adapters/bingAdapter.ts` | Bing HTML 抓取 + 正则解析 |
|
2026-06-09 23:15:17 +08:00
|
|
|
|
| Brave 适配器 | `packages/builtin-tools/src/tools/WebSearchTool/adapters/braveAdapter.ts` | Brave LLM Context API 适配 |
|
|
|
|
|
|
|
|
|
|
|
|
#### 数据流
|
|
|
|
|
|
|
|
|
|
|
|
```mermaid
|
|
|
|
|
|
graph TD
|
|
|
|
|
|
A["模型调用 WebSearchTool(query, allowed_domains, blocked_domains)"] --> B["validateInput 校验"]
|
|
|
|
|
|
B --> C["createAdapter 选择后端"]
|
|
|
|
|
|
C --> D["adapter.search(query, options)"]
|
|
|
|
|
|
D --> E["onProgress query_update"]
|
|
|
|
|
|
D --> F["axios.get search-engine-url"]
|
|
|
|
|
|
F --> G["extractResults 按后端提取结果"]
|
|
|
|
|
|
G --> H["客户端域名过滤 allowed/blocked"]
|
|
|
|
|
|
H --> I["onProgress search_results_received"]
|
|
|
|
|
|
I --> J["格式化为 markdown 链接列表返回给模型"]
|
2026-06-08 23:08:57 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-06-09 23:15:17 +08:00
|
|
|
|
### Bing 适配器技术细节
|
2026-06-08 23:08:57 +08:00
|
|
|
|
|
2026-06-09 23:15:17 +08:00
|
|
|
|
#### 反爬绕过
|
2026-06-08 23:08:57 +08:00
|
|
|
|
|
2026-06-09 23:15:17 +08:00
|
|
|
|
使用 13 个 Edge 浏览器请求头(含 `Sec-Ch-Ua`、`Sec-Fetch-*` 等),避免 Bing 返回 JS 渲染的空页面。`setmkt=en-US` 参数强制美式英语市场,避免 IP 地理定位导致区域化结果。
|
2026-06-08 23:08:57 +08:00
|
|
|
|
|
2026-06-09 23:15:17 +08:00
|
|
|
|
#### URL 解码(`resolveBingUrl()`)
|
2026-06-08 23:08:57 +08:00
|
|
|
|
|
|
|
|
|
|
Bing 返回的重定向 URL 格式:`bing.com/ck/a?...&u=a1aHR0cHM6Ly9...`
|
|
|
|
|
|
|
|
|
|
|
|
- `u` 参数前 2 字符为协议前缀:`a1` = https,`a0` = http
|
|
|
|
|
|
- 剩余部分为 base64url 编码的真实 URL
|
|
|
|
|
|
- Bing 内部链接和相对路径被过滤返回 `undefined`
|
|
|
|
|
|
|
2026-06-09 23:15:17 +08:00
|
|
|
|
#### 摘要提取(`extractSnippet()`)
|
2026-06-08 23:08:57 +08:00
|
|
|
|
|
|
|
|
|
|
三级降级策略:
|
|
|
|
|
|
|
|
|
|
|
|
1. `<p class="b_lineclamp...">` — Bing 的搜索摘要段落
|
|
|
|
|
|
2. `<div class="b_caption">` 内的 `<p>` — 备选摘要位置
|
|
|
|
|
|
3. `<div class="b_caption">` 直接文本 — 最终 fallback
|
|
|
|
|
|
|
2026-06-09 23:15:17 +08:00
|
|
|
|
#### 域名过滤
|
2026-06-08 23:08:57 +08:00
|
|
|
|
|
|
|
|
|
|
客户端侧实现,支持子域名匹配:
|
2026-06-09 23:15:17 +08:00
|
|
|
|
|
2026-06-08 23:08:57 +08:00
|
|
|
|
- `allowedDomains`:白名单,结果域名必须匹配列表中的某项(含子域名)
|
|
|
|
|
|
- `blockedDomains`:黑名单,匹配的结果被过滤
|
|
|
|
|
|
- 两者不可同时使用(`validateInput` 校验)
|
|
|
|
|
|
|
2026-06-09 23:15:17 +08:00
|
|
|
|
### 适配器选择逻辑
|
2026-06-08 23:08:57 +08:00
|
|
|
|
|
2026-06-09 23:15:17 +08:00
|
|
|
|
`createAdapter()` 按以下优先级选择后端:
|
2026-06-08 23:08:57 +08:00
|
|
|
|
|
2026-06-09 23:15:17 +08:00
|
|
|
|
1. `WEB_SEARCH_ADAPTER=api|bing|brave` 显式指定
|
|
|
|
|
|
2. Anthropic 官方 API Base URL → ApiSearchAdapter
|
|
|
|
|
|
3. 第三方代理 / 非官方端点 → BingSearchAdapter
|
2026-06-08 23:08:57 +08:00
|
|
|
|
|
2026-06-09 23:15:17 +08:00
|
|
|
|
显式指定 `WEB_SEARCH_ADAPTER=brave` 时,会改用 Brave LLM Context API 后端,并要求 `BRAVE_SEARCH_API_KEY` 或 `BRAVE_API_KEY`。
|
2026-06-08 23:08:57 +08:00
|
|
|
|
|
2026-06-09 23:15:17 +08:00
|
|
|
|
### 接口定义
|
2026-06-08 23:08:57 +08:00
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
|
interface WebSearchAdapter {
|
|
|
|
|
|
search(query: string, options: SearchOptions): Promise<SearchResult[]>
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface SearchResult {
|
|
|
|
|
|
title: string
|
|
|
|
|
|
url: string
|
|
|
|
|
|
snippet?: string
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface SearchOptions {
|
|
|
|
|
|
allowedDomains?: string[]
|
|
|
|
|
|
blockedDomains?: string[]
|
|
|
|
|
|
signal?: AbortSignal
|
|
|
|
|
|
onProgress?: (progress: SearchProgress) => void
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-06-09 23:15:17 +08:00
|
|
|
|
### 文件索引
|
2026-06-08 23:08:57 +08:00
|
|
|
|
|
|
|
|
|
|
| 文件 | 职责 |
|
|
|
|
|
|
|------|------|
|
|
|
|
|
|
| `packages/builtin-tools/src/tools/WebSearchTool/WebSearchTool.ts` | 工具定义入口 |
|
|
|
|
|
|
| `packages/builtin-tools/src/tools/WebSearchTool/prompt.ts` | 搜索工具 prompt |
|
|
|
|
|
|
| `packages/builtin-tools/src/tools/WebSearchTool/UI.tsx` | 终端 UI 渲染 |
|
|
|
|
|
|
| `packages/builtin-tools/src/tools/WebSearchTool/adapters/types.ts` | 适配器接口 |
|
|
|
|
|
|
| `packages/builtin-tools/src/tools/WebSearchTool/adapters/index.ts` | 适配器工厂 |
|
|
|
|
|
|
| `packages/builtin-tools/src/tools/WebSearchTool/adapters/apiAdapter.ts` | API 服务端搜索适配器 |
|
|
|
|
|
|
| `packages/builtin-tools/src/tools/WebSearchTool/adapters/bingAdapter.ts` | Bing HTML 解析适配器 |
|
|
|
|
|
|
| `src/tools.ts` | 工具注册 |
|
2026-06-09 23:15:17 +08:00
|
|
|
|
|
|
|
|
|
|
## 关联笔记
|
|
|
|
|
|
|
|
|
|
|
|
- [[web-browser-tool]]
|
|
|
|
|
|
- [[all-features-guide]]
|