Voltar para o blog
Desenvolvimento de IA

Como criar um analista de dados de IA totalmente local com OpenClaw e Ollama

4 de abril de 2026
23:03
TutorialOllamaOpenClaw
Como criar um analista de dados de IA totalmente local com OpenClaw e Ollama

Como criar um analista de dados de IA totalmente local com OpenClaw e Ollama

Neste tutorial, você vai montar um analista de dados de IA 100% local, capaz de:

  • ler arquivos CSV, Excel e JSON;

  • analisar métricas e tendências sem enviar dados para a nuvem;

  • gerar um gráfico automaticamente;

  • criar um relatório em Markdown com insights;

  • usar o OpenClaw como camada de orquestração e o Ollama como modelo local.

O objetivo é construir uma base sólida, compreensível tanto para quem está começando quanto para quem já trabalha com dados, automação ou IA local.

O que você vai construir

Ao final, você terá um projeto local com esta lógica:

  1. Você fornece um arquivo de dados.

  2. O OpenClaw recebe o comando do usuário e dispara o fluxo.

  3. Um script Python faz a leitura do dataset, encontra colunas relevantes, cria visualizações e monta um relatório.

  4. O Ollama entra como motor local de raciocínio e resumo.

  5. Todos os arquivos são gerados no seu computador, sem depender de APIs externas.

Arquivos de saída esperados

  • trend_chart.png — gráfico gerado automaticamente;

  • analysis_report.md — relatório com KPIs, observações e resumo;

  • tool_trace.json — trilha de execução para auditoria.

Arquitetura do projeto

ComponenteFunçãoOpenClawRecebe o pedido, organiza a execução e chama as ferramentas locais.OllamaExecuta o modelo de linguagem localmente, sem enviar prompts para a nuvem.PythonLê, processa e resume os dados; também gera gráficos e relatórios.Pandas + MatplotlibTratamento tabular e visualização de dados.

Em termos simples: OpenClaw pensa a execução do fluxo, Ollama responde localmente e Python faz o trabalho analítico.

Ferramentas necessárias e links oficiais

Abaixo estão os links oficiais das ferramentas mencionadas neste tutorial:

OpenClaw: Agente local que orquestra o fluxo - https://openclaw.ai/

Documentação OpenClaw: Instalação e configuração - https://docs.openclaw.ai/

Ollama: Execução local de modelos - https://ollama.com/download

Biblioteca de modelos Ollama: Escolha e download de modelos - https://ollama.com/library

Modelo Qwen3: Modelo local sugerido neste tutorial - https://ollama.com/library/qwen3

Node.js Runtime: exigido pelo OpenClaw - https://nodejs.org/en/download

Python: Motor do script analítico - https://www.python.org/downloads/

Requisitos mínimos recomendados

  • Sistema operacional: Windows, macOS ou Linux;

  • Windows: prefira WSL2 para ter menos atrito com OpenClaw;

  • Node.js: versão 24 LTS de preferência;

  • Python: 3.11 ou superior;

  • Espaço em disco: pelo menos alguns GB livres para modelos e ambiente virtual;

  • Memória: quanto maior o modelo, maior a necessidade de RAM/VRAM.

Para começar com bom equilíbrio entre qualidade e consumo de recursos, este tutorial usa o modelo qwen3:8b.

Etapa 1: instalar o Python

Baixe e instale o Python pela página oficial:

https://www.python.org/downloads/

No Windows, marque a opção Add Python to PATH durante a instalação.

Como verificar

python --version

ou, em alguns sistemas:

python3 --version

Etapa 2: instalar o Node.js

O OpenClaw precisa do Node.js. Baixe a versão LTS oficial:

https://nodejs.org/en/download

Como verificar

node --version npm --version

Etapa 3: instalar o Ollama

Baixe o instalador oficial do Ollama:

https://ollama.com/download

Depois, confira se tudo está funcionando:

ollama --version

Inicie o serviço do Ollama

Em muitos sistemas, basta abrir o Ollama. Se quiser iniciar via terminal:

ollama serve

Se o serviço estiver ativo, a API local ficará disponível em:

http://localhost:11434

Etapa 4: baixar um modelo local

Agora vamos baixar um modelo que servirá como “cérebro” do seu analista local.

ollama pull qwen3:8b

Depois, confira os modelos instalados:

ollama list

Página oficial do modelo: https://ollama.com/library/qwen3

Etapa 5: instalar o OpenClaw

Você pode usar o instalador oficial.

macOS / Linux / WSL2

curl -fsSL https://openclaw.ai/install.sh | bash

Windows PowerShell

iwr -useb https://openclaw.ai/install.ps1 | iex

Depois, rode o onboarding:

