Voltar para Projetos

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.

PythonFastAPIReact 19TypeScriptNode.jsLangChainGemini LiveOpenAIPostgreSQLSupabaseTailwind CSSSemantic RouterGoogle ADKWebSocket
C.O.R.A — Cognitive Orchestrator and Responsive Assistant

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 responder
  • delegar: transfere workloads longos ou especializados para o deepagent
  • toolbox: 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

  1. O browser abre a aplicação e conecta ao voice_service
  2. O voice_service emite token efêmero e prepara a sessão live
  3. O browser se conecta ao Gemini Live com o token
  4. O modelo processa áudio e decide acionar uma tool
  5. A chamada de tool passa pelo voice_service para o core
  6. O core executa: acessa memória, verifica planner, aciona integração
  7. Se o trabalho for longo, delega para o deepagent e retorna imediatamente
  8. O voice_service compacta o retorno e devolve ao runtime live
  9. 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.