Nos meus dias trabalhando em projetos de agentes de IA, discutir sobre patterns de agentes se tornou algo quase como nosso dia a dia e também parte estratégica da tecnologia. Isso passou a ser conversa de inúmeras rodas de debate, mas, até o momento, não nos debruçamos de fato sobre a problemática em detalhes e como um novo design pattern poderia resolver esse problema.
Foi pensando no padrão BFF como motor principal de arquitetura que veio a grande luz: por que não se valer de um padrão para resolver problemas, digamos, parecidos, de Back-end para agentes? Ou, como foi batizado por um colega de trabalho (Samuel) — e que me fez muito sentido para mim, nasce então um design pattern chamado — BFA (Back-end for Agents).
Esse post documenta minha compreensão sobre como desenvolvemos essa técnica e como podemos implementá-la em nosso dia a dia.
Minha compreensão da evolução de componentes de agentes de inteligência artificial
Se pararmos para pensar, gosto de usar uma analogia no meu dia a dia de trabalho: agentes nada mais são do que jornadas que já conhecemos e dominamos como engenheiros de software. Veja minha analogia, e vem de encontro com a mesma que Phil Calçado pensou na criação do BFF:

O que vemos aqui? O padrão com o qual trabalhamos há tempos na criação de softwares, onde, ao nascer um sistema, nascia também um backend e um frontend — ou, até mesmo, tudo ficava na mesma camada. Isso também valia para o banco de dados, que poderia ser único ou múltiplo, dependendo da aplicação.
Para quem conhece o PostgreSQL, sabe que muitos de nós nos valíamos dos schemas para representar essas camadas de aplicação. Ou seja, um schema para a aplicação de cartão, outro para pessoas e, por fim, SMS, todos no mesmo banco de dados.
Cada camada dessa ficava acoplada ao seu componente, ou ao que chamamos de alto acoplamento. Podemos até dizer que era “meio que independente”, porque o banco de dados ficava em seu próprio servidor, com seu host, o backend também, e, por fim, o frontend igualmente separado. Porém, o acoplamento se dava pelo fato de serem usados pela mesma aplicação. No caso, o backend era usado pelo mesmo sistema, o que trazia problemas de independência.
Mesmo que fossem arquiteturas complexas e complicadas, com o tempo, no geral, foi fácil traçar a linha entre banco de dados, backend e frontend. Podemos dizer que estava bem demarcado onde um começava e o outro terminava.
O grande problema estava no reaproveitamento desses backends. O que ocorria com muita frequência — e até diria mais, especialmente na camada de backend — eram as duplicações de classes, métodos e até mesmo regras idênticas. Isso gerava grandes problemas para identificar onde se encontrava a regra central. À medida que o software crescia, mais problemas surgiam, pois o frontend também sofria com essa questão: um backend pesado e cheio de regras que, por sua vez, não servia ao propósito final daquele frontend.
Essa situação é muito bem explicada por Phil em seu artigo sobre o BFF (Back-end for Front-end), e aqui vale para nós, criadores de agentes, pois essa semelhança oculta em nossas aplicações também existe. No entanto, gostaria de explicar a problemática mais adiante, quando entraremos na questão do que estou sugerindo como um novo pattern.

Aqui mora a grande questão: com a necessidade de maior reutilização entre as camadas, podemos perceber que elementos de uma camada podem estar presentes em outras, duplicados ou criados com novas regras.
Isso ocorre porque cada camada é uma unidade de negócios, com seus próprios domínios e regras, mas que pode acabar precisando de algo que se encontra em outra camada. Esse foi exatamente o problema identificado na questão dos back-ends e que motivou o surgimento do BFF proposto por Phil.
Foi pensando em toda essa questão que ele propôs, juntamente com a equipe do SoundCloud, algo simples e bem funcional: o famoso BFF, os quais são a arquitetura a seguir:

O ponto primordial dessa arquitetura é a flexibilidade entre serviços, tornando-os reutilizáveis. Basicamente, consiste em selecionar o que o serviço precisa, escrever um código que chame esse serviço, mesclar os dados recebidos e, por fim, renderizar. Ou seja, em vez de ter a interface do usuário voltada para um sistema de backend, a interface do usuário era o próprio aplicativo.
Para quem já programou, talvez se lembre de uma época em que houve uma forte tendência de separação usando o padrão MVC (Model, View e Controller). Imagine algo parecido, mas onde a camada de frontend esteja realmente desacoplada e o backend da API também. Assim, esse frontend — ou jornada, como no exemplo de cartão — teria um backend que chamamos de BFF, que serve com sua própria API e contempla exatamente o que aquele frontend precisa.
O padrão Back-end para Agentes (BFA)
Valendo-me da mesma questão levantada por Phil, me peguei pensando se não estaríamos partindo do mesmo problema, mas com uma ótica nova para a aplicação de agentes. Isso porque, quem já construiu agentes talvez acabe sempre iniciando com uma arquitetura que não seja exatamente essa, mas muito parecida:
Press enter or click to view image in full size

