Microsoft Lança AI Agent Framework: Explicação Detalhada com Exemplos

Este artigo tem um vídeo curto:TikTok

1. Visão Geral

A Microsoft acaba de lançar oficialmente (GA – General Availability) um framework unificado para construir, orquestrar e operar AI Agents, unificando dois produtos anteriores: Semantic Kernel e AutoGen. Isso não é apenas uma novidade de produto — redefine como você deve projetar um sistema com LLM que “decide suas próprias ações” em vez de apenas responder uma pergunta.

Este artigo explica o que diferencia um AI Agent de um chatbot comum, o que a Microsoft lançou especificamente, e então você vai construir um agent minimalista usando Java 21 + Spring Boot 3 + Spring AI (integrado com Azure OpenAI) para entender o mecanismo subjacente, embora o framework original da Microsoft rode em .NET e Python.

2. O que é um AI Agent?

Um chatbot comum recebe uma pergunta, chama o LLM uma vez e retorna uma resposta. Um Agent é diferente porque repete o ciclo pensamento-ação várias vezes, decidindo automaticamente se precisa chamar uma ferramenta (API, banco de dados, arquivo…) ou não, antes de fornecer a resposta final.

Características Chatbot AI Agent
Número de chamadas ao LLM 1 vez/pergunta Múltiplas vezes, auto-repetição
Uso de ferramentas externas Geralmente não Sim, ferramentas escolhidas pelo modelo
Estado Sem estado ou armazena histórico de chat Tem memória, pode fazer checkpoint
Latência Baixa Mais alta (múltiplas rodadas)
Confiabilidade Fácil de controlar Precisa de guardrails, intervenção humana

2.1. O Ciclo Reason–Act (ReAct)

O mecanismo central que a maioria dos frameworks de agent usam atualmente é ReAct: o modelo “pensa” (Thought), escolhe uma ação (Action) que é chamar uma ferramenta, recebe o resultado (Observation), e repete até ter informação suficiente para responder (Final Answer).

Thought: O usuário pergunta sobre o status do pedido ORD-001, preciso consultá-lo.
Action: lookupOrder("ORD-001")
Observation: Pedido ORD-001: status SHIPPED, total 450000 BRL
Thought: Tenho informação suficiente.
Final Answer: Seu pedido ORD-001 está sendo entregue, total 450.000 BRL.

Esta é a parte que o Microsoft Agent Framework (e o Spring AI que você usará abaixo) automatiza — você não precisa escrever este ciclo manualmente, apenas declarar ferramentas e o prompt do sistema.

3. O que a Microsoft “lançou” para AI Agent

Antes da unificação, a Microsoft tinha duas linhas de desenvolvimento paralelas:

  • Semantic Kernel: SDK orientado para produção, enfatiza plugins type-safe, integração empresarial (Azure, .NET), adequado para implantação estável.
  • AutoGen: orientado para pesquisa, forte em conversação multi-agent — múltiplos agents “conversam” entre si para resolver tarefas complexas.

O novo framework combina os pontos fortes de ambos, incluindo as seguintes capacidades principais:

  • Padrões de orquestração prontos: sequencial (agent A termina depois B), concorrente (múltiplos agents rodam em paralelo depois se combinam), hand-off (um agent passa a tarefa para outro especializado), group chat (múltiplos agents discutem antes de responder).
  • Execução durável/com estado: o agent pode fazer checkpoint no meio do caminho, retomar se o processo falhar — importante para tarefas longas (minutos a horas).
  • Observabilidade integrada: rastreamento seguindo o padrão OpenTelemetry, você pode ver cada passo Thought/Action/Observation em produção.
  • Human-in-the-loop: pausa o agent para aguardar aprovação humana antes de executar ações sensíveis (reembolsos, exclusão de dados…).
  • Azure AI Foundry Agent Service: runtime hospedado para implantar agents, com catálogo de ferramentas pronto (Bing search, intérprete de código, recuperação de arquivos) e suporte a Model Context Protocol (MCP) para conectar ferramentas externas seguindo um padrão aberto, sem lock-in de vendor.

O framework original roda em .NET/Python, mas o padrão é universal. A seção seguinte reconstrói esse padrão exato em Java para você ver como funciona em nível de código.

4. Arquitetura Central de um AI Agent

