C.O.R.A — Cognitive Orchestrator and Responsive Assistant
Plataforma de orquestração cognitiva com interface multimodal, voz em tempo real, tool calling semântico, memória persistente e delegação de workloads para agentes especializados. Construída para entender os problemas reais de engenharia quando IA precisa agir no mundo, não só conversar sobre ele.

C.O.R.A -- Cognitive Orchestrator and Responsive Assistant
C.O.R.A é um assistente de IA pessoal com foco operacional, construído para ir além do chatbot. O sistema combina interface web, voz em tempo real, tool calling, memória contextual, planejamento com aprovação humana e delegação de workloads longos para agentes especializados. Comecei chamando de Jarvis, depois renomeei para C.O.R.A quando o escopo ficou claro: não é um assistente de perguntas e respostas, é uma plataforma de orquestração cognitiva.
O projeto existe porque eu queria entender os problemas reais de engenharia que aparecem quando IA precisa agir no mundo, não só conversar sobre ele.
O que o projeto resolve
A maioria dos assistentes de IA peca em um dos dois lados: ou são muito limitados (respondem perguntas, param aí), ou são muito acoplados (o frontend conversa direto com a API do modelo, sem separação de responsabilidades, sem memória, sem governança).
C.O.R.A foi desenhado com uma premissa diferente: o modelo é um runtime de decisão, não o sistema inteiro. Ele decide o que fazer. Ferramentas bem definidas executam. Memória persiste entre sessões. Tarefas longas rodam em background sem bloquear a conversa.
Arquitetura em quatro blocos
O sistema está organizado em quatro serviços com responsabilidades distintas. Essa separação não foi a escolha inicial, foi o resultado de entender o que acontece quando tudo fica no mesmo lugar.
Frontend multimodal (web/)
React 19, TypeScript e Vite entregam a interface pública. Aqui ficam chat, dashboard, planner, scheduler e as camadas de captura de microfone, câmera e tela compartilhada.
O que não é trivial nessa camada: streaming de áudio no browser, integração com a Live API de voz em tempo real, e gerenciar estado de múltiplas superfícies operacionais (chat, voz, planner) sem que uma interfira na outra.
Gateway de voz e bridge da Live API (voice_service/)
Esse é o serviço que mais causa confusão quando explico o projeto, e também o que evidencia decisões técnicas mais específicas.
O voice_service é um serviço Node.js/Express que fica entre o browser e
o modelo de voz em tempo real (Gemini Live). Não é um proxy burro. Ele
resolve problemas concretos do protocolo:
Emissão de token efêmero por sessão. O browser não pode ter acesso direto
às credenciais da API. O voice_service emite um token com validade curta
para cada sessão live, isolando as credenciais reais do cliente.
Compactação de respostas de tools. O Gemini Live tem uma limitação
importante: retornar payloads grandes de ferramentas pode quebrar a sessão.
Quando uma tool retorna uma estrutura longa, o voice_service resume o
retorno antes de devolvê-lo ao runtime live. Esse detalhe parece pequeno mas
é um exemplo claro de engenharia prática: conhecer os limites do protocolo e
adaptar a arquitetura para operar com confiabilidade dentro deles, não tentar
ignorá-los.
Proxy HTTP e WebSocket para o backend interno. O core Python nunca é
exposto diretamente ao frontend público. Toda comunicação passa pelo
voice_service, que atua como porta pública do sistema.
Backend de agente, tools e memória (core/)
O core é o backend Python em FastAPI. Aqui está a maior parte da lógica:
runtime do agente, registro e execução de tools, memória e persistência de
turnos, planner de tarefas, scheduler local, alertas e integrações externas.
O modelo não fica acoplado à interface. As capacidades são expostas como ferramentas com contratos explícitos. O backend sustenta tanto fluxos síncronos (chat e voz) quanto assíncronos (jobs, notificações, automações agendadas).
Processamento profundo e assíncrono (deepagent/)
O deepagent foi separado do core para tarefas longas, especializadas ou
custosas. Pesquisa profunda, análise de documentos extensos, workloads que
levam minutos para completar.
A razão da separação é direta: o fluxo de conversa em tempo real tem requisitos de latência incompatíveis com processamento profundo. Misturar os dois no mesmo runtime significa ou degradar a experiência de chat esperando jobs longos, ou executar jobs longos com os recursos que deveriam estar disponíveis para o caminho crítico. Separar os dois resolve ambos os lados sem sacrificar nenhum.
As decisões de engenharia que mais importam
As três tools centrais
O coração do runtime do agente são três tools:
buscar_memoria: recupera contexto relevante antes de responderdelegar: transfere workloads longos ou especializados para odeepagenttoolbox: aciona o sistema de execução prática (automações, integrações, ações)
Esse desenho reduz acoplamento entre modelo e implementação. O modelo não "faz tudo". Ele decide quando consultar memória, quando delegar trabalho profundo e quando acionar capacidades práticas. A separação torna o sistema auditável: é possível inspecionar exatamente qual tool foi chamada, com que parâmetros e com que resultado.
Roteamento semântico para ferramentas
O toolbox não usa um switch por palavras-chave para decidir qual ferramenta
acionar. Ele usa seleção semântica com embeddings para escolher as ferramentas
mais relevantes ao intent atual.
Além disso, suporta tools dinâmicas carregadas de data/dynamic_tools/. Isso
significa que é possível adicionar novas capacidades ao sistema sem modificar
o agente central, sem reescrever código existente, sem reiniciar o runtime.
Esse padrão resolve um problema comum em sistemas agentic que crescem: o catálogo de ferramentas fica grande, e manutenção manual de qual tool usar para qual intent vira um gargalo. Roteamento semântico escala melhor do que regras estáticas.
Memória com gateway e fallback explícito
Em vez de injetar contexto de forma improvisada no system prompt, o C.O.R.A tem uma camada dedicada de memória com contrato explícito.
O memory_gateway busca snapshot de memória, contexto recente, memória
semântica e arquivos de identidade e comportamento. Quando o gateway não
responde, existe fallback: o agente continua operando com um contexto
degradado em vez de falhar completamente.
Esse padrão de tolerância a falha em sistemas de IA é subestimado. Demo funciona com tudo disponível. Produção precisa se comportar de forma previsível quando alguma parte do sistema está lenta ou indisponível.
Human-in-the-loop no planner
O planner de tarefas não foi modelado como automação cega. Existe um workflow de aprovação com etapas explícitas, campos de owner, critérios de aceite e transições de estado.
Isso não é detalhe de UX. É reconhecimento de um princípio central de sistemas agentic sérios: autonomia útil precisa ser combinada com pontos de controle. Quando o risco ou a ambiguidade de uma ação aumentam, o sistema para e espera aprovação humana em vez de prosseguir por inferência.
Fluxo de uma interação por voz
- O browser abre a aplicação e conecta ao
voice_service - O
voice_serviceemite token efêmero e prepara a sessão live - O browser se conecta ao Gemini Live com o token
- O modelo processa áudio e decide acionar uma tool
- A chamada de tool passa pelo
voice_servicepara ocore - O
coreexecuta: acessa memória, verifica planner, aciona integração - Se o trabalho for longo, delega para o
deepagente retorna imediatamente - O
voice_servicecompacta o retorno e devolve ao runtime live - O modelo continua a conversa com o resultado
Esse fluxo mantém a latência da conversa controlada independentemente do que acontece nos bastidores.
Stack
Backend: Python, FastAPI, Uvicorn, SQLite, PostgreSQL/Supabase
Gateway e bridge: Node.js, Express
IA e agentes: Gemini Live, OpenAI, OpenRouter, LangChain, semantic-router, sentence-transformers, Google ADK
Frontend: React 19, TypeScript, Vite, Zustand, Tailwind CSS, Radix UI, Framer Motion, Web Audio APIs
Integrações: ClickUp, Paperclip, smart home via python-kasa, email, Telegram, notificações push, scheduler local
O que aprendi construindo esse sistema
O principal aprendizado foi sobre onde os problemas reais aparecem em sistemas agentic, e eles raramente são onde se espera.
O modelo de linguagem em si não foi o problema em nenhum momento. Os problemas foram: como manter contexto coerente entre turnos sem encher o prompt com tudo, como coordenar dois fluxos de execução com requisitos de latência diferentes, como fazer o protocolo de voz em tempo real funcionar de forma confiável quando as ferramentas retornam dados volumosos, como estruturar tools de forma que o sistema seja extensível sem virar um monolito de lógica condicional.
Esses são problemas de engenharia de software aplicados a sistemas de IA. Não basta entender o modelo. É preciso entender o sistema inteiro, incluindo as partes que não têm nada de IA.
O segundo aprendizado importante: separação de responsabilidades em sistemas agentic não é só boa prática de software. É o que torna o sistema depurável. Quando algo quebra em produção, a questão é: foi o modelo, foi a tool, foi a memória, foi o gateway? Com camadas separadas e contratos explícitos, essa pergunta tem resposta. Com tudo misturado, não tem.