O que podemos perceber de cara? Os nomes mudaram, mas os problemas continuam os mesmos?
Venho me questionando sobre isso, e alguns protocolos até já servem como uma “solução para o problema” — como o MCP e o A2A, por exemplo. Mas aqui não estamos na ótica da problemática de protocolos, e sim de um sabor arquitetural: um padrão que podemos usar. Ou, como diz a famosa frase, precisamos de um design pattern que ajude a resolver essa questão.
Por ora, gostaria de entrar contigo na questão principal: os problemas que a arquitetura anterior traz.
Primeiramente, podemos falar de acoplamento forte, ou seja, lógica de APIs, tradução semântica e decisões misturadas. Com isso, qualquer alteração na API pode interferir e quebrar o meu agente — por exemplo, um agente de atendimento e um de cadastro que, por sua vez, usam a mesma API, mas com regras distintas.
Outro problema é o reuso limitado: se outro agente precisar da mesma informação, precisamos reimplementar a lógica.
A escalabilidade e evolução também são diferentes, ou seja, é difícil testar e fazer rollout de partes isoladas.
Por fim, há a questão da segurança dispersa, pois cada um pode implementar seu próprio padrão, e também a observabilidade fragmentada, já que não há uma fronteira clara para métricas, traces e fallback.
Esses são problemas conhecidos do que chamamos de aplicações monolíticas.
Como o BFA pode ajudar?
Bom, por se tratar de um design pattern que resolve a camada de backend para o agente, ela atua como uma camada mediadora entre o agente — que contém o LLM, o prompt e a memória.
Aqui, foi um ponto onde fiz um estudo sobre outra camada que não pertence ao BFA, mas sim ao agente. Podemos uni-la a um segundo design pattern, sendo a camada de multiagentes, com, por exemplo, um agente supervisor, responsável por receber a requisição e encaminhar para outros agentes que, por sua vez, têm seus próprios BFAs.
Como a ideia não é entrar nesse detalhe agora, recomendo a leitura:
Entendendo o Design Pattern de Multi-Agentes com Supervisor do LangGraph
Essa semana, no meu trabalho, passamos por uma discussão de arquitetura de agentes. Fiquei o final de semana com isso…
Voltando ao nosso design pattern BFA, ele é responsável por cuidar da camada de backend para o agente. O agente não deverá chamar diretamente as APIs — por exemplo, de crédito e saldo. Em vez disso, ele invoca operações padronizadas expostas por um BFA.
E é aqui que entra o figurão responsável por tornar isso possível: o MCP. Novamente, não entrarei na questão de protocolos, mas recomendo a leitura:
Function Calling vs MCP (Model Context Protocol): Qual a melhor forma de integrar ferramentas ao…
Fala, galera, tudo beleza? Hoje vou falar com vocês sobre um assunto que tem chamado minha atenção. Vou sair um pouco…
Aqui o jogo muda em nossa arquitetura, pois nossos agentes não têm mais a responsabilidade de possuir uma tool/function calling do padrão LangChain, por exemplo. O que eles passam a fazer agora é chamar nossa arquitetura BFA, que será responsável por toda a problemática necessária para o funcionamento do agente.
Por exemplo, em nossa época de saldo e cartão de crédito, eles invocam operações padronizadas expostas pelo BFA via protocolo MCP. Veja o exemplo da arquitetura:
Press enter or click to view image in full size

