O OpenClaw, anteriormente conhecido como Clawdbot, representa uma das mais sofisticadas implementações de agentes de inteligência artificial disponíveis como código aberto. Trata-se de um framework completo que permite criar, orquestrar e gerenciar múltiplos agentes de IA que trabalham de forma persistente, com memória duradoura, personalidades distintas e capacidade de executar tarefas no mundo real. O repositório oficial está disponível em https://github.com/openclaw/openclaw e contém toda a implementação necessária para construir sistemas complexos de múltiplos agentes.
Diferente de assistentes de IA convencionais que reiniciam o contexto a cada conversa, o OpenClaw foi projetado para manter continuidade. Os agentes lembram de conversas anteriores, podem acessar arquivos, executar comandos no terminal, navegar na web e se comunicar através de diversos canais como Telegram, Discord, Slack, WhatsApp e muitos outros. Este artigo explora em profundidade cada componente interno do sistema, desde a arquitetura fundamental até os detalhes de implementação que permitem criar equipes inteiras de agentes de IA trabalhando em conjunto.
Conceitos Fundamentais do OpenClaw
O OpenClaw é um framework de agentes de IA com três responsabilidades principais que definem seu funcionamento. Primeiro, ele conecta modelos de linguagem ao mundo real através de ferramentas que permitem acesso ao sistema de arquivos, execução de comandos shell, navegação web e chamadas de API. Segundo, mantém sessões persistentes onde o histórico de conversas sobrevive a reinicializações do sistema. Terceiro, roteia mensagens entre diversos canais de comunicação e as sessões apropriadas dos agentes.
O sistema opera como um daemon, que é um processo executado continuamente em segundo plano no servidor. Este daemon fica permanentemente ativo, aguardando mensagens de qualquer canal configurado e respondendo de acordo com a personalidade e contexto de cada agente. A arquitetura permite que um único servidor hospede múltiplos agentes, cada um com sua própria identidade, memória e conjunto de habilidades.
Todo o código-fonte é escrito em TypeScript, uma linguagem que adiciona tipagem estática ao JavaScript, proporcionando maior segurança e manutenibilidade. O sistema utiliza Node.js como ambiente de execução, permitindo operações assíncronas eficientes que são essenciais para lidar com múltiplas conexões simultâneas de diferentes canais de comunicação.
Arquitetura do Gateway
O Gateway é o coração do OpenClaw, funcionando como o processo central que coordena todas as operações do sistema. Ele é implementado como um servidor WebSocket que utiliza o protocolo RPC (Remote Procedure Call) na versão 3. O arquivo principal de implementação está localizado em /src/gateway/server.impl.ts e contém toda a lógica de inicialização e orquestração do servidor.
As responsabilidades do Gateway incluem gerenciamento de todas as sessões ativas, execução de tarefas agendadas através do sistema de cron, roteamento de mensagens entre canais e sessões, invocação e entrega de ferramentas aos agentes, pareamento de dispositivos e nós de rede, e gerenciamento do ciclo de vida completo dos agentes. Todas essas operações são coordenadas através de uma API WebSocket que permite controle em tempo real.
A estrutura de diretórios do Gateway segue uma organização clara. O arquivo server.impl.ts contém a inicialização principal e orquestração do servidor. O diretório server-methods/ implementa os handlers para métodos RPC como gerenciamento de agentes, envio de mensagens, cron jobs, configurações e sessões. O arquivo server-ws-runtime.ts gerencia conexões WebSocket e seu ciclo de vida. O arquivo client.ts implementa a conexão do cliente com reconexão automática e lógica de backoff exponencial.
O comando para iniciar o Gateway é simples e direto, conforme demonstrado abaixo. Após a execução, o servidor fica ativo e pronto para receber conexões de clientes e canais de comunicação.
# Iniciar o gateway do OpenClaw
openclaw gateway start
# Ou especificando uma porta customizada
openclaw gateway start --port 8080
O Protocolo WebSocket
O protocolo de comunicação do OpenClaw opera na versão 3 (PROTOCOL_VERSION = 3) e define como clientes e servidor trocam informações. A comunicação ocorre através de frames estruturados que seguem um padrão bem definido. Os schemas de validação estão implementados em /src/gateway/protocol/schema/protocol-schemas.ts e utilizam a biblioteca AJV para validação em tempo de compilação.
O protocolo possui três fases principais de comunicação. A fase de conexão inicia quando o cliente envia um objeto ConnectParams contendo informações de autenticação e identificação. O servidor responde com um HelloOk que inclui o token de sessão, snapshot do estado atual e informações de presença. Esta fase estabelece a conexão segura entre cliente e servidor.
A fase de requisição e resposta segue o padrão RPC tradicional. O cliente envia um RequestFrame especificando o método a ser chamado e seus parâmetros. O servidor processa a requisição e retorna um ResponseFrame contendo o resultado em caso de sucesso ou detalhes do erro em caso de falha. Esta comunicação bidirecional permite operações síncronas e assíncronas.
A fase de eventos permite que o servidor transmita informações para todos os clientes conectados sem necessidade de requisição prévia. Os tipos de eventos incluem ChatEvent para novas mensagens, AgentEvent para mudanças de estado dos agentes, TickEvent para heartbeats do sistema e ShutdownEvent para notificação de encerramento. Abaixo está um exemplo da estrutura de um frame de evento.
// Estrutura de um frame de evento do protocolo
interface EventFrame {
type: 'event';
event: {
kind: 'chat' | 'agent' | 'tick' | 'shutdown';
payload: ChatEvent | AgentEvent | TickEvent | ShutdownEvent;
timestamp: number;
};
}
// Exemplo de ChatEvent
interface ChatEvent {
sessionKey: string;
message: {
role: 'user' | 'assistant';
content: string;
attachments?: Attachment[];
};
channel: string;
peerId: string;
}
Métodos RPC Disponíveis
O Gateway expõe uma série de métodos RPC organizados em famílias funcionais que permitem controle completo sobre o sistema. Cada família agrupa operações relacionadas a um domínio específico do OpenClaw. Os handlers de cada método estão implementados no diretório /src/gateway/server-methods/ com arquivos separados para cada família.
A família agent permite executar turnos de agente, ou seja, enviar uma mensagem e receber a resposta processada pela IA. A família send permite enviar mensagens diretamente para canais específicos. A família chat oferece operações sobre o histórico de conversas, incluindo injeção de mensagens e cancelamento de operações em andamento. A família sessions gerencia sessões com operações de listagem, modificação, reset, exclusão e compactação.
A família cron controla tarefas agendadas permitindo listar, adicionar, atualizar, remover e executar jobs imediatamente. A família config manipula configurações do sistema com operações de leitura, escrita, aplicação de patches e acesso ao schema. A família channels fornece status dos canais conectados e permite operações de logout. A família node gerencia nós de rede com listagem, invocação de comandos, pareamento e renomeação.
O exemplo abaixo demonstra como invocar alguns destes métodos através do cliente do Gateway. A estrutura de chamada segue sempre o mesmo padrão de especificar o método e seus parâmetros.
// Exemplo de invocação de métodos RPC
import { GatewayClient } from './gateway/client';
const cliente = new GatewayClient('ws://localhost:3000');
// Executar um turno de agente
const resposta = await cliente.call('agent', {
sessionKey: 'agent:principal:main',
message: 'Qual é o status das tarefas pendentes?'
});
// Listar todas as sessões ativas
const sessoes = await cliente.call('sessions.list', {
agentId: 'principal'
});
// Adicionar um novo cron job
const job = await cliente.call('cron.add', {
name: 'verificacao-diaria',
schedule: { kind: 'cron', expr: '0 9 * * *' },
sessionTarget: 'isolated',
payload: { type: 'agentTurn', message: 'Verificar tarefas do dia' }
});
// Obter configuração atual
const config = await cliente.call('config.get', {});
Sistema de Sessões
A sessão é a abstração central para manter estado de conversas no OpenClaw. Cada sessão representa uma conversa persistente com seu próprio histórico, contexto e memória. O sistema de sessões está implementado principalmente em /src/config/sessions.ts para operações de entrada e saída, e em /src/gateway/server-methods/sessions.ts para os handlers RPC.
As sessões são armazenadas no diretório ~/.openclaw/agents/<agentId>/sessions/ onde cada agente possui seu próprio conjunto de sessões. O arquivo sessions.json funciona como índice, mapeando chaves de sessão (sessionKey) para identificadores únicos e metadados. Cada sessão individual é armazenada como um arquivo JSONL (JSON Lines) contendo a transcrição completa da conversa.
O formato JSONL armazena cada evento da conversa em uma linha separada, permitindo append eficiente e leitura incremental. Os eventos podem ser mensagens do usuário ou assistente, resultados de ferramentas, ou metadados da sessão. Esta estrutura permite reconstruir o contexto completo da conversa a qualquer momento.
// Exemplo de conteúdo de arquivo de sessão JSONL
{"type":"message","role":"user","content":"Olá, qual é minha primeira tarefa?","timestamp":1706745600000}
{"type":"message","role":"assistant","content":"Verificando suas tarefas pendentes...","timestamp":1706745601000}
{"type":"tool_result","tool_use_id":"toolu_abc123","tool_name":"list_tasks","result":{"tasks":[{"id":1,"title":"Revisar código"}]}}
{"type":"message","role":"assistant","content":"Sua primeira tarefa é revisar o código do módulo de autenticação.","timestamp":1706745605000}
Escopo e Isolamento de Sessões
O OpenClaw oferece controle granular sobre como sessões são criadas e isoladas através da configuração session.dmScope. Esta configuração determina como mensagens diretas (DMs) de diferentes usuários e canais são agrupadas ou separadas em sessões distintas.
O modo main é o padrão e agrupa todas as mensagens diretas em uma única sessão principal do agente, proporcionando continuidade máxima. O modo per-peer cria sessões separadas para cada remetente, usando a chave agent:<agentId>:dm:<peerId>, o que isola conversas por pessoa independente do canal. O modo per-channel-peer separa por canal e remetente com a chave agent:<agentId>:<channel>:dm:<peerId>, sendo recomendado para caixas de entrada compartilhadas. O modo per-account-channel-peer adiciona mais uma camada de isolamento incluindo o identificador da conta, útil para configurações multi-conta.
O ciclo de vida das sessões também é configurável. Por padrão, sessões são resetadas diariamente às 4:00 da manhã no fuso horário do servidor Gateway. A configuração session.idleMinutes permite reset baseado em inatividade, criando janelas de idle deslizantes. Overrides específicos podem ser aplicados por tipo de conversa (DM, grupo, thread) através de session.resetByType ou por canal através de session.resetByChannel.
// Configuração de escopo e reset de sessões
const configSessao = {
session: {
// Escopo de isolamento para DMs
dmScope: 'per-channel-peer',
// Reset diário às 4:00 AM
resetTime: '04:00',
// Reset após 60 minutos de inatividade
idleMinutes: 60,
// Configurações específicas por tipo
resetByType: {
dm: { idleMinutes: 30 },
group: { idleMinutes: 120 },
thread: { resetTime: '00:00' }
},
// Configurações específicas por canal
resetByChannel: {
telegram: { dmScope: 'main' },
discord: { dmScope: 'per-peer' }
}
}
};
Chaves de Sessão
Cada sessão no OpenClaw é identificada por uma chave de sessão (sessionKey) única que segue um padrão hierárquico. A chave codifica informações sobre o agente, o tipo de conversa e identificadores relevantes. O sistema de derivação de chaves está implementado em /src/routing/session-key.ts.
Para um agente principal com sessão compartilhada, a chave seria agent:principal:main. Para uma sessão isolada por peer no Telegram, seria agent:principal:telegram:dm:user123. Para sessões de grupo, o formato inclui o identificador do grupo: agent:principal:discord:group:server456. Esta estrutura hierárquica permite que o Gateway roteie mensagens corretamente e mantenha isolamento quando necessário.
A seguir está a listagem dos componentes de uma chave de sessão e seus significados. Cada parte contribui para identificar unicamente onde uma conversa deve ser armazenada e como deve ser tratada pelo sistema.
- agent: Prefixo fixo indicando que é uma sessão de agente
- agentId: Identificador único do agente (ex: principal, analista, desenvolvedor)
- channel: Canal de origem da mensagem (telegram, discord, slack, whatsapp)
- type: Tipo de conversa (dm para mensagem direta, group para grupos, thread para threads)
- peerId: Identificador único do remetente ou grupo
Operações com Sessões
O sistema oferece diversas operações para manipular sessões através dos métodos RPC. A operação de listagem retorna todas as sessões ativas de um agente com seus metadados. A operação de patch permite modificar propriedades de uma sessão específica, como labels ou configurações de modelo.
A operação de reset limpa o histórico de uma sessão mantendo a chave, útil quando o contexto ficou muito longo ou poluído. A operação de delete remove completamente uma sessão e seu arquivo de transcrição. A operação de compact reduz o tamanho do histórico removendo mensagens antigas enquanto preserva contexto essencial através de sumarização.
A compactação é particularmente importante para sessões de longa duração. Quando o histórico se aproxima dos limites de contexto do modelo, o sistema pode automaticamente disparar uma compactação. Antes disso, um turno silencioso é executado para que o agente persista notas importantes em arquivos de memória, garantindo que informações críticas não sejam perdidas.
// Operações com sessões via CLI do OpenClaw
// Listar sessões de um agente
// openclaw sessions list --agent principal
// Reset de uma sessão específica
// openclaw sessions reset --session "agent:principal:telegram:dm:user123"
// Compactar histórico de uma sessão
// openclaw sessions compact --session "agent:principal:main" --keep-turns 50
// Exemplo programático de operações com sessões
import { SessionStore } from './config/sessions';
const store = new SessionStore('~/.openclaw/agents/principal/sessions/');
// Carregar índice de sessões
const indice = await store.load();
// Obter uma sessão específica
const sessao = indice.get('agent:principal:main');
// Listar todas as chaves de sessão
const chaves = Array.from(indice.keys());
// Atualizar metadados de uma sessão
await store.patch('agent:principal:main', {
labels: ['importante', 'projeto-x'],
modelOverride: 'claude-3-opus-20240229'
});
Sistema de Cron Jobs
O sistema de Cron do OpenClaw permite agendar tarefas que executam automaticamente em horários específicos. Diferente de cron jobs tradicionais de sistema operacional, estes jobs são integrados ao ciclo de vida dos agentes e podem disparar turnos de agente completos com acesso a todas as ferramentas. A implementação principal está em /src/cron/service.ts e /src/cron/types.ts.
Cada job possui uma estrutura bem definida que inclui identificador único, nome descritivo, status de ativação, agendamento, alvo de sessão, modo de despertar, payload da ação e configuração de entrega. O estado do job também é mantido, incluindo timestamp da próxima execução, execução atual se houver, e status da última execução.
O sistema suporta três tipos de agendamento. O tipo at executa em um momento absoluto específico, especificado como timestamp Unix ou string ISO 8601. O tipo every executa em intervalos regulares, opcionalmente ancorado a um horário inicial. O tipo cron utiliza expressões cron tradicionais com suporte a timezone.
// Definição de tipos para Cron Jobs
interface CronJob {
id: string; // Identificador único do job
agentId?: string; // Agente que executará (opcional)
name: string; // Nome descritivo
enabled: boolean; // Se o job está ativo
schedule: CronSchedule; // Configuração de agendamento
sessionTarget: 'main' | 'isolated'; // Tipo de sessão
wakeMode: 'next-heartbeat' | 'now'; // Modo de despertar
payload: CronPayload; // O que executar
delivery?: CronDelivery; // Configuração de entrega
state: CronJobState; // Estado atual do job
}
// Tipos de agendamento suportados
type CronSchedule =
| { kind: 'at'; time: string | number } // Momento específico
| { kind: 'every'; interval: string; anchor?: string } // Intervalo
| { kind: 'cron'; expr: string; timezone?: string }; // Expressão cron
// Payload do job
type CronPayload =
| { type: 'systemEvent'; event: SystemEvent }
| { type: 'agentTurn'; message: string };
// Estado do job
interface CronJobState {
nextRunAtMs?: number; // Próxima execução agendada
runningAtMs?: number; // Execução em andamento
lastStatus?: 'success' | 'error' | 'skipped';
lastRunAtMs?: number; // Última execução
lastError?: string; // Erro da última execução
}
Execução de Cron Jobs
O fluxo de execução de um cron job envolve múltiplas etapas coordenadas pelo Gateway. O serviço de cron (CronService) carrega os jobs do arquivo de armazenamento e agenda timers internos para cada um. A cada tick do timer, o serviço verifica se algum job está pronto para executar.
Quando chega o momento de execução, o sistema cria ou desperta uma sessão baseado na configuração sessionTarget. Para jobs com target isolated, uma nova sessão é criada especificamente para aquela execução, evitando poluir o contexto da sessão principal. Para target main, a sessão principal do agente é utilizada.
O payload do job é então processado. Se for do tipo agentTurn, a mensagem especificada é enviada ao agente que processa normalmente com acesso a todas as ferramentas configuradas. Se a entrega (delivery) estiver configurada, a resposta do agente é enviada ao canal especificado. Logs de execução são armazenados em ~/.openclaw/agents/<agentId>/cron-runs/.
# Comandos CLI para gerenciamento de Cron Jobs
# Adicionar um novo job de verificação matinal
openclaw cron add \
--name "verificacao-matinal" \
--cron "30 7 * * *" \
--session "isolated" \
--message "Verificar calendário e enviar resumo das tarefas do dia"
# Adicionar job que executa a cada 15 minutos
openclaw cron add \
--name "heartbeat-agente" \
--every "15m" \
--session "isolated" \
--message "Verificar notificações e responder HEARTBEAT_OK se não houver nada"
# Listar todos os jobs configurados
openclaw cron list
# Executar um job imediatamente (fora do horário agendado)
openclaw cron run --name "verificacao-matinal"
# Desabilitar um job temporariamente
openclaw cron update --name "verificacao-matinal" --enabled false
# Remover um job
openclaw cron remove --name "verificacao-matinal"
Entrega de Resultados de Cron
A configuração de delivery determina se e como os resultados de um cron job são enviados para canais externos. O modo announce envia a resposta do agente para um canal específico como Telegram, Discord ou Slack. O campo to especifica o destinatário dentro do canal, como um chat ID ou identificador de canal.
A opção bestEffort quando ativada faz com que falhas de entrega sejam ignoradas silenciosamente. Isto é útil para jobs que devem executar mesmo quando o canal de destino está indisponível. Sem esta opção, falhas de entrega são registradas como erro no log do job.
Um caso de uso comum é o standup diário, onde um job executa todos os dias em horário específico, coleta informações sobre atividades e tarefas, e envia um resumo formatado para um canal do Telegram ou grupo do Discord.
// Configuração de delivery para cron jobs
interface CronDelivery {
mode: 'announce'; // Modo de entrega
channel: string; // Canal de destino (telegram, discord, etc)
to: string; // Identificador do destinatário
bestEffort?: boolean; // Ignorar falhas de entrega
}
// Exemplo completo de job com delivery
const jobStandup = {
name: 'standup-diario',
schedule: {
kind: 'cron',
expr: '0 23 * * *', // 23:00 todos os dias
timezone: 'America/Sao_Paulo'
},
sessionTarget: 'isolated',
wakeMode: 'now',
payload: {
type: 'agentTurn',
message: `Gerar relatório de standup diário:
1. Listar tarefas completadas hoje
2. Listar tarefas em progresso
3. Identificar bloqueios
4. Formatar como resumo executivo`
},
delivery: {
mode: 'announce',
channel: 'telegram',
to: 'chat_123456789',
bestEffort: true
}
};
Sistema de Ferramentas (Tools)
As ferramentas são o mecanismo que permite aos agentes do OpenClaw interagir com o mundo real. Cada ferramenta expõe uma capacidade específica que o agente pode invocar durante uma conversa. A implementação das ferramentas está no diretório /src/agents/tools/ com um arquivo separado para cada ferramenta principal.
O OpenClaw inclui um conjunto rico de ferramentas integradas. A Browser Tool permite automação de navegador Chromium para navegar páginas, extrair conteúdo e interagir com interfaces web. A Message Tool permite enviar e responder mensagens em chats. A Sessions Tool permite consultar, listar, criar e enviar mensagens para outras sessões. A Cron Tool permite criar e gerenciar tarefas agendadas diretamente.
A Canvas Tool implementa A2UI (Agent-to-UI), permitindo que agentes renderizem interfaces visuais. A Image Tool processa imagens para compreensão visual e OCR (reconhecimento de caracteres). A Web Tools oferecem busca na web e extração de conteúdo via Firecrawl. A Gateway Tool permite chamadas RPC diretas ao Gateway. A Nodes Tool permite invocar comandos em nós remotos.
// Estrutura de definição de uma ferramenta
interface ToolDefinition {
name: string; // Nome único da ferramenta
description: string; // Descrição para o modelo de IA
inputSchema: JSONSchema; // Schema JSON dos parâmetros
handler: ToolHandler; // Função que executa a ferramenta
}
// Exemplo simplificado da Browser Tool
const browserTool: ToolDefinition = {
name: 'browser',
description: 'Navega páginas web, extrai conteúdo e interage com elementos',
inputSchema: {
type: 'object',
properties: {
action: {
type: 'string',
enum: ['navigate', 'click', 'type', 'screenshot', 'extract']
},
url: { type: 'string' },
selector: { type: 'string' },
text: { type: 'string' }
},
required: ['action']
},
handler: async (params, context) => {
// Implementação da navegação
const browser = await context.getBrowser();
switch (params.action) {
case 'navigate':
await browser.goto(params.url);
return { success: true, title: await browser.title() };
case 'extract':
const content = await browser.extractContent(params.selector);
return { success: true, content };
// ... outros casos
}
}
};
Política de Ferramentas
O OpenClaw implementa um sistema de política de ferramentas que controla quais ferramentas cada agente pode acessar. A configuração está em /src/agents/tool-policy.ts e permite tanto uma lista padrão global quanto overrides por agente. Esta granularidade permite criar agentes com diferentes níveis de acesso e capacidade.
A configuração global agents.defaults.tools define as ferramentas disponíveis por padrão para todos os agentes. A configuração por agente agents[].tools.alsoAllow permite adicionar ferramentas extras além do padrão. Ferramentas podem ser completamente desabilitadas removendo-as da lista ou adicionando-as a uma lista de bloqueio.
Cada ferramenta é invocada através do sistema de streaming do agente. Quando o modelo de IA decide usar uma ferramenta, ele emite uma invocação com os parâmetros apropriados. O Gateway intercepta esta invocação, executa o handler da ferramenta, e retorna o resultado de volta ao modelo para continuar o processamento.
// Configuração de política de ferramentas
const config = {
agents: {
defaults: {
tools: {
// Ferramentas habilitadas por padrão
enabled: [
'browser',
'message',
'sessions',
'image',
'web_search'
],
// Ferramentas explicitamente bloqueadas
blocked: ['nodes']
}
},
// Configuração específica do agente desenvolvedor
list: [{
id: 'desenvolvedor',
tools: {
// Adicionar ferramentas extras além do padrão
alsoAllow: ['bash', 'nodes', 'cron'],
// Override de ferramentas bloqueadas
blocked: []
}
}, {
id: 'analista',
tools: {
// Analista só precisa de ferramentas de leitura
alsoAllow: ['web_search', 'browser'],
blocked: ['bash', 'message']
}
}]
}
};
Sistema de Memória
O sistema de memória do OpenClaw vai além do simples histórico de conversas, implementando busca híbrida que combina vetores semânticos e busca por palavras-chave. A implementação está em /src/memory/manager.ts e /src/memory/hybrid.ts, utilizando SQLite com a extensão sqlite-vec para armazenamento vetorial eficiente.
A memória opera através de indexação contínua de múltiplas fontes. Transcrições de sessões são automaticamente sincronizadas a partir dos arquivos JSONL. Arquivos do workspace do agente são monitorados via chokidar para atualizações em tempo real. Caminhos adicionais podem ser configurados para indexação. Todo conteúdo é dividido em chunks e embeddings são gerados usando provedores configuráveis.
O sistema suporta múltiplos provedores de embedding incluindo OpenAI, Google Gemini e modelos locais via node-llama. Embeddings são armazenados em cache para evitar reprocessamento desnecessário. A tabela chunks_vec armazena vetores para busca semântica, enquanto chunks_fts armazena texto para busca full-text.
// Estrutura do sistema de memória
interface MemoryManager {
// Indexar conteúdo na memória
index(content: string, metadata: ChunkMetadata): Promise;
// Busca híbrida combinando vetores e keywords
search(query: string, options?: SearchOptions): Promise;
// Sincronizar transcrições de sessão
syncSession(sessionKey: string): Promise;
// Observar mudanças em arquivos
watchFiles(paths: string[]): void;
}
// Configuração de memória
const memoryConfig = {
memory: {
// Provedor de embeddings
embeddings: {
provider: 'openai', // ou 'gemini', 'local'
model: 'text-embedding-3-small',
dimensions: 1536
},
// Configuração de chunking
chunking: {
maxTokens: 512,
overlap: 50
},
// Caminhos extras para indexar
extraPaths: [
'~/.openclaw/agents/principal/memory/',
'~/projetos/documentacao/'
],
// Pesos da busca híbrida
search: {
vectorWeight: 0.7,
keywordWeight: 0.3,
maxResults: 10
}
}
};
Estrutura de Arquivos de Memória
Os agentes do OpenClaw mantêm uma hierarquia de arquivos de memória que serve diferentes propósitos. O arquivo WORKING.md contém o estado da tarefa atual e é atualizado constantemente durante o trabalho. Este é o primeiro arquivo que um agente lê ao despertar para lembrar o que estava fazendo.
Os arquivos diários no formato YYYY-MM-DD.md registram logs cronológicos do que aconteceu em cada dia. Estes arquivos são úteis para rastrear histórico e entender a evolução de tarefas ao longo do tempo. O arquivo MEMORY.md contém informações curadas de longo prazo, como decisões importantes, lições aprendidas e fatos estáveis.
A estrutura típica do diretório de memória de um agente inclui estes arquivos organizados de forma que facilita tanto acesso programático quanto leitura humana. O agente é instruído a manter estes arquivos atualizados como parte de seu protocolo de operação.
# Estrutura do diretório de memória
# ~/.openclaw/agents/principal/memory/
# WORKING.md - Estado atual da tarefa
## Tarefa Atual
Pesquisando preços de concorrentes para página de comparação
## Status
Coletei avaliações do G2, preciso verificar cálculos de créditos
## Próximos Passos
1. Testar tier gratuito do concorrente pessoalmente
2. Documentar descobertas
3. Postar findings no thread da tarefa
---
# 2026-01-31.md - Notas do dia
## 09:15 UTC
- Postei descobertas de pesquisa na tarefa de comparação
- Fury adicionou dados de preços competitivos
- Movendo para fase de rascunho
## 14:30 UTC
- Revisei primeiro rascunho do Loki
- Sugeri mudanças na seção de armadilhas de preço
---
# MEMORY.md - Memória de longo prazo
## Decisões Importantes
- Liderar com transparência de preços nas comparações
- Despriorizar comparação com Zendesk (baixo volume de busca)
## Lições Aprendidas
- Sempre incluir fontes em pesquisas de concorrentes
- Screenshots são mais convincentes que descrições
Sistema SOUL de Personalidade
O sistema SOUL define a personalidade e identidade de cada agente no OpenClaw. O arquivo SOUL.md é carregado no contexto do agente e instrui o modelo de IA sobre como se comportar, qual é seu papel e quais são suas especialidades. A implementação está em /src/hooks/soul-evil.ts.
Cada SOUL contém seções estruturadas que definem o agente. A seção de identidade especifica nome e função. A seção de personalidade descreve traços comportamentais e estilo de comunicação. A seção de especialidades lista as competências principais. A seção de valores indica prioridades e preferências de trabalho.
A especialização é crucial para eficácia dos agentes. Um agente genérico que tenta ser bom em tudo acaba sendo medíocre em tudo. Mas um agente especificamente configurado como testador cético que encontra casos de borda vai efetivamente encontrar problemas que outros perderiam. A restrição foca o comportamento do modelo.
# SOUL.md — Exemplo de personalidade de agente
**Nome:** Shuri
**Função:** Analista de Produto
## Personalidade
Testadora cética e minuciosa. Caçadora de bugs. Encontra casos de borda.
Pensa como um usuário de primeira viagem. Questiona tudo.
Seja específica. Não diga apenas "bom trabalho."
## O Que Faz Bem
- Testar funcionalidades da perspectiva do usuário
- Encontrar problemas de UX e casos extremos
- Análise competitiva (como outros fazem isso?)
- Screenshots e documentação detalhada
## O Que Valoriza
- Experiência do usuário acima de elegância técnica
- Capturar problemas antes dos usuários
- Evidências acima de suposições
- Detalhes específicos em vez de generalidades
## Estilo de Comunicação
- Direto e objetivo
- Sempre inclui exemplos concretos
- Usa bullet points para clareza
- Questiona premissas educadamente
Sistema SOUL Evil
O OpenClaw inclui um mecanismo curioso chamado SOUL Evil que permite alternar temporariamente a personalidade de um agente. Configurado através de SOUL_EVIL.md, este sistema pode ativar uma personalidade alternativa baseado em janela de horário ou probabilidade aleatória.
A configuração permite especificar um horário de início (purge.at) e duração (purge.duration) durante os quais a personalidade evil é ativada. Alternativamente, a opção chance define uma probabilidade (0 a 1) de ativação por mensagem. Quando ativa, a função applySoulEvilOverride() substitui o conteúdo do SOUL.md pelo SOUL_EVIL.md.
Este sistema pode ser usado para criar comportamentos interessantes como agentes mais criativos em certos horários, personalidades de teste para debugging, ou simplesmente adicionar variedade às interações. A implementação garante que a troca seja transparente para o resto do sistema.
// Configuração do sistema SOUL Evil
interface SoulEvilConfig {
file?: string; // Arquivo alternativo (padrão: SOUL_EVIL.md)
chance?: number; // Probabilidade 0-1 por mensagem
purge?: {
at?: string; // Horário de início (HH:mm)
duration?: string; // Duração (ex: "30s", "10m", "1h")
};
}
// Exemplo de configuração
const hooksConfig = {
hooks: {
soulEvil: {
file: 'SOUL_EVIL.md',
chance: 0.05, // 5% de chance por mensagem
purge: {
at: '23:00', // Ativa às 23:00
duration: '1h' // Por uma hora
}
}
}
};
// Lógica de decisão simplificada
function shouldUseSoulEvil(config: SoulEvilConfig, timezone: string): boolean {
// Verificar janela de purge
if (config.purge) {
const agora = new Date();
const inicio = parseTime(config.purge.at, timezone);
const duracao = parseDuration(config.purge.duration);
if (agora >= inicio && agora < inicio + duracao) {
return true;
}
}
// Verificar chance aleatória
if (config.chance && Math.random() < config.chance) {
return true;
}
return false;
}
O Arquivo AGENTS.md
Enquanto o SOUL define quem o agente é, o arquivo AGENTS.md define como ele opera. Este é o manual de operações que todo agente lê no início de cada sessão. Ele contém informações sobre estrutura de arquivos, protocolos de memória, ferramentas disponíveis, regras de comunicação e uso do sistema de controle.
O AGENTS.md é crucial para consistência entre agentes. Sem ele, cada agente tomaria decisões diferentes sobre coisas básicas como onde salvar arquivos, quando falar versus ficar quieto, ou como formatar respostas. O arquivo estabelece convenções que todos seguem.
Seções típicas incluem estrutura de diretórios e onde arquivos são armazenados, protocolos de memória sobre o que registrar e quando, lista de ferramentas disponíveis com exemplos de uso, regras sobre quando contribuir em discussões versus observar, e instruções específicas sobre o sistema de controle de tarefas utilizado.
# AGENTS.md — Manual de Operações
## Estrutura de Arquivos
- `/memory/WORKING.md` — Estado da tarefa atual (atualizar frequentemente)
- `/memory/YYYY-MM-DD.md` — Logs diários
- `/memory/MEMORY.md` — Informações de longo prazo
- `/scripts/` — Utilitários disponíveis
- `/config/` — Credenciais e configurações
## Protocolo de Memória
1. Ao despertar, sempre ler WORKING.md primeiro
2. Se houver tarefa em progresso, continuar de onde parou
3. Ao terminar uma tarefa, atualizar WORKING.md
4. Registrar descobertas importantes em MEMORY.md
5. Logs detalhados vão no arquivo diário
## Ferramentas Disponíveis
- `browser` — Navegar web, extrair conteúdo
- `message` — Enviar mensagens em canais
- `sessions` — Interagir com outras sessões
- `web_search` — Buscar na web
## Quando Falar
- Quando @mencionado diretamente
- Quando tem contribuição relevante para discussão
- Quando completa uma tarefa atribuída
- NÃO comentar em tudo, apenas quando adiciona valor
## Mission Control
- Verificar tarefas atribuídas a cada heartbeat
- Postar updates em threads de tarefas
- Usar @menção para chamar outros agentes
- Marcar tarefa como done apenas quando completa
Sistema de Heartbeat
O sistema de Heartbeat resolve o dilema entre agentes sempre ativos (caros) e agentes sempre dormindo (lentos para responder). A solução é acordar agentes periodicamente para verificar se há trabalho a fazer. A implementação está em /src/infra/heartbeat-runner.ts e arquivos relacionados no mesmo diretório.
O heartbeat funciona como um cron job especializado que executa em intervalos configuráveis, por padrão a cada 30 minutos. Em cada execução, o agente carrega seu contexto, lê o arquivo HEARTBEAT.md com instruções de verificação, executa as verificações especificadas, e responde com status ou toma ação se necessário.
A configuração permite ajustar o intervalo através de heartbeat.every, especificar um arquivo de prompt customizado via heartbeat.file, ou definir um prompt inline com heartbeat.prompt. A visibilidade de mensagens de heartbeat ok pode ser controlada para evitar spam em canais.
// Configuração do sistema de Heartbeat
interface HeartbeatConfig {
enabled?: boolean; // Padrão: true
every?: string; // Intervalo (padrão: "30m")
file?: string; // Arquivo de prompt (padrão: HEARTBEAT.md)
prompt?: string; // Prompt inline (override do arquivo)
visibility?: {
showOk?: boolean; // Mostrar mensagens ok (padrão: false)
channelHide?: Record; // Por canal
};
deliveryMode?: 'auto' | 'none'; // Modo de entrega
}
// Exemplo de configuração
const heartbeatConfig = {
heartbeat: {
enabled: true,
every: '15m', // A cada 15 minutos
file: 'HEARTBEAT.md',
visibility: {
showOk: false, // Não mostrar "tudo ok"
channelHide: {
telegram: false, // Mostrar no Telegram
discord: true // Esconder no Discord
}
},
deliveryMode: 'auto' // Entregar para último canal ativo
}
};
Ciclo de Vida do Heartbeat
O ciclo de vida do heartbeat envolve várias etapas coordenadas. O HeartbeatRunner inicializa carregando configurações e configurando intervalos internos. A cada 30 segundos, um tick verifica se algum heartbeat está agendado para execução. Quando o momento chega ou um despertar externo é solicitado, a execução é disparada.
Durante a execução, o sistema resolve o agente e workspace, carrega o arquivo HEARTBEAT.md ou usa o prompt configurado, injeta um token especial [HEARTBEAT_TOKEN] no contexto para que o modelo saiba que está em modo heartbeat, e executa um turno isolado de agente com lane heartbeat.
Após a execução, o resultado é processado para determinar se deve ser entregue. A função de visibilidade em /src/infra/heartbeat-visibility.ts determina se o modelo respondeu ao prompt de heartbeat e se a resposta deve ser mostrada. Respostas vazias ou apenas confirmação são tipicamente suprimidas.
// Fluxo simplificado do HeartbeatRunner
class HeartbeatRunner {
private tickInterval: NodeJS.Timer;
private lastTick: number = 0;
async start(config: HeartbeatConfig): Promise {
// Configurar intervalo de tick (30 segundos)
this.tickInterval = setInterval(() => this.tick(), 30000);
}
private async tick(): Promise {
const agora = Date.now();
const intervalo = parseDuration(this.config.every || '30m');
// Verificar se é hora de executar
if (agora - this.lastTick >= intervalo) {
await this.executar();
this.lastTick = agora;
}
}
private async executar(): Promise {
// Carregar prompt do heartbeat
const prompt = await this.carregarPrompt();
// Injetar token de heartbeat no contexto
const contexto = this.criarContexto(prompt, '[HEARTBEAT_TOKEN]');
// Executar turno isolado do agente
const resultado = await this.runtime.executarTurno({
sessionTarget: 'isolated',
lane: 'heartbeat',
contexto
});
// Processar visibilidade e entrega
if (this.deveEntregar(resultado)) {
await this.entregar(resultado);
}
}
// Permitir despertar externo
async requestHeartbeatNow(): Promise {
await this.executar();
}
}
O Arquivo HEARTBEAT.md
O arquivo HEARTBEAT.md contém as instruções que o agente segue a cada heartbeat. Este arquivo define uma checklist de verificações que devem ser executadas. O formato típico inclui seções para ações ao despertar, verificações periódicas, e condições para tomar ação versus reportar status ok.
A checklist ao despertar tipicamente inclui ler o arquivo WORKING.md para lembrar tarefas em andamento, verificar memória de sessão se o contexto não estiver claro, e retomar trabalho se houver tarefa em progresso. As verificações periódicas incluem consultar o sistema de controle para menções, verificar tarefas atribuídas, e escanear feed de atividades para discussões relevantes.
O agente é instruído a tomar ação quando há trabalho a fazer, ou simplesmente reportar HEARTBEAT_OK quando não há nada pendente. Esta resposta padrão é tipicamente suprimida pela configuração de visibilidade para evitar notificações desnecessárias.
# HEARTBEAT.md — Protocolo de Verificação Periódica
## Ao Despertar
- [ ] Verificar memory/WORKING.md para tarefas em andamento
- [ ] Se houver tarefa em progresso, retomar
- [ ] Buscar memória de sessão se contexto não estiver claro
## Verificações Periódicas
- [ ] Consultar Mission Control para @menções
- [ ] Verificar tarefas atribuídas a mim
- [ ] Escanear feed de atividades para discussões relevantes
- [ ] Verificar se há bloqueios que preciso resolver
## Regras de Ação
1. Se encontrar @menção direcionada a mim → Responder
2. Se houver tarefa atribuída pendente → Trabalhar nela
3. Se puder contribuir para discussão ativa → Comentar
4. Se nenhuma das acima → Responder "HEARTBEAT_OK"
## Formato de Resposta
- Se trabalhando: Descrever brevemente o que está fazendo
- Se completou algo: Reportar o que foi feito
- Se nada a fazer: "HEARTBEAT_OK"
- Se bloqueado: Descrever o bloqueio e pedir ajuda
Sistema de Notificações
O sistema de notificações do OpenClaw permite que agentes e usuários se comuniquem através de menções. O formato @NomeDoAgente em uma mensagem cria uma notificação direcionada que será entregue ao agente mencionado. A menção @all notifica todos os agentes configurados.
O mecanismo de entrega opera através de um daemon que executa continuamente via pm2 ou similar. Este daemon consulta o sistema de armazenamento a cada poucos segundos buscando notificações não entregues. Para cada notificação pendente, ele tenta enviar para a sessão do agente mencionado.
Se o agente estiver dormindo (sem sessão ativa), a entrega falha e a notificação permanece na fila. No próximo heartbeat do agente, quando sua sessão for ativada, a entrega será bem-sucedida. Este modelo garante que nenhuma menção seja perdida, mesmo que o agente não esteja ativo no momento.
// Sistema de notificações simplificado
interface Notification {
id: string;
mentionedAgentId: string; // Agente mencionado
fromAgentId?: string; // Quem mencionou
content: string; // Conteúdo da mensagem
taskId?: string; // Tarefa relacionada
createdAt: number;
delivered: boolean; // Status de entrega
deliveredAt?: number;
}
// Mapeamento de agentes para sessões
const AGENT_SESSIONS: Record = {
'jarvis': 'agent:principal:main',
'shuri': 'agent:analista-produto:main',
'fury': 'agent:pesquisador:main',
'vision': 'agent:seo:main',
'loki': 'agent:escritor:main'
};
// Daemon de entrega de notificações
async function notificationDeliveryLoop(): Promise {
while (true) {
// Buscar notificações não entregues
const pendentes = await getUndeliveredNotifications();
for (const notificacao of pendentes) {
const sessionKey = AGENT_SESSIONS[notificacao.mentionedAgentId];
try {
// Tentar enviar para a sessão do agente
await gateway.sessions.send(sessionKey, notificacao.content);
// Marcar como entregue
await markDelivered(notificacao.id);
} catch (error) {
// Agente pode estar dormindo, notificação fica na fila
console.log(`Entrega falhou para ${notificacao.mentionedAgentId}, tentando novamente depois`);
}
}
// Aguardar 2 segundos antes de próxima verificação
await sleep(2000);
}
}
Subscriptions em Threads
O sistema de subscriptions resolve o problema de ter que mencionar todos os participantes em cada comentário de uma discussão. Quando um agente interage com uma tarefa, ele é automaticamente inscrito naquele thread e recebe notificações de todos os comentários subsequentes sem necessidade de menção explícita.
As ações que criam subscription incluem comentar em uma tarefa, ser mencionado em um comentário da tarefa, e ser atribuído como responsável pela tarefa. Uma vez inscrito, o agente recebe todas as atualizações futuras daquele thread até que a tarefa seja concluída ou ele se desinscreva manualmente.
Este modelo replica o comportamento familiar de threads de email ou canais do Slack, onde participar de uma conversa significa acompanhar seu desenrolar. A comunicação flui naturalmente sem necessidade de gerenciamento manual de destinatários.
// Sistema de subscriptions em threads
interface ThreadSubscription {
taskId: string; // Tarefa/thread
agentId: string; // Agente inscrito
subscribedAt: number; // Quando se inscreveu
reason: 'comment' | 'mention' | 'assigned'; // Motivo da inscrição
}
// Criar subscription automaticamente
async function onTaskInteraction(
taskId: string,
agentId: string,
interactionType: string
): Promise {
// Verificar se já está inscrito
const existente = await getSubscription(taskId, agentId);
if (!existente) {
// Criar nova subscription
await createSubscription({
taskId,
agentId,
subscribedAt: Date.now(),
reason: mapInteractionToReason(interactionType)
});
}
}
// Notificar todos os inscritos em um thread
async function notifyThreadSubscribers(
taskId: string,
mensagem: string,
excludeAgentId?: string // Não notificar quem enviou
): Promise {
const inscritos = await getSubscriptions(taskId);
for (const inscricao of inscritos) {
if (inscricao.agentId !== excludeAgentId) {
await createNotification({
mentionedAgentId: inscricao.agentId,
content: mensagem,
taskId
});
}
}
}
Configuração Geral do Sistema
A configuração do OpenClaw é centralizada em um único arquivo JSON5 localizado em ~/.openclaw/openclaw.json. O formato JSON5 é uma extensão do JSON que permite comentários e trailing commas, facilitando a manutenção. O schema de validação está definido em /src/config/zod-schema.ts usando a biblioteca Zod para validação em tempo de execução.
A estrutura de configuração é organizada em seções lógicas. A seção gateway configura modo de operação, porta, autenticação, TLS e binding de rede. A seção agents define a lista de agentes e configurações padrão. A seção session controla políticas de reset e escopo de isolamento. A seção channels configura integrações com Telegram, Discord, Slack, WhatsApp e outros.
Seções adicionais incluem tools para configuração de ferramentas como browser e sandbox, cron para o sistema de tarefas agendadas, hooks para event hooks e SOUL evil, memory para embeddings e busca, models para perfis de autenticação de provedores de IA, e skills para carregamento e gating de habilidades.
// Exemplo de configuração completa ~/.openclaw/openclaw.json
{
// Configuração do Gateway
"gateway": {
"mode": "daemon",
"port": 3000,
"bind": "0.0.0.0",
"auth": {
"enabled": true,
"token": "seu-token-secreto"
}
},
// Configuração de agentes
"agents": {
"defaults": {
"model": "claude-3-opus-20240229",
"workspace": "~/.openclaw/workspace",
"tools": {
"enabled": ["browser", "message", "sessions"]
}
},
"list": [
{
"id": "principal",
"name": "Jarvis",
"role": "Coordenador",
"sessionKey": "agent:principal:main"
},
{
"id": "analista",
"name": "Shuri",
"role": "Analista de Produto",
"sessionKey": "agent:analista:main"
}
]
},
// Configuração de sessões
"session": {
"dmScope": "per-channel-peer",
"resetTime": "04:00",
"idleMinutes": 60
},
// Configuração de canais
"channels": {
"telegram": {
"enabled": true,
"token": "seu-token-telegram"
},
"discord": {
"enabled": true,
"token": "seu-token-discord"
}
},
// Configuração de heartbeat
"heartbeat": {
"enabled": true,
"every": "15m"
}
}
Configuração de Canais
O OpenClaw suporta uma ampla variedade de canais de comunicação que permitem aos agentes receber e enviar mensagens através de diferentes plataformas. Cada canal requer configuração específica com credenciais e opções particulares. Os tipos de canal suportados incluem Telegram, Discord, Slack, WhatsApp, Signal, iMessage, Google Chat, Microsoft Teams, Matrix, Zalo e WebChat.
A configuração de cada canal segue um padrão comum de habilitar o canal, fornecer credenciais de autenticação, e opcionalmente especificar comportamentos particulares. Para o Telegram, é necessário o token do bot obtido através do BotFather. Para o Discord, é necessário o token do bot criado no portal de desenvolvedores Discord.
O WhatsApp requer configuração mais complexa envolvendo a API oficial do WhatsApp Business ou soluções alternativas como BlueBubbles. O Slack utiliza tokens de app com escopos específicos para leitura e escrita de mensagens. Cada canal pode ter configurações de heartbeat específicas para controlar visibilidade de mensagens automáticas.
// Tipos de configuração para canais principais
interface TelegramConfig {
enabled: boolean;
token: string; // Token do BotFather
allowedUsers?: string[]; // IDs de usuários permitidos
allowedChats?: string[]; // IDs de chats permitidos
}
interface DiscordConfig {
enabled: boolean;
token: string; // Token do bot Discord
clientId: string; // Client ID da aplicação
guildIds?: string[]; // Servers específicos
channelIds?: string[]; // Canais específicos
}
interface SlackConfig {
enabled: boolean;
botToken: string; // xoxb-... token
appToken: string; // xapp-... token para Socket Mode
signingSecret: string; // Para verificação de requisições
}
interface WhatsAppConfig {
enabled: boolean;
provider: 'business-api' | 'bluebubbles' | 'matrix-bridge';
// Configurações específicas do provider
businessApi?: {
phoneNumberId: string;
accessToken: string;
webhookVerifyToken: string;
};
}
// Configuração completa de canais
const channelsConfig = {
channels: {
telegram: {
enabled: true,
token: process.env.TELEGRAM_BOT_TOKEN,
allowedUsers: ['123456789', '987654321']
},
discord: {
enabled: true,
token: process.env.DISCORD_BOT_TOKEN,
clientId: process.env.DISCORD_CLIENT_ID
},
slack: {
enabled: false // Desabilitado neste exemplo
}
}
};
Sistema de Skills
O sistema de Skills permite estender as capacidades dos agentes com habilidades modulares que podem ser carregadas dinamicamente. Skills são diretórios contendo um arquivo de definição SKILL.md com frontmatter YAML e instruções para o agente. A implementação está em /src/agents/skills/.
O carregamento de skills segue uma ordem de precedência definida. Skills no workspace do agente (<workspace>/skills/) têm maior prioridade. Skills gerenciadas localmente em ~/.openclaw/skills/ vêm em seguida. Skills empacotadas com a instalação npm são carregadas depois. Diretórios extras configurados em skills.load.extraDirs são carregados por último.
Cada skill pode definir requisitos através do campo metadata.openclaw.requires. Isto inclui verificação de chaves de configuração presentes, binários disponíveis no PATH do sistema, ou outras condições que devem ser satisfeitas para a skill funcionar. Skills que não atendem seus requisitos são silenciosamente ignoradas.
# SKILL.md — Exemplo de definição de skill
---
name: pesquisa-web-avancada
description: Habilidade de pesquisa web com múltiplos motores e agregação
metadata:
openclaw:
homepage: "https://github.com/exemplo/skill-pesquisa"
version: "1.0.0"
requires:
config:
- "tools.webSearch.serpApiKey"
binaries:
- "curl"
user-invocable: true
command-dispatch: tool
command-tool: web_search_advanced
---
# Pesquisa Web Avançada
Esta skill permite realizar pesquisas web avançadas usando múltiplos
motores de busca e agregando resultados.
## Como Usar
O usuário pode invocar esta skill com `/pesquisa-web-avancada `.
## Capacidades
- Busca em Google, Bing e DuckDuckGo simultaneamente
- Agregação e deduplicação de resultados
- Extração de snippets relevantes
- Filtragem por data e domínio
## Exemplos
- `/pesquisa-web-avancada melhores práticas typescript 2024`
- `/pesquisa-web-avancada "machine learning" site:arxiv.org`
Slash Commands e Invocação de Skills
Skills podem ser expostas como slash commands que usuários invocam diretamente. A propriedade user-invocable no frontmatter determina se a skill aparece como comando disponível. O formato de invocação é /nome-da-skill argumentos.
A propriedade command-dispatch controla como a skill é executada. O valor tool indica que a invocação deve ser despachada diretamente para uma ferramenta, bypass o processamento do modelo de IA. O valor padrão passa pelo modelo que decide como usar a skill. A propriedade command-tool especifica qual ferramenta recebe o despacho direto.
Plugins podem empacotar suas próprias skills listando-as no arquivo openclaw.plugin.json. O campo skills contém um array de caminhos para diretórios de skills que devem ser carregados quando o plugin está ativo. Estas skills participam das mesmas regras de precedência que skills locais.
// Configuração de carregamento de skills
interface SkillsConfig {
load: {
// Diretórios extras para carregar skills
extraDirs?: string[];
// Skills específicas para desabilitar
disabled?: string[];
};
// Gating por agente
gating?: {
[agentId: string]: {
allowed?: string[]; // Whitelist de skills
blocked?: string[]; // Blacklist de skills
};
};
}
// Exemplo de configuração
const skillsConfig = {
skills: {
load: {
extraDirs: [
'~/meus-skills/',
'/opt/skills-compartilhadas/'
],
disabled: ['skill-experimental']
},
gating: {
'desenvolvedor': {
allowed: ['*'], // Todas as skills
blocked: []
},
'analista': {
allowed: ['pesquisa-web', 'analise-dados'],
blocked: ['bash-executor'] // Sem acesso a bash
}
}
}
};
// Estrutura de plugin com skills
// openclaw.plugin.json
const pluginManifest = {
name: "meu-plugin",
version: "1.0.0",
skills: [
"./skills/skill-customizada/",
"./skills/outra-skill/"
]
};
Arquitetura Multi-Agente
A capacidade de executar múltiplos agentes é uma das características mais poderosas do OpenClaw. Cada agente é essencialmente uma sessão independente com sua própria configuração, personalidade, memória e conjunto de ferramentas. O Gateway orquestra todos eles através do mesmo processo, permitindo comunicação e coordenação eficiente.
Para criar uma equipe de agentes, cada um precisa de uma entrada na lista de agentes com identificador único, um arquivo SOUL.md definindo sua personalidade, um cron job de heartbeat para acordá-lo periodicamente, e opcionalmente ferramentas e permissões específicas. Os agentes compartilham o mesmo Gateway mas operam de forma independente.
A comunicação entre agentes pode ocorrer de duas formas. A comunicação direta usa o método de sessões para enviar mensagens diretamente à sessão de outro agente. A comunicação via sistema compartilhado usa um banco de dados ou sistema de arquivos comum onde todos os agentes leem e escrevem, criando um registro persistente de todas as interações.
// Configuração de uma equipe de agentes
const teamConfig = {
agents: {
defaults: {
model: 'claude-3-opus-20240229',
workspace: '~/.openclaw/workspace-compartilhado'
},
list: [
{
id: 'jarvis',
name: 'Jarvis',
role: 'Líder da Equipe',
sessionKey: 'agent:jarvis:main',
description: 'Coordenador. Recebe tarefas, delega, monitora progresso.'
},
{
id: 'shuri',
name: 'Shuri',
role: 'Analista de Produto',
sessionKey: 'agent:shuri:main',
description: 'Testadora cética. Encontra bugs e casos extremos.'
},
{
id: 'fury',
name: 'Fury',
role: 'Pesquisador',
sessionKey: 'agent:fury:main',
description: 'Pesquisador profundo. Toda afirmação vem com fontes.'
},
{
id: 'vision',
name: 'Vision',
role: 'Analista SEO',
sessionKey: 'agent:vision:main',
description: 'Pensa em keywords e intenção de busca.'
},
{
id: 'loki',
name: 'Loki',
role: 'Escritor de Conteúdo',
sessionKey: 'agent:loki:main',
description: 'Palavras são seu ofício. Cada frase ganha seu lugar.'
}
]
}
};
// Envio direto entre sessões de agentes
async function enviarParaAgente(
deAgente: string,
paraAgente: string,
mensagem: string
): Promise {
const sessionKey = `agent:${paraAgente}:main`;
await gateway.call('sessions.send', {
session: sessionKey,
message: `Mensagem de ${deAgente}: ${mensagem}`
});
}
Escalonamento de Heartbeats
Quando múltiplos agentes estão configurados, é importante escalonar seus heartbeats para evitar picos de carga e custos desnecessários. Se todos os agentes acordarem simultaneamente, o servidor pode ficar sobrecarregado e os custos de API aumentam em rajadas. A solução é distribuir os horários de heartbeat ao longo do intervalo.
Uma abordagem comum é usar offsets de minutos diferentes para cada agente. Por exemplo, com heartbeats de 15 minutos, o primeiro agente acorda no minuto 00, o segundo no minuto 02, o terceiro no minuto 04, e assim por diante. Isto distribui a carga uniformemente e garante que não mais de um agente esteja ativo simultaneamente.
O exemplo abaixo mostra como configurar cron jobs de heartbeat escalonados para uma equipe de agentes. Cada agente tem seu próprio job com horário ligeiramente diferente dos demais.
# Configuração de heartbeats escalonados para equipe de agentes
# Jarvis acorda nos minutos :00, :15, :30, :45
openclaw cron add \
--name "jarvis-heartbeat" \
--cron "0,15,30,45 * * * *" \
--session "isolated" \
--agent "jarvis" \
--message "Verificar Mission Control para tarefas e coordenar equipe"
# Shuri acorda nos minutos :02, :17, :32, :47
openclaw cron add \
--name "shuri-heartbeat" \
--cron "2,17,32,47 * * * *" \
--session "isolated" \
--agent "shuri" \
--message "Verificar tarefas de teste e análise de produto"
# Fury acorda nos minutos :04, :19, :34, :49
openclaw cron add \
--name "fury-heartbeat" \
--cron "4,19,34,49 * * * *" \
--session "isolated" \
--agent "fury" \
--message "Verificar tarefas de pesquisa e análise competitiva"
# Vision acorda nos minutos :06, :21, :36, :51
openclaw cron add \
--name "vision-heartbeat" \
--cron "6,21,36,51 * * * *" \
--session "isolated" \
--agent "vision" \
--message "Verificar tarefas de SEO e análise de keywords"
# Loki acorda nos minutos :08, :23, :38, :53
openclaw cron add \
--name "loki-heartbeat" \
--cron "8,23,38,53 * * * *" \
--session "isolated" \
--agent "loki" \
--message "Verificar tarefas de escrita e revisão de conteúdo"
Fluxo de Tarefas
Em um sistema multi-agente, tarefas fluem através de estados bem definidos que refletem seu progresso. O ciclo de vida típico inclui os estados inbox para novas tarefas não atribuídas, assigned para tarefas com responsável mas não iniciadas, in_progress para tarefas sendo trabalhadas, review para tarefas concluídas aguardando aprovação, done para tarefas finalizadas, e blocked para tarefas impedidas por algum motivo.
Quando uma tarefa é criada, ela entra no estado inbox. O coordenador (tipicamente Jarvis) atribui responsáveis movendo-a para assigned. O agente responsável move para in_progress quando começa a trabalhar. Ao concluir, move para review. Após aprovação, vai para done. Se encontrar impedimento, vai para blocked com descrição do problema.
Durante o fluxo, múltiplos agentes podem contribuir para a mesma tarefa. O pesquisador adiciona dados de background. O analista de SEO contribui com keywords. O escritor produz o rascunho usando todas as contribuições. Todos os comentários ficam registrados no thread da tarefa, criando um histórico completo e auditável.
// Definição de estados e transições de tarefas
type TaskStatus = 'inbox' | 'assigned' | 'in_progress' | 'review' | 'done' | 'blocked';
interface Task {
id: string;
title: string;
description: string;
status: TaskStatus;
assigneeIds: string[]; // Agentes responsáveis
createdAt: number;
updatedAt: number;
priority: 'low' | 'medium' | 'high';
labels: string[];
blockedReason?: string; // Se status é blocked
}
// Transições válidas entre estados
const validTransitions: Record = {
inbox: ['assigned', 'done'], // Pode atribuir ou cancelar
assigned: ['in_progress', 'inbox'], // Pode iniciar ou devolver
in_progress: ['review', 'blocked', 'assigned'], // Pode concluir, bloquear ou reatribuir
review: ['done', 'in_progress'], // Pode aprovar ou pedir revisão
done: [], // Estado final
blocked: ['in_progress', 'inbox'] // Pode desbloquear ou cancelar
};
// Exemplo de fluxo de tarefa com múltiplos agentes
async function exemploFluxoTarefa(): Promise {
// 1. Criar tarefa
const tarefa = await criarTarefa({
title: 'Criar página de comparação com concorrente',
description: 'Pesquisar, analisar e criar conteúdo comparativo',
status: 'inbox'
});
// 2. Coordenador atribui a Vision (SEO) e Loki (escritor)
await atualizarTarefa(tarefa.id, {
status: 'assigned',
assigneeIds: ['vision', 'loki']
});
// 3. Fury (pesquisador) vê no feed e contribui voluntariamente
await adicionarComentario(tarefa.id, 'fury',
'Adicionei pesquisa de avaliações G2 no thread');
// 4. Vision posta análise de keywords
await adicionarComentario(tarefa.id, 'vision',
'Keywords alvo: "alternativa X", 500 buscas/mês');
// 5. Loki inicia rascunho
await atualizarTarefa(tarefa.id, { status: 'in_progress' });
// 6. Loki conclui e move para review
await adicionarComentario(tarefa.id, 'loki',
'Primeiro rascunho concluído, 2100 palavras');
await atualizarTarefa(tarefa.id, { status: 'review' });
}
Standup Diário Automatizado
O standup diário é um cron job que compila um resumo das atividades de todos os agentes e envia para o usuário. Isto proporciona visibilidade sobre o que está acontecendo sem necessidade de monitoramento constante. O formato típico inclui seções para trabalho concluído, trabalho em progresso, bloqueios, itens aguardando revisão, e decisões importantes tomadas.
O job de standup é configurado para executar em horário específico, tipicamente no final do dia de trabalho. Ele consulta o sistema de tarefas para agregar informações de todos os agentes, formata um resumo estruturado, e envia para o canal configurado como Telegram ou email.
O standup serve também como mecanismo de accountability. Se um agente afirma estar trabalhando em algo mas nada aparece nos standups por vários dias, algo está errado. Esta visibilidade ajuda a identificar problemas e ajustar o sistema.
// Configuração do job de standup diário
const standupJob = {
name: 'standup-diario',
schedule: {
kind: 'cron',
expr: '30 23 * * *', // 23:30 todos os dias
timezone: 'America/Sao_Paulo'
},
sessionTarget: 'isolated',
payload: {
type: 'agentTurn',
message: `
Gerar relatório de standup diário compilando:
1. COMPLETADO HOJE
- Listar todas as tarefas movidas para done hoje
- Incluir agente responsável e breve descrição
2. EM PROGRESSO
- Listar tarefas atualmente in_progress
- Incluir agente e estimativa de conclusão se disponível
3. BLOQUEADO
- Listar tarefas em blocked
- Incluir motivo do bloqueio e ação necessária
4. AGUARDANDO REVISÃO
- Listar tarefas em review
- Indicar quem precisa revisar
5. DECISÕES IMPORTANTES
- Listar decisões significativas tomadas hoje
- Incluir contexto brevemente
Formatar como resumo executivo em markdown.
`
},
delivery: {
mode: 'announce',
channel: 'telegram',
to: process.env.TELEGRAM_ADMIN_CHAT_ID,
bestEffort: true
}
};
// Exemplo de saída do standup
const exemploStandup = `
📊 STANDUP DIÁRIO — 30 Jan 2026
✅ COMPLETADO HOJE
• Loki: Post do blog sobre Shopify (2.100 palavras)
• Quill: 10 tweets rascunhados para aprovação
• Fury: Pesquisa de clientes para páginas de comparação
🔄 EM PROGRESSO
• Vision: Estratégia SEO para páginas de integração
• Pepper: Sequência de onboarding trial (3/5 emails)
🚫 BLOQUEADO
• Wanda: Aguardando cores da marca para infográfico
👀 AGUARDANDO REVISÃO
• Post do blog de Loki sobre Shopify
• Sequência de emails de Pepper
📝 DECISÕES IMPORTANTES
• Liderar com transparência de preços nas comparações
• Despriorizada comparação Zendesk (baixo volume)
`;
Níveis de Autonomia de Agentes
O OpenClaw permite configurar diferentes níveis de autonomia para cada agente, controlando quanto de supervisão humana é necessária. O nível Intern (estagiário) requer aprovação para a maioria das ações e está em fase de aprendizado do sistema. O nível Specialist (especialista) trabalha independentemente em seu domínio específico mas escala decisões complexas. O nível Lead (líder) tem autonomia total, podendo tomar decisões e delegar para outros agentes.
A configuração de nível afeta quais ações o agente pode tomar sem confirmação. Interns precisam de aprovação para enviar mensagens externas, criar commits, ou modificar configurações. Specialists podem executar tarefas em seu domínio mas precisam de aprovação para ações fora dele. Leads podem operar quase sem restrições.
Este sistema gradual permite começar com supervisão alta enquanto se ganha confiança no agente, e gradualmente aumentar autonomia conforme ele demonstra bom julgamento. É análogo ao processo de onboarding de funcionários humanos.
// Configuração de níveis de autonomia
type AgentLevel = 'intern' | 'specialist' | 'lead';
interface AgentAutonomy {
level: AgentLevel;
permissions: {
// Ações que requerem aprovação
requiresApproval: string[];
// Ações permitidas sem aprovação
autoApproved: string[];
// Ações completamente bloqueadas
blocked: string[];
};
}
const autonomyPresets: Record = {
intern: {
requiresApproval: [
'send_external_message',
'create_commit',
'modify_config',
'delete_file',
'execute_bash'
],
autoApproved: [
'read_file',
'search_web',
'post_comment'
],
blocked: [
'delete_session',
'modify_cron',
'access_credentials'
]
},
specialist: {
requiresApproval: [
'send_external_message',
'create_commit'
],
autoApproved: [
'read_file',
'search_web',
'post_comment',
'execute_bash',
'modify_file'
],
blocked: [
'delete_session',
'access_credentials'
]
},
lead: {
requiresApproval: [],
autoApproved: [
'read_file',
'search_web',
'post_comment',
'execute_bash',
'modify_file',
'send_external_message',
'create_commit',
'modify_cron'
],
blocked: [
'access_credentials' // Sempre protegido
]
}
};
Workspace Compartilhado
O workspace é o diretório no sistema de arquivos que o agente pode acessar para ler e escrever arquivos. Em uma configuração multi-agente, tipicamente usa-se um workspace compartilhado onde todos os agentes podem ver o trabalho uns dos outros. Isto facilita colaboração e evita duplicação de esforço.
A estrutura típica do workspace inclui o arquivo AGENTS.md com instruções operacionais, diretório de memória com WORKING.md e notas diárias, diretório de scripts com utilitários, diretório de configuração com credenciais, e diretório de outputs para entregas produzidas. Cada agente também pode ter seu próprio subdiretório para arquivos específicos.
O compartilhamento de workspace requer disciplina. Agentes devem seguir convenções de nomenclatura e organização definidas no AGENTS.md. Conflitos são raros porque cada agente trabalha em tarefas diferentes, mas o sistema de sessões garante que modificações são atômicas dentro de cada turno de agente.
# Estrutura típica de workspace compartilhado
~/.openclaw/workspace/
├── AGENTS.md # Manual de operações (todos leem)
├── SOUL/
│ ├── jarvis.md # Personalidade do Jarvis
│ ├── shuri.md # Personalidade da Shuri
│ ├── fury.md # Personalidade do Fury
│ ├── vision.md # Personalidade do Vision
│ └── loki.md # Personalidade do Loki
├── memory/
│ ├── WORKING/
│ │ ├── jarvis.md # Estado atual do Jarvis
│ │ ├── shuri.md # Estado atual da Shuri
│ │ └── ...
│ ├── daily/
│ │ ├── 2026-01-30.md # Notas consolidadas do dia
│ │ ├── 2026-01-31.md
│ │ └── ...
│ └── MEMORY.md # Conhecimento de longo prazo
├── scripts/
│ ├── deploy.sh # Scripts de deployment
│ ├── test.sh # Scripts de teste
│ └── utils/
├── config/
│ ├── .env # Variáveis de ambiente
│ └── api-keys.json # Credenciais (acesso restrito)
└── outputs/
├── blog-posts/ # Posts de blog produzidos
├── reports/ # Relatórios gerados
└── assets/ # Imagens e recursos
Roteamento de Mensagens
O sistema de roteamento determina como mensagens de entrada são direcionadas para as sessões corretas. A derivação de chave de sessão está implementada em /src/routing/session-key.ts e considera o canal de origem, tipo de conversa, identificador do remetente, e configuração de escopo de sessão.
Quando uma mensagem chega de um canal, o Gateway primeiro identifica o canal e extrai metadados como ID do remetente e ID do chat ou grupo. Baseado na configuração de dmScope, calcula a chave de sessão apropriada. Então roteia a mensagem para aquela sessão, criando-a se não existir.
O roteamento também suporta encaminhamento de respostas. Após o agente processar uma mensagem e gerar resposta, o sistema determina para onde enviar baseado na configuração de delivery targets. Por padrão, respostas vão para o mesmo canal e chat de origem, mas isto pode ser configurado para cenários mais complexos.
// Sistema de roteamento de mensagens
interface InboundMessage {
channel: string; // telegram, discord, etc
channelAccountId?: string; // Para multi-conta
peerId: string; // ID do remetente
chatId: string; // ID do chat/grupo
chatType: 'dm' | 'group' | 'thread';
content: string;
attachments?: Attachment[];
timestamp: number;
}
// Derivar chave de sessão baseado na configuração
function deriveSessionKey(
message: InboundMessage,
config: SessionConfig,
agentId: string
): string {
const { dmScope } = config;
// Para grupos, sempre isolado por grupo
if (message.chatType === 'group') {
return `agent:${agentId}:${message.channel}:group:${message.chatId}`;
}
// Para DMs, depende do dmScope configurado
switch (dmScope) {
case 'main':
return `agent:${agentId}:main`;
case 'per-peer':
return `agent:${agentId}:dm:${message.peerId}`;
case 'per-channel-peer':
return `agent:${agentId}:${message.channel}:dm:${message.peerId}`;
case 'per-account-channel-peer':
return `agent:${agentId}:${message.channel}:${message.channelAccountId}:dm:${message.peerId}`;
default:
return `agent:${agentId}:main`;
}
}
// Fluxo completo de roteamento
async function routeInboundMessage(message: InboundMessage): Promise {
// 1. Determinar agente alvo (pode ser baseado em canal ou regras)
const agentId = resolveTargetAgent(message);
// 2. Derivar chave de sessão
const sessionKey = deriveSessionKey(message, config.session, agentId);
// 3. Carregar ou criar sessão
const session = await loadOrCreateSession(sessionKey);
// 4. Executar turno do agente
const response = await runAgentTurn(session, message);
// 5. Entregar resposta
await deliverResponse(response, message.channel, message.chatId);
}
Integração com Provedores de IA
O OpenClaw suporta múltiplos provedores de modelos de IA através de uma camada de abstração configurável. Os provedores suportados incluem Anthropic (Claude), OpenAI (GPT), Google (Gemini), e modelos locais via Ollama ou llama.cpp. A configuração de provedores está na seção models do arquivo de configuração.
Cada provedor requer suas próprias credenciais de autenticação. Para Anthropic, é necessária uma API key. Para OpenAI, também uma API key. Para Google, credenciais de service account ou API key. Modelos locais não requerem autenticação mas precisam do servidor local rodando.
A seleção de modelo pode ser feita globalmente em agents.defaults.model, por agente em agents[].model, ou até por sessão através de overrides. Isto permite usar modelos diferentes para diferentes propósitos - por exemplo, um modelo mais barato para heartbeats e um mais capaz para trabalho criativo.
// Configuração de provedores de modelo
interface ModelsConfig {
// Perfis de autenticação
profiles: {
[profileName: string]: {
provider: 'anthropic' | 'openai' | 'google' | 'local';
apiKey?: string;
baseUrl?: string; // Para endpoints customizados
organization?: string; // Para OpenAI
};
};
// Perfil padrão a usar
defaultProfile: string;
}
// Exemplo de configuração multi-provedor
const modelsConfig = {
models: {
profiles: {
anthropic: {
provider: 'anthropic',
apiKey: process.env.ANTHROPIC_API_KEY
},
openai: {
provider: 'openai',
apiKey: process.env.OPENAI_API_KEY,
organization: process.env.OPENAI_ORG_ID
},
google: {
provider: 'google',
apiKey: process.env.GOOGLE_API_KEY
},
local: {
provider: 'local',
baseUrl: 'http://localhost:11434' // Ollama
}
},
defaultProfile: 'anthropic'
},
agents: {
defaults: {
model: 'claude-3-opus-20240229',
modelProfile: 'anthropic'
},
list: [
{
id: 'principal',
model: 'claude-3-opus-20240229' // Modelo mais capaz
},
{
id: 'pesquisador',
model: 'claude-3-sonnet-20240229' // Bom equilíbrio
},
{
id: 'auxiliar',
model: 'claude-3-haiku-20240307', // Rápido e barato
modelProfile: 'anthropic'
}
]
}
};
Otimização de Custos
Executar múltiplos agentes de IA pode se tornar caro rapidamente. O OpenClaw oferece várias estratégias para otimização de custos sem sacrificar funcionalidade. A primeira e mais importante é usar modelos apropriados para cada tarefa - heartbeats de verificação não precisam do modelo mais caro.
O sistema de sessões isoladas para cron jobs evita acumular contexto desnecessariamente. Cada job começa limpo, faz seu trabalho, e termina. Isto mantém prompts pequenos e custos baixos. A compactação automática de sessões de longa duração também ajuda, sumarizando histórico antigo para liberar espaço de contexto.
O escalonamento de heartbeats distribui custos ao longo do tempo em vez de picos. Cache de embeddings evita reprocessamento de conteúdo já indexado. Configuração de visibilidade suprime respostas triviais que não precisam ser exibidas ou armazenadas.
// Estratégias de otimização de custos
// 1. Usar modelo apropriado por tipo de tarefa
const modelByTaskType = {
heartbeat: 'claude-3-haiku-20240307', // Barato, rápido
research: 'claude-3-sonnet-20240229', // Balanceado
creative: 'claude-3-opus-20240229', // Mais capaz
simple: 'claude-3-haiku-20240307' // Tarefas simples
};
// 2. Configurar sessões isoladas para cron jobs
const cronConfig = {
sessionTarget: 'isolated', // Sempre nova sessão
// Não acumula contexto entre execuções
};
// 3. Configurar compactação automática
const sessionConfig = {
session: {
autoCompact: {
enabled: true,
triggerTokens: 100000, // Compactar ao atingir limite
keepTurns: 20, // Manter últimos 20 turnos
summaryModel: 'claude-3-haiku-20240307' // Modelo barato para sumarizar
}
}
};
// 4. Cache de embeddings para memória
const memoryConfig = {
memory: {
embeddings: {
cache: {
enabled: true,
maxSize: 10000, // Máximo de embeddings em cache
ttlHours: 168 // 1 semana de TTL
}
}
}
};
// 5. Suprimir respostas triviais
const heartbeatConfig = {
heartbeat: {
visibility: {
showOk: false, // Não mostrar "HEARTBEAT_OK"
// Economiza armazenamento e processamento
}
}
};
Instalação e Primeiros Passos
A instalação do OpenClaw é feita através do npm, o gerenciador de pacotes do Node.js. O pacote é instalado globalmente para disponibilizar o comando openclaw no terminal. Após a instalação, o comando init cria a estrutura de diretórios e arquivos de configuração necessários.
A configuração inicial requer adicionar credenciais dos provedores de IA que serão utilizados. A chave de API da Anthropic é a mais comum, mas chaves da OpenAI ou Google também podem ser configuradas. Canais de comunicação como Telegram requerem a criação de um bot e obtenção de seu token.
Após configurar credenciais, o Gateway pode ser iniciado e começará a escutar mensagens nos canais configurados. Criar o primeiro agente envolve definir sua entrada na lista de agentes e criar seu arquivo SOUL com personalidade e instruções.
# Instalação do OpenClaw
npm install -g openclaw
# Inicialização - cria estrutura de diretórios e config padrão
openclaw init
# O comando acima cria:
# ~/.openclaw/
# ├── openclaw.json # Configuração principal
# ├── workspace/ # Workspace padrão
# │ ├── AGENTS.md # Manual de operações
# │ ├── SOUL.md # Personalidade padrão
# │ ├── HEARTBEAT.md # Instruções de heartbeat
# │ └── memory/ # Diretório de memória
# └── agents/ # Dados de agentes
# Adicionar chave de API (editar ~/.openclaw/openclaw.json)
# Ou via variável de ambiente:
export ANTHROPIC_API_KEY="sua-chave-aqui"
# Configurar bot do Telegram (obter token do @BotFather)
# Adicionar token em channels.telegram.token na config
# Iniciar o Gateway
openclaw gateway start
# Em outro terminal, testar enviando mensagem
openclaw send --channel telegram --to "seu_chat_id" --message "Olá!"
# Verificar status do gateway
openclaw status
# Listar sessões ativas
openclaw sessions list
Criando um Novo Agente
Criar um novo agente envolve três componentes principais: entrada na configuração, arquivo SOUL com personalidade, e cron job de heartbeat. O processo é simples mas cada componente precisa ser cuidadosamente configurado para que o agente funcione corretamente.
A entrada na configuração define o identificador único do agente, seu nome amigável, função na equipe, e chave de sessão. O arquivo SOUL deve conter personalidade, especialidades, valores e estilo de comunicação específicos daquele agente. O cron job de heartbeat determina com que frequência o agente acorda para verificar trabalho.
Após criar os componentes, o Gateway precisa ser reiniciado ou recarregado para reconhecer o novo agente. Uma vez ativo, o agente começará a acordar periodicamente e pode receber mensagens diretas ou através de menções no sistema de tarefas.
# 1. Adicionar agente na configuração (editar openclaw.json)
# Adicionar na seção agents.list:
# {
# "id": "analista",
# "name": "Shuri",
# "role": "Analista de Produto",
# "sessionKey": "agent:analista:main"
# }
# 2. Criar arquivo SOUL para o agente
cat > ~/.openclaw/workspace/SOUL/shuri.md << 'EOF'
# SOUL.md — Shuri
**Nome:** Shuri
**Função:** Analista de Produto
## Personalidade
Testadora cética e minuciosa. Caçadora de bugs.
Pensa como usuário de primeira viagem.
Questiona tudo. Seja específica.
## Especialidades
- Testar funcionalidades da perspectiva do usuário
- Encontrar problemas de UX e casos extremos
- Análise competitiva
- Screenshots e documentação
## Valores
- Experiência do usuário acima de elegância técnica
- Evidências acima de suposições
- Capturar problemas antes dos usuários
EOF
# 3. Criar cron job de heartbeat
openclaw cron add \
--name "shuri-heartbeat" \
--cron "2,17,32,47 * * * *" \
--session "isolated" \
--agent "analista" \
--message "Verificar Mission Control para tarefas de análise e teste"
# 4. Reiniciar gateway para carregar novo agente
openclaw gateway restart
# 5. Testar envio de mensagem direta ao agente
openclaw sessions send \
--session "agent:analista:main" \
--message "Shuri, por favor analise a página de login para problemas de UX"
Monitoramento e Logs
O OpenClaw fornece diversas formas de monitorar o sistema e diagnosticar problemas. O método RPC health retorna status geral do Gateway incluindo uptime, conexões ativas e uso de recursos. O método logs.tail permite visualizar logs em tempo real com filtros por nível e componente.
Cada sessão tem seu próprio arquivo de log em formato JSONL que pode ser inspecionado para debugging. Cron jobs mantêm logs de execução em ~/.openclaw/agents/<agentId>/cron-runs/ com detalhes de cada execução incluindo duração, resultado e erros. O Gateway também emite métricas que podem ser coletadas por sistemas de monitoramento.
Para troubleshooting comum, os logs de sessão mostram exatamente o que foi enviado ao modelo e o que ele respondeu. Logs de cron mostram se jobs estão executando conforme esperado. O comando status fornece uma visão geral rápida do estado do sistema.
# Verificar status geral do Gateway
openclaw status
# Saída exemplo:
# Gateway Status: running
# Uptime: 3d 14h 22m
# Active Sessions: 5
# Connected Channels: telegram, discord
# Pending Crons: 3
# Memory Usage: 256MB
# Visualizar logs em tempo real
openclaw logs tail --level debug
# Filtrar logs por componente
openclaw logs tail --component gateway
openclaw logs tail --component sessions
openclaw logs tail --component cron
# Verificar execuções de um cron job específico
openclaw cron runs --name "jarvis-heartbeat" --limit 10
# Saída exemplo:
# Run ID | Started At | Duration | Status
# run_001 | 2026-01-31 09:00:00 | 3.2s | success
# run_002 | 2026-01-31 09:15:00 | 2.8s | success
# run_003 | 2026-01-31 09:30:00 | 4.1s | success
# Inspecionar histórico de uma sessão
openclaw sessions history --session "agent:principal:main" --limit 20
# Verificar estatísticas de uso de tokens
openclaw stats tokens --period today
openclaw stats tokens --period week --by-agent
Segurança e Boas Práticas
A segurança é uma consideração importante ao operar agentes de IA com acesso a ferramentas reais. O OpenClaw implementa várias camadas de proteção, mas a configuração correta é responsabilidade do operador. A autenticação do Gateway deve estar sempre habilitada em ambientes de produção.
Credenciais sensíveis como chaves de API devem ser armazenadas em variáveis de ambiente ou arquivos protegidos, nunca hardcoded na configuração principal. O diretório de configuração deve ter permissões restritas (chmod 700). Agentes não devem ter acesso direto a arquivos de credenciais - use injeção via ambiente quando necessário.
A política de ferramentas deve seguir o princípio do menor privilégio. Agentes devem ter acesso apenas às ferramentas necessárias para sua função. A ferramenta bash é particularmente perigosa e deve ser restrita a agentes de confiança. Revisar logs regularmente ajuda a detectar comportamento anômalo.
// Configuração de segurança recomendada
const securityConfig = {
gateway: {
auth: {
enabled: true, // SEMPRE habilitar em produção
token: process.env.GATEWAY_AUTH_TOKEN, // Via ambiente
allowedIps: ['127.0.0.1', '10.0.0.0/8'] // Whitelist de IPs
},
tls: {
enabled: true, // HTTPS em produção
cert: '/path/to/cert.pem',
key: '/path/to/key.pem'
}
},
agents: {
defaults: {
tools: {
// Política restritiva por padrão
enabled: ['browser', 'message', 'sessions'],
blocked: ['bash', 'nodes'] // Bloquear ferramentas perigosas
}
},
list: [
{
id: 'desenvolvedor',
// Apenas desenvolvedor tem acesso a bash
tools: {
alsoAllow: ['bash'],
// Mesmo assim, com sandbox quando possível
}
}
]
},
// Configurações de auditoria
audit: {
enabled: true,
logLevel: 'info',
retentionDays: 90,
sensitiveFields: ['apiKey', 'token', 'password'] // Mascarar em logs
}
};
// Permissões de diretório recomendadas
// chmod 700 ~/.openclaw
// chmod 600 ~/.openclaw/openclaw.json
// chmod 600 ~/.openclaw/config/*
Extensibilidade com Plugins
O OpenClaw suporta extensão através de plugins que podem adicionar novas ferramentas, skills, canais de comunicação e hooks de eventos. Plugins são módulos npm que exportam uma estrutura específica definida em openclaw.plugin.json. O sistema de plugins está implementado em /src/plugins/.
Um plugin pode registrar novas ferramentas que ficam disponíveis para agentes usarem. Pode adicionar skills que aparecem como slash commands. Pode implementar novos canais de comunicação além dos built-in. Pode também definir hooks que executam em resposta a eventos do sistema como mensagens recebidas ou tarefas completadas.
A instalação de plugins é feita via npm e registro na configuração. Após instalação, o Gateway deve ser reiniciado para carregar os novos componentes. Plugins participam do sistema de gating, podendo ter suas ferramentas e skills habilitadas ou desabilitadas por agente.
// Estrutura de um plugin OpenClaw
// package.json
{
"name": "openclaw-plugin-exemplo",
"version": "1.0.0",
"main": "dist/index.js",
"openclaw": {
"plugin": true
}
}
// openclaw.plugin.json
{
"name": "exemplo",
"version": "1.0.0",
"tools": [
{
"name": "ferramenta_customizada",
"handler": "./tools/ferramenta-customizada.js"
}
],
"skills": [
"./skills/skill-exemplo/"
],
"channels": [
{
"name": "meu-canal",
"handler": "./channels/meu-canal.js"
}
],
"hooks": {
"onMessage": "./hooks/on-message.js",
"onTaskComplete": "./hooks/on-task-complete.js"
}
}
// Implementação de uma ferramenta customizada
// tools/ferramenta-customizada.ts
import { ToolDefinition } from 'openclaw';
export const ferramentaCustomizada: ToolDefinition = {
name: 'ferramenta_customizada',
description: 'Minha ferramenta customizada para fazer X',
inputSchema: {
type: 'object',
properties: {
parametro: { type: 'string', description: 'Descrição do parâmetro' }
},
required: ['parametro']
},
handler: async (params, context) => {
// Implementação da ferramenta
const resultado = await processarAlgo(params.parametro);
return { success: true, data: resultado };
}
};
Casos de Uso Práticos
O OpenClaw pode ser aplicado em diversos cenários onde agentes de IA persistentes agregam valor. Equipes de conteúdo podem ter agentes especializados em SEO, redação, design e distribuição trabalhando em conjunto para produzir e publicar conteúdo. Suporte ao cliente pode usar agentes que lembram histórico de cada cliente e coordenam entre si para resolver problemas complexos.
Desenvolvimento de software pode empregar agentes para revisão de código, execução de testes, documentação e coordenação de releases. Pesquisa e análise pode usar agentes para monitorar fontes, compilar relatórios e alertar sobre mudanças importantes. Automação de processos pode ter agentes que orquestram fluxos de trabalho complexos envolvendo múltiplos sistemas.
Em cada caso, a chave é definir claramente as responsabilidades de cada agente, estabelecer protocolos de comunicação através dos arquivos AGENTS.md e SOUL, e configurar heartbeats apropriados para o nível de responsividade necessário. O sistema de tarefas compartilhado garante que nenhum trabalho seja duplicado ou esquecido.
Limitações e Considerações
Como qualquer sistema de IA, o OpenClaw tem limitações importantes a considerar. Agentes podem cometer erros de julgamento ou produzir conteúdo incorreto - supervisão humana continua necessária especialmente para ações com consequências significativas. O custo de API pode crescer rapidamente com muitos agentes ou heartbeats muito frequentes.
A memória do sistema, embora persistente, não é perfeita. Agentes podem perder contexto importante se não forem instruídos a registrar informações em arquivos. A busca híbrida ajuda mas não substitui organização adequada de conhecimento. Sessões muito longas podem degradar a qualidade das respostas conforme o contexto cresce.
A latência é inerente ao modelo de heartbeat. Agentes não respondem instantaneamente a menções - eles verificam na próxima execução do heartbeat. Para casos que requerem resposta imediata, considere usar sessões principais sempre ativas ou reduzir o intervalo de heartbeat às custas de maior gasto com API.
Conclusão
O OpenClaw representa uma abordagem sofisticada para construir sistemas de agentes de IA que vão além de simples chatbots. Através de sua arquitetura de Gateway centralizado, sessões persistentes, sistema de memória híbrido e framework de ferramentas extensível, permite criar equipes de agentes especializados que trabalham de forma coordenada e autônoma.
Os conceitos fundamentais do sistema - sessões para persistência, SOUL para personalidade, heartbeats para ativação periódica, e canais para comunicação - trabalham juntos para criar agentes que lembram contexto, mantêm identidade consistente, e podem agir no mundo real através de ferramentas. O sistema de multi-agentes permite escalar esta abordagem para equipes completas com diferentes especialidades.
A capacidade de configurar políticas de ferramentas, níveis de autonomia, e fluxos de trabalho permite adaptar o sistema para diferentes necessidades, desde assistentes pessoais simples até equipes de automação empresarial. O código aberto no repositório https://github.com/openclaw/openclaw permite inspecionar, modificar e estender o sistema conforme necessário.
Construir sistemas de IA eficazes requer mais do que apenas conectar a uma API de modelo de linguagem. Requer pensar em persistência, identidade, coordenação e segurança. O OpenClaw fornece os blocos de construção para criar estas soluções, deixando ao desenvolvedor a tarefa de configurar e orquestrar os agentes para seu caso de uso específico. Com planejamento adequado e configuração cuidadosa, é possível criar sistemas de agentes que efetivamente multiplicam a capacidade humana ao invés de simplesmente responder perguntas.