After studying this material, you should be able to:
Before diving into DSG, you need to understand why it was built.
Scenario: A user searches "450 north" on DoorDash.
| Without Grounding | With Grounding |
|---|---|
| Model guesses: restaurant | Evidence reveals: craft brewery |
| Routes to: restaurant results | Routes to: alcohol/beverage results |
Key Insight: Correct intent classification directly affects what inventory gets shown to users. Wrong classification = wrong results = poor user experience.
Grounding means giving the LLM real-world evidence (from web search or catalogs) to support its reasoning, rather than relying solely on its training data.
Native Search = The model provider (e.g., Google, Anthropic) handles search internally within their API.
Think of native search like a black box. One request goes in, one answer comes out, and you cannot see or control what happens inside.
Native Search:
[Your Agent] → [Model + Search bundled together] → [Answer]
↑
You cannot separate these
Agent A asks "What is X?" → pays for search
Agent B asks "What is X?" → pays for search again
↑
No shared cache exists
This is subtle but critical for production systems.
Instruction given to model: "Provide ONLY the final answer entity with no explanation"
| Approach | Response | Parseable? |
|---|---|---|
| Native Search | "Based on the search results, after comparing the two buildings..." (245 characters) | ❌ No |
| DSG | "Yes" (3 characters) | ✅ Yes |
Why does this happen? Native search injects results inside the generation stream, which changes how the model behaves. DSG returns evidence as a separate structured tool response, keeping generation behavior consistent.
Measured impact: On HotpotQA, Claude Sonnet 4 violated "answer only" instructions 78.1% of the time when native search was enabled.
Native Search:
[Agent] ←→ [Model + Search Provider] ← tightly coupled
DSG:
[Agent] ←→ [Reasoning Model]
↕
[DSG Gateway] ← shared, controllable layer
↕
[Serper | BrightData | Firecrawl | Exa | Tavily]
DSG separates reasoning from retrieval so either can change independently.
| Property | What It Means |
|---|---|
| MCP-compatible interface | Standard protocol all agents use to access search |
| Provider registry | Multiple search backends registered as interchangeable options |
| Shared gateway | One integration point for all agents and models |
| Normalized results | Every provider's output converted to: title + source URL + snippet |
Different providers return data in different formats. DSG converts all of them into one consistent schema:
Raw Provider Output (varies): DSG Normalized Output (always):
{result_title: "...", → {title: "...",
link: "...", url: "...",
description: "..."} snippet: "..."}
This gives the model explicit provenance (where the information came from) and gives engineers an inspectable artifact for debugging.
Every search query follows this exact sequence. Think of it as a decision tree that prioritizes cheap options first.
Query arrives
↓
1. NORMALIZE the query
(so "best pizza NYC" and "best pizza in NYC" hit same cache)
↓
2. CHECK EXACT CACHE
→ HIT? Return immediately. No provider call. Done.
→ MISS? Continue...
↓
3. CHECK SEMANTIC CACHE
(embedding similarity - finds near-duplicate queries)
→ HIT? Return cached result. Done.
→ MISS? Continue...
↓
4. WALK PROVIDER FALLBACK CHAIN
Try Provider 1 → timeout/error? → Try Provider 2 → etc.
↓
5. NORMALIZE the response
(convert to title/URL/snippet schema)
↓
6. WRITE BOTH CACHE LAYERS
(with TTL tuned to how fast this answer goes stale)
↓
7. RETURN structured tool response
(preserves output contract)
↓
8. EMIT TELEMETRY
(provider, cache outcome, latency, cost)
Design Principle: The system is built to avoid calling external providers whenever possible. External calls are the expensive last resort.
Not all information ages at the same rate:
| Query Type | Cache Duration |
|---|---|
| "What is the capital of France?" | Long TTL (stable fact) |
| "What is the current price of X?" | Short TTL (changes frequently) |
From Figure 3 and the production data:
Public Benchmarks (HotpotQA, SimpleQA, FreshQA):
Production QIU Workload:
| Dataset | Native Accuracy | DSG Accuracy | Native Cost/1K | DSG Cost/1K | Savings |
|---|---|---|---|---|---|
| Retail (N=7,988) | 93.40% | 93.90% | $7.90 | $0.110 | 98.6% |
| Long-tail (N=2,335) | 87.62% | 87.79% | $10.37 | $0.146 | 98.6% |
Critical observation: DSG slightly exceeded native search accuracy in production while costing 98%+ less. This is the headline result.
| Cache State | Hit Rate | Cost/1K Queries | Avg Latency |
|---|---|---|---|
| Cold | 6.2% | $0.7385 | 4,570 ms |
| Warm | 99.4% | $0.0045 | 1,465 ms |
Warm cache = 68% latency reduction + ~99% cost reduction on search
Compounding effect: Because the cache is shared across all agents and workloads, it warms faster than per-agent caches would. A query answered for one workload benefits all other workloads.
This is a key advantage of decoupling. You can now measure the effect of retrieval depth:
Depth 2 → 78.7% accuracy
Depth 6 → 84.9% accuracy (+6.2 points) ← good default
Depth 10 → 85.5% accuracy (+0.6 points) ← diminishing returns
Practical decision: Use depth 6 as default. Only increase to 10 when that extra 0.6% accuracy justifies the added cost and latency.
| Dimension | Native Search | DSG |
|---|---|---|
| Accuracy | Strong, especially for fresh/recent info | Near-parity; matches or exceeds in production |
| Cost | Fixed, bundled, opaque | Tunable, far lower |
| Latency | Provider-managed, opaque | Cache-optimizable |
| Repeated queries | No reuse | 99.4% warm hit rate |
| Portability | Locked to model provider | Provider-agnostic |
| Output contracts | Frequently violated | Preserved via structured tool boundary |
Does freshness matter more than cost/control?
YES → Consider native search (or register it as a DSG provider)
NO → Use DSG with appropriate provider and depth settings
Important nuance: DSG underperformed on FreshQA (recency-sensitive questions). Native search providers have indexing advantages for very recent information. The solution is to register native search as one provider option within DSG, not to abandon DSG entirely.
Knowing what a system cannot do is as important as knowing what it can.
┌─────────────────────────────────────────────────────┐
│ REASONING and RETRIEVAL evolve at different │
│ speeds. Separating them lets you: │
│ │
│ • Improve either independently │
│ • Choose quality/freshness/latency/cost balance │
│ per workload │
│ • Measure what you cannot currently see │
│ • Reuse what you currently pay for twice │
└─────────────────────────────────────────────────────┘
The 98% cost reduction was not achieved by sacrificing quality. It was achieved by: