Brief IA : Gemma 4 et Ollama : Transformer un LLM local en agent de recherche

Gemma 4 et Ollama : Transformer un LLM local en agent de recherche

Brief IA
Tom Levy·6 min·2 vues

La transformation d'un LLM local en agent de recherche est réalisée grâce à l'utilisation de Gemma 4, Ollama et OpenAI Agents SDK, qui permettent de créer un agent autonome capable d'effectuer des recherches sur le web. L'intégration de Tavily MCP ajoute des capacités de recherche, rendant cet agent capable de rassembler des informations et de synthétiser des réponses. Cette avancée est significative car elle pourrait révolutionner l'accès à l'information sans dépendre des infrastructures cloud.

En bref
1Gemma 4, Ollama et OpenAI Agents SDK permettent de créer un agent de recherche local.
2L'installation d'Ollama et Gemma 4 E4B est essentielle pour configurer l'agent.
3Tavily MCP est utilisé pour intégrer des capacités de recherche web à l'agent.
💡Pourquoi c'est importantLa création d'agents locaux autonomes pourrait révolutionner l'accès à l'information sans dépendre des infrastructures cloud.
Le brief IA que lisent les pros

Tu veux les meilleurs outils IA avant les autres ?

On teste et on décrypte les nouveaux outils IA chaque soir, en 5 min. Gratuit.

Inclus dès l'inscription : notre sélection des meilleurs guides & comparatifs IA.

Choisis ton rythme

Gratuit · Pas de spam · Désabonnement en 1 clic

📄
L'analyse en français

De LLM Local à Agent Utilisateur d'Outils

Applications LLM

L'utilisation d'un LLM local est une perspective intéressante, mais après quelques interactions, on peut se demander quelles autres fonctionnalités peuvent être ajoutées. Cet article explore la transformation d'un LLM local en un agent capable d'utiliser des outils externes. Nous allons utiliser :

  • Le modèle Gemma 4 (avec des variantes adaptées aux périphériques) comme LLM local
  • Ollama pour servir le LLM local
  • OpenAI Agents SDK pour l'exécution de l'agent
  • Tavily comme exemple d'outil externe

L'objectif est de construire un mini-agent de recherche approfondie capable de rechercher sur le web, de rassembler des preuves et de synthétiser une réponse avec des citations, en fonction d'une question utilisateur. À la fin de cet article, vous disposerez d'un agent de recherche local fonctionnel et d'un modèle d'implémentation réutilisable pour transformer un modèle local en agent IA local.

Configuration de la Pile d'Agent Local

Avant de coder, quatre éléments doivent être préparés : Ollama, Gemma 4 (en particulier le modèle Gemma 4 E4B), OpenAI Agents SDK, et Tavily MCP.

Pour commencer, installez Ollama. Sur Windows, téléchargez l'installateur depuis le site officiel d'Ollama ou utilisez winget dans PowerShell :

winget install Ollama.Ollama

Sur Linux, installez Ollama avec :

curl -fsSL https://ollama.com/install.sh | sh

Vérifiez l'installation avec :

ollama --version

Sur Windows, lancez Ollama depuis le menu Démarrer pour activer le point de terminaison API local.

Ensuite, récupérez le modèle local. Utilisez la variante Gemma 4 E4B :

ollama pull gemma4:e4b

Le modèle E4B est bien adapté pour des flux de travail d'agents locaux. Si votre machine est plus limitée, essayez la variante plus légère E2B :

ollama pull gemma4:e2b

Installez ensuite la bibliothèque d'exécution de l'agent avec OpenAI Agents SDK :

pip install openai-agents

Installez également le client compatible OpenAI :

pip install openai

Notez que le client sera pointé vers le point de terminaison local d'Ollama, donc nous n'enverrons pas de requêtes à OpenAI.

Enfin, configurez un point de terminaison Tavily MCP. Si vous ne l'avez pas utilisé auparavant, Tavily est une API de recherche pour les applications LLM. Créez un compte Tavily et obtenez une clé API. Générez un lien MCP :

https://mcp.tavily.com/mcp/?tavilyApiKey=<votre-clé-api>

Tavily est utilisé ici comme un outil MCP pratique, mais d'autres outils compatibles MCP peuvent être intégrés.

Configurer l'Agent de Recherche Local

Avec OpenAI Agents SDK, voici l'objet Agent final à composer :

from agents import Agent
name="Local Research Agent",
instructions=RESEARCH_AGENT_INSTRUCTIONS,
mcp_servers=[tavily_server],
mcp_config={"include_server_in_tool_names": True},

Le Modèle

