Utilisation de l'API Web Search d'Ollama en Python

Créer des agents de recherche IA avec Python et Ollama

Sommaire

La bibliothèque Python d’Ollama intègre désormais des fonctionnalités natives de recherche web Ollama. Avec seulement quelques lignes de code, vous pouvez enrichir vos LLM locaux avec des informations en temps réel provenant du web, réduisant ainsi les hallucinations et améliorant la précision.

digital space

Démarrage rapide

Comment installer la bibliothèque Python d’Ollama pour la recherche web ? Installez la version 0.6.0 ou ultérieure en utilisant pip install 'ollama>=0.6.0'. Cette version inclut les fonctions web_search et web_fetch.

pip install 'ollama>=0.6.0'

Pour la gestion des environnements et des paquets Python, envisagez d’utiliser uv, un gestionnaire de paquets Python rapide, ou de configurer un environnement virtuel en utilisant venv pour isoler vos dépendances.

Créez une clé API depuis votre compte Ollama et définissez-la comme variable d’environnement :

export OLLAMA_API_KEY="your_api_key"

Sous Windows PowerShell :

$env:OLLAMA_API_KEY = "your_api_key"

Recherche web de base

La manière la plus simple de rechercher sur le web avec Ollama :

import ollama

# Simple web search
response = ollama.web_search("What is Ollama?")
print(response)

Sortie :

results = [
    {
        "title": "Ollama",
        "url": "https://ollama.com/",
        "content": "Cloud models are now available in Ollama..."
    },
    {
        "title": "What is Ollama? Features, Pricing, and Use Cases",
        "url": "https://www.walturn.com/insights/what-is-ollama",
        "content": "Our services..."
    },
    {
        "title": "Complete Ollama Guide: Installation, Usage & Code Examples",
        "url": "https://collabnix.com/complete-ollama-guide",
        "content": "Join our Discord Server..."
    }
]

Contrôle du nombre de résultats

import ollama

# Get more results
response = ollama.web_search("latest AI news", max_results=10)

for result in response.results:
    print(f"📌 {result.title}")
    print(f"   {result.url}")
    print(f"   {result.content[:100]}...")
    print()

Récupération du contenu complet d’une page

Quelle est la différence entre web_search et web_fetch dans Ollama Python ? web_search interroge Internet et retourne plusieurs résultats de recherche avec titres, URL et extraits. web_fetch récupère le contenu complet d’une URL spécifique, en retournant le titre de la page, le contenu au format markdown et les liens. Le contenu markdown retourné par web_fetch est parfait pour un traitement ultérieur — si vous avez besoin de convertir du HTML en markdown dans d’autres contextes, consultez notre guide sur la conversion de HTML en Markdown avec Python.

from ollama import web_fetch

result = web_fetch('https://ollama.com')
print(result)

Sortie :

WebFetchResponse(
    title='Ollama',
    content='[Cloud models](https://ollama.com/blog/cloud-models) are now available in Ollama\n\n**Chat & build with open models**\n\n[Download](https://ollama.com/download) [Explore models](https://ollama.com/models)\n\nAvailable for macOS, Windows, and Linux',
    links=['https://ollama.com/', 'https://ollama.com/models', 'https://github.com/ollama/ollama']
)

Combiner recherche et récupération

Un motif courant consiste à rechercher d’abord, puis à récupérer le contenu complet des résultats pertinents :

from ollama import web_search, web_fetch

# Search for information
search_results = web_search("Ollama new features 2025")

# Fetch full content from the first result
if search_results.results:
    first_url = search_results.results[0].url
    full_content = web_fetch(first_url)
    
    print(f"Title: {full_content.title}")
    print(f"Content: {full_content.content[:500]}...")
    print(f"Links found: {len(full_content.links)}")

Création d’un agent de recherche

Quels modèles Python fonctionnent le mieux avec les agents de recherche Ollama ? Les modèles avec de fortes capacités d’utilisation d’outils fonctionnent le mieux, y compris qwen3, gpt-oss, et des modèles cloud comme qwen3:480b-cloud et deepseek-v3.1-cloud. Pour des cas d’usage plus avancés nécessitant des sorties structurées de ces modèles, consultez notre guide sur les LLM avec sortie structurée utilisant Ollama et Qwen3. Une fois que les outils ou le mode JSON retournent des charges utiles que vous souhaitez faire confiance, la validation de la sortie structurée des LLM en Python qui tient la route couvre l’analyse, les vérifications Pydantic, les nouvelles tentatives et les tests côté application.

Tout d’abord, tirez un modèle capable :

ollama pull qwen3:4b

Agent de recherche simple

Voici un agent de recherche de base capable de décider autonomiquement quand effectuer une recherche :

from ollama import chat, web_fetch, web_search

available_tools = {'web_search': web_search, 'web_fetch': web_fetch}

messages = [{'role': 'user', 'content': "what is ollama's new engine"}]

while True:
    response = chat(
        model='qwen3:4b',
        messages=messages,
        tools=[web_search, web_fetch],
        think=True
    )
    
    if response.message.thinking:
        print('🧠 Thinking:', response.message.thinking[:200], '...')
    
    if response.message.content:
        print('💬 Response:', response.message.content)
    
    messages.append(response.message)
    
    if response.message.tool_calls:
        print('🔧 Tool calls:', response.message.tool_calls)
        for tool_call in response.message.tool_calls:
            function_to_call = available_tools.get(tool_call.function.name)
            if function_to_call:
                args = tool_call.function.arguments
                result = function_to_call(**args)
                print('📥 Result:', str(result)[:200], '...')
                # Truncate result for limited context lengths
                messages.append({
                    'role': 'tool', 
                    'content': str(result)[:2000 * 4], 
                    'tool_name': tool_call.function.name
                })
            else:
                messages.append({
                    'role': 'tool', 
                    'content': f'Tool {tool_call.function.name} not found', 
                    'tool_name': tool_call.function.name
                })
    else:
        break

Comment gérer de grands résultats de recherche web en Python ? Tronquez les résultats pour qu’ils s’adaptent aux limites de contexte. L’approche recommandée consiste à extraire une partie de la chaîne de résultat pour obtenir environ 8000 caractères (2000 jetons × 4 caractères) avant de la transmettre au modèle.

Agent de recherche avancé avec gestion des erreurs

Voici une version améliorée avec une meilleure gestion des erreurs :

from ollama import chat, web_fetch, web_search
import json

class SearchAgent:
    def __init__(self, model: str = 'qwen3:4b'):
        self.model = model
        self.tools = {'web_search': web_search, 'web_fetch': web_fetch}
        self.messages = []
        self.max_iterations = 10
        
    def query(self, question: str) -> str:
        self.messages = [{'role': 'user', 'content': question}]
        
        for iteration in range(self.max_iterations):
            try:
                response = chat(
                    model=self.model,
                    messages=self.messages,
                    tools=[web_search, web_fetch],
                    think=True
                )
            except Exception as e:
                return f"Error during chat: {e}"
            
            self.messages.append(response.message)
            
            # If no tool calls, we have a final answer
            if not response.message.tool_calls:
                return response.message.content or "No response generated"
            
            # Execute tool calls
            for tool_call in response.message.tool_calls:
                result = self._execute_tool(tool_call)
                self.messages.append({
                    'role': 'tool',
                    'content': result,
                    'tool_name': tool_call.function.name
                })
        
        return "Max iterations reached without final answer"
    
    def _execute_tool(self, tool_call) -> str:
        func_name = tool_call.function.name
        args = tool_call.function.arguments
        
        if func_name not in self.tools:
            return f"Unknown tool: {func_name}"
        
        try:
            result = self.tools[func_name](**args)
            # Truncate for context limits
            result_str = str(result)
            if len(result_str) > 8000:
                result_str = result_str[:8000] + "... [truncated]"
            return result_str
        except Exception as e:
            return f"Tool error: {e}"

# Usage
agent = SearchAgent(model='qwen3:4b')
answer = agent.query("What are the latest features in Ollama?")
print(answer)

Recherche web asynchrone

Puis-je utiliser la recherche web Python d’Ollama avec du code asynchrone ? Oui, la bibliothèque Python d’Ollama prend en charge les opérations asynchrones. Utilisez AsyncClient pour les opérations de recherche et de récupération web non bloquantes dans les applications asynchrones.

import asyncio
from ollama import AsyncClient

async def async_search():
    client = AsyncClient()
    
    # Perform multiple searches concurrently
    tasks = [
        client.web_search("Ollama features"),
        client.web_search("local LLM tools"),
        client.web_search("AI search agents"),
    ]
    
    results = await asyncio.gather(*tasks)
    
    for i, result in enumerate(results):
        print(f"Search {i + 1}:")
        for r in result.results[:2]:
            print(f"  - {r.title}")
        print()

# Run async search
asyncio.run(async_search())

Agent de recherche asynchrone

import asyncio
from ollama import AsyncClient

async def async_research_agent(question: str):
    client = AsyncClient()
    messages = [{'role': 'user', 'content': question}]
    
    while True:
        response = await client.chat(
            model='qwen3:4b',
            messages=messages,
            tools=[client.web_search, client.web_fetch],
        )
        
        messages.append(response.message)
        
        if not response.message.tool_calls:
            return response.message.content
        
        # Execute tool calls concurrently
        tool_tasks = []
        for tool_call in response.message.tool_calls:
            if tool_call.function.name == 'web_search':
                task = client.web_search(**tool_call.function.arguments)
            elif tool_call.function.name == 'web_fetch':
                task = client.web_fetch(**tool_call.function.arguments)
            else:
                continue
            tool_tasks.append((tool_call.function.name, task))
        
        # Gather results
        for tool_name, task in tool_tasks:
            result = await task
            messages.append({
                'role': 'tool',
                'content': str(result)[:8000],
                'tool_name': tool_name
            })

# Run
answer = asyncio.run(async_research_agent("What's new in Python 3.13?"))
print(answer)

Longueur du contexte et performances

Quelle longueur de contexte dois-je définir pour les agents de recherche Python ? Définissez la longueur du contexte à environ 32000 jetons pour des performances raisonnables. Les agents de recherche fonctionnent le mieux avec une longueur de contexte complète, car web_search et web_fetch peuvent retourner des milliers de jetons.

from ollama import chat, web_search

# Set higher context for search-heavy tasks
response = chat(
    model='qwen3:4b',
    messages=[{'role': 'user', 'content': 'Research the latest AI developments'}],
    tools=[web_search],
    options={
        'num_ctx': 32768,  # 32K context
    }
)

Intégration du serveur MCP

Ollama fournit un serveur MCP Python qui permet la recherche web dans n’importe quel client MCP. Pour un guide complet sur la création de serveurs MCP en Python avec des capacités de recherche et de scraping web, consultez notre tutoriel détaillé sur la Création de serveurs MCP en Python.

Intégration Cline

Configurez les serveurs MCP dans les paramètres de Cline :

Gérer les serveurs MCP → Configurer les serveurs MCP → Ajouter :

{
  "mcpServers": {
    "web_search_and_fetch": {
      "type": "stdio",
      "command": "uv",
      "args": ["run", "path/to/web-search-mcp.py"],
      "env": { "OLLAMA_API_KEY": "your_api_key_here" }
    }
  }
}

Intégration Codex

Ajoutez à ~/.codex/config.toml :

[mcp_servers.web_search]
command = "uv"
args = ["run", "path/to/web-search-mcp.py"]
env = { "OLLAMA_API_KEY" = "your_api_key_here" }

Création de votre propre serveur MCP

#!/usr/bin/env python3
"""Simple MCP server for Ollama web search."""

import os
from mcp.server import Server
from mcp.types import Tool, TextContent
from ollama import web_search, web_fetch

app = Server("ollama-web-search")

@app.tool()
async def search_web(query: str, max_results: int = 5) -> str:
    """Search the web for information."""
    results = web_search(query, max_results=max_results)
    
    output = []
    for r in results.results:
        output.append(f"**{r.title}**\n{r.url}\n{r.content}\n")
    
    return "\n---\n".join(output)

@app.tool()
async def fetch_page(url: str) -> str:
    """Fetch the full content of a web page."""
    result = web_fetch(url)
    return f"# {result.title}\n\n{result.content}"

if __name__ == "__main__":
    app.run()

Exemples pratiques

Ces exemples démontrent des applications réelles de l’API de recherche web d’Ollama. Vous pouvez étendre ces motifs pour construire des systèmes plus complexes — par exemple, en combinant les résultats de recherche avec la génération de PDF en Python pour créer des rapports de recherche.

Résumé d’actualités

from ollama import chat, web_search

def summarize_news(topic: str) -> str:
    # Search for recent news
    results = web_search(f"{topic} latest news", max_results=5)
    
    # Format search results for the model
    news_content = "\n\n".join([
        f"**{r.title}**\n{r.content}"
        for r in results.results
    ])
    
    # Ask the model to summarize
    response = chat(
        model='qwen3:4b',
        messages=[{
            'role': 'user',
            'content': f"Summarize these news items about {topic}:\n\n{news_content}"
        }]
    )
    
    return response.message.content

summary = summarize_news("artificial intelligence")
print(summary)

Assistant de recherche

from ollama import chat, web_search, web_fetch
from dataclasses import dataclass

@dataclass
class ResearchResult:
    question: str
    sources: list
    answer: str

def research(question: str) -> ResearchResult:
    # Search for relevant information
    search_results = web_search(question, max_results=3)
    
    # Fetch full content from top sources
    sources = []
    full_content = []
    
    for result in search_results.results[:3]:
        try:
            page = web_fetch(result.url)
            sources.append(result.url)
            full_content.append(f"Source: {result.url}\n{page.content[:2000]}")
        except:
            continue
    
    # Generate comprehensive answer
    context = "\n\n---\n\n".join(full_content)
    
    response = chat(
        model='qwen3:4b',
        messages=[{
            'role': 'user',
            'content': f"""Based on the following sources, answer this question: {question}

Sources:
{context}

Provide a comprehensive answer with citations to the sources."""
        }]
    )
    
    return ResearchResult(
        question=question,
        sources=sources,
        answer=response.message.content
    )

# Usage
result = research("How does Ollama's new model scheduling work?")
print(f"Question: {result.question}")
print(f"Sources: {result.sources}")
print(f"Answer: {result.answer}")

Modèles recommandés

Modèle Paramètres Idéal pour
qwen3:4b 4B Recherches locales rapides
qwen3 8B Agent polyvalent
gpt-oss Divers Tâches de recherche
qwen3:480b-cloud 480B Raisonnement complexe (cloud)
gpt-oss:120b-cloud 120B Recherche longue (cloud)
deepseek-v3.1-cloud - Analyse avancée (cloud)

Bonnes pratiques

  1. Tronquer les résultats : Tronquez toujours les résultats web pour qu’ils s’adaptent aux limites de contexte (environ 8000 caractères)
  2. Gestion des erreurs : Enveloppez les appels d’outils dans des blocs try/except pour les pannes réseau
  3. Limitation de débit : Respectez les limites de débit de l’API Ollama pour la recherche web
  4. Longueur du contexte : Utilisez environ 32000 jetons pour les agents de recherche
  5. Asynchrone pour l’échelle : Utilisez AsyncClient pour les opérations concurrentes
  6. Tests : Écrivez des tests unitaires pour vos agents de recherche afin d’assurer la fiabilité
  7. Bases de Python : Gardez sous la main une aide-mémoire Python pour une référence rapide sur la syntaxe et les motifs courants

Liens utiles

S'abonner

Recevez de nouveaux articles sur les systèmes, l'infrastructure et l'ingénierie IA.