Um agent minimalista precisa de 4 componentes: Planner (que é o LLM), Tool (funções que o agent pode chamar), Memory (histórico de conversa/resultados das ferramentas), Executor (ciclo de orquestração). Spring AI encapsula Executor e Planner através do ChatClient, você apenas precisa declarar Tools.

4.1. Dependência Maven

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-azure-openai-spring-boot-starter</artifactId>
    <version>1.0.0</version>
</dependency>

Configuração de conexão com Azure OpenAI (serviço GPT da Microsoft, implantado via Azure):

spring.ai.azure.openai.api-key=${AZURE_OPENAI_KEY}
spring.ai.azure.openai.endpoint=${AZURE_OPENAI_ENDPOINT}
spring.ai.azure.openai.chat.options.deployment-name=gpt-4o-mini

4.2. Definindo Ferramentas para o Agent

Uma ferramenta é um método Java comum, marcado com @Tool para que o modelo saiba que pode chamá-lo e com que parâmetros.

public record Order(String id, String status, BigDecimal total) {}

public interface OrderService {
    Order findById(String orderId);
}

@Service
public class OrderTools {

    private final OrderService orderService;

    public OrderTools(OrderService orderService) {
        this.orderService = orderService;
    }

    @Tool(description = "Consulta o status e o total de um pedido pelo código do pedido")
    public String lookupOrder(String orderId) {
        Order order = orderService.findById(orderId);
        return "Pedido %s: status %s, total %s BRL"
            .formatted(order.id(), order.status(), order.total());
    }
}

O description em @Tool é o que o modelo lê para decidir se deve chamar lookupOrder ou não — escreva descrições claras e específicas, o agent escolherá a ferramenta certa com mais precisão.

4.3. Agent Chamando Ferramentas Automaticamente via ChatClient

@Service
public class SupportAgentService {

    private final ChatClient chatClient;

    public SupportAgentService(ChatClient.Builder builder, OrderTools orderTools) {
        this.chatClient = builder
            .defaultSystem("""
                Você é um assistente de suporte ao cliente de uma loja online.
                Se a pergunta for sobre um pedido, use a ferramenta lookupOrder.
                Responda de forma concisa, amigável, em português.
                """)
            .defaultTools(orderTools)
            .build();
    }

    public String handle(String userMessage) {
        return chatClient.prompt()
            .user(userMessage)
            .call()
            .content();
    }
}

A linha .defaultTools(orderTools) registra o conjunto de ferramentas, ChatClient executa automaticamente o ciclo ReAct internamente: envia o prompt junto com a lista de ferramentas para o modelo, se o modelo retornar uma solicitação para chamar lookupOrder, Spring AI executa automaticamente o método Java correspondente, passa o resultado (Observation) de volta para o modelo, e então você recebe a resposta final. Você não escreve o ciclo manualmente — esta é exatamente a parte que o Microsoft Agent Framework e Spring AI fazem da mesma forma essencialmente.

> handle("Onde está meu pedido ORD-001?")
Seu pedido ORD-001 está sendo entregue (SHIPPED), total 450.000 BRL!

Nota: O modelo só chama a ferramenta quando “decide” que precisa — nem toda pergunta ativa uma ferramenta. Se o usuário perguntar “vocês fazem envios internacionais?”, o modelo responde diretamente sem chamar lookupOrder.

5. Multi-agent: Quando um Agent Não é Suficiente

Uma das capacidades destacadas que a Microsoft lançou é o hand-off — transferência de conversas entre agents especializados. Para problemas pequenos, você pode simular com um roteador simples, sem precisar de um framework multi-agent complexo:

@Service
public class AgentRouter {

    private final SupportAgentService orderAgent;
    private final RefundAgentService refundAgent;

    public AgentRouter(SupportAgentService orderAgent, RefundAgentService refundAgent) {
        this.orderAgent = orderAgent;
        this.refundAgent = refundAgent;
    }

    public String route(String userMessage) {
        String lower = userMessage.toLowerCase();
        if (lower.contains("reembolso") || lower.contains("refund")) {
            return refundAgent.handle(userMessage);
        }
        return orderAgent.handle(userMessage);
    }
}

Este roteador atua como um “orquestrador” minimalista. Em maior escala, a escolha de qual agent manipular também deve ser deixada para o próprio LLM decidir (classificação de intenção pelo modelo), em vez de hard-code contains() — a abordagem manual é adequada apenas para demos ou conjuntos de intenções muito pequenos e estáveis.

