Usando a API de Pesquisa Web do Ollama em Python

Construa agentes de busca com IA com Python e Ollama

Conteúdo da página

A biblioteca Python do Ollama agora inclui capacidades nativas de pesquisa web do OLLama. Com apenas algumas linhas de código, você pode complementar 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 instalar 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 uv, um gerenciador rápido de pacotes Python, ou configure um ambiente virtual usando venv para isolar suas dependências.

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

export OLLAMA_API_KEY="your_api_key"

No PowerShell do Windows:

$env:OLLAMA_API_KEY = "your_api_key"

Pesquisa Básica na Web

A forma 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 estão agora 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 do Discord. .."
    }
]

Controlando o Número de Resultados

import ollama

# Obter mais resultados
response = ollama.web_search("notícias mais 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()

Recuperando 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 vários 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 os links. O conteúdo em markdown retornado por web_fetch é perfeito para processamento adicional — se você precisar converter HTML em 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) estão agora disponíveis no Ollama\n\n**Converse e construa com modelos abertos**\n\n[Baixe](https://ollama.com/download) [Explore 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 Recuperação

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

from ollama import web_search, web_fetch

# Pesquisar por informações
search_results = web_search("novas funcionalidades do Ollama 2025")

# Recuperar 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 capacidades fortes 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 exigem saídas estruturadas desses modelos, consulte nosso guia sobre LLMs com Saída Estruturada usando Ollama e Qwen3.

Primeiro, puxe 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 motor 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 limites de contexto
                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 resultados de pesquisa web grandes no Python? Truncar resultados para caber nos limites de contexto. A abordagem recomendada é cortar a string do resultado para aproximadamente 8000 caracteres (2000 tokens × 4 caracteres) antes de passá-la 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 a conversa: {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 "Iterações máximas atingidas 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 da ferramenta: {e}"

# Uso
agent = SearchAgent(model='qwen3:4b')
answer = agent.query("Quais são as novas funcionalidades 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 pesquisas e recuperações web não bloqueantes em aplicações assíncronas. Para comparações de desempenho entre Python e outras linguagens em contextos sem servidor, veja nossa análise sobre desempenho do AWS Lambda entre JavaScript, Python e Golang.

import asyncio
from ollama import AsyncClient

async def async_search():
    client = AsyncClient()
    
    # Realizar várias pesquisas simultaneamente
    tasks = [
        client.web_search("funcionalidades do Ollama"),
        client.web_search("ferramentas de LLM locais"),
        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 simultaneamente
        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 é novo no Python 3.13?"))
print(answer)

Comprimento do Contexto e Desempenho

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

from ollama import chat, web_search

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

Integração com o Servidor MCP

O Ollama fornece um servidor MCP em Python que permite a pesquisa web em qualquer cliente MCP. Para um guia abrangente sobre como construir servidores MCP em Python com capacidades de pesquisa e raspagem web, veja nosso tutorial detalhado sobre Construção de 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": "your_api_key_here" }
    }
  }
}

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" = "your_api_key_here" }

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

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

Exemplos Práticos

Esses exemplos demonstram aplicações reais 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.

Sumarizador de Notícias

from ollama import chat, web_search

def summarize_news(topic: str) -> str:
    # Pesquisar por notícias recentes
    results = web_search(f"{topic} últimas notícias", 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
    ])
    
    # Perguntar ao modelo para resumir
    response = chat(
        model='qwen3:4b',
        messages=[{
            'role': 'user',
            'content': f"Resuma esses 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 por informações relevantes
    search_results = web_search(question, max_results=3)
    
    # Recuperar conteúdo completo de fontes principais
    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 essa 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 longa (nuvem)
deepseek-v3.1-cloud - Análise avançada (nuvem)

Boas Práticas

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