dsh-web-tools

# dsh-web-tools 让 DeepSeek Harness 拥有直连全网与社媒平台的搜索与抓取能力。 **9 大 Web Provider 原生能力适配 · SearchHints 语义编译 · 多源自动容灾 · 小红书 / Twitter X 平台检索**

GitHub Stars MIT License DeepSeek Harness TypeScript

[English](README.md) | **简体中文**
## 它解决什么问题 当联网能力只依赖一个 Web Provider 时,额度耗尽、限流或服务异常都可能直接中断检索;而简单接入多个搜索 API,往往又只能使用它们共同支持的基础能力,没有真正发挥不同搜索源各自擅长的搜索模式、分类、时效、域名策略和正文提取能力。 dsh-web-tools 将 Exa、Tavily、Firecrawl、Parallel、Brave、You.com、Jina、Keenable、SearXNG,以及小红书、Twitter / X 接入 DSH 标准 `web_search` / `web_fetch`。 在统一 DSH 工具接口的同时,dsh-web-tools 通过 SearchHints 归一化查询意图,再针对不同 Provider 分别编译为其支持的原生参数,尽可能使用各家的分类、时效、域名、地区、深度搜索与正文提取能力;同时通过多 API Key、Provider Fallback 和平台专用浏览器会话,提高整个联网链路的可用性。 --- **核心亮点**: - **9 大 Web Provider 原生能力深度适配**:保持统一 `web_search` / `web_fetch` 接口,但不把不同搜索源压成最低公共能力。针对 Exa、Tavily、Firecrawl、Parallel、Brave、You.com、Jina、Keenable、SearXNG 分别适配搜索类型、时效、域名策略、地区语言、深度检索与正文提取能力。 - **SearchHints → Provider-specific 参数编译**:将 Query 中的技术 / 论文 / 新闻、时效、域名、地区与语言等搜索意图归一化,再按不同 Provider 的能力映射为各自原生参数;整个过程由确定性代码完成,不增加额外 LLM 调用。 - **小红书与 Twitter / X 平台来源**:两个平台均通过独立的本地浏览器 Profile 提供已登录站内搜索、详情抓取,以及页面实际返回的评论或回复。 - **多搜索源调度与自动容灾**:支持多 API Key 分配、鉴权失败切换、429 冷却、Ordered / Round-Robin / Random 路由,以及可配置 Provider Fallback。 - **DSH 原生工具集成**:直接复用标准 `web_search` / `web_fetch`,模型侧无需学习额外工具,同时提供会话级「联网搜索」模式。 ```text DSH Agent │ web_search / web_fetch │ ▼ SearchHints topic / freshness / domains locale / cleanQuery ... │ Provider-specific compilation │ ┌────────┬─────────┬───────────┬──────────┐ │ Exa │ Tavily │ Firecrawl │ Parallel │ ... │ │ │ │ │ │category│ topic │ github │objective │ │ date │ chunks │ research │ policy │ │domains │ time │ tbs │ queries │ └────────┴─────────┴───────────┴──────────┘ ```

dsh-web-tools 搜索策略与多源调度

