🎯 Um navegador em nuvem personalizável e anti-detecção alimentado por Chromium desenvolvido internamente, projetado para rastreadores web e agentes de IA. 👉Experimente agora
De volta ao blog

CrewAI + Scrapeless: Execute uma Equipe de Coleta Multi-Agent com um LLM Local.

Ethan Brown
Ethan Brown

Advanced Bot Mitigation Engineer

30-Jul-2026

TL;DR:

  • Este é um verdadeiro fluxo de trabalho multi-agente. Três agentes CrewAI acessam uma página ao vivo, extraem registros estruturados e validam o resultado por meio de uma transferência de tarefas sequencial.
  • Somente o coletor tem acesso à web. O Coletor de Página da Web recebe a ferramenta scrape_markdown do Scrapeless MCP; o extractor e o validador trabalham apenas com os resultados das tarefas anteriores.
  • O LLM roda localmente. Todos os três agentes usam qwen2.5:0.5b através do Ollama, de modo que o fluxo de trabalho não requer uma chave de API LLM em nuvem.
  • A execução bem-sucedida não prova a extração correta. crew.kickoff() foi concluído, mas a saída da validação capturada se contradisse e teve que ser rejeitada.
  • A validação em produção deve ser determinística. Analise a saída do modelo em Python, valide os campos necessários e compare os valores extraídos com a resposta original do MCP.
  • Gratuito para começar. Novas contas do Scrapeless incluem tempo de execução gratuito do Navegador de Scraping — inscreva-se em app.scrapeless.com.

Introdução: Uma Equipe Completa Não É Necessariamente um Pipeline Confiável

Um Agente CrewAI conectado a uma ferramenta Scrapeless MCP já pode acessar uma página ao vivo. Uma equipe CrewAI é uma reivindicação diferente: dois ou mais agentes com responsabilidades separadas devem passar o trabalho uns para os outros e terminar com crew.kickoff() retornando um resultado.

Este guia constrói esse segundo fluxo de trabalho.

Você criará uma equipe de três agentes que:

  1. Acessa uma página ao vivo através do Servidor MCP Scrapeless.
  2. Extrai registros de citação estruturados do Markdown retornado.
  3. Valida esses registros antes que eles deixem o fluxo de trabalho.

Todos os três agentes rodam em um modelo local do Ollama. Nenhuma chave de API da OpenAI, Anthropic ou de outro LLM em nuvem é necessária. A única credencial externa é a chave da API Scrapeless utilizada pela ferramenta MCP.

A integração é completada com sucesso. No entanto, a resposta final capturada é internamente inconsistente. Essa distinção é a lição mais importante deste tutorial: um fluxo de trabalho de agente concluído é evidência de execução, não evidência de que os dados resultantes são confiáveis.

O Que Você Pode Fazer com Esta Equipe

O fluxo de trabalho atribui uma responsabilidade a cada agente:

  • Coletor de Página da Web: Chama a ferramenta scrape_markdown do Scrapeless MCP contra uma URL ao vivo e retorna o conteúdo da página.
  • Especialista em Extração de Dados: Lê o Markdown coletado e o converte em uma matriz JSON.
  • Validador de QA: Verifica os registros extraídos em busca de campos ausentes e relata o resultado.

O CrewAI passa as saídas das tarefas por meio de um contexto de tarefa explícito. O extractor recebe a saída da tarefa de coleta, e o validador recebe a saída da tarefa de extração.

Nada precisa ser copiado manualmente entre os três agentes.

Isso difere de conectar um modelo local diretamente a uma função Python de coleta e extração. O guia de web scraping do Ollama cobre esse padrão mais simples.

Aqui, o CrewAI controla a orquestração:

  • Três agentes
  • Três prompts delimitados
  • Três limites de token separados
  • Uma transferência sequencial gerida pelo framework

Por Que Usar uma Equipe em vez de Um Único Agente?

Um único agente com uma ferramenta de scraping deve decidir o que coletar, como interpretar a página, como formatar o resultado e se esse resultado é aceitável.

Dividir essas responsabilidades em papéis separados oferece um controle mais claro sobre o fluxo de trabalho.

Cada agente recebe:

  • Um objetivo específico
  • Uma tarefa focada
  • Seu próprio limite de saída
  • Acesso apenas às ferramentas que precisa

Isso pode ser especialmente útil com modelos locais menores. Ao invés de pedir a um modelo para coletar, extrair, formatar e validar simultaneamente, cada etapa gerencia um trabalho mais limitado.

A separação também oferece pontos de inspeção mais claros. Em um pipeline de produção, você pode salvar ou validar a saída após cada tarefa e identificar se uma falha ocorreu durante a recuperação, extração ou validação.

Por Que o Servidor MCP Scrapeless?

A especificação do Protocolo de Contexto de Modelo define uma maneira padrão para que um cliente de IA descubra e invoque ferramentas expostas por um servidor.

O Servidor MCP Scrapeless expõe dados da web e capacidades de navegador através daquela interface de ferramenta. O CrewAI não precisa implementar renderização de páginas, roteamento de proxy ou infraestrutura de navegador diretamente. Ele apenas precisa se conectar ao servidor e anexar a ferramenta necessária a um agente.

A visão geral do Servidor MCP Scrapeless explica a família de ferramentas mais ampla, incluindo recuperação de páginas, busca e ferramentas de controle de navegador.

Para este fluxo de trabalho, a equipe precisa apenas de uma ferramenta:

text Copy
scrape_markdown

Recupera a página alvo e retorna o conteúdo em um formato que o agente de extração a montante pode ler.

Você pode conferir a documentação do desenvolvedor do Scrapeless para os detalhes mais recentes de conexão do servidor e argumentos das ferramentas.

Pré-requisitos

Antes de executar a equipe, você precisa de:

  • Python 3.10 ou posterior
  • CrewAI e Ferramentas CrewAI
  • Uma chave de API Scrapeless
  • Ollama instalado e em execução localmente
  • O modelo qwen2.5:0.5b baixado no Ollama

Você não precisa de OPENAI_API_KEY, ANTHROPIC_API_KEY ou outra credencial LLM hospedada. Cada objeto LLM do CrewAI neste exemplo aponta para o servidor local Ollama.

Passo 1 — Instalar o CrewAI e Suporte MCP

O exemplo verificado usa pacotes CrewAI fixos:

bash Copy
pip install "crewai==1.15.4" "crewai-tools[mcp]==1.15.4"

O extra [mcp] instala as dependências do cliente MCP necessárias pelo MCPServerAdapter. O adaptador converte definições de ferramentas MCP em ferramentas que os agentes CrewAI podem chamar.

Passo 2 — Configurar o Modelo Local Ollama

Puxe o modelo usado neste exemplo:

bash Copy
ollama pull qwen2.5:0.5b

Confirme que o Ollama pode vê-lo:

bash Copy
ollama list

Normalmente, o Ollama expõe sua API local em:

text Copy
http://localhost:11434

Se o Ollama estiver instalado, mas a equipe não conseguir se conectar, confirme que o serviço Ollama está em execução antes de iniciar o script Python.

Em seguida, configure a chave de API Scrapeless no seu shell:

bash Copy
export SCRAPELESS_API_KEY="sua_chave_api_aqui"

Ler a chave de uma variável de ambiente mantém ela fora do arquivo fonte em Python.

Passo 3 — Apontar o CrewAI para o Ollama

Crie uma configuração LLM separada para cada agente:

python Copy
from crewai import LLM

fetch_llm = LLM(
    model="ollama/qwen2.5:0.5b",
    base_url="http://localhost:11434",
    max_tokens=180,
    temperature=0,
)

extract_llm = LLM(
    model="ollama/qwen2.5:0.5b",
    base_url="http://localhost:11434",
    max_tokens=100,
    temperature=0,
)

validate_llm = LLM(
    model="ollama/qwen2.5:0.5b",
    base_url="http://localhost:11434",
    max_tokens=70,
    temperature=0,
)

Todas as três configurações usam o mesmo modelo, mas seus limites de saída refletem suas responsabilidades:

  • O coletor tem mais espaço para retornar o conteúdo da página.
  • O extrator precisa de tokens suficientes para um pequeno array JSON.
  • O validador só precisa produzir um relatório compacto.

Definir temperature=0 reduz a variação na saída. Isso não garante resultados determinísticos ou corretos, especialmente com um modelo local pequeno.

Na inferência local apenas com CPU, max_tokens também é um controle importante em tempo de execução. Limites inferiores impedem que um agente gere respostas desnecessariamente longas, embora o tamanho do modelo, hardware, comprimento do contexto e número de interações do agente também afetem o tempo de execução.

Passo 4 — Conectar o CrewAI ao Servidor MCP Scrapeless

Importe MCPServerAdapter e defina a conexão remota MCP:

python Copy
import os
from crewai_tools import MCPServerAdapter

server_params = {
    "url": "https://api.scrapeless.com/mcp",
    "transport": "streamable-http",
    "headers": {
        "x-api-token": os.environ["SCRAPELESS_API_KEY"]
    },
}

A configuração contém três valores importantes:

  • url aponta para o endpoint MCP Scrapeless.
  • transport informa ao cliente para usar HTTP Streamável.
  • x-api-token autentica a solicitação com sua chave Scrapeless.

A chave é acessada com:

python Copy
os.environ["SCRAPELESS_API_KEY"]

O Python irá interromper imediatamente se a variável de ambiente estiver ausente, o que é preferível a iniciar silenciosamente uma equipe sem credenciais de ferramenta válidas.

Passo 5 — Verificar a Ferramenta MCP Disponível

Antes de construir a equipe completa, verifique se o adaptador pode descobrir a ferramenta solicitada:

python Copy
with MCPServerAdapter(server_params, "scrape_markdown") as tools:
    print([tool.name for tool in tools])

A execução de verificação retornou:

text Copy
['scrape_markdown']

Isso confirma que:

  • O cliente MCP alcançou o servidor.
  • O servidor aceitou o cabeçalho de autenticação.
  • A ferramenta solicitada estava disponível para o CrewAI.

Isso não prova que cada solicitação futura de página conterá os dados esperados, ou que um modelo a montante interpretará a resposta corretamente.

A Superfície da Ferramenta MCP Usada Aqui

MCPServerAdapter pode expor ferramentas do servidor para agentes CrewAI. Passar "scrape_markdown" limita esse fluxo de trabalho à única ferramenta que ele precisa:

python Copy
with MCPServerAdapter(server_params, "scrape_markdown") as tools:
    ...

Essa superfície de ferramenta mais reduzida é útil para a confiabilidade do agente. O coletor não precisa selecionar entre ferramentas de navegador ou pesquisa não relacionadas, e os agentes de extração e validação não recebem ferramentas.

A fronteira de permissão é direta:

Agente Acesso à ferramenta Responsabilidade
Recuperador de Página Web scrape_markdown Recuperar a página alvo
Especialista em Extração de Dados Nenhum Converter conteúdo buscado em JSON
Validador de QA Nenhum Verificar os registros extraídos

Apenas o recuperador pode fazer uma requisição web ao vivo.

Como Usá-lo na Prática: Construir e Executar a Equipe

Defina os Três Papéis dos Agentes

Crie um Agente para cada etapa:

python Copy
from crewai import Agent

recuperador = Agent(
    role="Recuperador de Página Web",
    goal=(
        "Buscar a URL exata dada usando a ferramenta scrape_markdown "
        "e devolver sua saída bruta."
    ),
    backstory=(
        "Recupera páginas web públicas para membros da equipe que não podem "
        "navegar na web por conta própria."
    ),
    tools=tools,
    llm=fetch_llm,
    max_iter=2,
)

extrator = Agent(
    role="Especialista em Extração de Dados",
    goal=(
        "Transformar o markdown da página recuperada em um registro "
        "estruturado limpo de cada citação e seu autor."
    ),
    backstory=(
        "Lê markdown bruto raspado e extrai exatamente os "
        "campos que um banco de dados precisa."
    ),
    llm=extract_llm,
    max_iter=2,
)

validador = Agent(
    role="Validador de QA",
    goal="Verificar os registros de citações extraídas quanto à completude antes de serem enviados.",
    backstory=(
        "Rejeita registros incompletos ou malformados e relata "
        "exatamente o que verificou."
    ),
    llm=validate_llm,
    max_iter=2,
)

Apenas recuperador recebe tools=tools.

O extrator e o validador devem atuar a partir do contexto da tarefa. Eles não podem navegar independentemente pela página alvo ou fazer outra requisição MCP.

Por que Definir max_iter=2?

max_iter limita o número de ciclos de raciocínio e ação que um agente pode realizar durante uma tarefa.

Um valor de 2 dá ao recuperador espaço suficiente para solicitar uma chamada de ferramenta e, em seguida, produzir uma resposta final. Também evita que um modelo pequeno continue através de um número excessivo de loops internos.

O limite é um mecanismo de controle, não uma garantia de correção. Se um agente produzir JSON malformado ou aceitar campos vazios, atingir o limite de iteração com sucesso não torna essa saída válida.

Anexe a Ferramenta MCP Apenas ao Recuperador

O papel do recuperador é definido de forma restrita:

  1. Receber a URL alvo.
  2. Chamar scrape_markdown.
  3. Retornar a saída da ferramenta sem comentários adicionais.

O extrator nunca recebe a URL ao vivo como uma instrução de navegação. Ele lê o conteúdo retornado pelo recuperador.

O validador nunca recebe a ferramenta MCP. Ele lê apenas a saída do extrator.

Essa separação facilita a compreensão e a auditoria do fluxo de dados.

Conecte o Contexto da Tarefa Sequencial

As tarefas do CrewAI podem referenciar tarefas anteriores através do argumento context:

python Copy
extrair_tarefa = Task(
    ...,
    context=[recuperar_tarefa],
)

validar_tarefa = Task(
    ...,
    context=[extrair_tarefa],
)

A transferência é, portanto:

text Copy
recuperar_tarefa → extrair_tarefa → validar_tarefa

O extrator recebe a resposta final da tarefa de busca. O validador recebe a resposta final da tarefa de extração.

Não é necessária nenhuma passagem manual de strings.

Execute a Equipe Com crew.kickoff()

O seguinte é o script completo:

python Copy
import os

from crewai import Agent, Crew, LLM, Process, Task
from crewai_tools import MCPServerAdapter

URL_ALVO = "https://quotes.toscrape.com/tag/obvious/"

parametros_do_servidor = {
    "url": "https://api.scrapeless.com/mcp",
    "transport": "streamable-http",
    "headers": {
        "x-api-token": os.environ["SCRAPELESS_API_KEY"]
    },
}

fetch_llm = LLM(
    model="ollama/qwen2.5:0.5b",
    base_url="http://localhost:11434",
    max_tokens=180,
    temperature=0,
)

extract_llm = LLM(
    model="ollama/qwen2.5:0.5b",
    base_url="http://localhost:11434",
    max_tokens=100,
    temperature=0,
)

validate_llm = LLM(
    model="ollama/qwen2.5:0.5b",
    base_url="http://localhost:11434",
    max_tokens=70,
    temperature=0,
)

with MCPServerAdapter(parametros_do_servidor, "scrape_markdown") as tools:
    recuperador = Agent(
        role="Recuperador de Página Web",
        goal=(
            f"Buscar a URL exata {URL_ALVO} usando a "
            "ferramenta scrape_markdown e devolver sua saída bruta."
        ),
        backstory=(
            "Recupera páginas web públicas para membros da equipe que "
            "não podem navegar na web por conta própria."
        ),
        tools=tools,
        llm=fetch_llm,
        max_iter=2,
    )

    extrator = Agent(
        role="Especialista em Extração de Dados",
        goal=(
            "Transformar o markdown da página recuperada em um registro "
            "estruturado limpo de cada citação e seu autor."
        ),
        backstory=(
            "Lê markdown bruto raspado e extrai exatamente "
            "os campos que um banco de dados precisa."
        ),
        llm=extract_llm,
        max_iter=2,
    )

    validador = Agent(
        role="Validador de QA",
        goal=(
            "Verificar os registros de citações extraídas quanto à completude "
            "antes de serem enviados."
        ),
        backstory=(
            "Rejeita registros incompletos ou malformados e "
"relata exatamente o que verificou."
O resultado da integração ainda é útil:

- CrewAI criou três agentes.
- O coletor recebeu uma ferramenta Scrapeless MCP ao vivo.
- O contexto da tarefa conectou os três estágios.
- `crew.kickoff()` foi concluído.
- Nenhuma chave de LLM na nuvem foi usada.

No entanto, a execução não suporta confiar nos campos resultantes. A saída final combinou uma contagem zero, valores vazios e uma declaração de sucesso.

Um modelo sub-1B pode ser útil para testar orquestração, mas essa execução mostra por que não deve ser tratado automaticamente como um extrator de dados estruturados confiável.

## Adicionar Validação Determinística Após a Equipe

A validação em linguagem natural ainda é saída do modelo. Um agente validador pode interpretar mal dados malformados, negligenciar valores vazios ou gerar uma conclusão que entra em conflito com seu próprio relatório.

Portanto, a validação em produção deve ocorrer em código comum após o fluxo de trabalho do modelo.

### Analisar a Saída do Extrator

Use `json.loads` para analisar a resposta do extrator.

Rejeite o resultado se:

- Não for JSON válido.
- O valor de nível superior não for um array.
- A resposta incluir prosa ao redor do JSON.
- O array estiver inesperadamente vazio.

### Validar os Campos Necessários

Para cada registro, verifique se:

- `text` existe.
- `author` existe.
- Ambos os valores são strings.
- Ambos os valores permanecem não vazios após a remoção de espaços em branco.
- Nenhum valor é um espaço reservado óbvio.

Não permita que uma declaração em linguagem natural como “todos os campos estão completos” sobreponha uma verificação programática falhada.

### Rejeitar Contagens Contraditórias

Se o validador relatar uma contagem, compare-a com o comprimento real do array JSON.

Um relatório que afirma uma entrada completa enquanto também relata uma contagem de zero deve falhar imediatamente.

### Comparar Valores Extraídos com a Fonte

Mantenha o Markdown original retornado por `scrape_markdown`.

Para campos copiados, como citações e nomes de autores, confirme que os valores extraídos aparecem na resposta da fonte. Isso ajuda a detectar conteúdo alucinado, truncado ou substituído.

### Preservar Saídas Intermediárias da Tarefa

O exemplo imprime apenas a saída final da equipe. Para depuração e monitoramento em produção, preserve a saída de cada tarefa.

Isso lhe dá três artefatos separados:

1. Markdown bruto coletado
2. JSON extraído
3. Relatório de validação

Com essas saídas disponíveis, você pode identificar exatamente em qual estágio os dados foram perdidos em vez de inferir a partir da resposta final.

### Aumentar a Capacidade do Modelo Quando Necessário

Uma validação mais robusta pode rejeitar resultados ruins, mas não pode restaurar o texto da fonte que um modelo não conseguiu preservar.

Se um modelo pequeno perder dados repetidamente durante a extração ou validação, use um modelo local maior ou um modelo hospedado mais capaz. Não enfraqueça as verificações apenas para fazer o pipeline parecer bem-sucedido.

## Conclusão

Uma equipe CrewAI operando em um modelo local Ollama pode se conectar ao Servidor Scrapeless MCP, chamar uma ferramenta de scraping ao vivo, passar dados por três agentes e completar `crew.kickoff()` sem uma chave de LLM na nuvem.

Esse é o resultado da integração.

A saída final capturada ainda estava errada o suficiente para ser rejeitada: ela relatou uma contagem zero e valores vazios enquanto simultaneamente afirmava que os dados estavam completos.

Trate a conclusão do fluxo de trabalho e a correção dos dados como condições separadas. Preserve as saídas intermediárias, valide registros estruturados em Python, compare valores extraídos com a resposta do MCP e falhe no pipeline sempre que essas verificações discordarem da conclusão do modelo.

## Pronto para Construir uma Equipe de Chamada de Ferramentas?

[Crie uma conta gratuita no Scrapeless](https://app.scrapeless.com/passport/login/?utm_source=website&utm_medium=blog&utm_campaign=mcpserver&utm_term=crewai-multi-agent-scraping-scrapeless) para obter sua chave de API e conectar o CrewAI a uma ferramenta de dados da web ao vivo.

Depois de entender o número de páginas e chamadas de agentes que seu fluxo de trabalho requer, revise os [planos de preços do Scrapeless](https://www.scrapeless.com/pt/pricing?utm_source=website&utm_medium=blog&utm_campaign=mcpserver&utm_term=crewai-multi-agent-scraping-scrapeless).

Para perguntas sobre implementação e suporte da comunidade:

- [Junte-se ao Discord do Scrapeless](https://discord.gg/VU2vtbq7Q2)
- [Junte-se à comunidade do Telegram do Scrapeless](https://t.me/scrapeless)

## FAQ

**P: Uma equipe CrewAI precisa de uma chave de LLM na nuvem para funcionar?**

Não. Configurar `model="ollama/qwen2.5:0.5b"` e `base_url="http://localhost:11434"` direciona cada agente para o servidor local Ollama. A equipe não precisa de uma chave de LLM hospedada da OpenAI, Anthropic ou outros.

Este fluxo de trabalho ainda precisa de uma chave de API do Scrapeless porque o coletor chama o Servidor Scrapeless MCP remoto.

**P: Como o CrewAI passa a saída de um agente para o próximo?**

Cada `Task` a jusante recebe uma lista `context` contendo uma tarefa anterior.

Por exemplo:

```python
extract_task = Task(
    ...,
    context=[fetch_task],
)

O CrewAI inclui a resposta final da tarefa de coleta no contexto do extrator. O mesmo mecanismo passa o resultado da extração para o validador.

P: Por que apenas o coletor recebe a ferramenta MCP?
O fetcher é o único agente responsável por recuperar o conteúdo das páginas ao vivo. O extractor e o validator devem operar com base nas saídas de tarefas existentes.

Limitar o acesso às ferramentas reduz escolhas desnecessárias e torna o fluxo de trabalho mais fácil de auditar.

Q: O que controla max_iter=2?

max_iter limita quantos ciclos de raciocínio e ação um agente pode realizar durante uma tarefa.

Um valor de 2 dá ao fetcher a margem para uma chamada de ferramenta e uma resposta final, enquanto impede um loop sem fim. Ele limita a execução, mas não garante que a resposta final do agente seja correta.

Q: O modelo local pequeno extraiu a citação correta?

Não. A equipe foi concluída, mas a saída do validador final começou com:

text Copy
0  ["", "", ""]

Então, afirmou que existia uma entrada completa e que todos os campos estavam não vazios. Como essas declarações se contradizem, o resultado deve ser rejeitado.

Q: Por que usar validação determinística se a equipe já tem um agente de QA?

Um agente de QA ainda é um LLM. Ele pode ignorar campos faltantes ou gerar uma conclusão que entre em conflito com os dados que lhe foram dados para inspecionar.

As verificações determinísticas em Python fornecem uma decisão independente de aprovação/reprovação com base na sintaxe JSON, comprimento do array, campos obrigatórios e correspondência de fonte.

Q: Quão lenta foi a execução local do Ollama?

A execução completa da verificação levou 542 segundos na máquina testada. Essa medida se aplica apenas ao hardware específico, modelo, página, prompts e configuração de agente usados no teste.

A inferência local da CPU pode levar minutos quando várias turnos de agentes estão envolvidos.

Q: O que deve ser registrado em uma equipe de produção?

Preservar pelo menos:

  • A resposta da ferramenta MCP
  • Cada saída de tarefa intermediária
  • Os dados estruturados analisados
  • Erros de validação determinística
  • O resultado final da equipe
  • O tempo de execução para cada etapa

Isso torna possível localizar a etapa que alterou ou descartou os dados de origem.

Q: O que devo verificar antes de raspar um site ao vivo?

Revise os termos do site e as diretivas de /robots.txt, que seguem o Protocolo de Exclusão de Robôs.

Mantenha a lista de alvos limitada, use páginas públicas e evite dar a um agente autônomo uma instrução de rastreamento em aberto.

Na Scorretless, acessamos apenas dados disponíveis ao público, enquanto cumprem estritamente as leis, regulamentos e políticas de privacidade do site aplicáveis. O conteúdo deste blog é apenas para fins de demonstração e não envolve atividades ilegais ou infratoras. Não temos garantias e negamos toda a responsabilidade pelo uso de informações deste blog ou links de terceiros. Antes de se envolver em qualquer atividade de raspagem, consulte seu consultor jurídico e revise os termos de serviço do site de destino ou obtenha as permissões necessárias.

Artigos mais populares

Catálogo