from openai import AsyncOpenAI
from agents import OpenAIChatCompletionsModel
MODEL_NAME = "gemma4:e4b"
OLLAMA_BASE_URL = "http://localhost:11434/v1"
client = AsyncOpenAI(
api_key="ollama",
base_url=OLLAMA_BASE_URL,
model = OpenAIChatCompletionsModel(
model=MODEL_NAME,
openai_client=client,

Créez un client pointant vers le point de terminaison local compatible OpenAI d'Ollama. Utilisez OpenAIChatCompletionsModel pour envelopper le modèle Gemma dans un objet modèle, permettant au SDK des agents d'utiliser ce modèle dans la boucle de l'agent.

L'Instruction

Définissez l'instruction pour l'agent avec le comportement de recherche souhaité :

from datetime import datetime
CURRENT_DATE = datetime.now().strftime("%B %d, %Y")
RESEARCH_AGENT_INSTRUCTIONS = f"""
Vous êtes un assistant de recherche concis.
Répondez à la question de l'utilisateur en la transformant en une petite tâche de recherche sur le web.
Utilisez la date actuelle lors de l'interprétation des questions sensibles au temps : {CURRENT_DATE}.
[Comportement de recherche]
Commencez par une requête de recherche ciblée.
Pour les questions de recommandation ou de comparaison, complétez cette boucle de recherche avant de répondre :
identifiez d'abord les principales options, puis recherchez un contexte de comparaison, puis synthétisez une recommandation.
Utilisez des recherches de suivi lorsque les premiers résultats sont insuffisants, contradictoires ou ne couvrent qu'une partie de la question.
Préférez des sources pertinentes et crédibles, et suivez quelle source soutient chaque affirmation importante.
Avant de répondre, vérifiez si les preuves rassemblées suffisent à soutenir la conclusion.
[Sortie attendue]
Donnez d'abord une réponse directe, puis expliquez brièvement les preuves qui la soutiennent.
Incluez des liens vers des sources pour les affirmations factuelles clés.
Ne comptez pas sur la mémoire pour des faits qui peuvent avoir changé.
N'inventez pas de détails manquants.
Gardez la réponse concise.
"""

Équipez l'agent de l'outil de recherche web. Utilisez le moteur de recherche Tavily via MCP :

from agents import Agent, Runner
from agents.mcp import MCPServerStreamableHttp
TAVILY_MCP_URL = "VOTRE_TAVILY_MCP_URL"
async with MCPServerStreamableHttp(
params={"url": TAVILY_MCP_URL},
) as tavily_server:
tools = await tavily_server.list_tools()
print("Outils Tavily disponibles :")
for tool in tools:
description = (tool.description or "").replace("\n", " ")
print(f"- {tool.name}: {description[:120]}")
name="Local Research Agent",
instructions=RESEARCH_AGENT_INSTRUCTIONS,
mcp_servers=[tavily_server],
mcp_config={"include_server_in_tool_names": True},
result = await Runner.run(agent, RESEARCH_QUESTION, max_turns=MAX_TURNS)

Ce code effectue trois actions :

  • Il ouvre une connexion au serveur MCP de Tavily avec async with MCPServerStreamableHttp(...) as tavily_server:. Une fois connecté, Tavily expose ses outils disponibles au SDK des agents.

  • Crée l'objet Agent à l'intérieur du contexte MCP. Notez que mcp_servers=[tavily_server] attache les outils MCP de Tavily à l'agent.

  • Exécute l'agent avec result = await Runner.run(agent, RESEARCH_QUESTION, max_turns=MAX_TURNS). Le gestionnaire de contexte est crucial car la connexion MCP n'est active qu'à l'intérieur du bloc async with.

mcp_config={"include_server_in_tool_names": True} est principalement pour la lisibilité dans la trace. Sans cela, le nom de l'outil apparaîtrait uniquement comme tavily_search. Avec cela, le nom de l'outil apparaîtra comme mcp_tavily__tavily_search. Cela rend plus clair que l'appel d'outil provient du serveur MCP de Tavily.

Exécuter une Question de Recherche

Maintenant que l'agent est configuré, testons-le avec une question concrète :

« Quel match de la Coupe du Monde du 23 juin 2026 avait les enjeux les plus importants en phase de groupes, et pourquoi ? »

Pour inspecter ce qui s'est passé, imprimez une trace compacte :

def compact(value: object, limit: int = 220) -> str:
text = str(value).replace("\n", " ")
return text if len(text) <= limit else text[:limit] + "..."
for step, item in enumerate(result.new_items, start=1):
raw_item = getattr(item, "raw_item", None)
raw_type = getattr(raw_item, "type", "")
raw_name = getattr(raw_item, "name", "")
raw_output = getattr(raw_item, "output", "")
f"{step:02d} | {type(item).__name__} | "
f"{raw_type or raw_name} | {compact(raw_output or raw_item)}"

Dans ma course, la trace ressemblait à ceci :

01 | ToolCallItem | function_call | ResponseFunctionToolCall(arguments='{"query":"World Cup 2026 group stage matches June 23, 2026 stakes"}', name='mcp_tavily__tavily_search', ...)
02 | ToolCallOutputItem |  | {'call_id': ..., 'output': ...}
03 | MessageOutputItem | message | ResponseOutputMessage(... réponse finale ...)

Cela permet de voir le comportement agentique directement. Dans cette exécution, le modèle local Gemma a décidé d'appeler l'outil de recherche Tavily, le SDK des agents a exécuté cet appel d'outil et a renvoyé les résultats au modèle. Ensuite, le modèle a produit la réponse finale.

Pour voir la réponse finale, imprimez :

print(result.final_output)

L'agent a utilisé un seul tour de recherche pour arriver à cette conclusion.

Suivez Brief IA

L'actu IA du jour, aussi dans votre fil.

Commentaires