Les modèles DeepSeek offrent de solides capacités de raisonnement mais ne disposent pas d'un accès intégré à la recherche web. Lorsque les utilisateurs posent des questions sur l'actualité, les prix ou les versions récentes, DeepSeek refuse soit de répondre, soit invente des informations obsolètes. Le grounding de recherche résout cela en récupérant les données SERP pertinentes et en les injectant dans le contexte de la requête avant que DeepSeek génère sa réponse. Ce tutoriel montre comment ajouter le grounding de recherche à tout agent basé sur DeepSeek en utilisant l'API Scavio à 0,005 $ par recherche.
Prérequis
- Python 3.9+ installé
- bibliothèque openai installée (DeepSeek utilise une API compatible OpenAI)
- bibliothèque requests installée
- Une clé API DeepSeek et une clé API Scavio
Parcours
Étape 1: Configurer le client DeepSeek
DeepSeek utilise une API compatible OpenAI, vous utilisez donc la bibliothèque Python OpenAI avec une URL de base personnalisée. Configurez à la fois les clients DeepSeek et de recherche.
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')Étape 2: Détecter quand le grounding est nécessaire
Toutes les requêtes n'ont pas besoin de recherche. Construisez un classifieur qui décide en fonction du contenu de la requête s'il faut rechercher ou laisser DeepSeek répondre à partir de ses données d'entraînement.
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}')Étape 3: Construire la fonction de chat DeepSeek avec grounding
Créez la fonction principale qui recherche optionnellement, construit le contexte et appelle DeepSeek avec des prompts groundés ou non.
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)Étape 4: Ajouter le support des conversations multi-tours
Pour les conversations, conservez l'historique des messages et ne faites le grounding que lorsque le tour actuel en a besoin. Le contexte de grounding précédent est déjà dans l'historique.
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()}')Exemple 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'))Exemple 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');Sortie attendue
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