Tutorial

How to Build DeepSeek Search Grounding

Ground DeepSeek model responses with live search data. Step-by-step Python tutorial for adding web search to DeepSeek-based agents.

DeepSeek models offer strong reasoning capabilities but lack built-in web search access. When users ask about current events, pricing, or recent releases, DeepSeek will either refuse to answer or hallucinate outdated information. Search grounding solves this by fetching relevant SERP data and injecting it into the prompt context before DeepSeek generates its response. This tutorial shows how to add search grounding to any DeepSeek-based agent using the Scavio API at $0.005 per search.

Prerequisites

  • Python 3.9+ installed
  • openai library installed (DeepSeek uses OpenAI-compatible API)
  • requests library installed
  • A DeepSeek API key and a Scavio API key

Walkthrough

Step 1: Set up the DeepSeek client

DeepSeek uses an OpenAI-compatible API, so you use the OpenAI Python library with a custom base URL. Set up both the DeepSeek and search clients.

Python
from openai import OpenAI
import requests, os

# DeepSeek client
deepseek = OpenAI(
    api_key=os.environ['DEEPSEEK_API_KEY'],
    base_url='https://api.deepseek.com'
)

# Search client
SCAVIO_KEY = os.environ['SCAVIO_API_KEY']

def web_search(query: str, max_results: int = 5) -> str:
    resp = requests.post('https://api.scavio.dev/api/v1/search',
        headers={'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json'},
        json={'query': query, 'country_code': 'us'})
    results = resp.json().get('organic_results', [])[:max_results]
    return '\n\n'.join(
        f'Source: {r["link"]}\nTitle: {r["title"]}\n{r.get("snippet", "")}'
        for r in results
    )

print('DeepSeek + Search grounding ready')

Step 2: Detect when grounding is needed

Not every query needs search. Build a classifier that decides based on query content whether to search or let DeepSeek answer from its training data.

Python
def needs_grounding(user_message: str) -> bool:
    grounding_signals = [
        'latest', 'current', 'today', 'now', '2025', '2026',
        'price', 'cost', 'how much', 'release', 'version',
        'news', 'update', 'recent', 'best', 'top', 'compare'
    ]
    message_lower = user_message.lower()
    return any(signal in message_lower for signal in grounding_signals)

# Test:
for q in ['explain quantum computing', 'best Python IDE 2026', 'what is recursion']:
    print(f'Ground: {needs_grounding(q):5} | {q}')

Step 3: Build the grounded DeepSeek chat function

Create the main function that optionally searches, builds the context, and calls DeepSeek with grounded or ungrounded prompts.

Python
def ask_deepseek(user_message: str, ground: bool = None) -> str:
    should_ground = ground if ground is not None else needs_grounding(user_message)
    messages = []
    if should_ground:
        search_context = web_search(user_message)
        system_prompt = f"""You are a helpful assistant with access to current web search results.
Use the search results below to provide accurate, up-to-date answers.
Cite sources with URLs when referencing specific facts.
If the search results do not contain relevant information, say so.

Search Results:
{search_context}"""
        messages.append({'role': 'system', 'content': system_prompt})
    else:
        messages.append({'role': 'system',
                        'content': 'You are a helpful assistant. Answer from your knowledge.'})
    messages.append({'role': 'user', 'content': user_message})
    response = deepseek.chat.completions.create(
        model='deepseek-chat',
        messages=messages,
        max_tokens=1000,
        temperature=0.7
    )
    return response.choices[0].message.content

# Test grounded query:
answer = ask_deepseek('What are the top Python web frameworks in 2026?')
print(answer)

Step 4: Add multi-turn conversation support

For conversations, maintain message history and only ground when the current turn needs it. Previous grounding context is already in the history.

Python
class GroundedDeepSeek:
    def __init__(self):
        self.history = []
        self.search_count = 0

    def chat(self, user_message: str) -> str:
        self.history.append({'role': 'user', 'content': user_message})
        if needs_grounding(user_message):
            context = web_search(user_message)
            self.search_count += 1
            system = f'Use these search results:\n{context}'
            messages = [{'role': 'system', 'content': system}] + self.history
        else:
            messages = self.history.copy()
        response = deepseek.chat.completions.create(
            model='deepseek-chat',
            messages=messages,
            max_tokens=1000
        )
        answer = response.choices[0].message.content
        self.history.append({'role': 'assistant', 'content': answer})
        return answer

    def cost_so_far(self) -> str:
        return f'{self.search_count} searches = ${self.search_count * 0.005:.3f}'

agent = GroundedDeepSeek()
print(agent.chat('What is the latest DeepSeek model?'))
print(f'Search cost: {agent.cost_so_far()}')

Python Example

Python
from openai import OpenAI
import os, requests

deepseek = OpenAI(api_key=os.environ['DEEPSEEK_API_KEY'], base_url='https://api.deepseek.com')
SCAVIO_KEY = os.environ['SCAVIO_API_KEY']

def search(query, k=5):
    resp = requests.post('https://api.scavio.dev/api/v1/search',
        headers={'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json'},
        json={'query': query, 'country_code': 'us'})
    return '\n'.join(f'{r["title"]}: {r.get("snippet", "")}'
        for r in resp.json().get('organic_results', [])[:k])

def ask(question):
    ctx = search(question)
    resp = deepseek.chat.completions.create(
        model='deepseek-chat',
        messages=[
            {'role': 'system', 'content': f'Use search results:\n{ctx}'},
            {'role': 'user', 'content': question}
        ], max_tokens=500)
    return resp.choices[0].message.content

print(ask('Best Python web frameworks 2026'))

JavaScript Example

JavaScript
import OpenAI from 'openai';

const deepseek = new OpenAI({
  apiKey: process.env.DEEPSEEK_API_KEY,
  baseURL: 'https://api.deepseek.com'
});
const SCAVIO_KEY = process.env.SCAVIO_API_KEY;

async function search(query) {
  const resp = await fetch('https://api.scavio.dev/api/v1/search', {
    method: 'POST',
    headers: { 'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json' },
    body: JSON.stringify({ query, country_code: 'us' })
  });
  const data = await resp.json();
  return (data.organic_results || []).slice(0, 5)
    .map(r => `${r.title}: ${r.snippet || ''}`).join('\n');
}

async function ask(question) {
  const ctx = await search(question);
  const resp = await deepseek.chat.completions.create({
    model: 'deepseek-chat',
    messages: [
      { role: 'system', content: `Search results:\n${ctx}` },
      { role: 'user', content: question }
    ], max_tokens: 500
  });
  console.log(resp.choices[0].message.content);
}

ask('Best Python frameworks 2026');

Expected Output

JSON
Ground: False | explain quantum computing
Ground:  True | best Python IDE 2026
Ground: False | what is recursion

Based on current search results, the top Python web frameworks in 2026 are:
1. FastAPI - async-first, ideal for APIs (Source: https://...)
2. Django - full-featured with built-in admin (Source: https://...)
3. Flask - lightweight and flexible (Source: https://...)

Search cost: 1 searches = $0.005

Related Tutorials

Frequently Asked Questions

Most developers complete this tutorial in 15 to 30 minutes. You will need a Scavio API key (free tier works) and a working Python or JavaScript environment.

Python 3.9+ installed. openai library installed (DeepSeek uses OpenAI-compatible API). requests library installed. A DeepSeek API key and a Scavio API key. A Scavio API key gives you 250 free credits per month.

Yes. The free tier includes 250 credits per month, which is more than enough to complete this tutorial and prototype a working solution.

Scavio has a native LangChain package (langchain-scavio), an MCP server, and a plain REST API that works with any HTTP client. This tutorial uses the raw REST API, but you can adapt to your framework of choice.

Start Building

Ground DeepSeek model responses with live search data. Step-by-step Python tutorial for adding web search to DeepSeek-based agents.