Quando alguém decide construir uma carreira tech internacional, quase sempre a conversa gira em torno de idioma, currículo e oportunidade. Parece uma decisão de coragem. Um salto. Uma virada de chave.
Eu também pensei assim.
Mas ninguém me disse que o maior desafio não seria técnico. Seria estratégico.
Mudar de país não é levar sua senioridade pronta. É reapresentar sua senioridade para um sistema que não viveu sua história. Você chega com anos de experiência, projetos entregues, decisões tomadas sob pressão. Só que, do outro lado, ninguém acompanhou isso. Você deixa de ser referência e volta a ser observado.
Lembro claramente das primeiras reuniões que participei fora do Brasil ano passado. Eu tinha clareza sobre o que precisava ser feito. Já tinha passado por situações parecidas antes. No Brasil, eu teria sido mais direto. Teria feito uma recomendação objetiva e seguido adiante.
Mas ali, eu percebi que o ritmo era outro.
As decisões eram mais circulares. A comunicação era mais medida. A discordância precisava vir embalada em contexto. Não era sobre estar certo. Era sobre como conduzir a conversa sem gerar ruído desnecessário.
Foi ali que caiu a ficha. Não era só adaptação cultural. Era gestão de ambiente.
Carreira internacional é um projeto porque exige mapeamento constante. Você precisa entender quem realmente influencia decisões. Precisa alinhar expectativa com mais frequência. Precisa comunicar impacto com intenção. Entrega isolada não constrói reputação. Consistência constrói.
E tem a gestão de risco, que quase ninguém calcula. Trabalhar em outro idioma o dia inteiro consome energia. Pequenas interações exigem mais atenção. Você pensa duas vezes antes de responder. Ajusta tom. Revisa mentalmente o que vai falar. Isso drena recurso. E todo projeto que drena recurso precisa ser administrado com consciência.
Nos primeiros meses, eu percebi que estava mais cansado fazendo o mesmo tipo de trabalho que já fazia antes. Não era falta de competência. Era falta de familiaridade com o sistema. Eu ainda estava construindo mapa.
A maioria das pessoas trata essa fase como se fosse temporária e automática. Não é. Se você não gerencia os primeiros 90 dias como fase crítica, começa a duvidar da própria capacidade. Quando, na verdade, o que falta é estratégia.
Com o tempo, a perspectiva muda. Você começa a planejar a médio prazo. Entende que reputação local é construída com pequenos acertos repetidos. Aprende a alinhar expectativa antes de entregar. Aprende a ler silêncio em reunião. Aprende que influência, em outro país, não vem do volume da sua voz, mas da consistência da sua presença.
Carreira tech internacional não é glamour. É governança pessoal. É execução disciplinada em ambiente novo. É aceitar que você vai reaprender a navegar mesmo sendo experiente.
A diferença é que quase ninguém faz isso com método.
E qual é o método?
Não é um framework sofisticado. É algo mais simples e mais difícil ao mesmo tempo. Tratar sua transição como um projeto de longo prazo. Definir fases. Mapear riscos reais. Revisar estrategia a cada trimestre. Pedir feedback de forma intencional. Ajustar posicionamento antes de ajustar currículo. Medir reputação pelo que você ouve nas entrelinhas, não só pelo que aparece no organograma.
Quando você começa a fazer isso, a carreira deixa de ser uma aposta emocional e vira construção deliberada.
A transição deixa de ser um salto no escuro e vira execução.
O ciclo de QA, um conjunto de práticas que garantem a qualidade de um software desde a definição de requisitos até os testes finais e o monitoramento pós-produção, está passando por uma das maiores mudanças desde a chegada da automação. A adoção de IA generativa deixou de ser uma aposta futurista para se tornar uma alavanca concreta de eficiência, previsibilidade e escala. O movimento ganhou velocidade à medida que modelos generativos passaram a ser integrados diretamente aos pipelines de desenvolvimento, permitindo que a qualidade acompanhasse o ritmo acelerado das entregas. O que antes demandava grandes times manualizando testes repetitivos, hoje é sustentado por automações inteligentes capazes de interpretar requisitos, aprender com dados reais de uso e evoluir continuamente com o produto.
O avanço mais visível ocorre na geração e priorização de casos de teste. A leitura automática de user stories e logs transforma o processo de desenho de cenários em uma atividade dinâmica, guiada por probabilidade real de falha e contexto de negócio. Essa inteligência muda o próprio papel do QA, que passa de executor para curador, garantindo relevância e consistência dos testes enquanto a IA acelera a criação, a manutenção e a priorização. A automação contínua de regressões segue o mesmo caminho. Scripts deixam de ser artefatos estáticos e passam a se adaptar ao comportamento do sistema por meio de auto healing, preservando estabilidade mesmo em ambientes de mudanças frequentes. O impacto direto aparece no tempo, no custo e no volume de retrabalho que deixam de consumir o ciclo de desenvolvimento.
Os ganhos começam a se consolidar em números. A redução de até 40% no tempo dedicado à criação e manutenção de automações evidencia como a geração inteligente de testes substitui tarefas repetitivas por atividades de análise e curadoria. A economia média de 30% em custos de QA reforça o efeito de uma estrutura sob demanda, movida por automações sustentáveis que escalam conforme a necessidade do negócio. A eficiência das regressões cresce até 50% graças a execuções paralelas e priorização baseada em risco. E a queda de incidentes em produção chega a 60% quando regressão contínua e observabilidade de qualidade caminham juntas. O ponto central é que automação e IA só produzem resultados consistentes quando conectadas a métricas de impacto, permitindo que qualidade e performance do produto conversem diretamente com receita, churn, NPS e risco operacional.
As frentes mais transformadas são também as mais críticas do ciclo de QA. Testes funcionais e regressões se beneficiam imediatamente da geração autônoma de cenários e da atualização inteligente de scripts. Performance e carga passam a contar com análises preditivas de gargalos e simulações automáticas orientadas por machine learning. Usabilidade e experiência do cliente avançam com monitoramento sintético e leitura do comportamento real dos usuários. Segurança se fortalece por meio da identificação automática de vulnerabilidades em código e APIs, com apoio de análises estáticas e generativas. A convergência dessas camadas cria um fluxo contínuo de qualidade guiado por IA, no qual a técnica conversa com o negócio e o negócio determina o foco da automação.
Esse movimento já se comprova na prática. Em um projeto recente no setor industrial o desafio era estabilizar o ciclo de releases semanais e reduzir falhas na produção. A geração automática de casos de regressão a partir do backlog reduziu a dependência de criação manual, enquanto a integração das automações ao pipeline CI/CD (Continuous Integration e Continuous Delivery), permitiu execuções mais rápidas e precisas. A leitura contínua das métricas de falha e cobertura consolidou um modelo de feedback capaz de orientar ajustes de sprint para sprint. Em 90 dias, a cobertura automatizada das jornadas críticas chegou a 78%, os incidentes de produção caíram 45%, os custos mensais de QA diminuíram 32% e o tempo médio de release passou de dez para seis dias. Resultados desse porte demonstram que a combinação entre IA generativa, governança e automação contínua é capaz de transformar a qualidade em vantagem competitiva.
Ainda assim, a adoção de IA generativa em QA exige cuidados que não podem ser ignorados. A rastreabilidade de scripts e dados produzidos por modelos generativos é essencial para manter a auditabilidade. A validação humana precisa continuar atenta a falsos positivos e a testes de baixo valor que podem escapar à lógica dos modelos. A integração com dados sensíveis requer protocolos rígidos de segurança, especialmente em ambientes regulados. E os times precisam estar preparados para interpretar e ajustar o trabalho da IA, garantindo que ela atue como aceleradora e não como substituta da inteligência humana. Governança, observabilidade e curadoria são tão importantes quanto o modelo em si.
A incorporação da IA generativa no ciclo de QA marca uma mudança estrutural na forma como times de tecnologia entregam valor. A qualidade deixa de ser um gargalo no fim da cadeia e passa a atuar como motor de decisão, antecipando riscos e influenciando prioridades desde o início. A automação inteligente amplia a capacidade humana ao transformar dados em ação, reduzindo incertezas e fortalecendo a previsibilidade das entregas. O futuro da engenharia de software será definido por quem conseguir unir modelos generativos, governança madura e visão de negócio em um fluxo contínuo de qualidade. A escolha agora é entre acompanhar a evolução ou continuar reagindo aos problemas depois que chegaram ao usuário.
Fundamentação: QuestPDF e geração determinística de layout
QuestPDF é uma biblioteca .NET que permite gerar PDFs por meio de bibliotecas baseadas em composição de layouts (QUESTPDF, 2026). Em vez de converter HTML/CSS para PDF, o QuestPDF descreve explicitamente a hierarquia de containers e componentes, reduzindo a ambiguidade de renderização e fornecendo controle fino sobre tipografia, espaçamentos, grids e tabelas. Na prática, isso desloca a “fonte de verdade” do layout para o código, o que facilita versionamento, revisão e testes em pipelines de CI/CD.
Do ponto de vista operacional, um gerador de PDF é sensível a variáveis como fontes disponíveis, imagens e uso de memória. O modelo determinístico de composição reduz variabilidade entre ambientes, mas não elimina a necessidade de padronização de assets (p.ex., incorporar fontes no container ou distribuí-las como recursos do serviço). Assim, a biblioteca é parte da solução; o restante depende do desenho arquitetural de como dados são coletados, como o documento é gerado (sincrono vs. assíncrono) e como o artefato é entregue e auditado.
Materiais e métodos
O método adotado é descritivo e aplicado, orientado a padrões de arquitetura de software e práticas de engenharia. Parte-se do problema de geração de documentos em sistemas distribuídos e modela-se um fluxo de referência: (i) coleta de dados por serviços de domínio, (ii) composição do payload de geração, (iii) geração do PDF via serviço dedicado e (iv) entrega/armazenamento do artefato. Em seguida, discute-se como requisitos não funcionais (latência, escalabilidade, rastreabilidade e segurança) influenciam as decisões de implementação.
Os trechos de código apresentados têm caráter ilustrativo e visam demonstrar interfaces e responsabilidades, não constituindo um benchmark formal. O foco é enfatizar separação de preocupações (layout vs. domínio), reprodutibilidade (idempotência e cache) e observabilidade (tracing e métricas) como critérios de qualidade para serviços de geração.
Arquiteturas de referência para geração de documentos
Microserviços e isolamento da capacidade de renderização
Em arquiteturas de microserviços, a geração de documentos é frequentemente isolada em um serviço dedicado (document service) (NADAREISHVILI, 2016). Essa separação reduz o acoplamento entre regras de negócio e renderização, evita que serviços de domínio carreguem dependências de layout e permite escalar horizontalmente a geração de PDFs de forma independente. Além disso, o isolamento favorece governança do ciclo de vida do documento (versionamento, auditoria e retenção), pois o serviço de documentos torna-se o ponto natural para aplicar políticas uniformes.
O serviço dedicado pode receber comandos sincrônicos (HTTP) quando o usuário final precisa do documento imediatamente, ou assíncronos (mensageria) quando o documento é pesado, quando há picos de carga ou quando a geração deve ser resiliente a falhas temporárias. Independentemente do modo de invocação, recomenda-se que o serviço opere sobre DTOs já normalizados e validados, evitando dependência direta em banco de dados de domínio ou chamadas em cascata durante a renderização.
O API Gateway pode atuar como fachada do sistema, centralizando autenticação, versionamento, rate limiting e roteamento (LEVCOVITZ et al., 2016). Em cenários de documentos, ele pode orquestrar chamadas para múltiplos serviços a fim de construir um payload completo (por exemplo, dados de pedido, cliente e pagamentos) antes de solicitar a geração do PDF. Essa abordagem melhora a experiência do consumidor da API, mas deve ser usada com cautela para evitar que o gateway se torne um orquestrador complexo e difícil de manter.
Uma alternativa é deslocar a composição de dados para um serviço de aplicação (backend-for-frontend ou orchestration service) que monta o DTO e chama o serviço de documentos. Assim, o gateway mantém-se fino e os fluxos ficam mais testáveis. A escolha depende do grau de complexidade e do modelo organizacional de responsabilidades.
publicclassDocumentsController:ControllerBase{privatereadonlyDocumentGenerationService _service;publicDocumentsController(DocumentGenerationService service){
_service = service;}[HttpPost("invoice")]publicasyncTask<IActionResult>Generate([FromBody]Invoice invoice){var pdf =await _service.GenerateInvoiceAsync(invoice);returnFile(pdf,"application/pdf","invoice.pdf");}}
Mensageria e processamento assíncrono
Para documentos com alto custo de renderização (muitas páginas, imagens, tabelas extensas) ou quando a geração ocorre em lote, o processamento assíncrono é preferível (STAAR et al., 2018). Nesse modelo, a API recebe a solicitação e publica um comando/evento em uma fila (p.ex., Azure Service Bus, RabbitMQ ou Kafka). Um worker consumidor realiza a geração do PDF e persiste o artefato em um repositório de objetos (Blob Storage, S3) ou no banco, retornando um identificador para consulta posterior. Essa estratégia melhora resiliência e evita timeouts no caminho síncrono, ao custo de maior complexidade de consistência e UX (o usuário precisa aguardar/consultar o resultado).
Uma implicação importante é a idempotência: mensagens podem ser entregues mais de uma vez, e o sistema deve tratar isso sem produzir duplicidade ou inconsistências (SABBAG FILHO, 2025). Assim, a chave de idempotência (por exemplo, o hash do payload normalizado) torna-se um elemento central do desenho.
Estratégias de escalabilidade e qualidade em produção
Separação entre domínio e layout
Uma prática essencial é evitar misturar regras de negócio com código de layout. O documento deve receber um DTO pronto, isto é, uma estrutura com os dados necessários e já calculados (totais, impostos, regras de exibição). Com isso, a classe de documento concentra-se na apresentação, enquanto serviços de domínio/aplicação permanecem responsáveis por validação e cálculos. Esse arranjo tende a reduzir efeitos colaterais, facilita testes e diminui a probabilidade de divergência entre o estado do negócio e o documento renderizado.
Na prática, organiza-se o código por tipos de documento (por exemplo, invoice, report, contract), e cada tipo possui um layout versionado. Versionamento é relevante quando a empresa precisa regenerar documentos historicamente, respeitando o layout vigente na data de emissão.
Cache e idempotência
Documentos são frequentemente requisitados com os mesmos dados (reimpressão, reenvio, auditoria). Nesses casos, é eficiente utilizar cache por conteúdo (MERTZ; NUNES, 2017). Um procedimento comum é computar um hash do payload (ou uma chave composta por identificadores e versão do layout) e usar essa chave para localizar o PDF previamente gerado em um armazenamento rápido (p.ex., Redis) ou em um storage de objetos. Com isso, reduz-se custo computacional, melhora-se latência e, em cenários assíncronos, simplifica-se o tratamento de reentregas de mensagens.
Entretanto, a estratégia de cache exige cuidado com invalidação: mudanças em dados de domínio ou no layout devem alterar a chave. Recomenda-se incluir explicitamente um campo de versão de layout e, quando aplicável, um campo de “versão de cálculo” para refletir mudanças de regras de negócio que afetam o documento.
Observabilidade e SLOs
Em produção, a geração de documentos deve ser observável. Isso envolve rastreamento distribuído (correlacionando a requisição do usuário até a geração e persistência), logs estruturados com identificadores de documento e métricas como tempo de renderização, tamanho do arquivo gerado, taxa de cache hit/miss e taxa de falhas por tipo. Com OpenTelemetry, é possível padronizar tracing e métricas, e definir SLOs (por exemplo, percentis de latência para geração síncrona ou tempo de conclusão para filas assíncronas).
Um detalhe frequentemente negligenciado é a coleta de métricas por “classe” de documento. Documentos distintos têm custos muito diferentes (uma fatura simples vs. um relatório com dezenas de páginas). Sem essa segmentação, alertas e capacity planning tornam-se imprecisos.
Implementação: exemplo em C# com QuestPDF
A seguir apresenta-se um exemplo mínimo de documento para fatura, com foco na estrutura de composição. Em cenários reais, recomenda-se encapsular estilos (tipografia, cores, espaçamentos) em uma camada compartilhada e utilizar recursos para imagens/logotipos, garantindo consistência visual entre documentos.
Observa-se que o exemplo retorna um array de bytes. Em serviços de documentos, é comum acoplar essa saída a uma estratégia de armazenamento (por exemplo, persistir no blob e retornar uma URL temporária) e, quando necessário, anexar metadados (identificador, versão do layout, checksum e timestamps) para auditoria e reprocessamento controlado.
Ambiente heterogêneo: contraponto em Go
Em organizações com múltiplas stacks, serviços não-.NET também podem produzir PDFs. A decisão por centralizar a geração em um único serviço (por exemplo, .NET com QuestPDF) ou permitir múltiplos geradores (um por stack) envolve trade-offs. Centralizar reduz variação visual e concentra governança de layout; distribuir permite autonomia de times e evita dependência tecnológica, porém aumenta o risco de inconsistência entre documentos e dificulta padronização.
O trecho a seguir ilustra, de forma simplificada, um gerador em Go. Embora seja funcional, ele evidencia que a consistência de layout e tipografia exigirá disciplina adicional, especialmente quando documentos precisam ser equivalentes entre stacks diferentes.
Documentos frequentemente contêm dados sensíveis (PII, informações financeiras e contratuais). Portanto, a arquitetura deve considerar criptografia em repouso e em trânsito, controle de acesso baseado em identidade e autorização, URLs temporárias (signed URLs) para downloads e auditoria de acessos. Em contextos regulatórios como LGPD, recomenda-se ainda minimização de dados no documento, mascaramento quando aplicável, política de retenção e mecanismos de exclusão/anonimização quando exigidos por obrigações legais.
Outra consideração prática é o tratamento de logs: jamais registrar conteúdo do documento ou payload completo sem necessidade. Em geral, registra-se apenas identificadores, hashes e metadados essenciais para diagnóstico.
Discussão e ameaças à validade
A proposta apresentada enfatiza separação de responsabilidades, idempotência e observabilidade, mas há limitações. Primeiramente, não foi conduzida avaliação experimental (benchmark) comparando QuestPDF com alternativas HTML-to-PDF ou bibliotecas de outras linguagens. Assim, conclusões sobre desempenho devem ser interpretadas como recomendações de engenharia baseadas em propriedades arquiteturais e experiência prática, não como prova empírica formal.
Além disso, a eficácia do cache depende da estabilidade do payload e da frequência de reimpressões. Em domínios com dados altamente voláteis, o cache pode ter baixa taxa de acerto. Por fim, a escolha entre síncrono e assíncrono envolve a experiência do usuário e requisitos de negócio: há casos em que o usuário precisa do PDF imediatamente, o que força otimizações no caminho síncrono e aumento de capacidade para lidar com picos.
Conclusão
O QuestPDF oferece uma abordagem moderna e controlável para geração de documentos em ambientes .NET, com vantagens relevantes para arquiteturas distribuídas devido à previsibilidade e ao controle programático do layout. Ao tratar documentos como uma capacidade independente, idealmente por meio de um serviço dedicado, e ao combinar padrões como cache, idempotência e mensageria, é possível obter uma solução escalável, resiliente e observável para workloads corporativos.
Como trabalho futuro, recomenda-se avaliar empiricamente o desempenho e o consumo de recursos em diferentes classes de documento, bem como comparar estratégias de persistência (blob vs. banco) e políticas de versionamento de layout sob requisitos de auditoria e reprocessamento.
NADAREISHVILI, Irakli et al. Microservice architecture: aligning principles, practices, and culture. ” O’Reilly Media, Inc.”, 2016.
LEVCOVITZ, Alessandra; TERRA, Ricardo; VALENTE, Marco Tulio. Towards a technique for extracting microservices from monolithic enterprise systems. arXiv preprint arXiv:1605.03175, 2016.
STAAR, Peter WJ et al. Corpus conversion service: A machine learning platform to ingest documents at scale. In: Proceedings of the 24th ACM SIGKDD International Conference on Knowledge Discovery & Data Mining. 2018. p. 774-782.
SABBAG FILHO, Nagib. Idempotence in Distributed Systems: Ensuring Consistency in APIs and Messaging. Leaders Tec, v. 2, n. 31, 2025.
MERTZ, Jhonny; NUNES, Ingrid. Understanding application-level caching in web applications: a comprehensive introduction and survey of state-of-the-art approaches. ACM Computing Surveys (CSUR), v. 50, n. 6, p. 1-34, 2017.
Quem já esta atuando com inteligência artificial desde 2022 sabe que por muito tempo (e ate hoje) o contexto e pergunta fornecido a IA é extremamente importante, principalmente em grandes contextos como chatbot corporativos, multiagentes e fluxos complexos de automação, qual quer virgula, letra maiúscula, mudança de palavra que para nós é meramente igual pode quebrar toda a performance e confiabilidade final.
Passamos para a fase de se aprofundar em prompt com a tal da “engenharia de prompt” que inclusive a Anthropic lançou seu curso gratuito que na tradução seria algo como Fluência em prompt ( https://www.anthropic.com/learn/claude-for-you) eu mesmo terminei o curso e percebi o quão complexo e bem estruturado deve ser os contextos para nossos agentes e suas instruções. Recentemente a mais ou menos 3 semanas venho estudando um framework em python chamado Dspy que tem como principal objetivo abstrair essa complexidade mudando para uma abordagem de programação modular e não de forma manual com prompts.
OBS: Ao final vou disponibilizar um projeto completo funcional no github.
Como surgiu o Dspy:
Ele foi desenvolvido por alunos De Stanford (pra variar rsrsrs) de forma modular, ou seja, você tem assinaturas (que são uma espécie de contratos), módulos que são a forma algoritmia de definir qual tipo de estratégia de raciocinou será utilizado, como CoT (Chain Of Thought), few-shot, ReAct que é basicamente raciocinar e agir entrou outros. Portanto o Dspy surgiu para resolver a fragilidade e a falta de escalabilidade referente ao prompt engineer manual, mas mais na frente vai ficar muito claro.
Motivadores para se utilizar o Despy:
1° Inadequação do “Prompt Engineering”:Os fundadores notaram que o desenvolvimento de aplicações de IA era baseado em tentativas A/B até acertar o prompt e descobriram strings estáticas e frágeis, com o Despy você definir a entrada e a saída e ele se encarrega de encontrar o melhor prompt e salvar.
2° Portabilidade entre Modelos: Um prompt otimizado pelo Dspy pode mudar facilmente entre modelos, seja GPT, Gemini, Kimi etc.. Isso por que o Dspy aprende novamente o melhor prompt para seu cenário e modelo.
3° Programabilidade: Transformar o design de sistemas de IA em algo próximo da engenharia de software onde grandes frameworks como Langchain, Crew.AI e SDKs são próximos a engenharia de software isso deixa mais suave e familiar.
4° Auto-refinamento: O modelo recebe uma nova chance de gerar a saída, agora ciente do erro anterior e das instruções de correção, transformando a inferência em um processo de “autocura”.
Em resumo, o DSPy nasceu da pergunta: ” Podemos projetar programas de LLM que aprendam a se aprimorar sozinhos em vez de reescrevermos prompts manualmente”.
Conceitos principais do Dspy:
Signatures:Declaram a tarefa (entrada/saídas) sem especificar como o modelo deve realizá-la.
from dspy import ReAct
class QAWithReAct(dspy.Signature):
"""Responder perguntas usando ferramentas externas quando necessário."""
question: str = dspy.InputField()
answer: str = dspy.OutputField(desc="Resposta final para o usuário")
Modules: Define a estratégia que são blocos de construção reutilizáveis que encapsulam técnicas de raciocínio como ‘ChainOfThought’ e ‘ReAct’.
class CoTSentimentClassifier(dspy.Module):
def __init__(self):
super().__init__()
self.cot = dspy.ChainOfThought(SentimentSignature)
def forward(self, sentence: str) -> dspy.Prediction:
# O LM é induzido a “pensar passo a passo” antes de dar o rótulo.
return self.cot(sentence=sentence)
Optimizers: A Otimização são algoritmos que ajustam automaticamente os prompts para maximizar uma métrica de avaliação definida pelo usuário:
Essa estrutura aumenta drasticamente a precisão em tarefas complexas, como problemas matemáticos.
Imagem gerada por Airton Lira Junior – 30/01/2026.
DSPy, a coleta de dados
Esta é a base que permite a transição do ajuste manual de prompts para a otimização sistemática. Diferente do treinamento tradicional de deep learning que exige milhares de registros, o DSPy é projetado para funcionar com conjuntos de dados muito pequenos, muitas vezes necessitando de apenas 5 a 10 exemplos para começar a gerar resultados robustos.
1. A Unidade Básica: dspy.Example
Toda a estrutura de dados no framework gira em torno do objeto dspy.Example. Ele funciona como um dicionário Python especializado que armazena os campos de entrada e as saídas esperadas para o seu programa
2. Definição de Entradas com .with_inputs()
Ao coletar seus dados, você deve informar explicitamente ao framework quais campos são as entradas da tarefa utilizando o método .with_inputs(). Isso é crucial para que os otimizadores saibam quais informações estarão disponíveis para o modelo no momento da inferência e quais devem ser geradas ou aprendidas
Por exemplo:
def _format_for_dspy(self, df: pd.DataFrame) -> list[Example]:
"""Formats a DataFrame into a list of dspy.Example objects."""
formatted_examples = []
for _, row in tqdm(df.iterrows(), total=df.shape[0], desc="Formatting examples"):
example = Example(
text=row['text'],
sentiment=row['sentiment']
).with_inputs("text")
formatted_examples.append(example)
return formatted_examples
3. Dados Não Rotulados e Bootstrapping:
Uma das maiores vantagens do DSPy é a capacidade de trabalhar com dados incompletos ou sem rótulos. Se você possuir apenas as perguntas (inputs), o compilador pode utilizar um modelo de linguagem mais forte (como o GPT-4o) atuando como um “professor” para gerar automaticamente as cadeias de raciocínio e respostas corretas (traços) durante o processo de bootstrapping. Esses traços bem-sucedidos tornam-se, então, o conjunto de treinamento para otimizar modelos menores ou mais eficientes. Da hora não?
Para quem não entendeu essa questão de “professor” e bootstraping deixa eu simplificar:
DSPy permite otimizar programas de IA sem precisar de dados prontos com respostas. Vou quebrar isso em partes simples. Normalmente, para treinar IA você precisa de:
Pergunta: "Qual a capital da França?" → Resposta: "Paris"
Pergunta: "2+2=?" → Resposta: "4"
Mas e se você só tem as perguntas? Sem respostas prontas.
Como o DSPy Resolve (Bootstrapping)
1. Você dá só as perguntas
perguntas = [
"Qual a capital da França?",
"Quanto é 2+2?",
"Explique gravidade"
]
2. DSPy usa um “Professor” (LM forte)
Configura GPT-4o (ou Gemini Pro) como teacher_settings
Esse professor inventa as respostas + raciocínio:
Pergunta: "Qual a capital da França?"
Professor GPT-4o gera:
→ Raciocínio: "França é um país europeu..."
→ Resposta: "Paris"
# 1. Só perguntas (sem respostas)
trainset = [{"question": "Capital da França?"} for _ in range(20)]
# 2. Professor GPT-4o gera respostas
teleprompter = BootstrapFewShot(metric=validate_qa) # usa GPT-4o como teacher
# 3. Otimiza Llama3.2 local
compiled = teleprompter.compile(program, trainset=trainset)
3.Configuração e Flexibilidade de Modelos:
• Independência de Modelo: Capacidade de alternar entre APIs remotas (OpenAI, Anthropic) e modelos locais via Ollama ou SGLang.
• Configuração Centralizada: Uso do dspy.settings.configure para gerenciar LMs e modelos de recuperação (RM) globalmente
DSPy permite trocar modelos de IA com 1 linha de código. Não importa se é OpenAI, local ou Google.
1. Independência de Modelo (Plug & Play)
Mesma lógica, LMs diferentes:
# Seu programa DSPy (igual sempre)
classifier = SentimentClassifier()
# === OPÇÃO 1: OpenAI caro (produção) ===
lm_openai = dspy.OpenAI(model='gpt-4o-mini')
dspy.settings.configure(lm=lm_openai)
result1 = classifier("Gostei muito!") # Usa GPT-4o-mini
# === OPÇÃO 2: Modelo LOCAL grátis (teste) ===
lm_local = dspy.OllamaLocal(model='llama3.2:1b', base_url='http://localhost:11434')
dspy.settings.configure(lm=lm_local)
result2 = classifier("Gostei muito!") # Usa Llama LOCAL
# === OPÇÃO 3: Google Gemini (rápido/barato) ===
lm_gemini = dspy.Google(model='gemini-1.5-flash')
dspy.settings.configure(lm=lm_gemini)
result3 = classifier("Gostei muito!") # Usa Gemini
Resultado: result1.sentiment, result2.sentiment, result3.sentiment usam o MESMO código, só mudando a config.
Um lugar controla TUDO:
# Config global (válida para TODO o programa DSPy)
dspy.settings.configure(
lm=dspy.OpenAI(model='gpt-4o-mini'), # LM principal
rm=dspy.FaissRM( # Retriever para RAG
embedding_model=dspy.OpenAI(model='text-embedding-3-small')
),
cache=False, # Cache de chamadas
temperature=0.7 # Criatividade
)
# Agora TODO programa usa essa config automaticamente
program1 = ChainOfThought(signature)
program2 = MIPROv2(metric)
# Ambos usam GPT-4o-mini + Faiss automaticamente
Lista de LMs Suportados (2026):
Remotos:
– OpenAI: gpt-4o, gpt-4o-mini
– Anthropic: claude-3.5-sonnet
– Google: gemini-2.0-pro
– Mistral: mistral-large
Locais:
– Ollama: llama3.2, phi3, gemma2
– SGLang: serve qualquer modelo local
– vLLM: alta performance local
Aplicações Práticas e Estudos de Caso:
• RAG (Geração Aumentada de Recuperação): Construção de pipelines de busca e resposta otimizáveis.
• Raciocínio Multi-hop: O uso do módulo SimplifiedBaleen para tarefas complexas que exigem múltiplas etapas de busca.
• Text-to-SQL e Classificação: Exemplos de como o DSPy lida com extração de dados estruturados e tarefas de negócios como análise de NPS
• Asserções e Sugestões (Assertions & Suggestions): Imposição de restrições computacionais em tempo de execução com mecanismos de backtracking (retrocesso).
• Módulo Refine: O sucessor das asserções para o auto-refinamento iterativo de saídas baseado em feedback
Um exemplo que gosto muiot que é o Text-to-SQL:
import dspy
import sqlite3
from typing import List
# Configuração (troque pela sua API)
dspy.settings.configure(lm=dspy.OpenAI(model='gpt-4o-mini'))
# Schema do banco (exemplo e-commerce)
SCHEMA = """
Tabelas:
- products: id, name, price, category, stock
- orders: id, product_id, customer_id, quantity, order_date
- customers: id, name, email, city
"""
class TextToSQLSignature(dspy.Signature):
"""Gera SQL válido para consulta de banco de dados.
Schema das tabelas:
{SCHEMA}
Use apenas SELECT, WHERE, JOIN, GROUP BY, ORDER BY.
"""
question: str = dspy.InputField(desc="Pergunta em linguagem natural")
sql_query: str = dspy.OutputField(desc="SQL válido e otimizado")
class SQLExecutor(dspy.Module):
def __init__(self):
super().__init__()
self.generator = dspy.ChainOfThought(TextToSQLSignature)
def forward(self, question: str, conn: sqlite3.Connection) -> dspy.Prediction:
# Gera SQL
sql_pred = self.generator(question=question)
sql = sql_pred.sql_query.strip()
try:
# Executa e pega resultados
cursor = conn.execute(sql)
results = cursor.fetchall()
columns = [desc[0] for desc in cursor.description]
return dspy.Prediction(
sql_query=sql,
results=results,
columns=columns,
error=None
)
except Exception as e:
return dspy.Prediction(
sql_query=sql,
results=[],
columns=[],
error=str(e)
)
# Banco de teste em memória
def create_test_db():
conn = sqlite3.connect(':memory:')
conn.execute("""
CREATE TABLE products (id INTEGER PRIMARY KEY, name TEXT, price REAL, category TEXT, stock INTEGER);
CREATE TABLE orders (id INTEGER PRIMARY KEY, product_id INTEGER, customer_id INTEGER, quantity INTEGER);
CREATE TABLE customers (id INTEGER PRIMARY KEY, name TEXT, city TEXT);
""")
# Dados de teste
conn.executemany("INSERT INTO products VALUES (?, ?, ?, ?, ?)",
[(1, 'iPhone 15', 5000.0, 'eletronicos', 10),
(2, 'Notebook Dell', 3000.0, 'eletronicos', 5),
(3, 'Mesa Gamer', 800.0, 'moveis', 20)])
conn.executemany("INSERT INTO customers VALUES (?, ?, ?)",
[(1, 'João Silva', 'São Paulo'),
(2, 'Maria Santos', 'Rio de Janeiro')])
conn.executemany("INSERT INTO orders VALUES (?, ?, ?, ?)",
[(1, 1, 1, 2), (2, 2, 1, 1), (3, 1, 2, 1)])
return conn
# USO
if __name__ == "__main__":
conn = create_test_db()
sql_module = SQLExecutor()
questions = [
"Qual o produto mais caro?",
"Quantos iPhones temos em estoque?",
"Qual cliente comprou mais produtos?",
"Total de vendas por categoria"
]
for q in questions:
result = sql_module(question=q, conn=conn)
print(f"\n Pergunta: {q}")
print(f"SQL: {result.sql_query}")
print(f"Resultados: {list(zip(result.columns, result.results)) if result.results else 'OK'}")
if result.error:
print(f"Erro: {result.error}")
conn.close()
Repare que no contrato (Signature) eu especifico apenas o que vai entrar e a saida esperada e ele se encarrega no do prompt:
question: str = dspy.InputField(desc="Pergunta em linguagem natural")
sql_query: str = dspy.OutputField(desc="SQL válido e otimizado")
A Saída será algo como:
Certo e agora como otimizar para selecionar os melhores prompts? E ai que vem os optimizers…
O objetivo deste artigo foi, acima de tudo, despertar a sua curiosidade sobre como o DSPy está transformando o processo artesanal de “prompt engineering” em uma disciplina de engenharia de software rigorosa e sistemática. Ao longo desta exploração, vimos que a fascinante ideia central da biblioteca é tratar modelos de linguagem como funções parametrizadas dentro de um grafo computacional, permitindo que o comportamento do sistema seja definido por código estruturado em vez de strings frágeis.
Essa mudança de paradigma permite que os desenvolvedores se concentrem na lógica declarativa por meio de assinaturas e módulos reutilizáveis, delegando ao compilador do DSPy a tarefa de gerar instruções e exemplos otimizados para maximizar métricas específicas. Seja na construção de sistemas RAG robustos ou no desenvolvimento de agentes complexos, o framework oferece uma base para criar software de IA que é portátil entre diferentes modelos, confiável e capaz de se auto-aperfeiçoar com base em dados.
Melhores práticas para dividir datasets no Dspy:
As melhores práticas para dividir datasets no DSPy seguem uma lógica de engenharia de software rigorosa, adaptada para a natureza estocástica dos modelos de linguagem. Diferente do aprendizado profundo tradicional, o DSPy permite começar com volumes muito pequenos de dados, mas exige separação cuidadosa para garantir a generalização (ou modularização que mencionei anteriormente).
1. Separação Rigorosa de Conjuntos
É fundamental manter conjuntos distintos para evitar o overfitting (ajuste excessivo) dos prompts aos exemplos de treino. As fontes sugerem três divisões principais:
• Trainset: Usado pelos otimizadores para realizar o bootstrapping (geração automática de exemplos de raciocínio) e ajustar as instruções.
• Devset (ou Valset): Utilizado durante o processo de compilação por algoritmos de busca (como o Random Search) para selecionar qual versão do programa obteve a melhor pontuação na métrica
• Testset: Reservado exclusivamente para a validação final, garantindo que as melhorias obtidas durante a otimização funcionem em dados nunca vistos pelo compilado
class SentimentMiproManager:
def __init__(self, train_size=0.8): # Adicionado parâmetro de proporção
full_dataset = sentiment_dataset_train()
self.base_program = SentimentClassifier()
if not full_dataset:
print("Erro: Dataset vazio!")
return
# --- SEÇÃO DE SEPARAÇÃO (SPLIT) ---
# Embaralhamos para garantir que a distribuição de classes seja aleatória
random.seed(42)
random.shuffle(full_dataset)
split_idx = int(len(full_dataset) * train_size)
self.trainset = full_dataset[:split_idx] # Usado para compilar/otimizar
self.testset = full_dataset[split_idx:] # Usado para avaliação final
# ----------------------------------
print(f"Dataset carregado: {len(self.trainset)} treino / {len(self.testset)} teste")
self.compiled_program = None
def run_mipro_optimization(self, num_candidates: int = 2):
if not dspy.settings.lm:
raise ValueError("LM não configurado! Chame setup_llm() primeiro.")
print(f"\n{'='*60}")
print(f"Iniciando Otimização MIPROv2 com {len(self.trainset)} exemplos...")
teleprompter = MIPROv2(
metric=self._metric,
prompt_model=dspy.settings.lm,
task_model=dspy.settings.lm,
auto="light",
num_threads=1,
verbose=False
)
# O MIPRO usa o trainset para criar os prompts e demonstrações
self.compiled_program = teleprompter.compile(
self.base_program,
trainset=self.trainset,
max_bootstrapped_demos=2,
max_labeled_demos=4
)
Tópicos avançados do MiProV2:
O MIPROv2 (Multi-prompt Instruction PRoposals Optimizer Version 2) é um dos otimizadores mais robustos do DSPy, projetado para sistemas de larga escala onde a precisão máxima é essencial. Ele se diferencia por ser “data-aware” (sensível aos dados) e “demonstration-aware” (sensível às demonstrações), otimizando simultaneamente as instruções em linguagem natural e os exemplos few-shot para cada módulo do programa
1. Para que serve?
O MIPROv2 serve para substituir o ajuste manual de prompts por um processo de otimização matemática. Ele é ideal para:
• Sistemas de produção onde cada ganho percentual de acurácia é valioso.
• Cenários com conjuntos de dados moderados a grandes (ex: mais de 200 exemplos para evitar overfitting).
• Situações onde o desenvolvedor deseja que o framework encontre as melhores instruções e os melhores exemplos de uma só vez.
2. Funcionamento Interno
O MIPROv2 opera através de um ciclo de três estágios principais:
1. Estágio de Bootstrapping (Inicialização): O otimizador executa o programa em várias entradas do conjunto de treino para coletar traços (traces) de comportamento de entrada e saída. Ele filtra esses traços, mantendo apenas aqueles que resultaram em pontuações altas de acordo com a métrica definida.
2. Estágio de Proposta Fundamentada (Grounded Proposal): O MIPROv2 analisa o código do programa, os dados e os traços coletados para redigir múltiplas variações de instruções para cada prompt individual no pipeline.
3. Estágio de Busca Discreta (Discrete Search): Utiliza Otimização Bayesiana para explorar o espaço de busca.
◦ Ele amostraminibatches do treino para avaliar combinações de instruções e traços.
◦ Ummodelo substituto (surrogate model) probabilístico é atualizado com os resultados, prevendo quais direções de busca são mais promissoras através de uma função de aquisição chamada Expected Improvement (EI).
3. Parâmetros Avançados:
O MIPROv2 permite um controle fino sobre o orçamento computacional e a estratégia de busca através dos seguintes parâmetros:
• auto: Define configurações automáticas de hiperparâmetros. Pode ser “light” (rápido e barato), “medium” ou “heavy” (busca exaustiva).
• metric: A função Python que avalia a saída e guia a otimização.
• max_bootstrapped_demos: Define o número máximo de exemplos gerados automaticamente pelo “professor” a serem incluídos no prompt.
• max_labeled_demos: Define o número máximo de exemplos do conjunto de treino (com rótulos reais) a serem incluídos no prompt.
• minibatch_size: Tamanho do lote de dados usado em cada etapa da busca discreta para acelerar a avaliação.
• minibatch_full_eval_steps: Frequência com que o otimizador realiza uma avaliação completa no conjunto de dados, em vez de apenas no minibatch.
• num_threads: Número de threads para processamento paralelo durante a compilação.
• prompt_model: O modelo de linguagem específico encarregado de gerar as propostas de novas instruções (pode ser um modelo mais forte que o modelo “estudante”).
• teacher_settings: Configurações de LM para o programa “professor” que gera os traços iniciais durante o bootstrapping.
Em termos de resultados práticos, o uso do MIPROv2 em modo light elevou a acurácia de agentes ReAct de 24% para 51% e de sistemas de classificação de 62% para 82%
Imagem gerada pelo material desse curso por Airton Lira Junior.
Esperamos ter demonstrado que a era das “tentativas e erros” manuais em prompts está sendo superada por um futuro onde a programação sistemática de modelos de fundação é o novo padrão para a inteligência artificial. O DSPy não é apenas uma ferramenta, mas um convite para reimaginar como construímos sistemas inteligentes de forma escalável e mensurável
Convido você a dar uma Star e seguir meu projeto de aprendizado do Dsypy:
No Asaas, estamos vivendo um momento importante de evolução técnica. Nosso sistema cresceu, a operação ganhou escala, os produtos evoluíram e a complexidade do sistema aumentou junto com o negócio. Esse movimento é natural, mas traz um desafio importante: como continuar evoluindo com segurança, resiliência e autonomia dos times sem comprometer a estabilidade da plataforma?
É a partir desse contexto que entra a arquitetura celular.
Arquitetura celular é um conceito que costuma gerar curiosidade justamente por não ser um modelo tão difundido quanto outros padrões arquiteturais mais conhecidos. Além disso, em muitos casos, isso já está resolvido e o time acaba nem entendendo o funcionamento por trás do que usa. Por isso, antes de entrar nos detalhes técnicos, vale contextualizar por que esse tema se tornou tão relevante para nós.
Neste artigo, compartilhamos como esse conceito funciona na prática, quais problemas ele ajuda a resolver e por que estamos evoluindo nossa arquitetura para esse modelo no Asaas, conectando decisões técnicas com crescimento sustentável, experiência dos times e maturidade de engenharia.
Antes de tudo: o problema que queremos resolver
Durante muito tempo, escalar sistemas significou aumentar máquinas, dividir responsabilidades em serviços modulares ou aplicar técnicas como sharding de banco de dados. Essas abordagens resolvem parte do problema, mas frequentemente introduzem outros desafios.
Em arquiteturas tradicionais de escala, é comum observarqueclientes insatisfeitos degradam a experiência de todos. O sistema cresce, mas a previsibilidade e a resiliência diminuem.
A arquitetura atual do Asaas é robusta e estável, mas à medida que crescemos, queremos garantir que continue sustentando o negócio com a mesma qualidade. Arquitetura celular é nossa evolução, para buscarmos o seguinte:
Preparar para escala:
Crescimento horizontal e previsível adicionando células conforme necessário
Bancos de dados menores e mais performáticos
Processamento distribuído sem contenção entre clientes
Aumentar resiliência:
Blast radius controlado: problemas afetam apenas uma fração da base
Deploys graduais e seguros, célula por célula
Falhas contidas, sem cascata para todo o sistema
Otimizar recursos:
Infraestrutura dedicada para clientes com perfis muito diferentes
Configurações e otimizações específicas por célula
Melhor utilização de recursos, sem superdimensionamento global
Empresas como a Shopify sentiram isso de forma prática. Em 2015, ao escalar seu banco de dados por meio de sharding, conseguiram ganhos de performance, mas perderam resiliência. Uma falha em um único shard era capaz de indisponibilizar toda a plataforma. A resposta foi reorganizar a arquitetura em pods totalmente isolados, capazes de operar de forma independente.
A arquitetura celular nasce exatamente desse tipo de aprendizado.
O que é arquitetura celular
Uma arquitetura celular organiza o sistema em células independentes, onde cada célula é responsável por processar um grupo de requests, manter seu próprio estado e operar de forma autônoma. O princípio central é simples, mas poderoso: em vez de escalar um sistema monolítico cada vez maior e mais complexo, escalamos adicionando células independentes. Quando precisamos de mais capacidade, criamos uma nova célula. Quando uma célula falha, o impacto fica contido.
Essa ideia não surgiu de um único lugar. Ela aparece em diferentes momentos da história da computação:
O Actor Model, com comunicação baseada em mensagens e isolamento de estado
O Domain-Driven Design e seus Bounded Contexts bem definidos
Arquiteturas orientadas a eventos e message-driven systems
O conceito de cell-based architecture difundido por provedores como a AWS
Os pods da Shopify, um exemplo claro dessa lógica aplicada à prática em fintech
No fundo, todas essas abordagens apontam para o mesmo princípio: isolamento como estratégia de escala.
Como uma célula é composta no Asaas
No modelo que estamos construindo, uma célula arquitetural é uma unidade lógica completa e autossuficiente. Cada célula possui:
Infraestrutura completa: toda a stack do Asaas Core replicada
Banco de dados isolado: dedicado para aquela célula
Processamento independente: aplicações, workers, filas e caches próprios
Capacidade de operação autônoma: uma célula não depende de outra para funcionar
A segregação é feita por faixas de clientes. Por exemplo:
Célula 0: clientes de 1 a 1.000.000
Célula 1: clientes de 1.000.001 a 10.000.000
Células especializadas: clientes detratores podem ser isolados em células dedicadas
O roteamento acontece no CloudFront, através de Functions que analisam o request (seja por identificador de cliente, token JWT ou contexto da requisição) e direcionam para a célula correta. Isso significa que o roteamento é transparente para o cliente, a experiência é a mesma, mas a infraestrutura subjacente é isolada.
Comunicação entre células: eventos antes de tudo
Bancos isolados trazem um desafio importante: como lidar com operações que envolvem dados de clientes em células diferentes?
Exemplos práticos no Asaas:
Buscar informações de um CPF/CNPJ que pode estar em qualquer célula
Transferências entre contas Asaas de clientes em células diferentes
Notificações e webhooks que precisam consultar dados cross-cell
A arquitetura celular não funciona bem quando há acoplamento síncrono excessivo entre componentes. Por isso, sempre que possível, a comunicação entre células acontece de forma assíncrona e orientada a eventos.
Utilizamos SNS + SQS para materializar esse padrão:
Comandos acionam mudanças de estado dentro de uma célula
Eventos comunicam que algo relevante aconteceu
Outras células reagem apenas se tiverem interesse naquele fato
Esse modelo reduz dependências diretas e permite evolução incremental e segura. Você pode fazer deploy célula por célula, testar mudanças estruturais em produção com impacto limitado, e até manter células em versões diferentes durante migrações graduais. Chamadas síncronas podem existir, mas são exceção e passam por camadas de proteção como gateways ou proxies com circuit breakers e timeouts bem definidos.
Outro exemplo prático: transferência entre contas
Quando um cliente da Célula 0 transfere para um cliente da Célula 1:
A Célula 0 processa o débito e publica um evento de transferência no SNS utilizando o conceito de outbox;
SNS roteia para o SQS da célula destino;
A Célula 1 consome esse evento via SQS e processa o crédito;
Ambas as células mantêm consistência com mecanismos de retry e dead-letter queues para garantir a entrega.
O desafio do backoffice: agregação de dados
Um backoffice que precisa consultar e manipular dados de todas as células apresenta um desafio arquitetural importante. Não queremos que operações administrativas criem dependências síncronas entre todas as células.
Nossa solução: OpenSearch como camada de agregação.
Cada célula replica os dados necessários para visualização (normalmente listas, dashboards e consultas analíticas) para um cluster OpenSearch centralizado. Quando um operador de backoffice:
Lista clientes ou transações: a consulta vai para o OpenSearch
Seleciona um item específico: o backoffice identifica a célula correta e faz a consulta direta
Realiza uma operação: a ação é roteada para a célula responsável
Isso garante que o backoffice tenha visibilidade global sem criar acoplamento entre células. O OpenSearch não é a fonte da verdade, mas sim uma visualização otimizada para operações administrativas.
Dados centralizados: quando o isolamento não faz sentido
Nem tudo se beneficia do isolamento celular. Alguns dados precisam ser altamente íntegros, centralizados e de acesso ultrarrápido. O principal exemplo no Asaas é o processo de autenticação e autorização.
Para esses casos, utilizamos DynamoDB como store centralizado:
Sessões de usuário
Tokens de autenticação
Permissões e ACLs
Dados de routing (qual cliente pertence a qual célula)
O DynamoDB oferece latência consistente na casa dos milissegundos, alta disponibilidade e capacidade de escalar horizontalmente sem os trade-offs de consistência de bancos relacionais distribuídos.
Abaixo imagem exemplificando a centralização e agravação para backoffice e usuários:
O que isso muda na prática
Os ganhos da arquitetura celular são bastante concretos:
1. Contenção de falhas (Blast Radius Reduction)
Se uma célula falha, seja por bug, sobrecarga ou problema de infraestrutura, o impacto é limitado apenas aos clientes daquela célula. Os demais continuam operando normalmente.
2. Deploys graduais e seguros
Podemos fazer rollout de novas versões célula por célula, validando estabilidade antes de expandir. Se detectarmos problemas, o rollback é pontual.
3. Isolamento de performance
Um cliente com volume extremo de transações não degrada a experiência dos outros. Podemos até alocar células dedicadas para grandes clientes.
4. Escalabilidade incremental
O crescimento acontece de forma controlada: adicionamos novas células conforme necessário, sem precisar reestruturar o sistema inteiro.
5. Banco de dados gerenciável
Bancos menores significam backups mais rápidos, consultas mais eficientes, manutenções menos arriscadas e maior flexibilidade para otimizações específicas.
6. Autonomia dos times
Times podem evoluir features e realizar deploys em células específicas com menos coordenação e risco.
Desafios e trade-offs
Seria irresponsável apresentar arquitetura celular como solução mágica. Ela traz desafios próprios:
Complexidade operacional: gerenciar múltiplas células exige automação, observabilidade robusta e processos bem definidos
Consistência eventual: operações cross-cell precisam ser modeladas com cuidado
Migração gradual: não se adota arquitetura celular da noite para o dia — é um processo incremental
Custos de infraestrutura: replicar toda a stack aumenta custos (mas isso é compensado pela resiliência e performance)
Debugging distribuído: rastrear operações que atravessam células exige ferramentas de observabilidade madura
Arquitetura celular como caminho, não como solução pronta
Arquitetura celular não é uma decisão pontual nem um padrão que se adota de uma vez só. Trata-se de um caminho arquitetural que exige clareza de domínio, disciplina técnica e escolhas conscientes ao longo do tempo.
No Asaas, essa evolução nasce da necessidade de sustentar um sistema cada vez mais crítico para milhares de clientes, sem abrir mão de resiliência, autonomia dos times e segurança operacional. Construir células nos permite crescer com mais previsibilidade, reduzir impactos de falhas e evoluir em performance.
Mais do que um modelo técnico, arquitetura celular é uma forma de pensar escala. Ela parte do princípio de que:
Falhas são esperadas, não exceções
Isolamento é um aliado, não um custo
Autonomia dos componentes é fundamental para resiliência
Por que compartilhar isso?
Compartilhar essa visão faz parte do processo. Muitas empresas enfrentam desafios semelhantes à medida que crescem, e trocar aprendizados sobre arquitetura é uma forma de fortalecer o ecossistema como um todo.
Se você já trabalhou com arquitetura celular, tem dúvidas sobre a implementação ou está considerando esse modelo na sua empresa, adoraria ouvir sua perspectiva nos comentários. Quais desafios você enxerga? O que funcionou (ou não funcionou) na sua experiência?
Quer fazer parte dessa construção?
A arquitetura celular já está sendo construída no Asaas. Estamos buscando pessoas que queiram participar ativamente dessa evolução técnica, lidando com desafios reais de escala, resiliência e autonomia dos times.
Se você se interessa por arquitetura, gosta de resolver problemas complexos em escala real e quer fazer parte de um time que está redesenhando a base do produto para o futuro, esse desafio pode ser o seu próximo passo:
O ClawdBot (recentemente rebatizado como Moltbot) vive um hype intenso nos últimos dias na web, mas ele não importa apenas por ser “mais um bot de IA”. Ele importa porque expõe, de forma prática, um novo modelo de internet: uma web em que agentes de software executam ações em nosso nome, atravessando sistemas, APIs e interfaces de forma contínua.
Focar apenas na ferramenta perde o ponto principal. O ClawdBot é relevante como sinal de uma transição maior: estamos saindo de uma web baseada em interação para uma web baseada em delegação.
Este texto não é um tutorial nem um review. É uma análise do fenômeno, dos padrões de uso que explicam o hype e, principalmente, dos riscos reais de colocar agentes sempre ligados para operar partes sensíveis da nossa vida digital.
Agentic Web: quando intenção passa a valer mais do que interface
Depois da Web 1.0 (leitura) e da Web 2.0 (interação), começa a emergir um novo paradigma: a Agentic Web (em que agentes de IA passam a executar ações, não apenas respondendo usuários, mas de fato realizando ações que antes apenas humanos conseguiam). .
Tradicionalmente, software é construído assim: Interface → lógica → ação.
Na web de agentes, a ordem se inverte: Intenção → agente → múltiplas ações.
O usuário deixa de navegar, clicar e preencher formulários. Em vez disso, descreve o que quer que aconteça, e o agente de IA traduz essa intenção em operações distribuídas entre serviços e as opera.
O diferencial do ClawdBot está em tornar explícito um modelo em que o agente é o operador, não apenas um assistente consultivo.
Por que isso está acelerando agora?
Esse movimento não surgiu do nada. Três fatores se alinharam ao mesmo tempo:
1) Modelos que finalmente “aguentam” contexto
Modelos de linguagem passaram a manter histórico, interpretar intenções ambíguas, escolher ferramentas adequadas e corrigir caminhos. Isso torna viável delegar tarefas reais, não apenas fazer perguntas.
2) Infraestrutura já pronta há anos
E-mail, calendário, CRM, GitHub, pagamentos, mapas e mensageria já funcionam como APIs. Os agentes não reinventam esses serviços, eles os orquestram.
3) A interface certa venceu
Ao viver dentro de WhatsApp, Slack e Telegram, a IA deixa de ser “mais uma ferramenta” e vira parte natural do fluxo de trabalho. A fricção cai drasticamente e a adoção dispara.
O ClawdBot / Moltbot como sinal, não como exceção
É nesse contexto que o ClawdBot (ou Moltbot, após rebranding por questões de trademark) ganhou tração. Ele se apresenta como um agente self-hosted, sempre ativo, integrado a ferramentas reais do dia a dia: e-mail, calendário, GitHub, Slack, WhatsApp.
O projeto é open-source, evolui rápido e se posiciona como um “assistente de verdade”: não só responde, mas executa. Mais importante do que o nome ou a implementação é o que ele simboliza: agentes deixam de ser experimentos isolados e começam a operar fluxos completos.
Padrões de uso que explicam o hype
Os casos de uso que viralizaram não são impressionantes por si só. Eles importam porque revelam padrões recorrentes de delegação.
Triagem e síntese de trabalho
Em canais como Slack ou Teams, o agente é acionado para resumir decisões, gerar tickets ou preparar respostas. É a evolução natural do “copiar e colar no ChatGPT”, só que integrada ao fluxo.
Vida administrativa encaixada em hábitos
Lembretes, agenda, e-mails e pequenas decisões passam a ser resolvidos via mensagens. A IA se encaixa em rotinas já existentes, em vez de exigir novos hábitos.
O custo oculto da delegação: novos riscos sistêmicos
Delegar intenção é poderoso e perigoso.
Um agente como o ClawdBot tende a se tornar um concentrador de privilégios: acesso a e-mail, mensageria, calendário, repositórios, APIs, navegador e, em alguns casos, comandos de sistema.
Quando algo dá errado, o impacto não é local. O risco deixa de ser apenas técnico e passa a ser estrutural.
Onde estão os riscos reais (e como mitigar)
1) Exposição acidental de portas e interfaces
Interfaces pensadas para uso local acabam expostas na internet.
Mitigação: não expor UI publicamente, firewall estrito, acesso via rede privada (VPN/Tailscale), autenticação forte no gateway.
2) Chaves, tokens e credenciais viram “ouro”
O agente concentra segredos de múltiplos serviços.
Mitigação: vaults/variáveis com permissões corretas, rotação fácil, limites de gasto e princípio do menor privilégio.
3) Permissões demais + ações sem aprovação
Autonomia sem guardrails escala risco.
Mitigação: human-in-the-loop para ações sensíveis, allowlist de ferramentas, isolamento e logs auditáveis.
4) Prompt injection: o ataque mais subestimado
Se o agente lê entradas externas e tem ferramentas para agir, ele pode ser manipulado.
Mitigação: separar escopos por canal/contato, políticas claras de quem pode acionar o quê, validação de entradas e revisão de ações críticas.
Aqui não estamos falando de bugs, mas de um novo modelo de ameaça.
Resistência cultural, compliance e custo cognitivo
Mesmo que a tecnologia funcione, a adoção não é automática. Delegar ações exige abrir mão de controle, algo especialmente sensível em ambientes regulados como jurídico, financeiro e saúde.
Há também um custo cognitivo pouco discutido: confiar em um agente de IA implica revisar logs, entender limites e conviver com a ansiedade de “o que ele fez enquanto eu não estava olhando”. A Agentic Web não elimina responsabilidade humana, ela a desloca.
E onde entra o VPS nisso?
Agentes sempre ligados precisam de infraestrutura sempre ligada. Por isso, rodar em VPS é comum. Mas VPS é self-service: hardening, isolamento e exposição continuam sendo responsabilidade do usuário.
Do ponto de vista de plataforma, o que ajuda é:
Evitar portas padrão em serviços e gateways, reduzindo varreduras automáticas e ataques oportunistas;
Usar rede privada, firewall estrito e autenticação forte;
Reduzir defaults perigosos, especialmente em serviços não pensados para internet aberta;
Oferecer templates com hardening embutido, diminuindo erros comuns de configuração;
Documentar claramente os riscos e limites do modelo, para evitar falsas expectativas de segurança.
Infra simples, mas segura, vira acelerador de adoção.
Checklist rápido para mitigar riscos
Não exponha UI ou portas publicamente
Use rede privada e firewall estrito
Comece com poucas integrações
Ative aprovação humana para ações sensíveis
Use allowlist de ferramentas
Rotacione chaves e limite gastos
Monitore logs
Conclusão
O ClawdBot/Moltbot virou sensação porque entrega algo que muita gente queria há anos: um agente útil, no lugar certo, com integrações reais. Ao mesmo tempo, ele deixa explícito o trade-off fundamental da Agentic Web: produtividade alta exige governança alta.
Vale reforçar: o ClawdBot/Moltbot não é único e nem precisa ser. Ele é apenas um dos exemplos mais visíveis de uma onda maior de agentes de IA que começam a operar fora do modelo “chat como consulta” e entram no território da execução contínua. Outros projetos, com arquiteturas, níveis de abstração e modelos de governança diferentes, já exploram o mesmo espaço.
O que importa aqui não é a ferramenta específica, mas o padrão que ela revela: agentes sempre ligados, integrados a sistemas reais, executando intenções em nome do usuário. O ClawdBot não inaugura essa era sozinho, ele apenas a torna difícil de ignorar.
A pergunta não é se é seguro ou inseguro. A pergunta certa é: quais controles você colocou antes de delegar partes da sua vida digital a um agente de IA?
A crescente sofisticação dos ataques cibernéticos têm pressionado empresas a repensarem modelos tradicionais de defesa. Assinaturas estáticas, regras fixas e respostas reativas já não acompanham a velocidade e a complexidade das ameaças atuais. Nesse contexto, a chamada segurança data-driven ganha protagonismo ao utilizar grandes volumes de dados, correlacionar eventos e usar a inteligência artificial para identificar riscos em tempo real e antecipar movimentos maliciosos antes que causem impacto relevante.
O avanço da digitalização ampliou exponencialmente a superfície de ataque. Aplicações em nuvem, APIs, dispositivos conectados e ambientes híbridos geram trilhões de eventos diariamente. Cada log de acesso, requisição suspeita ou variação de comportamento contém sinais que, quando analisados de forma isolada, parecem irrelevantes. O diferencial do modelo data-driven está justamente na capacidade de correlacionar esses dados em escala, transformando ruído em inteligência acionável.
Big data como base da nova cibersegurança
O primeiro pilar dessa transformação é o big data. Plataformas modernas de segurança coletam e processam informações provenientes de múltiplas fontes, como firewalls, WAFs, servidores, aplicações, endpoints e serviços em nuvem. O objetivo não é apenas armazenar dados, mas criar uma visão integrada e contínua do ambiente digital.
Com infraestrutura adequada, esses dados passam a ser analisados em tempo real, permitindo a identificação de padrões anômalos que indicam tentativas de intrusão, exploração de vulnerabilidades ou movimentação lateral dentro da rede. Diferentemente de abordagens tradicionais, que dependem de indicadores conhecidos, o big data permite detectar comportamentos inéditos, ainda não catalogados em bases de ameaças.
O papel da inteligência artificial na detecção em tempo real
A inteligência artificial, especialmente técnicas de machine learning, é responsável por dar significado aos dados coletados. Algoritmos treinados com grandes volumes de informações históricas aprendem o comportamento normal de usuários, aplicações e sistemas. A partir disso, qualquer desvio relevante passa a ser sinalizado automaticamente.
Esse modelo é particularmente eficaz contra ataques avançados, como fraudes silenciosas, ataques de força bruta distribuídos, exploração de credenciais e ameaças internas. Em vez de buscar apenas assinaturas conhecidas, a IA analisa contexto, frequência, origem e impacto potencial das ações, reduzindo falsos positivos e acelerando a tomada de decisão.
Outro avanço importante é a automação da resposta. Em ambientes maduros, a própria plataforma pode isolar uma máquina, bloquear um IP ou limitar privilégios de acesso assim que um risco crítico é identificado. Isso reduz drasticamente o tempo entre a detecção e a contenção, um fator decisivo para minimizar danos.
De segurança reativa para segurança preditiva
O uso combinado de big data e IA desloca a cibersegurança de um modelo reativo para um modelo preditivo. Ao analisar tendências, recorrências e correlações, as equipes passam a identificar vetores de ataque em potencial antes que sejam explorados em larga escala.
Esse conceito é especialmente relevante em ambientes corporativos complexos, onde falhas raramente ocorrem por um único fator. Muitas violações são resultado de pequenas fragilidades acumuladas, como configurações incorretas, permissões excessivas e softwares desatualizados. A análise orientada por dados permite enxergar essas conexões e priorizar ações com base em risco real, não apenas em boas práticas genéricas.
Impacto na rotina das equipes de segurança
Para os times de cibersegurança, a abordagem data-driven também representa uma mudança operacional significativa. Analistas deixam de atuar apenas como reagentes a alertas e passam a trabalhar com inteligência contextualizada. Dashboards avançados, modelos de risco dinâmicos e análises comportamentais substituem listas extensas de eventos pouco relevantes.
Isso melhora a eficiência das equipes e reduz o desgaste causado pelo excesso de alertas. Em um cenário global de escassez de profissionais em segurança da informação, otimizar o uso do tempo humano torna-se tão importante quanto investir em tecnologia.
Desafios e responsabilidade no uso dos dados
Apesar dos benefícios, a segurança orientada por dados impõe desafios importantes. Qualidade da informação, governança, privacidade e compliance precisam ser tratados como prioridades. Dados imprecisos ou mal contextualizados comprometem a eficácia dos modelos e podem gerar decisões equivocadas.
Além disso, o uso de IA exige transparência e revisão contínua. Algoritmos precisam ser constantemente ajustados para acompanhar mudanças no ambiente e evitar vieses. Segurança data-driven não é um projeto pontual, mas um processo evolutivo que depende de maturidade técnica e cultural.
O futuro da detecção de ameaças
À medida que ataques se tornam mais automatizados e orientados por IA, a defesa também precisa evoluir no mesmo ritmo. A tendência é que a cibersegurança deixe de ser um conjunto de ferramentas isoladas e passe a funcionar como um ecossistema inteligente, capaz de aprender, adaptar-se e responder em tempo real.
A segurança data-driven não elimina riscos, mas redefine a forma como lidamos com eles. Ao transformar dados em inteligência contínua, empresas ganham capacidade de antecipação, resiliência operacional e proteção efetiva em um cenário digital cada vez mais complexo e hostil.
O ChatGPT deixou de ser apenas uma ferramenta generalista de linguagem para assumir um papel cada vez mais estratégico em um dos setores mais sensíveis da sociedade: a saúde. Com o anúncio do ChatGPT Health, a OpenAI formaliza um uso que já vinha acontecendo de maneira espontânea, com pessoas recorrendo à tecnologia para interpretar exames, esclarecer sintomas e buscar informações sobre medicamentos. A diferença agora está no grau de sofisticação e no nível de responsabilidade envolvidos.
IA na Saúde
A proposta do ChatGPT Health é ampliar significativamente esse escopo, permitindo perguntas mais específicas, análise de exames de imagem, integração de dados provenientes de dispositivos e a centralização de informações clínicas hoje distribuídas em diferentes sistemas. Do ponto de vista tecnológico, trata-se de um avanço consistente em engenharia de dados e modelos de linguagem aplicados a contextos críticos. Do ponto de vista ético, porém, a saúde expõe com clareza os limites da inteligência artificial, já que erros nesse campo extrapolam impactos operacionais e atingem diretamente a vida das pessoas.
A aquisição da startup Torch Health pela OpenAI reforça esse direcionamento. A tecnologia da empresa foi desenvolvida para lidar com um desafio estrutural do setor: dados de saúde altamente fragmentados entre hospitais, laboratórios, planos e dispositivos móveis. Tornar essas informações inteligíveis para sistemas de IA pode qualificar diagnósticos, melhorar o acompanhamento de pacientes e favorecer um cuidado mais contínuo. Tecnicamente, a estratégia é coerente. Socialmente, ela recoloca uma questão recorrente quando se fala em IA aplicada a contextos sensíveis: qual é o limite ético do uso dessa tecnologia.
Esse debate se torna ainda mais concreto quando observado à luz de iniciativas regulatórias recentes, como a lei aprovada no estado de Utah, nos Estados Unidos, que autoriza a renovação de receitas médicas por inteligência artificial. Em parceria com a startup Doctronic, o modelo permite que pacientes renovem medicamentos de uso contínuo após responderem a questionários clínicos, com envio direto da prescrição à farmácia em caso de aprovação. Embora restrito a um conjunto específico de medicamentos e com exclusões claras por segurança, o precedente está estabelecido.
O principal argumento a favor desse tipo de solução é o aumento do acesso à saúde. Para pessoas que vivem em regiões afastadas, com escassez de profissionais ou longos tempos de espera, a tecnologia pode representar uma alternativa concreta quando a opção anterior era nenhuma. Como observa Aydamari Faria-Jr no artigo Inteligência artificial como (mais) uma habilidade médica, indivíduos sem acesso efetivo ao sistema de saúde ou que tiveram experiências negativas com profissionais despreparados podem se beneficiar desses serviços, já que o parâmetro de comparação é o “nada”. Mesmo com uma taxa de erro relevante, o mercado entende que o saldo tende a ser positivo.
Podemos confiar?
O risco do viés de automação surge como um dos principais limites do uso da inteligência artificial na saúde. Sistemas desse tipo tendem a produzir respostas coerentes e plausíveis, o que favorece a confiança excessiva por parte dos usuários. O problema não está apenas na possibilidade de erro, mas no fato de que ele pode passar despercebido justamente porque a resposta parece correta. A saúde tende a ser um dos campos mais impactados por esse fenômeno.
No Brasil, essa discussão ganha contornos próprios. O país reúne um sistema público de saúde nacional, desigualdades regionais profundas e uma legislação robusta de proteção de dados. A adoção de soluções baseadas em inteligência artificial levanta questionamentos sobre soberania de dados, integração com o SUS e o papel da tecnologia como apoio à decisão médica, e não como sua substituição. Há potencial para uso em triagem, educação em saúde, acompanhamento de doenças crônicas e suporte a profissionais sobrecarregados, mas esse avanço depende também do letramento digital da população para que a tecnologia não se transforme em mais um fator de exclusão.