Skip to content

feat: add Serper search fallback + search cache + concurrency limiter#4

Open
andyzengmath wants to merge 4 commits into
samarth777:mainfrom
andyzengmath:feat/serper-cache-concurrency
Open

feat: add Serper search fallback + search cache + concurrency limiter#4
andyzengmath wants to merge 4 commits into
samarth777:mainfrom
andyzengmath:feat/serper-cache-concurrency

Conversation

@andyzengmath

Copy link
Copy Markdown

Problem

When multiple subagents run web searches in parallel (e.g. via the Workflow tool or Agent tool), DuckDuckGo aggressively rate-limits requests, causing cascading failures:

⚠ DDG Lite error: fetch failed
⚠ DDG Instant error: fetch failed
⚠ All search providers failed

This is a known issue — DDG was never designed for programmatic use at agent scale.

Solution

Three changes to proxy.mjs:

1. Serper.dev as fallback search provider

  • Adds Serper.dev (Google SERP API) as a fallback provider via SERPER_API_KEY env var
  • Free tier: 2,500 queries with no credit card
  • Positioned after Exa/Parallel MCP (free) and Brave, before DDG — only burns credits when free providers fail

2. Search result cache (5-min TTL)

  • Deduplicates identical queries across parallel subagents
  • Logs 📋 Search cache hit: for visibility
  • Caches even empty results to avoid re-hitting a failing provider

3. Concurrency semaphore (max 2 concurrent searches)

  • Prevents more than 2 search requests hitting external APIs simultaneously
  • Excess searches queue automatically (logs ⏳ Search queued:)
  • Eliminates the DDG rate-limit storm that causes cascading failures

Updated Provider Chain

1. Exa / Parallel MCP   (free, no quota — tried first)
2. Brave Search API      (if BRAVE_API_KEY set)
3. Serper.dev            (if SERPER_API_KEY set — NEW)
4. DuckDuckGo Lite       (now protected by concurrency semaphore)
5. DuckDuckGo Instant    (last resort)

New Environment Variable

Variable Description
SERPER_API_KEY Serper.dev API key for Google SERP fallback (free 2,500 queries at serper.dev)

Testing

Verified Serper returns results:

🔍 Web search: "University of Pennsylvania Mathematics alumni venture capital"
✓ Serper returned 5 results

Verified cache + concurrency with 4 parallel searches (2 unique, 2 duplicates):

✅ FETCHED (3 results): Penn math alumni venture capital
📋 CACHE HIT: Penn math alumni venture capital
⏳ QUEUED (2/2 active): Cambridge Churchill College founders
✅ FETCHED (3 results): Cambridge Churchill College founders

Only 2 API calls instead of 4 — cache saved 50%.

Depends On

This PR builds on #3 (MCP providers). The provider chain assumes Exa/Parallel MCP are available as the primary free providers.

🤖 Generated with Claude Code

andyzengmath and others added 4 commits June 30, 2026 14:47
Add PowerShell and CMD examples for running the proxy on Windows,
since launch.sh is bash-only.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
DuckDuckGo Lite has become unreliable due to aggressive CAPTCHA/bot
detection on automated requests. This causes web search to silently
fail with empty results.

Replace with Exa and Parallel MCP endpoints (same approach used by
OpenCode) as the primary search backend:

- Uses JSON-RPC 2.0 MCP protocol (tools/call method)
- Traffic split 50/50 between Exa and Parallel by default
- Automatic cross-fallback (if one fails, tries the other)
- Works without API keys out of the box
- 25-second timeout per request

Provider priority chain:
  1. Brave Search API (if BRAVE_API_KEY set)
  2. Exa/Parallel MCP (primary, free, no key needed)
  3. DuckDuckGo Lite (fallback, may hit CAPTCHAs)
  4. DuckDuckGo Instant Answer (last resort)

New env vars (all optional):
  - WEBSEARCH_PROVIDER: force "exa" or "parallel"
  - EXA_API_KEY: optional key for Exa
  - PARALLEL_API_KEY: optional key for Parallel
- Add Serper.dev (Google SERP API) as fallback search provider via SERPER_API_KEY env var
- Reorder provider chain: Exa/Parallel MCP (free) → Brave → Serper → DDG Lite → DDG Instant
- Add 5-min search result cache to deduplicate identical queries across parallel agents
- Add concurrency semaphore (max 2 concurrent searches) to prevent DDG rate-limit storms
- Route all search calls through throttled wrapper (executeWebSearchThrottled)

Fixes cascading 'DDG Lite error: fetch failed' / 'All search providers failed' errors
that occur when multi-agent workflows (e.g. Workflow tool) fire many parallel web searches.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Reorder provider list to match new priority (MCP first, paid APIs as fallback)
- Add Serper.dev to provider list and config table
- Document rate-limit protection (cache + concurrency semaphore)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant