Usando a API de Pesquisa Web do Ollama em Python

Construa agentes de busca de IA com Python e Ollama

Conteúdo da página

A biblioteca Python do Ollama agora inclui capacidades nativas de busca web do OLlama. Com apenas algumas linhas de código, você pode aprimorar seus LLMs locais com informações em tempo real da web, reduzindo alucinações e melhorando a precisão.

espaço digital

Começando

Como instalo a biblioteca Python do Ollama para pesquisa web? Instale a versão 0.6.0 ou superior usando pip install 'ollama>=0.6.0'. Esta versão inclui as funções web_search e web_fetch.

pip install 'ollama>=0.6.0'

Para gerenciar ambientes e pacotes Python, considere usar o uv, um gerenciador de pacotes Python rápido, ou configure um ambiente virtual usando venv para manter suas dependências isoladas.

Crie uma chave de API na sua conta Ollama e defina-a como uma variável de ambiente:

export OLLAMA_API_KEY="sua_chave_api"

No Windows PowerShell:

$env:OLLAMA_API_KEY = "sua_chave_api"

Pesquisa Web Básica

A maneira mais simples de pesquisar na web com o Ollama:

import ollama

# Pesquisa web simples
response = ollama.web_search("O que é Ollama?")
print(response)

Saída:

results = [
    {
        "title": "Ollama",
        "url": "https://ollama.com/",
        "content": "Modelos em nuvem agora estão disponíveis no Ollama..."
    },
    {
        "title": "O que é Ollama? Recursos, Preços e Casos de Uso",
        "url": "https://www.walturn.com/insights/what-is-ollama",
        "content": "Nossos serviços..."
    },
    {
        "title": "Guia Completo do Ollama: Instalação, Uso e Exemplos de Código",
        "url": "https://collabnix.com/complete-ollama-guide",
        "content": "Junte-se ao nosso servidor Discord..."
    }
]

Controlando a Quantidade de Resultados

import ollama

# Obter mais resultados
response = ollama.web_search("notícias recentes de IA", max_results=10)

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

Buscando o Conteúdo Completo da Página

Qual a diferença entre web_search e web_fetch no Python do Ollama? web_search consulta a internet e retorna múltiplos resultados de pesquisa com títulos, URLs e trechos. web_fetch recupera o conteúdo completo de uma URL específica, retornando o título da página, o conteúdo em markdown e links. O conteúdo em markdown retornado por web_fetch é perfeito para processamento adicional — se você precisar converter HTML para markdown em outros contextos, veja nosso guia sobre conversão de HTML para Markdown com Python.

from ollama import web_fetch

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

Saída:

WebFetchResponse(
    title='Ollama',
    content='[Modelos em nuvem](https://ollama.com/blog/cloud-models) agora estão disponíveis no Ollama\n\n**Converse e construa com modelos abertos**\n\n[Baixar](https://ollama.com/download) [Explorar modelos](https://ollama.com/models)\n\nDisponível para macOS, Windows e Linux',
    links=['https://ollama.com/', 'https://ollama.com/models', 'https://github.com/ollama/ollama']
)

Combinando Pesquisa e Busca

Um padrão comum é pesquisar primeiro e depois buscar o conteúdo completo dos resultados relevantes:

from ollama import web_search, web_fetch

# Pesquisar informações
search_results = web_search("novos recursos do Ollama 2025")

# Buscar conteúdo completo do primeiro resultado
if search_results.results:
    first_url = search_results.results[0].url
    full_content = web_fetch(first_url)
    
    print(f"Título: {full_content.title}")
    print(f"Conteúdo: {full_content.content[:500]}...")
    print(f"Links encontrados: {len(full_content.links)}")

Construindo um Agente de Pesquisa

Quais modelos Python funcionam melhor para agentes de pesquisa do Ollama? Modelos com fortes capacidades de uso de ferramentas funcionam melhor, incluindo qwen3, gpt-oss e modelos em nuvem como qwen3:480b-cloud e deepseek-v3.1-cloud. Para casos de uso mais avançados que requerem saídas estruturadas desses modelos, confira nosso guia sobre LLMs com Saída Estruturada usando Ollama e Qwen3.

Primeiro, baixe um modelo capaz:

ollama pull qwen3:4b

Agente de Pesquisa Simples

Aqui está um agente de pesquisa básico que pode decidir autonomamente quando pesquisar:

from ollama import chat, web_fetch, web_search

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

messages = [{'role': 'user', 'content': "qual é o novo mecanismo do ollama"}]

while True:
    response = chat(
        model='qwen3:4b',
        messages=messages,
        tools=[web_search, web_fetch],
        think=True
    )
    
    if response.message.thinking:
        print('🧠 Pensando:', response.message.thinking[:200], '...')
    
    if response.message.content:
        print('💬 Resposta:', response.message.content)
    
    messages.append(response.message)
    
    if response.message.tool_calls:
        print('🔧 Chamadas de ferramenta:', 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('📥 Resultado:', str(result)[:200], '...')
                # Truncar resultado para comprimentos de contexto limitados
                messages.append({
                    'role': 'tool', 
                    'content': str(result)[:2000 * 4], 
                    'tool_name': tool_call.function.name
                })
            else:
                messages.append({
                    'role': 'tool', 
                    'content': f'Ferramenta {tool_call.function.name} não encontrada', 
                    'tool_name': tool_call.function.name
                })
    else:
        break

Como lidar com grandes resultados de pesquisa web em Python? Trunque os resultados para caber nos limites de contexto. A abordagem recomendada é fatiar a string do resultado para aproximadamente 8000 caracteres (2000 tokens × 4 caracteres) antes de passar para o modelo.

Agente de Pesquisa Avançado com Tratamento de Erros

Aqui está uma versão aprimorada com melhor tratamento de erros:

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"Erro durante o chat: {e}"
            
            self.messages.append(response.message)
            
            # Se não houver chamadas de ferramenta, temos uma resposta final
            if not response.message.tool_calls:
                return response.message.content or "Nenhuma resposta gerada"
            
            # Executar chamadas de ferramenta
            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 "Máximo de iterações atingido sem resposta final"
    
    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"Ferramenta desconhecida: {func_name}"
        
        try:
            result = self.tools[func_name](**args)
            # Truncar para limites de contexto
            result_str = str(result)
            if len(result_str) > 8000:
                result_str = result_str[:8000] + "... [truncado]"
            return result_str
        except Exception as e:
            return f"Erro na ferramenta: {e}"

# Uso
agent = SearchAgent(model='qwen3:4b')
answer = agent.query("Quais são os recursos mais recentes do Ollama?")
print(answer)

Pesquisa Web Assíncrona

Posso usar a pesquisa web do Ollama Python com código assíncrono? Sim, a biblioteca Python do Ollama suporta operações assíncronas. Use AsyncClient para pesquisa e busca web sem bloqueio em aplicações assíncronas. Para comparações de desempenho entre Python e outras linguagens em contextos serverless, veja nossa análise de desempenho AWS Lambda em JavaScript, Python e Golang.

import asyncio
from ollama import AsyncClient

async def async_search():
    client = AsyncClient()
    
    # Realizar múltiplas pesquisas concorrentemente
    tasks = [
        client.web_search("recursos do Ollama"),
        client.web_search("ferramentas de LLM local"),
        client.web_search("agentes de pesquisa de IA"),
    ]
    
    results = await asyncio.gather(*tasks)
    
    for i, result in enumerate(results):
        print(f"Pesquisa {i + 1}:")
        for r in result.results[:2]:
            print(f"  - {r.title}")
        print()

# Executar pesquisa assíncrona
asyncio.run(async_search())

Agente de Pesquisa Assíncrono

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
        
        # Executar chamadas de ferramenta concorrentemente
        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))
        
        # Coletar resultados
        for tool_name, task in tool_tasks:
            result = await task
            messages.append({
                'role': 'tool',
                'content': str(result)[:8000],
                'tool_name': tool_name
            })

# Executar
answer = asyncio.run(async_research_agent("O que há de novo no Python 3.13?"))
print(answer)

Comprimento de Contexto e Desempenho

Qual comprimento de contexto devo definir para agentes de pesquisa Python? Defina o comprimento de contexto para aproximadamente 32000 tokens para um desempenho razoável. Agentes de pesquisa funcionam melhor com comprimento de contexto completo, pois web_search e web_fetch podem retornar milhares de tokens.

from ollama import chat, web_search