openclaw onboard --install-daemon

Verificação

openclaw doctor openclaw gateway status

Durante o onboarding, escolha a opção de usar Ollama local como provider principal.

Etapa 6: criar a estrutura do projeto

Crie uma pasta para o seu analista local:

mkdir local-data-analyst cd local-data-analyst

Estrutura sugerida:

local-data-analyst/ ├── data/ ├── docs/ ├── output/ ├── requirements.txt ├── main.py └── SKILL.md

Etapa 7: criar o ambiente Python

macOS / Linux / WSL2

python3 -m venv .venv source .venv/bin/activate

Windows PowerShell

python -m venv .venv .venv\Scripts\Activate.ps1

Arquivo requirements.txt

pandas matplotlib openpyxl tabulate

Instalar dependências

pip install -r requirements.txt

Etapa 8: criar o motor de análise em Python

Agora vem a parte central do projeto: o script que vai abrir o dataset, encontrar tendências, gerar um gráfico e montar um relatório.

Arquivo main.py

import argparse import json from pathlib import Path from urllib import request import pandas as pd import matplotlib.pyplot as plt def log_event(events, stage, action, detail): events.append({ "stage": stage, "action": action, "detail": detail }) def load_tabular_data(data_path: Path, events): ext = data_path.suffix.lower() if ext == ".csv": df = pd.read_csv(data_path) elif ext in {".tsv", ".tab"}: df = pd.read_csv(data_path, sep="\\t") elif ext in {".json", ".jsonl"}: try: df = pd.read_json(data_path) except ValueError: df = pd.read_json(data_path, lines=True) elif ext in {".xlsx", ".xls"}: df = pd.read_excel(data_path) else: raise ValueError(f"Formato não suportado: {ext}") log_event(events, "fs", "read", f"Arquivo carregado: {data_path.name}") return df def read_context_docs(docs_dir: Path, events): texts = [] if not docs_dir.exists(): return "" for file in docs_dir.iterdir(): if file.is_file() and file.suffix.lower() in {".txt", ".md"}: texts.append(f"## {file.name}\\n" + file.read_text(encoding="utf-8", errors="ignore")) log_event(events, "docs", "read", f"Documento lido: {file.name}") return "\\n\\n".join(texts).strip() def infer_date_column(df: pd.DataFrame): for col in df.columns: converted = pd.to_datetime(df[col], errors="coerce") if converted.notna().sum() >= max(3, len(df) // 3): return col, converted return None, None def infer_numeric_column(df: pd.DataFrame): numeric_cols = df.select_dtypes(include="number").columns.tolist() return numeric_cols[0] if numeric_cols else None def build_chart(df: pd.DataFrame, x_col: str, y_col: str, output_file: Path, events): plt.figure(figsize=(12, 6)) x_is_date = False converted = pd.to_datetime(df[x_col], errors="coerce") if converted.notna().sum() >= max(3, len(df) // 3): temp = df.copy() temp[x_col] = converted temp = temp.dropna(subset=[x_col, y_col]) grouped = temp.groupby(temp[x_col].dt.to_period("M"))[y_col].sum().reset_index() grouped[x_col] = grouped[x_col].astype(str) plt.plot(grouped[x_col], grouped[y_col], marker="o") x_is_date = True else: temp = df[[x_col, y_col]].dropna().groupby(x_col)[y_col].sum().reset_index() temp = temp.sort_values(y_col, ascending=False).head(15) plt.bar(temp[x_col].astype(str), temp[y_col]) plt.title(f"Tendência de {y_col} por {x_col}") plt.xlabel(x_col) plt.ylabel(y_col) plt.xticks(rotation=45, ha="right") plt.tight_layout() plt.savefig(output_file, dpi=150) plt.close() if x_is_date: log_event(events, "chart", "create", f"Gráfico temporal salvo em {output_file.name}") else: log_event(events, "chart", "create", f"Gráfico categórico salvo em {output_file.name}") def ollama_generate(model: str, prompt: str): url = "http://localhost:11434/api/generate" payload = json.dumps({ "model": model, "prompt": prompt, "stream": False }).encode("utf-8") req = request.Request( url, data=payload, headers={"Content-Type": "application/json"} ) with request.urlopen(req, timeout=120) as resp: body = json.loads(resp.read().decode("utf-8")) return str(body.get("response", "")).strip() def main(): parser = argparse.ArgumentParser() parser.add_argument("--docs-dir", required=True) parser.add_argument("--data-file", required=True) parser.add_argument("--output-dir", required=True) parser.add_argument("--prompt", required=True) parser.add_argument("--use-ollama", action="store_true") parser.add_argument("--model", default="qwen3:8b") parser.add_argument("--x-column", default="") parser.add_argument("--y-column", default="") args = parser.parse_args() events = [] data_file = Path(args.data_file) docs_dir = Path(args.docs_dir) output_dir = Path(args.output_dir) output_dir.mkdir(parents=True, exist_ok=True) df = load_tabular_data(data_file, events) docs_text = read_context_docs(docs_dir, events) x_col = args.x_column.strip() y_col = args.y_column.strip() if not y_col: y_col = infer_numeric_column(df) if not x_col: inferred_date_col, _ = infer_date_column(df) x_col = inferred_date_col or (df.columns[0] if len(df.columns) else "") if not x_col or not y_col: raise ValueError("Não foi possível inferir colunas suficientes para análise. Informe --x-column e --y-column manualmente.") chart_file = output_dir / "trend_chart.png" build_chart(df, x_col, y_col, chart_file, events) total_rows = len(df) total_cols = len(df.columns) null_count = int(df.isna().sum().sum()) sample = df.head(10).to_markdown(index=False) base_report = f\"\"\"# Relatório de Análise ## Resumo técnico - Arquivo analisado: {data_file.name} - Total de linhas: {total_rows} - Total de colunas: {total_cols} - Total de valores nulos: {null_count} - Coluna usada como eixo X: {x_col} - Coluna usada como eixo Y: {y_col} ## Prévia dos dados {sample} ## Estatísticas descritivas {df.describe(include="all").transpose().fillna("").to_markdown()} ## Observações iniciais - O gráfico principal foi salvo como `trend_chart.png`. - O rastreamento desta execução foi salvo como `tool_trace.json`. \"\"\" final_report = base_report if args.use_ollama: prompt = f\"\"\"Você é um analista de dados local. Com base no dataset abaixo, escreva: 1. um resumo executivo em português do Brasil; 2. três insights relevantes; 3. dois possíveis próximos passos de negócio. Pedido do usuário: {args.prompt} Contexto adicional: {docs_text[:5000] if docs_text else "Nenhum documento adicional fornecido."} Relatório técnico inicial: {base_report[:12000]} \"\"\" summary = ollama_generate(args.model, prompt) final_report += "\\n\\n## Interpretação gerada pelo modelo\\n" + summary log_event(events, "llm", "generate", f"Resumo gerado com o modelo {args.model}") report_file = output_dir / "analysis_report.md" report_file.write_text(final_report, encoding="utf-8") log_event(events, "report", "write", f"Relatório salvo em {report_file.name}") trace_file = output_dir / "tool_trace.json" trace_file.write_text(json.dumps(events, ensure_ascii=False, indent=2), encoding="utf-8") print("Análise concluída com sucesso.") print(f"Gráfico: {chart_file}") print(f"Relatório: {report_file}") print(f"Trace: {trace_file}") if __name__ == "__main__": main()

Etapa 9: criar a skill do OpenClaw

Agora vamos ensinar o OpenClaw a disparar esse fluxo com um único comando.

Arquivo SKILL.md

Substitua /CAMINHO/ABSOLUTO/DO/PROJETO pelo caminho real da sua pasta.

--- name: local-data-analyst description: Analista de dados local com OpenClaw + Ollama, gerando gráfico, relatório e trilha de execução. user-invocable: true command-dispatch: tool command-tool: exec command-arg-mode: raw --- Use esta skill como: /local-data-analyst <comando bruto> Template obrigatório: python3 /CAMINHO/ABSOLUTO/DO/PROJETO/main.py --docs-dir /CAMINHO/ABSOLUTO/DO/PROJETO/docs --data-file /CAMINHO/ABSOLUTO/DO/PROJETO/data/SEU_ARQUIVO.csv --output-dir /CAMINHO/ABSOLUTO/DO/PROJETO/output --prompt "Descreva tendências, alertas e oportunidades" --use-ollama --model qwen3:8b Saídas esperadas: - trend_chart.png - analysis_report.md - tool_trace.json

Essa skill cria um atalho operacional: em vez de você executar o script manualmente toda vez, o OpenClaw passa a orquestrar o fluxo.

Etapa 10: configurar o OpenClaw para usar o Ollama local

A forma mais simples é deixar o OpenClaw descobrir automaticamente os modelos do Ollama local.

macOS / Linux / WSL2

export OLLAMA_API_KEY="ollama-local"

Windows PowerShell

$env:OLLAMA_API_KEY="ollama-local"

Depois, escolha o modelo padrão:

openclaw models list openclaw models set ollama/qwen3:8b

Se quiser manter isso isolado por projeto, você também pode criar um arquivo de configuração local.

Exemplo de openclaw.local.json

{ "agents": { "defaults": { "model": { "primary": "ollama/qwen3:8b" } } } }

Se usar esse arquivo, aponte a variável de ambiente:

macOS / Linux / WSL2

export OPENCLAW_CONFIG_PATH="$PWD/openclaw.local.json"

Windows PowerShell

$env:OPENCLAW_CONFIG_PATH="$PWD\openclaw.local.json"

Etapa 11: preparar seus dados

Coloque seu dataset dentro da pasta data.

Exemplo:

data/ └── vendas.csv

Você também pode colocar arquivos de contexto em docs, por exemplo:

docs/ ├── objetivo.md └── contexto.txt

Exemplos de contexto útil:

  • metas de faturamento;

  • explicação das colunas do dataset;

  • contexto comercial da empresa;

  • hipóteses que você deseja validar.

Etapa 12: iniciar o sistema

Terminal 1 — iniciar o Ollama

ollama serve

Terminal 2 — iniciar o gateway do OpenClaw

openclaw gateway --force

Terminal 3 — disparar a análise

Exemplo de chamada manual:

openclaw agent --local --message '/local-data-analyst python3 /CAMINHO/ABSOLUTO/DO/PROJETO/main.py --docs-dir /CAMINHO/ABSOLUTO/DO/PROJETO/docs --data-file /CAMINHO/ABSOLUTO/DO/PROJETO/data/vendas.csv --output-dir /CAMINHO/ABSOLUTO/DO/PROJETO/output --prompt "Analise faturamento, sazonalidade, sinais de crescimento, anomalias e oportunidades" --use-ollama --model qwen3:8b'

Se tudo correr bem, o OpenClaw vai acionar o script e gerar estes arquivos:

  • output/trend_chart.png

  • output/analysis_report.md

  • output/tool_trace.json

Como ler o resultado

trend_chart.png

É o gráfico principal da análise. Dependendo do seu dataset, ele pode representar:

  • evolução temporal;

  • comparação por categoria;

  • distribuição resumida por agrupamento.

analysis_report.md

Esse é o arquivo mais importante para o usuário final. Ele traz:

  • informações básicas sobre o dataset;

  • estatísticas descritivas;

  • resumo interpretativo gerado pelo modelo local;

  • insights e próximos passos.

tool_trace.json

Serve para auditoria e troubleshooting. Você consegue ver quais etapas rodaram e em que ordem.

Boas práticas para um analista de dados local de verdade

  • use nomes de colunas claros, como data, faturamento, categoria, quantidade;

  • sempre documente o objetivo da análise em um arquivo .md dentro da pasta docs;

  • mantenha um dataset de teste pequeno para validar o fluxo antes de rodar em bases grandes;

  • salve saídas versionadas em pastas separadas quando quiser comparar resultados;

  • evite ativar recursos em nuvem se sua prioridade for privacidade total.

Limitações desta primeira versão

  • o script acima foi pensado para dados tabulares simples;

  • o suporte a documentos de contexto está focado em .txt e .md;

  • gráficos mais sofisticados podem exigir lógica específica por tipo de dataset;

  • modelos maiores podem exigir mais memória e mais tempo de resposta.

Ainda assim, esta base já é excelente para criar um analista de dados privado, auditável e executável localmente.

Expansões recomendadas para a próxima versão

  1. Adicionar leitura de PDF com uma biblioteca dedicada.

  2. Criar uma interface web local para upload de arquivos.

  3. Salvar relatórios também em HTML e PDF.

  4. Criar skills separadas por tipo de análise:

    • análise de vendas;

    • análise financeira;

    • análise de estoque;

    • análise de churn ou recorrência.

  5. Acoplar consultas SQL locais ou arquivos Parquet.

Problemas comuns e como resolver

O OpenClaw não encontra o Ollama

Confirme se o serviço está rodando:

ollama serve

Depois teste a API local:

curl http://localhost:11434/api/tags

O modelo não aparece na lista

Baixe novamente:

ollama pull qwen3:8b ollama list

O Python não consegue abrir o Excel

Instale a dependência:

pip install openpyxl

O script não identificou corretamente as colunas

Informe manualmente:

--x-column data --y-column faturamento

O Windows está dando mais erro do que deveria

Considere rodar todo o fluxo dentro do WSL2.

Conclusão

Com OpenClaw e Ollama, você pode montar um analista de dados de IA que funciona de forma totalmente local, sem depender de APIs pagas e sem expor dados sensíveis para terceiros.

Esse tipo de arquitetura é especialmente útil para empresas, times internos, dados confidenciais e experimentos em ambientes controlados.

Mais do que um simples chatbot, você passa a ter um fluxo analítico automatizado, auditável e extensível.

Referências oficiais