Usando a API de Web Search do Ollama em Python

Construa agentes de busca com IA usando Python e Ollama

Conteúdo da página

A biblioteca Python do Ollama agora inclui capacidades nativas de busca web 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.

digital space

Primeiros Passos

Como instalo a biblioteca Python do Ollama para busca 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 de pacotes Python rápido, ou configure um ambiente virtual usando venv para manter suas dependências isoladas.

Crie uma chave de API a partir da sua conta 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"

Busca Web Básica

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

import ollama

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

Saída:

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..."
    }
]

Controlando a Contagem de Resultados

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()

Buscando o Conteúdo Completo de Páginas

O que é web_search vs web_fetch no Python do Ollama? web_search consulta a internet e retorna vários resultados de busca 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ê precisa converter HTML para markdown em outros contextos, consulte nosso guia sobre converter HTML para Markdown com Python.

from ollama import web_fetch

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

Saída:

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']
)

Combinando Busca e Busca de Conteúdo

Um padrão comum é buscar primeiro e, em seguida, buscar o conteúdo completo de resultados relevantes:

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)}")

Construindo um Agente de Busca

Quais modelos Python funcionam melhor para agentes de busca Ollama? Modelos com fortes capacidades de uso de ferramentas funcionam melhor, incluindo qwen3, gpt-oss e modelos de nuvem como qwen3:480b-cloud e deepseek-v3.1-cloud. Para casos de uso mais avançados que exigem saídas estruturadas desses modelos, confira nosso guia sobre LLMs com Saída Estruturada usando Ollama e Qwen3. Uma vez que as ferramentas ou o modo JSON retornarem cargas de dados que você pretende confiar, a validação de saída estruturada de LLM em Python que funciona abrange a análise, verificações Pydantic, repetições e testes no lado da aplicação.

Primeiro, faça o download de um modelo capaz:

ollama pull qwen3:4b

Agente de Busca Simples

Aqui está um agente de busca básico que pode decidir autonomamente quando buscar:

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

Como lido com grandes resultados de busca web em Python? Trunque os resultados para se adequarem aos 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 Busca 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"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)

Busca Web Assíncrona

Posso usar a busca web do Python do Ollama com código assíncrono? Sim, a biblioteca Python do Ollama suporta operações assíncronas. Use AsyncClient para operações de busca e recuperação web não bloqueantes em aplicações assíncronas.

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())

Agente de Busca 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
        
        # 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)

Comprimento de Contexto e Desempenho

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

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
    }
)

Integração com Servidor MCP

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

Integração com Cline

Configure os 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
"""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()

Exemplos Práticos

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

Resumidor de Notícias

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)

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:
    # 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}")

Modelos Recomendados

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

Boas Práticas

  1. Truncar Resultados: Sempre trunque os resultados web para se adequarem aos limites de contexto (~8000 caracteres)
  2. Tratamento de Erros: Envolve as chamadas de ferramentas em try/except para falhas de rede
  3. Limitação de Taxa: Respeite os limites de taxa da API do Ollama para busca web
  4. Comprimento de Contexto: Use ~32000 tokens para agentes de busca
  5. Assíncrono para Escala: Use AsyncClient para operações simultâneas
  6. Testes: Escreva testes de unidade para seus agentes de busca para garantir a confiabilidade
  7. Fundamentos de Python: Mantenha uma folha de dicas de Python à mão para referência rápida sobre sintaxe e padrões comuns

Subscrever

Receba novos artigos sobre sistemas, infraestrutura e engenharia de IA.