# Definir contexto maior para tarefas pesadas em pesquisa
response = chat(
    model='qwen3:4b',
    messages=[{'role': 'user', 'content': 'Pesquise os últimos desenvolvimentos em IA'}],
    tools=[web_search],
    options={
        'num_ctx': 32768,  # Contexto de 32K
    }
)

Integração com Servidor MCP

O Ollama fornece um servidor MCP Python que permite pesquisa web em qualquer cliente MCP. Para um guia abrangente sobre a construção de servidores MCP em Python com capacidades de pesquisa e raspagem web, veja nosso tutorial detalhado sobre Construindo Servidores MCP em Python.

Integração com Cline

Configure servidores MCP nas configurações do Cline:

Gerenciar Servidores MCP → Configurar Servidores MCP → Adicionar:

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

Integração com Codex

Adicione a ~/.codex/config.toml:

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

Criando Seu Próprio Servidor MCP

#!/usr/bin/env python3
"""Servidor MCP simples para pesquisa web do Ollama."""

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:
    """Pesquisar informações na web."""
    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:
    """Buscar o conteúdo completo de uma página web."""
    result = web_fetch(url)
    return f"# {result.title}\n\n{result.content}"

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

Exemplos Práticos

Estes exemplos demonstram aplicações do mundo real da API de pesquisa web do Ollama. Você pode estender esses padrões para construir sistemas mais complexos — por exemplo, combinando resultados de pesquisa com geração de PDF em Python para criar relatórios de pesquisa.

Resumo de Notícias

from ollama import chat, web_search

def summarize_news(topic: str) -> str:
    # Pesquisar notícias recentes
    results = web_search(f"notícias recentes sobre {topic}", max_results=5)
    
    # Formatar resultados de pesquisa para o modelo
    news_content = "\n\n".join([
        f"**{r.title}**\n{r.content}"
        for r in results.results
    ])
    
    # Pedir ao modelo para resumir
    response = chat(
        model='qwen3:4b',
        messages=[{
            'role': 'user',
            'content': f"Resuma estes itens de notícias sobre {topic}:\n\n{news_content}"
        }]
    )
    
    return response.message.content

summary = summarize_news("inteligência artificial")
print(summary)

Assistente de Pesquisa

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:
    # Pesquisar informações relevantes
    search_results = web_search(question, max_results=3)
    
    # Buscar conteúdo completo das principais fontes
    sources = []
    full_content = []
    
    for result in search_results.results[:3]:
        try:
            page = web_fetch(result.url)
            sources.append(result.url)
            full_content.append(f"Fonte: {result.url}\n{page.content[:2000]}")
        except:
            continue
    
    # Gerar resposta abrangente
    context = "\n\n---\n\n".join(full_content)
    
    response = chat(
        model='qwen3:4b',
        messages=[{
            'role': 'user',
            'content': f"""Com base nas seguintes fontes, responda a esta pergunta: {question}

Fontes:
{context}

Forneça uma resposta abrangente com citações das fontes."""
        }]
    )
    
    return ResearchResult(
        question=question,
        sources=sources,
        answer=response.message.content
    )

# Uso
result = research("Como funciona o novo agendamento de modelos do Ollama?")
print(f"Pergunta: {result.question}")
print(f"Fontes: {result.sources}")
print(f"Resposta: {result.answer}")

Modelos Recomendados

Modelo Parâmetros Melhor Para
qwen3:4b 4B Pesquisas locais rápidas
qwen3 8B Agente de propósito geral
gpt-oss Vários Tarefas de pesquisa
qwen3:480b-cloud 480B Raciocínio complexo (nuvem)
gpt-oss:120b-cloud 120B Pesquisa de longa forma (nuvem)
deepseek-v3.1-cloud - Análise avançada (nuvem)

Melhores Práticas

  1. Truncar Resultados: Sempre trunque os resultados web para caber nos limites de contexto (~8000 caracteres)
  2. Tratamento de Erros: Envolver chamadas de ferramenta em try/except para falhas de rede
  3. Limitação de Taxa: Respeitar os limites de taxa de API do Ollama para pesquisa web
  4. Comprimento de Contexto: Usar ~32000 tokens para agentes de pesquisa
  5. Assíncrono para Escala: Usar AsyncClient para operações concorrentes
  6. Testes: Escreva testes unitários para seus agentes de pesquisa para garantir confiabilidade
  7. Básicos do Python: Mantenha uma lista de atalhos Python à mão para referência rápida de sintaxe e padrões comuns