06-03-04 — Agent Framework 1.0: MCP nativo, A2A, graph workflow engine

⏱ 15 minFontes validadas em: 2026-04-29

TL;DR

O AF 1.0 tem três features que o diferenciam tecnicamente: MCP nativo (agentes descobrem e consomem tools de qualquer servidor MCP sem código extra), A2A protocol (agentes de diferentes frameworks colaboram por HTTP/JSON), e graph workflow engine (herança do AutoGen: fluxos com estado, condicionais e paralelismo). Juntos, esses três pilares tornam o AF 1.0 o framework mais interoperável para enterprise.

MCP — Model Context Protocol nativo

MCP (Anthropic, 2024) define um protocolo padrão para que LLMs descubram e invoquem ferramentas. O AF 1.0 implementa tanto o lado client (consumir tools de servidores MCP) quanto o lado server (expor plugins como servidor MCP).

Consumindo um servidor MCP externo

using Microsoft.AgentFramework.MCP;

// Conecta a um servidor MCP (ex: servidor de acesso a banco de dados)
var mcpClient = new McpClient("https://meu-servidor-mcp.empresa.com");

// AF 1.0 descobre as tools automaticamente e as registra no Kernel
await kernel.AddMcpToolsAsync(mcpClient);

// A partir daqui, o agente pode usar qualquer tool do servidor MCP
// como se fossem plugins nativos — sem código adicional
var resultado = await kernel.InvokePromptAsync(
    "Quantos contratos vencem nos próximos 30 dias?",
    new KernelArguments(new OpenAIPromptExecutionSettings
    {
        FunctionChoiceBehavior = FunctionChoiceBehavior.Auto()
    }));

Expondo um agente como servidor MCP

// O agente AF 1.0 pode ser consumido por Claude, Cursor, qualquer cliente MCP
builder.Services.AddMcpServer(options =>
{
    options.ServerName = "Assistente Empresarial Impar";
    options.ServerVersion = "1.0.0";
    options.ExposeKernelFunctions = true;  // todos os plugins viram tools MCP
});

app.MapMcpEndpoints("/mcp");  // SSE em /mcp/sse, HTTP em /mcp/messages

A2A — Agent-to-Agent Protocol

A2A (Google, 2025 — adotado pela Microsoft no AF 1.0) permite que agentes de frameworks diferentes se descubram e colaborem:

sequenceDiagram participant ClientAgent as AF 1.0 Agent (C#) participant Registry as Agent Registry participant RemoteAgent as Google ADK Agent (Python) ClientAgent->>Registry: GET /.well-known/agent.json Registry-->>ClientAgent: Agent Card (capabilities, endpoint) ClientAgent->>RemoteAgent: POST /a2a/tasks/send Note over ClientAgent,RemoteAgent: JSON-RPC sobre HTTPS RemoteAgent-->>ClientAgent: TaskResult (streaming SSE)
using Microsoft.AgentFramework.A2A;

// Descobrir um agente remoto via URL do Agent Card
var remoteAgent = await A2AClient.DiscoverAgentAsync(
    "https://agente-clima.parceiro.com/.well-known/agent.json");

// Delegar tarefa — AF 1.0 trata o agente remoto como qualquer plugin
var resultado = await remoteAgent.SendTaskAsync(new A2ATask
{
    Message = new A2AMessage
    {
        Role = "user",
        Parts = [new TextPart("Qual a previsão para SP esta semana?")]
    }
});

// Streaming de resposta
await foreach (var evento in remoteAgent.StreamTaskAsync(task))
{
    Console.Write(evento.Delta?.Text);
}

Registrando seu agente para ser descoberto

// AF 1.0 gera e serve o Agent Card automaticamente
builder.Services.AddA2AServer(options =>
{
    options.AgentName = "Assistente Financeiro Impar";
    options.Description = "Análise financeira com acesso ao ERP SAP";
    options.Provider = new A2AProvider { Name = "Impar", Url = "https://impar.com.br" };
    options.Capabilities = new A2ACapabilities
    {
        Streaming = true,
        PushNotifications = true
    };
    options.Skills = [
        new A2ASkill { Id = "analise-contratos", Name = "Análise de Contratos" },
        new A2ASkill { Id = "kpis-financeiros", Name = "KPIs Financeiros" }
    ];
});

app.MapA2AEndpoints();  // serve /.well-known/agent.json e /a2a/tasks/*

Graph Workflow Engine

Herdado do AutoGen v0.4, o graph engine do AF 1.0 permite fluxos de trabalho com estado que vão além de simples tool calling:

using Microsoft.AgentFramework.Graph;

// Define o estado do workflow
record WorkflowState(string UserQuery, string? ResearchResult, string? FinalReport);

// Cria o grafo de workflow
var workflow = new AgentWorkflow<WorkflowState>()
    .AddNode("pesquisa", async (state, ctx) =>
    {
        var resultado = await ctx.InvokeAgentAsync<PesquisaAgent>(state.UserQuery);
        return state with { ResearchResult = resultado };
    })
    .AddNode("redacao", async (state, ctx) =>
    {
        var relatorio = await ctx.InvokeAgentAsync<RedacaoAgent>(state.ResearchResult!);
        return state with { FinalReport = relatorio };
    })
    .AddNode("revisao", async (state, ctx) =>
    {
        // Human-in-the-loop: pausa aguardando aprovação
        var aprovado = await ctx.RequestHumanApprovalAsync(
            state.FinalReport!,
            "Aprovar relatório para envio?");
        return state;
    })
    .AddConditionalEdge("pesquisa", state =>
        state.ResearchResult?.Length > 100 ? "redacao" : "pesquisa")  // retry se insuficiente
    .AddEdge("redacao", "revisao")
    .SetEntryPoint("pesquisa");

// Executar com checkpointing
var runner = new WorkflowRunner(workflow, checkpointer: new AzureTableCheckpointer());
var resultado = await runner.RunAsync(new WorkflowState("Analise concorrência Q2 2026"));

Exemplo integrado: MCP + A2A + Graph

// Um workflow que usa MCP para tools locais e A2A para delegar pesquisa
var workflow = new AgentWorkflow<RelatorioState>()
    .AddNode("coleta_dados", async (state, ctx) =>
    {
        // Tools via MCP (servidor de dados SAP)
        var kpis = await ctx.Kernel.InvokePromptAsync(
            "Busque KPIs do trimestre via MCP");
        return state with { KPIs = kpis.ToString() };
    })
    .AddNode("pesquisa_mercado", async (state, ctx) =>
    {
        // Delega pesquisa para agente especializado via A2A
        var agentePesquisa = await A2AClient.DiscoverAgentAsync(pesquisaAgentUrl);
        var pesquisa = await agentePesquisa.SendTaskAsync(
            new A2ATask { Message = state.KPIs! });
        return state with { MarketResearch = pesquisa.Result };
    })
    .AddNode("gera_relatorio", async (state, ctx) =>
    {
        // Geração local com todos os dados
        var relatorio = await ctx.Kernel.InvokePromptAsync(
            $"Gere relatório executivo com: KPIs={state.KPIs}, Mercado={state.MarketResearch}");
        return state with { Report = relatorio.ToString() };
    })
    .SetEntryPoint("coleta_dados");
MCP vs A2A: MCP é para ferramentas (funções stateless que retornam dados). A2A é para agentes (entidades com estado próprio, raciocínio e capacidade de subdeletar). Use MCP para integrar com APIs e sistemas; use A2A para colaboração entre agentes de diferentes domínios.

Como isso se conecta

  • 06-03-03 AF 1.0: visão geral — contexto e lifecycle do framework
  • Módulo 07 (MCP/A2A) — aprofundamento nos protocolos MCP e A2A
  • 06-04-02 Google ADK — ADK também implementa A2A; agentes ADK e AF 1.0 interoperam
  • 06-04-04 Desafio — o mesmo agente implementado com graph workflow do AF 1.0

Fontes

  1. Model Context Protocol — Official Docs
  2. Agent-to-Agent Protocol — Official Spec
  3. Microsoft Docs — MCP with Semantic Kernel / AF 1.0
  4. Microsoft DevBlog — AF 1.0 with MCP and A2A