## 9 大 Web Provider 原生能力深度适配 统一的是 DSH 的工具接口和搜索语义,不统一的是各家 Provider 的能力。 dsh-web-tools 通过 SearchHints 表达查询意图,再针对不同 Provider 分别构造请求,而不是把所有搜索源压缩成一套最低公共参数。 例如,同样是“搜索最近一周的 AI 编程资料”: * **Exa**:映射分类、ISO 日期范围与域名限制; * **Firecrawl**:技术查询映射至 `github` 分类,研究类查询映射至 `research`,并结合 `tbs` 时效过滤; * **Parallel**:组合 `objective`、`search_queries` 与 `source_policy`; * **Brave Search**:映射 freshness、国家与搜索语言,并优先使用 LLM Context; * **You.com**:通过 `boost_domains` 对指定域名进行软加权。 这些适配全部由确定性代码完成,不会为了选择 Provider 参数再额外调用一次 LLM。 * **Exa**:精确分类映射(publication / news / financial report)、ISO 日期范围与域名限制。 * **Firecrawl**:代码与技术查询映射至 `github` 分类,论文与学术查询映射至 `research`,并支持 `tbs` 时效、域名限制与 Clean Markdown 抓取。 * **Parallel**:双层语义优化(`objective` 软引导 + `search_queries` 纯净词)与 `source_policy` 域名/时效过滤。 * **Tavily**:支持 `basic` / `advanced` / `fast` / `ultra-fast` 搜索深度;`basic`、`advanced`、`fast` 模式支持 `chunks_per_source` 分块控制,并映射 `news` / `finance` 话题、日期区间、国家与域名约束。 * **Brave Search**:LLM Context 预提取端点,支持 `pd/pw/pm/py` 时效、国家与搜索语言。 * **You.com**:原生 **`boost_domains`** 软加权支持,时效与地区国家过滤。 * **Jina**:搜索关键词降噪与 ReaderLM-v2 高精度 Markdown 正文解析。 * **SearXNG**:自建元搜索支持 `categories` (it/science/news) 与 `time_range`。 * **Keenable**:Web 搜索,支持 `site` 域名限定与 `published_after` / `published_before` 日期过滤。 * **原生与通用正文提取 (`web_fetch`)**:配置 Tavily、Exa、Firecrawl、Parallel、You.com、Jina 时自动优先调用其原生云端提取接口;未配置或失败时,以及使用 SearXNG / Brave 时,自动平滑回退至**插件内置通用 HTTP 抓取器**(基于 Defuddle 纯本地 Markdown 解析与 SSRF / DNS 安全防护),无需额外配置或购买第三方 Fetch Key。 --- ## 平台搜索源(小红书与 Twitter / X) 区别于通用搜索引擎,插件通过专用浏览器会话直接连接社媒平台: * **原生独立浏览器会话架构**: * 基于本机已安装的 Edge / Chrome 专用 Profile 与 CDP 通信。 * **0 浏览器扩展、0 Playwright / Chromium 外部打包**。Cookie 由专用浏览器 Profile 管理,插件不会将其写入配置、日志或中转服务;浏览器仍会按正常认证流程发送给对应平台。 * **小红书**: * **笔记详情与评论抓取 (`web_fetch`)**:通过专用浏览器 Profile 解析 `__INITIAL_STATE__` 结构化数据并自动 DOM 兜底,保留完整 `xsec_token` 签名 URL;页面成功加载评论数据时,同时逐条提取一级评论与已返回的楼中楼回复。 * **站内搜索发现 (`web_search`)**:默认使用已登录浏览器,从 `/explore` 的真实搜索框进入,只输入清洗后的主题词,不带平台名或 `site:` 限定;同时区分登录墙、安全验证和真实退出登录。排查浏览器问题时可通过 `XHS_NATIVE_SEARCH=0` 临时关闭。 * **Twitter / X**: * **原生搜索、推文详情与回复**:通过 CDP 捕获 X Web 客户端自身的 GraphQL 数据流(SearchTimeline / TweetDetail),结构化解析目标推文及其回复树,并以 DOM 作为补充与兜底;支持 `from:`、`since:`、`until:` 等搜索算子。 单次详情抓取最多附带 30 条评论或回复,单条内容最多保留 800 个字符;仍有后续分页或楼中楼内容时会明确标记为截断,避免无界占用模型上下文。 > **能力边界说明**:对于正文主要位于图片中的小红书笔记,目前会返回标题、文字描述、互动数据、图片数量以及页面已加载的评论,但暂不识别图片中的文字,也不会自动抓取全部评论分页。 Agent 使用 `小红书:` 或 `X:` 作为平台路由前缀。前缀只负责选择平台,插件会在实际站内搜索前移除它;例如 `小红书: DeepSeek Harness` 最终输入小红书搜索框的是 `DeepSeek Harness`。 * **通用 Web 降级 (Web Fallback)**:平台来源未启用、运行时暂不可用或发生可重试故障时,改由已配置的通用搜索或抓取 Provider 处理;登录失效、访问受限、站内搜索受限、无效详情地址等非重试错误会直接返回,不会用索引内容冒充原生站内结果、详情或评论。 * **登录态自动验证**:Cookie 只作为第一层门槛。小红书要求同时存在 `a1` 与 `web_session`,随后还会通过交互浏览器稳定检查 `/explore` 的真实页面状态;可见登录墙会使旧 Session 立即失效并重新显示登录入口。搜索提交后的独立登录墙会直接标记为 `search-restricted`,不会再用网页索引结果掩盖站内搜索失败。

小红书与 Twitter X 登录态自动验证

--- ## 自定义搜索源与地址覆盖 (Issue #9) 除了内置的 9 大搜索源与社交媒体平台外,插件完整支持**自定义搜索源 (Custom Search Providers)** 与**内置源地址自定义**: * **内置源地址覆盖与恢复**: * 全部 9 大内置搜索源(Exa、Tavily、Firecrawl、Brave、You、Parallel、Jina、Keenable、SearXNG)均支持自定义服务地址(例如自建 API 网关、代理镜像)。 * 精确保留路径前缀(如 `/v1`、`/v2`),并在跨域名变更时进行凭证保护提示,支持随时一键恢复官方默认地址。 * **三条并列接入路径(单弹窗渐进式配置)**: * **兼容已有搜索接口**:遵循标准 Tavily JSON POST 规范,免配任何字段映射,适合快速接入各开源代理镜像或兼容网关。 * **使用协议模板**:预设 SearXNG JSON 等标准元搜索协议(`GET /search?format=json`),默认开箱免密钥,自动映射结果。 * **自定义 JSON 接口**:支持自研知识库、内网搜索网关或任意未收录的 RESTful API,开放完整自定义能力: * **自定义请求头 (Headers)**:自由添加额外的 HTTP 请求头,支持 `{{apiKey}}`、`{{query}}` 占位符。 * **嵌套 JSON 请求体模板 (`bodyTemplate`)**:POST 模式下支持编写任意嵌套的 JSON 请求体(如 `{"query": "{{query}}", "limit": "{{maxResults}}"}`),无需编写脚本代码。 * **URL 参数模板 (`paramsTemplate`)**:GET 或 Query 编码下支持灵活的 URL 查询参数模板与占位符映射。 * **声明式结果字段映射**:非执行式点路径映射(`itemsPath`、`urlPath`、`titlePath`、`snippetPath` 等),严格防御原型污染。 * **单次安全插值**:采用全局单次正则替换,杜绝用户搜索词内嵌占位符导致的凭证泄漏隐患。 * **实时语法校验**:JSON 请求体模板输入错误时前端实时标红提示,并禁用测试与保存,杜绝残留旧配置。 * **凭证与密钥轮换**: * 支持 Bearer Token、自定义 API Key Header、HTTP Basic(账号密码独立存储并带写入失败回滚补偿)或无需认证模式。 * 凭证由 DSH 凭证服务统一安全管理,配置视图中永不回显真实密钥,支持多 Key 轮换与健康冷却隔离。 * **草稿测试与搜索调度**: * 支持在保存前对草稿即时发起「测试搜索」,验证连通性、延迟与结果解析,测试不会污染正式环境的健康状态与熔断计数。 * 保存后可一键加入当前搜索策略,与内置搜索源共同享受顺序/轮询/随机路由与自动 Fallback 容灾。 * **分级安全授权与出站防护 (SSRF Defense)**: * **开箱即用免确认**:公网 HTTPS 目标及默认自建 SearXNG(`127.0.0.1:8080`、`localhost:8080`)内置预授权,零多余弹窗。 * **操作员一键确认 (409 Conflict 机制)**:对本地私网(RFC 1918)、未加密明文 HTTP 以及内网 DNS 解析到私有 IP 的自定义域名(通过 `resolvesToPrivateIp()` 自动探查),在测试或保存时弹出确认提示,用户点击确认后仅为该特定 `host:port` 签发出站许可,坚决拒绝静默自动授权。 * **共享端点授权生命周期自动管理**:系统通过 `managedBy: "custom-source"` 与引用计数跟踪授权;多个搜索源共享同一内网地址时安全复用,最后一个源删除或移走后自动撤销,绝不残留孤立授权,同时绝对不影响系统预设规则。 * **云元数据与链路本地硬拦截(绝对不可豁免)**:`169.254.0.0/16`、`fe80::/10` 全段(涵盖 `fe80::` 至 `febf::`)、IPv4-mapped 十六进制与点分十进制变体(`::ffff:a9fe:a9fe` 等)与 IMDSv6 地址在底层传输层无条件拦截,即使用户手动赋予授权也直接阻断。 * **代理自适应与套接字绑定**:Windows 系统代理环境下,公网自定义 API 自动通过 `undici.ProxyAgent` 隧道出站;内网与回环请求强制直连并锁定 DNS 预检 IP,杜绝 DNS Rebinding 风险。 * **配置平面对端校验**:管理接口基于真实 TCP Socket `remoteAddress` 进行物理层校验,严格防范 Host 请求头伪造。 --- ## 调度策略与容灾机制 * **多 API Key 负载与容灾**:支持为单个 Provider 配置多个 API Key,并发调用优先分配低 `inFlight` 的 Key,鉴权失败自动切换备用 Key。 * **确定性 Provider Fallback**:遇到网络异常、超时、5xx 服务端错误、429 限流或配额耗尽时,自动降级至链条中的下一搜索源。 * **429 Retry-After 临时冷却**:遭遇限流并携带 `Retry-After` 时触发零请求冷却,避免在冷却期内产生无效请求。 * **搜索路由策略**:`web_search` 支持顺序模式(Ordered)、轮询模式(Round-Robin)和随机模式(Random);`web_fetch` 始终按可抓取 Provider 的确定性链条执行。 * **会话级联网控制 (Search Mode)**:输入框集成单入口紧凑切换器(单按钮 + 极简下拉菜单),提供三档确定性检索模式(默认「智能联网」): * **智能联网 (Smart)**:弹性语义决策。由 Agent 根据上下文问题意图,自主判断是否调起外部网络检索。 * **始终联网 (Always)**:强一致性知识校验。要求 Agent 每轮对话至少完成一次有效的外部检索或内容深抓,确保回答具备外部权威可溯源依据。 * **关闭联网 (Off)**:确定性物理隔离。彻底抛弃依赖弱提示词(System Prompt)容易被模型忽略的弊端,采用**底层运行时三重物理拦截**(从可用工具集中动态剔除 `web_search` / `web_fetch`、单调守卫 Monotonic Guard 强行阻断历史惯性调用、首轮注入运行时断网说明),由宿主环境硬性判定,确保绝不产生外部网络请求。
交互菜单 (Picker Menu) 三态激活视觉呈现 (Active States)
联网模式切换菜单 智能联网 (Smart)
智能联网:按需自适应检索(默认)