Repare que as ferramentas de domínio — por exemplo, cartão de crédito, fatura e saldo do cliente — ficam encapsuladas dentro do BFA.
O BFA traduz, aplica políticas (autenticação, mascaramento, agregação), faz caching, logging e expõe uma fachada estável para os agentes — algo na linha de uma Anti-Corruption Layer, na prática.
Além disso, um supervisor, por exemplo, no LangGraph, poderia facilmente coordenar os subagentes especializados, como o agente de banco, o agente de atendimento e o de cadastro, agregando os resultados. Ele poderia até delegar, reavaliar e encaminhar chamadas.
Por fim, o BFA é tão poderoso que você pode até agregar tudo isso com um A2A.
Por que o BFA pode me ajudar até no desacoplamento semântico?
Vamos entender essa parte do nosso padrão.
Agora, cada agente tem seu LLM, prompt, memória e capacidade de decisão, e não lida mais diretamente com as APIs de domínios ou tools. A única questão principal dele é conhecer os detalhes de outras ferramentas ou agentes, pois o BFA expõe contratos estáveis via MCP.
Com isso, é possível ir longe e explorar, por exemplo, a comunicação dos agentes via A2A, onde cada agente pode invocar seu BFA ou outros agentes para obter dados e orquestrar a comunicação. Isso é possível pelo simples fato de termos desacoplado a carga principal — que é a obtenção dos dados, a racionalização da informação e a invocação de camadas de APIs.
Ou seja, fizemos um desacoplamento semântico, onde os agentes não precisam mais entender os detalhes uns dos outros. Eles compartilham abstrações ou facades providas pelos BFAs. Isso nos ajuda a ter contratos claros e versionados, onde cada operação é tipada e contratada, permitindo evoluir sem quebrar quem consome — ou o agente que consome.
Um dos maiores poderes dessa abordagem é o reuso e a composição: um agente composer pode orquestrar múltiplos subagentes, cada um chamando seu próprio BFA, sem replicar lógica de acesso.
Outro ganho é a questão de fallback e resiliência a falhas, pois os BFAs podem encapsular políticas de degradação, como cache e resposta parcial, sem obrigar o agente a decidir como lidar com isso.
Por fim, temos a simplificação do prompt e da decisão: o LLM nos agentes pode raciocinar em termos de operações de alto nível — por exemplo, “pegar resumo de cartão e verificar saldo disponível” — sem precisar saber como chamar três APIs para juntar esse tipo de informação.
Ainda, temos a liberdade de segregação em múltiplas etapas, onde poderíamos facilmente utilizar um LangGraph para quebrar em nós de decisão dentro do nosso agente.
Em outras palavras, a responsabilidade do agente é a jornada — e não o backend:
Press enter or click to view image in full size

Em nosso exemplo, o cliente pergunta: “Posso usar meu limite disponível para pagar uma compra? E qual o impacto no meu saldo?”
O supervisor identifica a necessidade de consultar crédito e saldo, e então chama cada subagente com seus respectivos BFAs, por exemplo:
AgenteCartãoDeCrédito → CreditoBFA: APIDeCartãoDeCrédito
AgenteDeSaldo → SaldoBFA: APIDeSaldo
Fechando a visão do nosso padrão BFA
Na tentativa de fomentar o padrão na comunidade de IA, gostaria de deixar um pattern card aqui, informando qual problema desejamos resolver com o nosso design pattern.
Problema:
A ideia central é que agentes de IA tendem a se acoplar diretamente às APIs de domínio, dados e prompts, além de duplicarem lógica. Com isso, criamos fragilidade e dificultamos a comunicação entre agentes.
Solução:
Introduzir uma camada intermediária (BFA) que encapsula APIs, aplica políticas, traduz dados e expõe operações estáveis via protocolos, como por exemplo o MCP.
Benefícios:
- Desacoplamento semântico
- Contratos versionados e claros
- Observabilidade centralizada
- Reuso de lógica e composição
Trade-offs:
- Adiciona mais uma camada (latência extra)
- Requer governança de versionamento
Exemplo:
Supervisor → Agente de Cartão → CreditBFA → API de Cartão
Supervisor → Agente de Saldo → BalanceBFA → API de Saldo
Futuro do padrão BFA?
O BFA é um padrão que ainda está nascendo, mas já mostrou ganhos claros de desacoplamento e reuso.
Deixo aqui um convite para você:
- Acompanhe o repositório do projeto: https://github.com/michaeldouglas/post_medium/tree/main/Python/post_multiagent
- Experimente isolar o backend dos seus agentes em um BFA.
- Use MCP como contrato de invocação.
- Compartilhe suas implementações e aprendizados.
Assim como o BFF transformou a arquitetura de frontends, acredito que o BFA pode transformar a maneira como construímos sistemas de agentes.
Agradecimentos
Gostaria de deixar meu agradecimento à minha equipe da RTX, que me proporciona, todos os dias, desafios que me fazem pensar. Também agradeço ao time de Inteligência do Itaú, que fez esse desafio nascer graças a uma discussão sobre MCP.
Espero que tenha ajudado você e por enquanto, é isso.
Um grande abraço do MD!