6. Escrevendo Testes para Ferramentas e Agents

A parte mais fácil de testar em um sistema de agent é a ferramenta — porque é um método Java puro, sem dependência do LLM. Você deve testar esta parte minuciosamente, pois o agent só é “inteligente” quanto a qualidade das ferramentas que chama.

class OrderToolsTest {

    @Test
    void shouldReturnOrderSummaryWithStatusAndTotal() {
        OrderService fakeOrderService = orderId ->
            new Order(orderId, "SHIPPED", new BigDecimal("450000"));

        OrderTools tools = new OrderTools(fakeOrderService);

        String result = tools.lookupOrder("ORD-001");

        assertThat(result)
            .contains("ORD-001")
            .contains("SHIPPED")
            .contains("450000");
    }
}

Como OrderService tem apenas um método findById, usamos uma lambda para criar uma implementação falsa em vez de precisar de uma dependência de framework de mock — é conciso e suficiente para este teste unitário.

class AgentRouterTest {

    @Test
    void shouldRouteRefundKeywordToRefundAgent() {
        SupportAgentService orderAgent = mock(SupportAgentService.class);
        RefundAgentService refundAgent = mock(RefundAgentService.class);
        when(refundAgent.handle(anyString())).thenReturn("Solicitação de reembolso registrada");

        AgentRouter router = new AgentRouter(orderAgent, refundAgent);

        String result = router.route("Quero reembolsar o pedido ORD-002");

        assertThat(result).isEqualTo("Solicitação de reembolso registrada");
        verify(refundAgent).handle(anyString());
        verify(orderAgent, never()).handle(anyString());
    }
}

Nota: Não escreva testes “end-to-end chamando LLM de verdade” em testes unitários — o resultado não é determinístico (o modelo pode responder diferente cada vez), consome créditos de chamadas de API e deixa a CI lenta/instável. Mock ChatClient ou teste as partes de ferramenta/roteador separadamente como acima; reserve um conjunto de testes de integração (rodados manualmente ou em horários vagos) para verificar se o agent escolhe a ferramenta correta em cenários reais.

7. Erros Comuns e Quando NÃO Usar Agent

  • Usar agent para o que pode ser resolvido com if-else: se a lógica de escolha de ação já é conhecida e fixa (por exemplo: sempre consultar pedido quando há um código como ORD-\d+), escrever código é geralmente mais barato, mais rápido e muito mais fácil de testar do que deixar o LLM “pensar” cada vez.
  • Ignorar guardrails para ações sensíveis: se o agent tem permissão para chamar ferramentas que deletam dados, reembolsos, enviam e-mails para clientes — sem aprovação humana (human-in-the-loop) ou limites de permissão de ferramentas, uma injeção de prompt ou erro de raciocínio do modelo pode ter consequências reais.
  • Não limitar o número de iterações: se o modelo continua escolhendo a ferramenta errada ou não tem dados suficientes para concluir, o ciclo ReAct pode iterar infinitamente, gastando tokens e dinheiro. Sempre defina um número máximo de passos e timeout.
  • Falta de observabilidade: quando o agent responde errado, você precisa poder revisar toda a sequência Thought/Action/Observation para debugar — sem logs/traces detalhados é quase impossível descobrir o que o modelo “pensou” para chegar a um resultado errado.
  • Latência e custo: cada passo no ciclo é uma chamada ao LLM. Uma pergunta simples pode custar 2-3 chamadas de modelo (e cada uma leva centenas de ms a alguns segundos). Para APIs que precisam de resposta instantânea (por exemplo, menos de 200ms), esse tipo de agent não é adequado.

8. Conclusão

A unificação pela Microsoft do Semantic Kernel e AutoGen em um único framework mostra uma tendência clara: os AI Agents estão evoluindo de “demos interessantes” para infraestrutura de produção que exige orquestração, estado, observabilidade e controles de permissão rigorosos como qualquer outro sistema enterprise. Quer você use .NET, Python ou Java/Spring AI como nos exemplos deste artigo, a essência da arquitetura continua girando em torno de quatro blocos: Planner, Tool, Memory, Executor — dominando estes quatro blocos, você consegue entender e aplicar qualquer framework de agent que surgir depois.

AI AgentMicrosoftSpring AIAzure OpenAILLM