始终联网 (Always)
始终联网:强求证高亮激活

关闭联网 (Off)
关闭联网:运行时硬性阻断
* **智能代理分流与内网直连 (Intranet Proxy Bypass)**:完整支持 Windows 系统代理及 `HTTP_PROXY` / `HTTPS_PROXY` / `NO_PROXY` 环境变量。内置 **DNS 预检与私网智能旁路**,公网请求正常走代理通道,而本地回环及解析至私网地址(RFC 1918)的自建搜索源(如局域网自建 SearXNG 或私有网关)自动采用底层直连拨号,彻底消弭开启系统代理时内网服务不可达的拓扑冲突。 --- ## 安装与更新 **DSH 版本支持**:`0.1.0-rc.6` 起,包含 `0.2.0-rc.x` 与 `0.2.1-rc.x`(`latest` / `next` 两条线均已验证)。版本要求写在 `peerDependencies` 中,DSH 会据此判断插件能否激活;升级 DSH 后若插件未激活,先执行一次 `dsh plugin --profile web update dsh-web-tools`。 ```bash # 安装插件 dsh plugin --profile web add github:A3Boy/dsh-web-tools # 更新插件 dsh plugin --profile web update dsh-web-tools # 卸载插件 dsh plugin --profile web remove dsh-web-tools ``` 重启 `dsh web`,在左侧侧边栏进入:`Settings` → `Web Search`。 --- ## Provider 支持矩阵 | Provider | 搜索 (Search) | 抓取/提取 (Fetch / Extract) | 核心特性与深度适配能力 | 配额查询 (Quota) | | --- | --- | --- | --- | --- | | [Exa](https://exa.ai) | 支持 | 支持,`/contents` | 语义检索 (`auto` / `fast` / `deep`)、垂直分类映射、Query-aware 高亮切片、ISO 日期范围与域名限制 | 控制台自查 | | [Tavily](https://tavily.com) | 支持 | 支持,`/extract` | 搜索深度 (`basic` / `advanced` / `fast` / `ultra-fast`),前三种模式支持分块控制,并映射 `news` / `finance`、日期、国家与域名参数 | 官方 API | | [Firecrawl](https://firecrawl.dev) | 支持 | 支持,`/scrape` | 技术查询映射 `github` 分类、学术查询映射 `research`,支持 `tbs`、域名限制与 Clean Markdown 提取 | 官方 API | | [Parallel](https://parallel.ai) | 支持 | 支持,`/v1/extract` | 双层语义检索 (`advanced` / `basic` / `turbo`)、`objective` 软引导、`source_policy` 域名/时效过滤 | 控制台自查 | | [Brave Search](https://brave.com/search/api/) | 支持 | — | 默认优先 LLM Context 预提取模式,支持时效/区域语言过滤,不支持时自动回退 Classic 搜索 | 响应头自动捕获 | | [You.com](https://you.com) | 支持 | 支持,`/v1/contents` | 搜索高亮片段提取、原生 **`boost_domains`** 软加权、时效与国家过滤、Markdown 正文接口 | 官方 API | | [Jina](https://jina.ai) | 支持 | 支持,Reader | 搜索关键词降噪、ReaderLM-v2 高精度 Markdown 转换、Token 预算控制 | 尽力解析 | | [SearXNG](https://docs.searxng.org) | 支持 | — | 开源自托管元搜索引擎,映射 `categories` (it/science/news) 与受支持的 `time_range`,适配器无需 API Key | 由自建实例决定 | | [Keenable](https://keenable.ai) | 支持 | — | Web 搜索 API(`X-API-Key`),将首个限定域名映射为 `site`,时效日期映射为 `published_after` / `published_before`,返回 `published_at`;`web_fetch` 使用内置通用抓取器 | 仅控制台 | ### 快速选型指南 新安装默认首选 Provider 为 **Exa**;已有安装继续沿用已保存的 Provider 配置。 | 需求场景 | 推荐首选 | 说明 | | --- | --- | --- | | **社媒内容发现 / 详情抓取** | **小红书 / Twitter / X** | 两个平台均支持已登录站内搜索、详情抓取,以及实际返回的评论或回复 | | **语义检索 / 技术文档** | **Exa** | 支持语义模式、分类、日期、域名与高亮参数 | | **预提取搜索上下文** | **Brave Search** | 优先使用 LLM Context,失败时回退 Classic Search | | **可调深度搜索与正文提取** | **Tavily** / **Parallel** | 提供 Provider 原生深度档位与内容提取接口 | | **正文转 Markdown** | **Firecrawl** / **Jina** | 支持正文提取、主内容过滤或 Reader 转换 | | **时效、地区与域名偏好** | **You.com** | 支持 freshness、地区语言和 `boost_domains` 参数 | | **自托管元搜索** | **SearXNG** | 使用用户自己的 SearXNG 地址,适配器不要求 API Key | | **Agent 检索 / 精炼摘要提取** | **Keenable** | 支持原生 `site` 域名限定与 `published_after` / `published_before` 发布日期过滤,高质量网页摘要抽取 | --- ## 本地开发 ```bash pnpm install # 安装依赖 pnpm test # 运行测试套件 pnpm run typecheck # 类型检查 pnpm run build # 编译构建 (产物输出至 lib/) ``` --- ## 常见问题 ### 自建 SearXNG 配置与排错 使用 Docker 或自托管 SearXNG 时,若提示 `no usable provider` 或返回 403 拒绝访问,请检查以下两项配置: 1. **必须开启 JSON 格式输出**:SearXNG 默认仅启用了 HTML 输出。编辑 SearXNG 的 `settings.yml` 文件,在 `search.formats` 中增加 `- json`: ```yaml search: formats: - html - json # 必须包含 json,供 API 接口调用 ``` 修改后重启 SearXNG 容器(例如 `docker restart searxng`)生效。 2. **免 Key 访问**:SearXNG 属于自建免 Key 搜索源,插件面板中无需填写 API Key(留空即可)。在 `Base URL` 中填入你的 SearXNG 实例地址(如 `http://127.0.0.1:8080`),点击「测试搜索」即可验证连通性。 ### 缓存与重新安装 若使用本地包或软链接升级遇到缓存问题,可前往 Profile 目录重新安装: ```bash cd ~/.dsh/profiles/web && pnpm install ``` Exa 和 Parallel 的余额需要在 Provider 控制台查看;Brave 的配额信息来自实际搜索响应头。配额展示仅用于状态说明,不影响正常检索与降级。 小红书和 Twitter / X 分别使用独立的本地浏览器 Profile。插件不会把原始 Cookie 导出到配置、日志或第三方中转服务;浏览器会按正常登录与访问流程将 Cookie 发送给对应的平台域名。 --- ## 许可 [MIT](LICENSE) © A3Boy