Análise Técnica de Alternativas de Arquitetura — Lead Flow

1. Introdução e Contexto

1.1. Objetivo do Documento

Este documento apresenta uma análise técnica detalhada comparando alternativas arquiteturais para implementação do Lead Flow (codinome: Konecty Black). O foco está em fornecer informação técnica objetiva para tomada de decisão, baseado em princípios de engenharia de software e análise de trade-offs.

Nota: Para a decisão final de arquitetura adotada, consulte o documento decisao-arquitetura-final.md.

1.2. Premissas Arquiteturais

A análise é fundamentada nos seguintes princípios de engenharia:

  • KISS (Keep It Simple, Stupid): Priorizar simplicidade sobre complexidade desnecessária
  • YAGNI (You Aren't Gonna Need It): Não adicionar funcionalidades ou complexidade antes de serem necessárias
  • DRY (Don't Repeat Yourself): Evitar duplicação de lógica e código
  • SOLID: Princípios de design orientado a objetos para código manutenível

Estes princípios são especialmente relevantes considerando que o desenvolvimento será guiado por IA, que avaliará e proporá a próxima atividade continuamente.

1.3. Requisitos Não-Funcionais Críticos

Performance e SLA: - Atribuição automática de lead em até 10 minutos - Primeira mensagem em até 3 minutos após atribuição - Agendamento de visita em 2h (solicitação direta) ou 48h (interesse confirmado) - Sistema responsivo para operações humanas e IA

Persistência e Durabilidade: - Processos que podem durar mais de 1 ano (nutrição de longo prazo) - Manutenção de estado durante todo o ciclo de vida do lead - Histórico completo de transições para análise e aprendizado

Confiabilidade: - Recuperação automática de falhas sem perda de estado - Garantia de execução de tarefas agendadas - Persistência durável mesmo com restarts ou falhas de infraestrutura

Integrações: - RabbitMQ para eventos externos e comunicação assíncrona - PostgreSQL para persistência de dados estruturados - LLMs para decisões guiadas por IA - Canais de comunicação: WhatsApp, Email, Telefone

Flexibilidade: - Bypass de tarefas quando apropriado (venda direta sem seguir todas as etapas) - Regras de transição configuráveis e evolutivas - Evolução do fluxo sem downtime ou perda de leads em processamento

1.4. Papel Central da IA no Processo

O Lead Flow será guiado por IA em múltiplos pontos de decisão:

  • Avaliação de estado: IA analisa continuamente o estado atual de cada lead
  • Proposição de ações: IA sugere próximas ações baseadas em contexto histórico e atual
  • Automação de decisões: IA decide transições de estado quando apropriado
  • Geração de conteúdo: IA gera scripts, emails e mensagens personalizadas
  • Aprendizado contínuo: Feedback loops para melhorar decisões ao longo do tempo

A arquitetura escolhida deve facilitar a integração com LLMs de forma eficiente, escalável e manutenível, permitindo que a IA tome decisões informadas com baixa latência e alto grau de confiabilidade.

1.5. Contexto Técnico do Projeto

Stack Existente (CRM Konecty): - CRM: Konecty (Node.js/TypeScript) - Banco de dados: PostgreSQL - Mensageria: RabbitMQ - CRM configurável e extensível

Novo Sistema Lead Flow: - Backend: Python 3.11+ - Integração nativa com CRM Konecty existente - Aproveitamento da infraestrutura PostgreSQL e RabbitMQ


2. Alternativas Arquiteturais

2.1. Alternativa 1: Abordagem Customizada Minimalista

Essência Técnica:

Construir uma solução custom utilizando componentes Python maduros e bem estabelecidos. A arquitetura se baseia em event-driven architecture com state machine implementada, usando PostgreSQL para persistência de estado e RabbitMQ para comunicação assíncrona.

Stack Técnico: - Python 3.11+ como linguagem principal - PostgreSQL 14+ para persistência (CTEs recursivas, JSONB, temporal tables) - RabbitMQ como broker de mensagens - Celery + Celery Beat para processamento assíncrono e agendamento - SQLAlchemy como ORM - Bibliotecas Python para state machine (python-statemachine, transitions)

Padrões de Design: - Event-driven architecture com eventos publicados via RabbitMQ - State machine com biblioteca especializada - Task queue pattern para tarefas assíncronas de longa duração - Event sourcing parcial para histórico de transições

Princípio Arquitetural: KISS aplicado - implementar apenas o essencial necessário para o Lead Flow funcionar, sem adicionar frameworks pesados ou funcionalidades não validadas.

2.2. Alternativa 2: Temporal.io

Essência Técnica:

Utilizar uma plataforma de workflow orchestration especializada que oferece execução durável nativa. Temporal foi projetado especificamente para workflows de longa duração com garantias de confiabilidade e recuperação automática.

Stack Técnico: - Python 3.11+ para implementação de workflows e activities - Temporal.io como motor de workflow orchestration - PostgreSQL 14+ para persistência de dados do domínio (lead, corretor, imóveis) - Temporal Server (self-hosted ou cloud) para gerenciamento de workflows - Python Temporal SDK para definição de workflows

Padrões de Design: - Workflow orchestration com workflows definidos como código Python imperativo - Durable execution com estado persistido automaticamente - Activity pattern para ações externas (chamadas LLM, APIs, comunicação) - Signal pattern para eventos externos que afetam workflows em execução - Query pattern para consultar estado de workflows ativos

Princípio Arquitetural: Confiabilidade e suporte nativo a processos de longa duração através de abstração especializada.

2.3. Alternativa 3: Abordagem Híbrida Incremental

Essência Técnica:

Começar com a abordagem customizada minimalista para validação rápida e aprendizado, com caminho evolutivo para migração gradual de componentes críticos para Temporal.io baseado em necessidade real comprovada.

Padrões de Design: - Strangler fig pattern para migração gradual sem rewrite completo - Adapter pattern para ponte entre sistemas durante transição - Evolução incremental baseada em métricas reais de performance e confiabilidade

Princípio Arquitetural: YAGNI aplicado rigorosamente - começar simples e adicionar complexidade apenas quando dor real é identificada e quantificada.


3. Análise Técnica Detalhada

3.1. Alternativa 1: Abordagem Customizada Minimalista

3.1.1. Vantagens Técnicas

Simplicidade Arquitetural

A arquitetura é composta de componentes isolados e compreensíveis: serviço Python que consome eventos do RabbitMQ, executa lógica de negócio, atualiza estado no PostgreSQL e agenda tarefas via Celery. Não há abstrações pesadas ou complexidade de framework - o código é direto e a lógica de negócio é visível. Debugging usa ferramentas Python padrão sem camadas adicionais.

Integração Natural com IA/LLMs

Python é a lingua franca de Machine Learning e IA. Todas as bibliotecas principais de LLM (OpenAI SDK, Anthropic SDK, LangChain, LlamaIndex) são primariamente Python. A integração é natural, com controle total sobre construção de prompts, gerenciamento de contexto e otimização de custos. Experimentação com diferentes modelos e estratégias é direta.

Controle Total e Flexibilidade

Controle absoluto sobre toda a lógica de negócio permite customização completa. Não há limitações impostas por frameworks. Adaptação a mudanças de requisitos é direta. Implementação de bypass de tarefas é simples - basta alterar a lógica de transição. Regras complexas ou exceções podem ser implementadas sem restrições.

Custo de Infraestrutura Controlado

A infraestrutura necessária é mínima: servidores Python (workers), PostgreSQL e RabbitMQ. Não há custos de licenciamento ou serviços gerenciados obrigatórios. A solução escala horizontalmente adicionando mais workers Celery. O custo é previsível e cresce linearmente com a carga.

Testabilidade Direta

Testes unitários são diretos de escrever e executar usando ferramentas Python padrão. A lógica de negócio está no código da aplicação, facilitando teste isolado. Mocks e fixtures são simples de implementar.

3.1.2. Desvantagens Técnicas

Complexidade de Implementação Manual

Uma state machine robusta requer código cuidadoso para gerenciar todas as transições possíveis. O gerenciamento de transições complexas aumenta com o número de estados e regras. A lógica de recuperação de falhas precisa ser implementada manualmente para cada tipo de falha. Event sourcing, mesmo parcial, requer design cuidadoso.

Limitações para Processos Muito Longos

Celery não foi projetado para processos que duram anos. Tarefas assíncronas típicas do Celery duram minutos ou horas, com hard limits comuns de 15 minutos para requests síncronos e aproximadamente 12 horas para tarefas assíncronas (fonte: pesquisa técnica). Para processos de anos, são necessários workarounds como polling periódico ou callbacks complexos. O gerenciamento de tarefas agendadas muito distantes no futuro requer design específico com persistência explícita.

Overhead Operacional

Monitoramento customizado precisa ser implementado. Não há dashboards nativos - é necessário integrar com Prometheus, Grafana ou similares. Alertas e observabilidade precisam ser configurados manualmente. O gerenciamento de workers Celery requer atenção (scaling, health checks, memory leaks potenciais). Configuração de retry policies é manual.

Desafios de Performance

RabbitMQ introduz latência de 100-500ms por tarefa em alguns cenários (fonte: pesquisa técnica), o que pode impactar SLAs críticos. Usar PostgreSQL como queue para tarefas agendadas pode causar index bloat e necessitar vacuum agressivo em alta escala (fonte: pesquisa técnica). A concorrência é limitada pelo design do worker pool - scaling requer adição manual de workers.

State Machine Error-Prone

State machines manuais são naturalmente propensas a bugs. Transições incorretas podem levar a estados inválidos. Debugging de state machines complexas é desafiador. Cada adição de estado ou transição aumenta a complexidade exponencialmente se não houver discipline.

3.1.3. Caveats (Pontos de Atenção Críticos)

Idempotência Obrigatória

Todas as operações devem ser idempotentes pois Celery pode executar retry automático em caso de falha. Operações não-idempotentes (como envio de email sem deduplicação) podem resultar em duplicação de ações. Deduplicação explícita é necessária em pontos críticos.

Atomicidade Transacional

Cuidado especial é necessário com transações que envolvem PostgreSQL e RabbitMQ simultaneamente. Não há transação distribuída nativa - é preciso implementar padrões como outbox pattern ou aceitar eventual consistency. Falhas parciais podem causar inconsistências.

Configuração de Timeouts em Múltiplas Camadas

Timeouts precisam ser configurados corretamente em todos os níveis: RabbitMQ (ack timeout), Celery (task timeout), HTTP clients (para chamadas LLM e APIs externas). Configuração incorreta pode levar a tarefas "fantasma" ou bloqueio de workers.

Risco de Deadlocks

Em state machines complexas com múltiplas transições concorrentes, há risco de deadlocks. Design cuidadoso de locks e ordem de aquisição de recursos é necessário. Transações PostgreSQL longas podem causar bloqueios.

High Availability

RabbitMQ precisa ser configurado em cluster para high availability. Celery Beat (scheduler) precisa ser singleton - apenas uma instância pode rodar simultaneamente, criando potential single point of failure. PostgreSQL precisa de índices otimizados para queries de estado frequentes.

Integração com CRM Konecty

Bridge entre Konecty (Node.js) e Lead Flow (Python) requer API bem definida ou eventos RabbitMQ padronizados. Consistência de dados entre sistemas precisa ser garantida. Versionamento de APIs é importante para evolução independente.

3.1.4. Limitations (Limitações Técnicas)

Limitações Fundamentais

Celery não suporta nativamente workflows de anos - workarounds são necessários mas aumentam complexidade significativamente. PostgreSQL como queue tem limitações conhecidas: write-heavy workload causa bloat, vacuum overhead pode impactar performance. RabbitMQ introduz latência mínima de aproximadamente 100ms por hop. State machine manual é naturalmente error-prone.

Restrições de Escala

Workers Celery têm limite de concorrência por worker (tipicamente 4-16 processos concorrentes). RabbitMQ pode se tornar bottleneck em cargas muito altas (dezenas de milhares de mensagens/segundo). PostgreSQL com carga write-heavy requer tuning específico e pode requerer sharding para escalar além de certo ponto.

Limitações de Funcionalidade

Não há UI nativa para visualização de workflows - qualquer interface precisa ser construída. Versionamento de workflows não é automático - é responsabilidade da aplicação. Histórico de execução não é nativo - precisa ser implementado explicitamente. Debugging de workflows complexos é difícil sem ferramentas customizadas.

Limitações de Observabilidade

Não há tracing distribuído nativo - precisa ser implementado. Métricas customizadas requerem instrumentação manual. Debugging de problemas em produção depende de logging adequado implementado proativamente.

3.1.5. Trade-offs Técnicos

Simplicidade vs Confiabilidade

Ganha-se código simples e compreensível. Perde-se confiabilidade automática - toda lógica de retry, error handling e recuperação precisa ser implementada manualmente. Cada linha de código de confiabilidade é uma linha que pode ter bugs.

Flexibilidade vs Complexidade

Ganha-se customização total da lógica sem restrições. Perde-se as facilidades de abstrações prontas - mais código para escrever, testar e manter. A liberdade total tem o custo de responsabilidade total.

Custo Inicial vs Custo de Manutenção

Ganha-se baixo custo inicial de infraestrutura. Perde-se em custo de manutenção contínua se a complexidade crescer sem controle. Debt técnico pode se acumular mais rápido em soluções custom.

Controle vs Produtividade

Ganha-se controle total sobre implementação. Perde-se produtividade que features prontas de frameworks especializados trariam. Funcionalidades que seriam nativas em Temporal precisam ser implementadas do zero.

3.1.6. Mitigations (Estratégias de Mitigação)

Para Processos Longos

Implementar uma tabela dedicada de scheduled_tasks com retry logic robusto. Usar polling periódico via Celery Beat para verificar tarefas vencidas (não depender apenas de Celery scheduler). Separar explicitamente estado do lead de estado de tarefas agendadas. Implementar archival automático de tarefas antigas.

Para Confiabilidade

Implementar idempotência rigorosa em todos os handlers. Usar transações PostgreSQL corretamente com rollback em caso de erro. Configurar RabbitMQ com acknowledgments explícitos. Implementar dead letter queues para mensagens que falharam múltiplas vezes.

Para Performance

Cachear leituras frequentes usando Redis. Otimizar índices PostgreSQL para queries comuns. Usar connection pooling para PostgreSQL e RabbitMQ. Monitorar e ajustar dinamicamente worker pool size baseado em carga.

Para Observabilidade

Implementar structured logging (JSON logs) desde o início. Usar Flower para monitoramento específico de Celery. Implementar métricas custom com Prometheus. Criar dashboards Grafana para visualização.

Para State Machine

Usar biblioteca especializada como python-statemachine ou transitions. Escrever testes exaustivos de todas as transições possíveis. Documentar state machine com diagramas. Implementar validações rigorosas em cada transição.


3.2. Alternativa 2: Temporal.io

3.2.1. Vantagens Técnicas

Suporte Nativo a Processos de Longa Duração

Temporal foi projetado especificamente para workflows que duram dias, meses ou anos. Workflows podem ter timers de duração arbitrária - um timer de 1 ano é tratado exatamente como um timer de 1 minuto. O estado é persistido automaticamente em cada passo, permitindo recuperação transparente. Não há workarounds necessários - é funcionalidade core do sistema.

Confiabilidade e Recuperação Automática

Execução durável é garantida por design - se um worker falha, outro retoma o workflow exatamente de onde parou. Retries são configuráveis e automáticos, tanto para workflows quanto para activities. Recuperação de falhas é transparente - o desenvolvedor não precisa implementar lógica de recuperação manualmente. Histórico completo de execução é mantido automaticamente.

Simplicidade de Código para Workflows

Workflows são definidos como código Python imperativo padrão - não é necessário definir state machines complexas explicitamente. A abstração de distribuição é feita pelo Temporal - o código workflow parece síncrono mas executa de forma distribuída. Versionamento de workflows é nativo - workflows antigos continuam rodando em versão antiga enquanto novos usam versão nova.

Observabilidade de Classe Mundial

Temporal UI fornece visualização nativa de todos os workflows ativos, histórico de execução, eventos, retries. Métricas e tracing são nativos - não é necessário instrumentação custom extensa. Debugging é facilitado pela UI - é possível ver exatamente em que passo cada workflow está. Histórico de execução completo permite análise post-mortem de problemas.

Escalabilidade Horizontal Nativa

Temporal escala horizontalmente por design - adicionar workers aumenta capacidade automaticamente. Task queues permitem paralelização natural de workloads. Performance é consistente independente da escala. O sistema foi projetado para cargas enterprise.

Integração Estruturada com IA

Activities são ideais para chamadas LLM - isoladas, retriáveis, testáveis. Retry automático de chamadas LLM falhas sem código adicional. Workflow state naturalmente mantém contexto para LLM entre chamadas. Signals permitem feedback de IA para workflows em execução. Testing de integração com LLM é facilitado por mock de activities.

3.2.2. Desvantagens Técnicas

Curva de Aprendizado

Temporal tem modelo de programação único e específico que requer aprendizado. Conceitos novos precisam ser assimilados: Workflows, Activities, Signals, Queries, Timers, Child Workflows. Restrições de código em workflows (determinismo) são não-intuitivas inicialmente. Há menos exemplos e recursos que para stacks tradicionais.

Complexidade de Infraestrutura

Temporal Server precisa ser gerenciado (se self-hosted) ou pago (se cloud). Banco de dados adicional é necessário para Temporal (PostgreSQL, MySQL ou Cassandra). Configuração de cluster Temporal para high availability é complexa. Overhead operacional é significativo - mais um sistema crítico para monitorar e manter.

Overhead para Workflows Simples

Setup inicial é mais complexo que solução custom simples. Pode ser overkill para workflows triviais. Infraestrutura dedicada é necessária mesmo para volume baixo. O benefício só justifica o custo para workflows realmente complexos ou de longa duração.

Limitações Documentadas

Event sourcing overhead: história de workflow pode crescer indefinidamente se workflow tem muitos eventos (fonte: pesquisa técnica). Debugging pode ser complexo: entender state transitions requer familiaridade com modelo Temporal. Python SDK é menos maduro que Go e Java SDKs (fonte: pesquisa técnica) - algumas features podem não estar disponíveis. Latência: arquitetura distribuída introduz overhead.

Vendor Lock-in

Código de workflows é acoplado a Temporal APIs - não há portabilidade direta. Migração futura para outro sistema seria complexa. Dependência de Temporal para operação - se Temporal tem problema, todo sistema é afetado.

3.2.3. Caveats (Pontos de Atenção Críticos)

Restrições de Determinismo em Workflows

Workflows devem ser determinísticos - não podem usar random, time.now, I/O direto, ou qualquer operação não-determinística. Toda operação externa deve ser feita via Activity. Violações de determinismo causam bugs sutis e difíceis de diagnosticar. Discipline de código rigorosa é necessária.

Gerenciamento de Workflow History Growth

História de workflow pode crescer indefinidamente em workflows com muitos eventos. History muito grande impacta performance e custos de storage. Design consciente é necessário para minimizar número de events. Monitoramento de history size é crítico.

Requisitos de Infraestrutura

Temporal Server requer recursos significativos (CPU, memória, storage). Setup de high availability é complexo - requer múltiplos nós, load balancer, database cluster. Storage para workflow history pode crescer rapidamente. Monitoring do cluster health é crítico.

Integração com RabbitMQ Existente

Temporal não substitui RabbitMQ diretamente - tem seu próprio sistema de task queues. Activities são necessárias para consumir eventos RabbitMQ - não há integração nativa. Bridge/adapter precisa ser implementado. Há dupla infraestrutura (RabbitMQ + Temporal) até possível migração completa.

3.2.4. Limitations (Limitações Técnicas)

Limitações do Python SDK

Python SDK tem menos features que Go e Java SDKs (fonte: pesquisa técnica). Comunidade Python no Temporal é menor - menos exemplos e bibliotecas complementares. Atualizações podem demorar mais para chegar ao Python SDK. Documentação e tutoriais focam mais em Go e Java.

Performance e Overhead

Latência adicional por arquitetura distribuída - operações passam por Temporal Server. Overhead de persistência de estado em cada step do workflow. Throughput depende de configuração e recursos do cluster Temporal. Para operações síncronas de baixa latência, Temporal pode não ser ideal.

Funcionalidade e Operação

Workflow versioning tem limitações - nem toda mudança de código é compatível. Migrações de workflow em execução podem ser complexas. Debugging de workflows rodando é limitado. Modificação de workflow state em execução é altamente restrita por design.

Integração e Testing

Integrações com sistemas externos são sempre via Activities - pode ser verboso. Testing de integrations requer mock de activities ou setup de test server Temporal. Testing end-to-end é mais complexo que em solução custom.

3.2.5. Trade-offs Técnicos

Confiabilidade vs Complexidade

Ganha-se confiabilidade automática robusta e testada em produção. Perde-se simplicidade - há complexidade de infraestrutura adicional (Temporal Server, cluster management).

Produtividade vs Aprendizado

Ganha-se produtividade após dominar Temporal - features prontas aceleram desenvolvimento. Perde-se tempo em aprendizado. ROI só é positivo se projeto é suficientemente complexo.

Abstração vs Controle

Ganha-se abstração poderosa que esconde complexidade de distribuição. Perde-se controle fino sobre detalhes de implementação. Otimizações low-level podem ser impossíveis. Está-se limitado ao que Temporal permite.

Custo de Setup vs Custo de Manutenção

Ganha-se menor custo de manutenção a longo prazo - features prontas reduzem código custom. Perde-se em custo de setup inicial (infraestrutura, aprendizado, configuração) que é significativamente maior. Temporal Cloud tem custo recorrente.

3.2.6. Mitigations (Estratégias de Mitigação)

Para Curva de Aprendizado

Começar com workflows extremamente simples para familiarização. Criar documentação interna detalhada com patterns e anti-patterns. Estudar exemplos oficiais e casos de uso similares.

Para Complexidade de Infraestrutura

Considerar Temporal Cloud inicialmente para reduzir overhead operacional. Automatizar deployment com Infrastructure as Code. Implementar monitoramento desde o início com alertas críticos. Documentar arquitetura e procedimentos operacionais.

Para History Growth

Arquivar workflows completed periodicamente. Configurar retention policies adequadas. Monitorar history size de workflows ativos. Design workflows para minimizar número de events. Usar continue-as-new pattern para workflows de duração muito longa.

Para Integração com RabbitMQ

Implementar Activity dedicada para consumir mensagens RabbitMQ. Usar Signal para notificar workflows de eventos externos via RabbitMQ. Criar adapter layer limpo entre RabbitMQ e Temporal. Documentar padrões de integração.

Para Limitações do Python SDK

Monitorar roadmap do Python SDK. Reportar issues prontamente. Ter workarounds documentados para limitações conhecidas.


3.3. Alternativa 3: Abordagem Híbrida Incremental

3.3.1. Vantagens Técnicas

Validação Antes de Investimento

Permite validar modelo de negócio e requisitos técnicos reais antes de investir em Temporal. Decisão de migração é baseada em necessidade comprovada, não em especulação. Dados reais informam a escolha ao invés de suposições arquiteturais.

Aprendizado Incremental

Aprendizado sobre Temporal pode acontecer gradualmente. Risco é distribuído - não há "big bang" que pode falhar. Aprendizado é baseado em problema real, não em teoria abstrata.

YAGNI Aplicado

Complexidade é adicionada apenas quando necessidade é comprovada com dados. Evita-se over-engineering prematuro. Decisões são informadas por métricas reais: quantos leads ficam em processo longo? Taxa de falhas de recuperação? Custo real de manutenção?

Flexibilidade de Decisão

Não há lock-in prematuro em nenhuma decisão. Se Temporal provar-se inadequado após POC, custo de voltar atrás é gerenciável. Se customizado for suficiente, não há desperdício de investimento em Temporal. Decisão final é data-driven.

Uso da Ferramenta Certa

Processos simples e rápidos permanecem customizados (simples, direto). Processos longos e complexos são migrados para Temporal (confiabilidade). Não há pressão para "padronizar tudo" - pragmatismo é permitido.

3.3.2. Desvantagens Técnicas

Complexidade de Dupla Arquitetura

Dois sistemas distintos para manter simultaneamente durante transição. Duas formas diferentes de implementar workflows - conhecimento de ambas necessário. Risco de inconsistência entre sistemas. Testing precisa cobrir ambos os sistemas e interação entre eles.

Overhead de Migração

Tempo investido em migração é tempo não investido em features. Risco de bugs durante transição - código antigo e novo coexistindo. Testing exaustivo é necessário para cada componente migrado. Rollback precisa ser possível.

Decisões de Fronteira Complexas

Difícil decidir exatamente o que migrar e quando. Risco de migração prematura ou tardia. Fronteira entre sistemas pode ser arbitrária.

Debt Técnico Temporário

Código bridge entre sistemas é temporário mas precisa ser mantido. Adaptadores temporários podem acumular. Documentação precisa cobrir ambos os sistemas. Time pode ficar confuso sobre abordagem correta.

3.3.3. Caveats (Pontos de Atenção Críticos)

Estratégia de Migração Clara

Definir critérios objetivos para migração desde o início: métricas que disparam decisão. Executar strangler fig pattern corretamente - substituir funcionalidade gradualmente, não rewrite big bang. Evitar "middle ground" permanente - coexistência deve ser temporária. Comunicar claramente a estratégia para alignment.

Consistência de Dados Entre Sistemas

Single source of truth para dados críticos (PostgreSQL). Event sourcing pode ajudar a manter histórico consistente. Reconciliação periódica pode ser necessária. Validações em múltiplos níveis.

Operação Dual

Duas stacks para monitorar simultaneamente. Expertise necessária em ambos sistemas. On-call precisa conhecer troubleshooting de ambos. Incidentes podem ser mais complexos.

3.3.4. Limitations (Limitações Técnicas)

Complexidade Operacional

Duas infraestruturas simultaneamente durante transição. Expertise em ambos sistemas é necessária. Deploy precisa coordenar ambos sistemas. Monitoramento e alertas precisam cobrir ambos.

Performance com Bridge

Adapter layer entre sistemas introduz latência adicional. Possível inconsistência de latência entre requests. Debugging de performance é mais difícil. Bottlenecks podem estar no bridge.

Risco de Migração Incompleta

Migração pode "estancar" no meio - sistemas coexistindo indefinidamente. Custo de completar migração pode ser subestimado. Pressão de features novas pode postergar migração.

3.3.5. Trade-offs Técnicos

Gradualismo vs Decisão

Ganha-se decisão informada por dados reais - não é aposta cega. Perde-se clareza de arquitetura única - período de dual complexity.

Flexibilidade vs Consistência

Ganha-se flexibilidade de escolher ferramenta certa para problema. Perde-se consistência de patterns - dois jeitos de fazer mesma coisa.

Baixo Risco Inicial vs Complexidade Temporária

Ganha-se baixo risco inicial - validação sem bet grande. Perde-se simplicidade durante transição - complexidade temporária é inevitável.

3.3.6. Mitigations (Estratégias de Mitigação)

Para Complexidade Dual

Definir fronteiras arquiteturais claras entre sistemas. Documentar quando usar cada sistema. Automatizar deploys de ambos sistemas. Criar abstrações comuns onde possível.

Para Migração

Migrar workflows isolados primeiro. Testing exaustivo durante migração. Rollback plan detalhado para cada componente. Feature flags para habilitar/desabilitar código novo gradualmente.

Para Consistência

Padrões de design comuns onde possível. Code review cross-system. Documentação unificada. Alignment regular de decisões técnicas.

Para Decisão de Convergência

Coletar métricas objetivas durante transição: custo de manutenção, bugs, velocidade desenvolvimento. Revisão técnica formal para decisão baseada em dados. Coragem para decidir: convergir para Temporal, voltar para custom, ou manter híbrido justificadamente.


4. Análise Contextual

4.1. Impacto da IA no Processo

Padrões de Integração com LLMs

A integração com LLMs é central ao Lead Flow - a IA avalia estado continuamente e propõe ações. Padrões arquiteturais relevantes:

Orchestrator-Worker Pattern: Agente orquestrador central (IA) avalia estado de leads e delega ações para workers especializados. O orquestrador mantém contexto global e toma decisões estratégicas. Workers executam ações específicas. Este pattern funciona bem tanto em custom quanto em Temporal.

Centralized Orchestration: Manager agent coordena todas as interações, mantém ledger de tarefas, suporta execução paralela e sequencial. Shared memory mantém estado consistente. Dynamic re-planning permite ajustes em tempo real. Temporal facilita este pattern com Workflow State e Signals.

State Evaluation: Agente acessa estado persistido (PostgreSQL) para decisões. Estado inclui histórico completo, metadata, interações. IA constrói contexto rico. Custom e Temporal divergem aqui - Temporal tem Workflow History nativo, Custom precisa implementar.

Como Cada Alternativa Facilita IA

Na abordagem customizada, Python é lingua franca de IA - todas as bibliotecas são Python-first. Controle total sobre construção de prompts e gerenciamento de contexto permite otimizações finas. Experimentação rápida é facilitada. Caching customizado pode reduzir custos significativamente. Porém, retry de chamadas LLM falhas é manual. Context management através de múltiplas chamadas é responsabilidade do desenvolvedor.

Com Temporal, Activities isolam chamadas LLM - cada chamada é retriável automaticamente. Workflow State naturalmente mantém contexto entre chamadas sucessivas. Testing é facilitado - Activities podem ser mockadas. Signals permitem feedback loops. Porém, há menos controle fino sobre otimizações de custo. Latência é ligeiramente aumentada por overhead de Activity execution.

Gerenciamento de Contexto e Janela de Tokens

LLMs têm janelas de contexto limitadas (tipicamente 8k-128k tokens). Gerenciar contexto é crítico para decisões de qualidade.

Estratégias necessárias: manter apenas contexto relevante na janela; usar summarization para histórico longo; structured prompts para consistency; priorizar informações recentes; truncar inteligentemente quando limite é atingido.

Custom oferece flexibilidade máxima mas responsabilidade total no context management. Temporal mantém histórico completo disponível mas custo de transferir para LLM é responsabilidade da aplicação.

Prompt Engineering e Few-Shot Learning

Qualidade de decisões da IA depende de prompt engineering. Elementos essenciais: system prompt definindo papel; contexto estruturado; few-shot examples; formato de saída estruturado (JSON); instruções claras.

Few-shot learning é crítico para consistência. Exemplos de transições bem-sucedidas ensinam a IA. Exemplos de edge cases previnem erros. Formato consistente facilita parsing.

Ambas abordagens suportam prompt engineering igualmente - é responsabilidade da aplicação. Custom tem vantagem em experimentação rápida. Temporal tem vantagem em versionamento - diferentes versões de workflows podem usar diferentes prompts.

Validação de Respostas LLM

LLMs podem retornar respostas mal formatadas ou incorretas. Validação rigorosa é necessária.

Estratégias: schema validation (Pydantic) para garantir formato; retry com prompt refinement se resposta inválida; fallback para regras determinísticas; confidence scoring; logging extensivo.

Custom dá controle total sobre validação. Temporal permite validação dentro de Activities - resposta inválida causa retry automático.

Automação vs Intervenção Humana

Nem todas as decisões devem ser automatizadas. Critérios: risco da decisão; confiança do LLM; reversibilidade; padrão vs edge case.

Decisões de baixo risco com alta confiança podem ser automatizadas. Decisões de alto impacto requerem humano (descartar lead, aceitar proposta final).

Ambas arquiteturas suportam este pattern - é lógica de aplicação. Temporal facilita pausar workflow para decisão humana - Signals são ideais.

Feedback Loops e Aprendizado

IA precisa melhorar baseado em outcomes reais. Feedback loops essenciais: coletar outcomes de decisões; A/B testing de prompts; refinamento contínuo; human feedback para casos edge; análise agregada.

Ambas suportam feedback loops - é lógica sobre dados coletados. Custom pode ter mais flexibilidade para experimentação. Temporal tem vantagem em histórico completo - facilita análise post-mortem.


5. Matriz de Decisão Técnica

Critério Técnico Customizada Temporal Híbrida
Simplicidade arquitetural ⭐⭐⭐⭐ Componentes diretos ⭐⭐⭐ Abstração, setup complexo ⭐⭐ Dual stack temporário
Integração com IA/LLMs ⭐⭐⭐⭐⭐ Python nativo, controle total ⭐⭐⭐⭐ Activities isolam bem ⭐⭐⭐⭐ Depende da fase
Suporte a processos longos (>1 ano) ⭐⭐ Workarounds necessários ⭐⭐⭐⭐⭐ Nativo e robusto ⭐⭐⭐ Gradual para Temporal
Confiabilidade e recuperação ⭐⭐⭐ Manual mas viável ⭐⭐⭐⭐⭐ Automática por design ⭐⭐⭐⭐ Melhora com migração
Escalabilidade técnica ⭐⭐⭐ Manual, requer tuning ⭐⭐⭐⭐⭐ Horizontal automático ⭐⭐⭐ Dual durante transição
Custo de infraestrutura ⭐⭐⭐⭐⭐ Mínimo ⭐⭐⭐ Médio-Alto ⭐⭐⭐ Médio temporariamente
Flexibilidade para mudanças ⭐⭐⭐⭐⭐ Total, sem restrições ⭐⭐⭐⭐ Alta, dentro do modelo ⭐⭐⭐⭐ Alta
Observabilidade ⭐⭐⭐ Custom, requer implementação ⭐⭐⭐⭐⭐ Nativo, UI completa ⭐⭐⭐ Dual, mais complexo
Manutenibilidade longo prazo ⭐⭐⭐ Requer discipline ⭐⭐⭐⭐ Workflows sustentáveis ⭐⭐ Durante coexistência
Risco de vendor lock-in ⭐⭐⭐⭐ Baixo (open-source) ⭐⭐ Médio-Alto (APIs específicas) ⭐⭐⭐ Mitigado

Interpretação: - ⭐⭐⭐⭐⭐ Excelente - ⭐⭐⭐⭐ Bom - ⭐⭐⭐ Adequado - ⭐⭐ Limitações significativas - ⭐ Inadequado

Insights da Matriz:

Customizada domina em: simplicidade, integração IA, custo, flexibilidade, baixo lock-in.

Temporal domina em: processos longos, confiabilidade automática, escalabilidade, observabilidade.

Híbrida oferece: transição baseada em dados, mas com complexidade dual temporária.

A escolha depende de qual critério é mais crítico para o contexto específico do projeto.


6. Riscos Técnicos e Mitigações

6.1. Riscos Comuns

Integração com LLM Falha ou Degradada

Impacto: Sistema não pode tomar decisões guiadas por IA. Probabilidade: Média. Mitigações: Fallback para regras determinísticas. Retry com exponential backoff. Circuit breaker pattern. Cache agressivo. Monitoramento contínuo. Testing de modo degradado.

Estado Inconsistente Entre Sistemas

Impacto: Decisões baseadas em dados incorretos. Probabilidade: Média-Alta em arquiteturas distribuídas. Mitigações: Single source of truth (PostgreSQL). Event sourcing para auditoria. Validações em múltiplos níveis. Reconciliação periódica. Idempotência rigorosa.

Performance Degrada com Escala

Impacto: SLAs não cumpridos. Probabilidade: Alta sem planejamento. Mitigações: Load testing contínuo. Monitoramento de métricas. Otimização de queries. Caching estratégico. Preparação para horizontal scaling. Capacity planning.

Custo de LLM Explode

Impacto: Custo operacional insustentável. Probabilidade: Média-Alta sem controles. Mitigações: Caching agressivo. Rate limiting interno. Usar modelos apropriados. Monitoramento de custos em tempo real. Alertas de budget. Circuit breaker.

Complexidade Cresce Descontroladamente

Impacto: Manutenibilidade degrada. Probabilidade: Alta sem discipline. Mitigações: Code reviews rigorosos. Refactoring contínuo. Documentação de decisões (ADRs). KISS/YAGNI enforced. Testes abrangentes. Métricas de qualidade.

6.2. Riscos Específicos

Customizada: State Machine Bugs

Mitigação: Usar biblioteca especializada. Testes exaustivos. Property-based testing. Visualização de state machine. Validações rigorosas.

Customizada: Perda de Tarefas Agendadas

Mitigação: Persistência explícita em PostgreSQL. Polling periódico. Redundância de scheduling. Monitoring de gaps.

Temporal: History Growth Descontrolado

Mitigação: Design para minimizar events. Continue-as-new pattern. Monitoring de history size. Archival automático. Retention policies.

Temporal: Custo Elevado

Mitigação: Estimar custos baseado em volume. Considerar self-hosted para volume alto. Otimizar executions. Monitoring contínuo.

Híbrida: Coexistência Indefinida

Mitigação: Definir deadline para convergência. Métricas objetivas. Commitment de completar migração. Não adicionar features em sistema a ser deprecado.


Versão: 1.0
Status: Análise técnica completa - para referência
Relacionado: Ver decisao-arquitetura-final.md para a decisão adotada