@wjunhere/dsh-web-providers
DeepSeek Harness(DSH)ctx.web 的搜索与抓取 provider,内部是有序兜底链:
- 搜索:
exa → tavily → jina-search,注册为 provider id dsh-search;
- 抓取:
jina → tavily extract,注册为 provider id dsh-fetch。
链对外仍是单个 provider,web_search / web_fetch 工具不变,模型无感知;前一后端失败
(403/404/超时/空正文)自动换下一个。
解决什么问题
- DSH 内置
web_fetch 走 DeepSeek Fetch API,目标站点不可达或被反爬时统一返回 HTTP 404;
Jina Reader 由 Jina 侧抓取并转 Markdown,能覆盖维基百科、GitHub raw、Hacker News 等站点。
- 官方 DeepSeek 搜索是一次完整模型调用;Exa 是纯检索 API,语义召回更适合英文技术内容。
- 官方 Exa provider 用精确 peer 版本,DSH 小版本升级就会在启动时被禁用;本包用范围 peer + 兜底链,
不再依赖单一后端是否可用。
安装
在 DSH profile 目录(例如 ~/.dsh/profiles/<name>)安装:
npm install @wjunhere/dsh-web-providers
把包加进 package.json 的 dsh.profile.bundles:
{
"dsh": { "profile": { "bundles": ["...", "@wjunhere/dsh-web-providers"] } }
}
再在 profile 的 cordis.patch.yml 里 pin 两个 provider:
- id: web
name: "@deepseek-ai/dsh-web"
config:
searchProvider: dsh-search
fetchProvider: dsh-fetch
重启 DSH 生效。
配置
凭据默认从启动环境的 EXA_API_KEY / TAVILY_API_KEY / JINA_API_KEY 读取,也可以写在
config 里(优先级高于环境变量)。
- insert:
- id: web-providers
name: '@wjunhere/dsh-web-providers'
config:
search:
order: [exa, tavily, jina] # 搜索链顺序
fetch:
order: [jina, tavily] # 抓取链顺序
exa:
apiKey: '' # 空则读 EXA_API_KEY
baseURL: https://api.exa.ai
proxyUrl: ''
searchType: auto # auto / keyword / neural
highlightsPerResult: 1
timeoutMs: 20000
tavily:
apiKey: '' # 空则读 TAVILY_API_KEY
baseURL: https://api.tavily.com
proxyUrl: '' # 大陆网络通常需要
searchDepth: basic # basic / advanced
extractDepth: basic
numResults: 5
maxContentChars: 100000
timeoutMs: 20000
jina:
apiKey: '' # 空则读 JINA_API_KEY
baseURL: https://r.jina.ai
searchBaseURL: https://s.jina.ai
proxyUrl: ''
timeoutMs: 30000
maxContentChars: 100000
minContentChars: 50
allowAnonymous: false
行为
- 搜索链:Exa 返回
sources[](无 highlight 的结果被丢弃);Tavily 返回 title/url/content
(content 截 500 字符当 snippet);Jina Search 返回 title/url/description。
任一成功即返回,全部失败时报 WEB_PROVIDER_ERROR 并附每段失败原因。
- 抓取链:Jina 返回
{ url, statusCode: 200, body: { kind: 'text', content } },正文前带标题;
失败(非 2xx、空正文、正文过短、拦截页)后回退 Tavily Extract 的 raw_content。
- 两链都遵守调用方
AbortSignal,每段有独立超时。
限制
- Tavily Extract 对反爬站点同样可能失败(如 Reddit);这类只能走浏览器路径。
- Exa 需要 API key;Jina 匿名模式只有 20 RPM(带 key 500 RPM)。
开发
npm install
EXA_API_KEY=... TAVILY_API_KEY=... JINA_API_KEY=... \
JINA_PROXY_URL=http://127.0.0.1:7897 TAVILY_PROXY_URL=http://127.0.0.1:7897 \
node test/providers.mjs
测试直接打真实 API,覆盖每个后端和两条兜底链,没有 mock。
License
MIT