dsh-search-failover
Verifieddsh-search-failover · v0.3.9 · MIT · Web UI
Provider-level web search+fetch pool for DeepSeek Harness: bypass the official LLM search channel (0 model tokens), failover/rotate across Exa/Tavily/Jina/Firecrawl/Serper/SerpApi/SearXNG/DDG/Brave with quota-aware circuit breaking, multi-key rotation, an
Install
dsh plugin add dsh-search-failover Confirm the layer applied with dsh --profile default --dump-config â see the install guide.
Source
Tags
Readme
dsh-search-failover
DeepSeek Harness (DSH) åç provider 级æºèœæçŽ¢ / æåæ±
çŽè¿æ£çŽ¢ç«¯ç¹ïŒæš¡å Token = 0 · 倿ºå®¹çŸ · å æèœ®è¯¢ · é¢åºŠæç¥çæ · AI èªäž»æ¢æº · ç°ä»£å¡çæµ Web GUI
䞺ä»ä¹äžçšå®æ¹é»è®€æçŽ¢ïŒ
DSH é»è®€éé deepseek-official äžæ¯äžçšæçŽ¢ APIïŒæ¯æ¬¡ web_search éœäŒåèµ·äžèœ®å®æŽ Messages æš¡åè°çšïŒç± DeepSeek åšæå¡ç«¯æ§è¡æçŽ¢ãè¿æå³çïŒ
宿¹ deepseek-official |
æ¬æä»¶ search-pool |
|
|---|---|---|
| æ£çŽ¢æ¹åŒ | äžæŽèœ® LLM è°çš + æå¡ç«¯ web_search å·¥å
· |
çŽè¿ Exa / Tavily / Jina / Firecrawl çæ£çŽ¢ç«¯ç¹ |
| æš¡å token | æ¯æ¬¡æçŽ¢éœç§ïŒinput + outputïŒïŒç»æè¿äŒåçäžäžæ | 0ïŒçº¯æ£çŽ¢ïŒäžç¢°ä»»äœ LLMïŒ |
| è®¡èŽ¹æ¥æº | DEEPSEEK_API_KEY äœé¢ |
ååŒæèªå·±çå 莹é¢åºŠ |
æå web_fetch |
åæ ·èµ°å®æ¹éé | 忥æ¥ç®¡ïŒJina Reader / Exa Contents / Tavily Extract / Firecrawl Scrape |
| 宿º / é¢åºŠèå°œ | æŽæ¡éŸè·¯ææ | çæå·åŽ + èªåšäžæ¢äžäžäžªåŒæ / äžäžäžª Key |
è£
äžå³æ searchProvider äž fetchProvider éœæå° search-poolãåžèœœåèªåšåèœå°å®æ¹ééã
âš æ žå¿ç¹æ§
- ð¡ïž Provider çº§éææ¿æ¢ïŒæ 䟵å
¥æ¥ç®¡ DSH
ctx.webç æçŽ¢ + æåïŒä¿æåçweb_search/web_fetchå·¥å ·çŸåäžåã - ð åéè·¯ç±çç¥ïŒ
- äŒå é¡ºåº (Failover)ïŒæäŒå 级ä»é«å°äœäŸæ¬¡å°è¯ïŒåäžäžªå端倱莥æçæèªåšäžæ¢äžäžäžªã
- å æèœ®è¯¢ (Weighted Rotate)ïŒæ 1~10 æéå°æçŽ¢æµéå¹³æå°ææå¥åº·åŒæïŒæå€§å抚干å倧æçŽ¢æºçå 莹é¢åºŠã
- â¡ æºèœé¢åºŠæç¥äžçæåš (Circuit Breaker)ïŒ
- éå°é¢åºŠèå°œïŒHTTP 402/429/Quota ExceededïŒâ é¿å·åŽ (1h)ïŒé¿å æ æè¯·æ±ïŒ
- éå°äžŽæ¶çœç»æåšïŒTransient ErrorïŒâ 5 åéå è¿ç» 3 次倱莥觊å çå·åŽ (60s)ïŒ
- å·åŽå°æèªåšååŒæ¢æŽ»ïŒæåç«å³æ¢å€ã
- ð€ AI èªäž»æ¢æºæèœ (
web_search_from)ïŒ- 䞺 Agent 泚å
¥äžå±æ¢æºå·¥å
·ãåœ AI 讀䞺é»è®€ç»æäžå€çæ³ãä¿¡æ¯è¿æ¶ææºåäžæ¶ïŒå¯èªäž»éæ©
exa/serper/tavily/jina/firecrawlçåŒæéæ°æçޢ并坹æ¯ã
- 䞺 Agent 泚å
¥äžå±æ¢æºå·¥å
·ãåœ AI 讀䞺é»è®€ç»æäžå€çæ³ãä¿¡æ¯è¿æ¶ææºåäžæ¶ïŒå¯èªäž»éæ©
- ðïž ç°ä»£å¡çæµ Web GUI è®Ÿçœ®é¢æ¿ïŒ
- åš DSH 讟眮页äžé®å¡«å/ä¿®æ¹ API Keyã忢çç¥ãææœæåºãæµè¯è¿éæ§ïŒä¿åå³å®æ¶çæïŒæ ééå¯è¿çšã
- å¯é¥å®å
šä¿ååšæ¬å°
~/.dsh/settings.yamlïŒç»äžäžæ¥ã
- ð ååŒæå€ Key 蜮æ¢ïŒåäžåç«¯å¯æ¢è¡æéå·å¡«å€äžª KeyïŒKey A é¢åºŠèå°œå å Key BïŒå šéšæäºæçæäžæ¢äžäžäžªåŒæã
- ð å
šçæéé
ïŒ
- æçŽ¢ïŒExa, Serper, Tavily (keyless å¿åæ¡£), Jina, SerpApi, Firecrawl, SearXNG (èªæç®¡), DuckDuckGo, Brave
- æåïŒJina Reader (
r.jina.ai) · Exa Contents · Tavily Extract · Firecrawl Scrape
ðïž æ¶ææŠè§
ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â AI Agent / User Chat â
ââââââââââââââââ¬âââââââââââââââââââââââââââââââââ¬âââââââââââââââ
â (é»è®€æçŽ¢ / æå) â (æŸåŒæ¢æº)
⌠âŒ
ââââââââââââââââââââââââââââââââ âââââââââââââââââââââââââââââââ
â åç web_search / web_fetch â â web_search_from (å¢åŒºå·¥å
·) â
ââââââââââââââââ¬ââââââââââââââââ ââââââââââââââââ¬âââââââââââââââ
â â
⌠âŒ
ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â SearchPoolProvider (search-pool) â
â â
â [è°åºŠå³ç] â
â âââ æå®æº (source): çŽè¿æå®åŒæ, äžèµ°æ± â
â âââ Failover: æ priority ååºäŸæ¬¡å°è¯ â
â âââ Rotate: æ weight å±åŒå æèœ®èœ¬ â
â â
â [çæäžå¥åº·å®æ€] â
â âââ CircuitBreaker çæ§åå端å¥åº·åºŠ â
â âââ é¢åºŠèå°œ(1h å·åŽ) / ç¬æ¶é误(60s å·åŽ) / æ¢æŽ»æ¢å€ â
ââââââââââââââââââââââââââââââââ¬ââââââââââââââââââââââââââââââââ
â
ââââââââââââ¬âââââââââââ¬ââââââŽâââââ¬âââââââââââ¬âââââââââââ¬âââââââââââ
⌠⌠⌠⌠⌠⌠âŒ
âââââââ ââââââââ ââââââââ ââââââââ ââââââââââââââââââ âââââââââââ
â Exa â âSerperâ âTavilyâ â Jina â âFirecrawlââSerp-â â SearXNG â
â â â .dev â â(Anon)â â AI â â .dev ââ Api â â (Local) â
âââââââ ââââââââ ââââââââ ââââââââ ââââââââââââââââââ âââââââââââ
ðïž è®Ÿçœ®é¢æ¿å®æºé¢è§
Â
- 宿¶å¯é¥å¡«åïŒéæ¶å¡«åææŽæ°ååŒæ API KeyïŒæ¯æå€è¡å€ KeyïŒïŒç¹å»ä¿åç«å³ççæãè¡å ãâãçŽèŸŸååŒæç³è¯·é¡µã
- çœé¡µæåæ¥ç®¡ïŒ
web_fetchåæ¥èµ°æçŽ¢æ± ïŒJina Reader / Exa / Tavily / FirecrawlïŒïŒäº«ååäžå¥çæäžå€ Keyã - äžé®æµè¯è¿æ¥ (â¶ æµè¯)ïŒå¯¹æå®å端åèµ· 1 æ¡æµè¯æçŽ¢ïŒæ¯«ç§çº§åéŠè¿éç¶æäžååºèæ¶ã
- åšæäŒå çº§è°æŽ (â / â)ïŒéè¿æé®è°æŽåŒæåš Failover éŸäžçäŒå 级ã
- 蜮询æéè°èïŒåšèœ®è¯¢åææš¡åŒäžïŒäžºäžååŒæè®Ÿçœ® 1~10 æéåŒã
- æ·»å èªå®ä¹åç«¯ïŒæ éæ¹åä»£ç æé 眮æä»¶ïŒçŽæ¥åšç颿·»å SearXNG å®äŸææ°å端ã
- é¢åºŠäœééè§ïŒè¡å çŽæ¥æŸç€ºæ¯æé¢åºŠæ¥è¯¢çå端ïŒåŠ SerpApiïŒçå¥é€ç±»åãå©äœæ¬¡æ°åéçœ®æ¥æã
ð å¿«éåŒå§
1. å®è£ æä»¶
åšäœ ç DSH é¡¹ç®æ Web Profile äžå®è£ ïŒ
# æ¹åŒ A: ä» npm å®è£
(æšè)
dsh plugin --profile web add dsh-search-failover
# æ¹åŒ B: æ¬å°å
é蜯éŸè°è¯ (åŒåè
)
git clone https://github.com/Walvez/dsh-search-failover.git
dsh plugin --profile web add link:$(pwd)/dsh-search-failover
2. å¯çšé 眮
åš cordis.patch.yml äžå£°ææèœœäžé»è®€å端é
眮ïŒ
- id: search-pool
name: dsh-search-failover
config:
strategy: failover # failover (äŒå
顺åº) | rotate (蜮询åæ)
maxResults: 8 # é»è®€è¿åæ¡æ°äžé
timeoutMs: 15000 # å䞪请æ±è¶
æ¶æ¶éŽ (ms)
backends:
- id: exa
kind: exa
apiKeyEnv: EXA_API_KEY # ä» ~/.dsh/.env 读å
priority: 1
- id: serper
kind: serper
apiKeyEnv: SERPER_API_KEY
priority: 2
- id: tavily
kind: tavily
apiKeyEnv: TAVILY_API_KEY
priority: 3
- id: jina
kind: jina
apiKeyEnv: JINA_API_KEY
priority: 4
- id: firecrawl
kind: firecrawl
apiKeyEnv: FIRECRAWL_API_KEY
priority: 5
- id: serpapi
kind: serpapi
apiKeyEnv: SERPAPI_API_KEY
priority: 6
- id: searxng
kind: searxng
baseURL: http://127.0.0.1:8080
priority: 7
circuit:
threshold: 3 # è¿ç»é误éåŒ
burstWindowMs: 300000 # ç»è®¡æ¶éŽçªå£ (5 åé)
cooldownMs: 60000 # ç¬æ¶é误å·åŽæ¶éŽ (1 åé)
quotaCooldownMs: 3600000 # é¢åºŠèå°œå·åŽæ¶éŽ (1 å°æ¶)
3. å¯åš DSH Web
dsh web
æåŒ Web GUI (é»è®€ http://127.0.0.1:3080)ïŒè¿å
¥ 讟眮 â æçŽ¢æ± å³å¯åšçé¢çŽæ¥ç®¡çææ Keyã
ð åç«¯åŒææ¯æäžé¢åºŠåè
åŒææ è¯ (kind) |
æçŽ¢ | æå | 宿¹å 莹é¢åºŠ (æ žå®) | å¯é¥ | ç³è¯·é¡µ |
|---|---|---|---|---|---|
exa |
â | â | 泚åé $20ïŒæ¯æèµ $10 | å¿ é¡» | dashboard.exa.ai |
serper |
â | â | 泚åèµ é 2,500 次 | å¿ é¡» | serper.dev |
tavily |
â | â | æ¯æ 1,000 creditsïŒæ key èµ°å¿åæ¡£ | å¯é | app.tavily.com |
jina |
â | â | å
莹泚å KeyïŒs.jina.ai æçŽ¢ / r.jina.ai æå |
å¿ é¡» | jina.ai |
firecrawl |
â | â | æ¯æ 1,000 credits | å¿ é¡» | firecrawl.dev |
serpapi |
â | â | æ¯æ 250 æ¬¡ïŒæ¯æå®æ¶é¢åºŠæ¥è¯¢ | å¿ é¡» | serpapi.com |
searxng |
â | â | èªæç®¡æ é | æ | docs.searxng.org |
brave |
â | â | éç»å¡ | å¿ é¡» | brave.com/search/api |
ddg |
â | â | å®å šå 莹 | æ | â |
åäžåç«¯å¯æ¢è¡æéå·å¡«å€äžª KeyãKey A é¢åºŠèå°œå å Key BïŒå šéšæäºæçæäžæ¢äžäžäžªåŒæã
ð€ AI èªäž»æ¢æºå·¥å
· (web_search_from)
åœ Agent 讀䞺é»è®€æçŽ¢ç»æäžçæ³æ¶ïŒå¯ä»¥äž»åšè°çšç±æ¬æä»¶æ³šåç web_search_from å·¥å
·ïŒ
å·¥å ·åæ°
{
"name": "web_search_from",
"description": "çšæå®çæçŽ¢å端(åŒæ)æçŽ¢åœåä¿¡æ¯å¹¶è¿å该æºåå§ç»æãå¯çšäºå€æºå¯¹æ¯ææ¢åŒæéè¯ã",
"parameters": {
"query": { "type": "string", "description": "æçŽ¢å
³é®è¯" },
"source": { "type": "string", "description": "æå®å端类å (äŸåŠ exa, serper, tavily, jina, firecrawl, searxng ç)" },
"maxResults": { "type": "number", "description": "è¿åç»ææ°éäžé (é»è®€ 8)" }
}
}
Agent å žåå·¥äœæµ
- Agent æ§è¡
web_search(query="ææ°ææ¯åšæ")èµ°é»è®€æçŽ¢æ± ïŒ - åç°ç»æå€§å€æ¯æ§é»æäžçžå
³ïŒAgent äž»åšè°çš
web_search_from(query="ææ°ææ¯åšæ", source="serper")ä» Google 宿¶çŽ¢åŒè·åç»æïŒ - 对æ¯åæºä¿¡æ¯ïŒèŸåºæåç¡®ãæåæ¶çåçã
𧪠åå æµè¯
项ç®å å«å®åçåå æµè¯å¥ä»¶ïŒèŠççæåšç¶ææºãå æèœ®è¯¢ãäŒå 级æåºã倿ºå®¹çŸãèªææ¢æŽ»çïŒïŒ
# è¿è¡åå
æµè¯
npm test
# è¿è¡çå®çœç»åçæµè¯
EXA_API_KEY=your_key node scripts/smoke.mjs exa serper tavily
ð åŒæºè®žå¯è¯
æ¬é¡¹ç®åºäº MIT License åŒæºã
æ¬¢è¿æäº€ Issue å Pull Request å ±åæ¹è¿ïŒ