Microsoft Agent Framework
O Microsoft Agent Framework é o SDK open source da Microsoft para construir agentes de IA e workflows multiagente em .NET e Python, e representa a evolução unificada dos projetos Semantic Kernel e AutoGen. Ele combina os pontos fortes dos dois em uma única plataforma, pensada para aplicações de IA robustas, interativas e seguras.
Neste guia, você vai conhecer os dois pilares do framework, criar seu primeiro agente em C# e avançar até workflows com ramificação e persistência de estado. Todos os exemplos seguem a API do período de preview público, quando o framework foi anunciado.
O que é o Microsoft Agent Framework
A Microsoft anunciou o framework no início de outubro de 2025, em preview público. Segundo o próprio time, ele é o sucessor direto do Semantic Kernel para a construção de agentes, criado pelas mesmas equipes do Semantic Kernel e do AutoGen.
Na prática, o Microsoft Agent Framework junta as abstrações simples do AutoGen para padrões de um ou vários agentes com os recursos corporativos do Semantic Kernel. Entre eles, estão gerenciamento de estado, segurança de tipos, filtros, telemetria e amplo suporte a modelos.
Além disso, o framework adiciona algo que nenhum dos dois tinha de forma nativa: workflows baseados em grafos. Com eles, você controla explicitamente o caminho de execução entre vários agentes e funções.
Resumindo os pontos centrais:
- Kit open source: um SDK para construir agentes de IA e workflows multiagente em .NET e Python.
- Sucessor unificado: combina a simplicidade do AutoGen com os recursos empresariais do Semantic Kernel.
- Duas capacidades primárias: agentes de IA individuais e workflows para orquestrar processos complexos.
- Status no lançamento: preview público, com desenvolvimento ativo e contribuições da comunidade.
Sobre o Semantic Kernel, o anúncio foi tranquilizador. A versão 1.x continua recebendo correções críticas e de segurança por pelo menos um ano depois que o novo framework sair do preview.
O código-fonte e os exemplos ficam no repositório microsoft/agent-framework no GitHub.
Agentes e workflows lado a lado
| Agentes de IA | Workflows |
|---|---|
| Usam LLMs para processar entradas e tomar decisões | Estruturas em grafo que conectam vários agentes e funções |
| Podem chamar ferramentas (funções C#) para realizar ações | Dão controle explícito sobre processos complexos e longos |
| Ideais para planejamento ad hoc, decisão autônoma e conversa | Suportam roteamento condicional, paralelismo e intervenção humana |
A documentação oficial dá uma regra simples para escolher. Use um agente quando a tarefa é aberta ou conversacional; use um workflow quando o processo tem etapas bem definidas.
Ela ainda faz um alerta valioso: se você consegue escrever uma função comum para resolver a tarefa, faça isso em vez de usar um agente. Agora que os dois pilares estão claros, vamos ao primeiro deles.
Construindo seu primeiro agente no Microsoft Agent Framework
O agente de IA é o bloco de construção fundamental do framework. Ele encapsula a interação com um Large Language Model (LLM), permitindo processar informações, tomar decisões e executar ações.
Entender a criação e o ciclo de vida do agente é o primeiro passo. Afinal, ferramentas, memória e workflows se apoiam nele.
Criando e executando um agente básico
O processo para colocar um agente em funcionamento tem três passos:
- Configurar o cliente: crie um cliente para o serviço de IA, como o
AzureOpenAIClient, com endpoint e credenciais. - Criar o agente: use
CreateAIAgente defina a personalidade e as diretrizes no parâmetroinstructions. - Executar o agente: chame
RunAsynccom a entrada do usuário para obter a resposta do LLM.
O exemplo abaixo cria um agente instruído a contar piadas. No preview, os pacotes eram instalados com a opção --prerelease do NuGet.
using System;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using OpenAI;
// Cria o agente, informando instruções e um nome
AIAgent agent = new AzureOpenAIClient(
new Uri("https://your-openai-resource.openai.azure.com"),
new AzureCliCredential())
.GetChatClient("gpt-4o-mini")
.CreateAIAgent(instructions: "You are good at telling jokes.", name: "Joker");
// Executa o agente
Console.WriteLine(await agent.RunAsync("Tell me a joke about a pirate."));
O AzureCliCredential usa o login feito com o Azure CLI. Por isso, rode az login antes de executar o exemplo localmente.
Se você está começando no assunto, o artigo criando seu primeiro agente de IA complementa bem este passo.
Conversas multiturno no Microsoft Agent Framework
Por padrão, os agentes do Microsoft Agent Framework não mantêm memória entre chamadas. Ou seja, cada invocação de RunAsync é independente da anterior.
Para manter o contexto, o estado da conversa fica fora do agente, em um objeto AgentThread. Você cria uma nova conversa com agent.GetNewThread() e passa o mesmo thread em todas as chamadas seguintes.
Dessa forma, o agente tem acesso ao histórico completo. No exemplo, ele lembra a piada da primeira interação e a modifica na segunda.
// Cria um thread para manter o estado da conversa
AgentThread thread = agent.GetNewThread();
// Primeira chamada
Console.WriteLine(await agent.RunAsync("Tell me a joke about a pirate.", thread));
// Segunda chamada, usando o mesmo thread para manter o contexto
Console.WriteLine(await agent.RunAsync(
"Now add some emojis to the joke and tell it in the voice of a pirate's parrot.", thread));
Vale um aviso sobre versões. Em versões posteriores do Microsoft Agent Framework, o AgentThread foi substituído pelo tipo AgentSession, criado com CreateSessionAsync, mas o conceito continua o mesmo.
Ferramentas e memória no Microsoft Agent Framework
No Microsoft Agent Framework, a utilidade real de um agente aparece quando ele vai além do conhecimento do LLM. Ferramentas permitem acessar APIs, consultar sistemas e executar código, transformando o agente em um assistente ativo.
Paralelamente, a memória permite reter informações entre conversas. Com isso, o agente fica mais útil, contextual e personalizado para cada usuário.
Usando function tools
Transformar um método C# em ferramenta é um processo declarativo:
- Crie um método C#: de preferência estático, com a lógica que você quer expor.
- Descreva a função: use o atributo
[Description]deSystem.ComponentModelna função e em cada parâmetro. - Crie uma AIFunction: chame
AIFunctionFactory.Create(MethodName)para converter o método. - Entregue ao agente: passe a lista de ferramentas no parâmetro
toolsao criar o agente.
A descrição é crucial, porque é por meio dela que o LLM entende o que a ferramenta faz. Primeiro, definimos o método.
using System.ComponentModel;
[Description("Get the weather for a given location.")]
static string GetWeather([Description("The location to get the weather for.")] string location)
=> $"The weather in {location} is cloudy with a high of 15°C.";
Em seguida, criamos o agente com a ferramenta GetWeather. A partir daí, o próprio agente decide quando invocá-la.
AIAgent agent = new AzureOpenAIClient(
new Uri("https://your-openai-resource.openai.azure.com"),
new AzureCliCredential())
.GetChatClient("gpt-4o-mini")
.CreateAIAgent(
instructions: "You are a helpful assistant",
tools: [AIFunctionFactory.Create(GetWeather)]);
Console.WriteLine(await agent.RunAsync("What is the weather like in Amsterdam?"));
Para se aprofundar, veja o artigo sobre tools no Agent Framework.
Human in the loop com aprovação de ferramentas
Algumas ações exigem supervisão humana, como apagar dados ou fazer um pagamento. Para esses casos, o Microsoft Agent Framework oferece um padrão de aprovação integrado.
Primeiro, envolva a função com new ApprovalRequiredAIFunction(myTool). Isso sinaliza ao agente que executar essa ferramenta exige consentimento.
Depois da execução, em vez de uma resposta final, a conversa pode conter um pedido de aprovação. Então, verifique se as mensagens da resposta trazem objetos FunctionApprovalRequestContent.
Apresente ao usuário o nome da função, em requestContent.FunctionCall.Name, e os argumentos. Por fim, crie a resposta com requestContent.CreateResponse(true), ou false para rejeitar, e envie-a ao agente em uma nova ChatMessage.
Nas versões mais recentes, o tipo de conteúdo passou a se chamar ToolApprovalRequestContent. Ainda assim, o fluxo de aprovação continua idêntico.
Adicionando memória com AIContextProvider
No Microsoft Agent Framework, o AIContextProvider é uma classe abstrata que injeta contexto antes da chamada do agente e inspeciona os resultados depois. Na prática, ele funciona como o mecanismo de memória do agente.
No preview, você sobrescrevia InvokingAsync para "lembrar" o agente de informações relevantes antes da chamada ao LLM. Já o InvokedAsync analisava as mensagens depois da resposta para extrair e guardar novos dados.
Para que a memória persista entre sessões, você também implementa a serialização. Assim, o estado é salvo e carregado junto com o AgentThread.
A classe UserInfoMemory abaixo mostra uma memória de longo prazo. Antes de cada turno, ela verifica se o nome do usuário é conhecido; se for, adiciona uma instrução com o nome, e se não for, pede ao agente que pergunte.
internal sealed class UserInfo
{
public string? UserName { get; set; }
public int? UserAge { get; set; }
}
internal sealed class UserInfoMemory : AIContextProvider
{
// O estado da memória fica guardado aqui
public UserInfo UserInfo { get; set; } = new UserInfo();
public override ValueTask<AIContext> InvokingAsync(
InvokingContext context, CancellationToken cancellationToken = default)
{
StringBuilder instructions = new();
if (this.UserInfo.UserName is null)
{
instructions.AppendLine("Ask the user for their name.");
}
else
{
instructions.AppendLine($"The user's name is {this.UserInfo.UserName}.");
}
return new ValueTask<AIContext>(new AIContext { Instructions = instructions.ToString() });
}
public override ValueTask InvokedAsync(
InvokedContext context, CancellationToken cancellationToken = default)
{
if (this.UserInfo.UserName is null)
{
// Exemplo simplificado: detecta se o usuário informou o nome
bool nameFound = context.RequestMessages.Last().Text.Contains("My name is");
if (nameFound)
{
this.UserInfo.UserName = "Extracted User"; // estado atualizado
}
}
return default;
}
public override JsonElement Serialize(JsonSerializerOptions? jsonSerializerOptions = null)
{
// Serializa a memória junto com o thread
return JsonSerializer.SerializeToElement(this.UserInfo, jsonSerializerOptions);
}
}
Depois de cada turno, o InvokedAsync analisa a última mensagem do usuário e guarda o nome, se ele foi informado. Em um cenário real, você usaria o próprio LLM ou uma saída estruturada para extrair nome e idade com precisão.
Por fim, você registra a memória na criação do agente por meio de uma AIContextProviderFactory. Ela garante que cada novo AgentThread receba sua própria instância de UserInfoMemory.
Orquestração com workflows no Microsoft Agent Framework
Agentes individuais são poderosos, mas o potencial completo aparece quando eles trabalham juntos. Workflows são grafos de execução que modelam processos de negócio combinando agentes, ferramentas e código de forma estruturada.
Assim, agentes especializados viram colaboradores de um processo maior. O artigo sobre como orquestrar agentes com workflows explora esse tema em detalhe.
Executors, edges e WorkflowBuilder
No Microsoft Agent Framework, três componentes formam o grafo direcionado de um workflow:
- Executors: os nós do grafo, ou seja, as unidades de trabalho. Podem ser um
AIAgentou uma classe C# que executa uma tarefa determinística. - Edges: as arestas que ligam os executors e definem para onde vai a saída de cada um.
- WorkflowBuilder: a API fluente que adiciona executors e arestas de forma programática.
Workflow sequencial
No padrão mais simples, a execução flui de forma linear. A saída de um executor vira a entrada do próximo, o que é ideal para etapas que precisam ocorrer em ordem.
O fluxo do exemplo é [Input] -> [UppercaseExecutor] -> [ReverseTextExecutor] -> [Output]. Primeiro, o texto vai para maiúsculas; depois, é invertido.
// Cria os executors
UppercaseExecutor uppercase = new();
ReverseTextExecutor reverse = new();
// Conecta os executors em sequência e define a saída final
WorkflowBuilder builder = new(uppercase);
builder.AddEdge(uppercase, reverse).WithOutputFrom(reverse);
var workflow = builder.Build();
// Executa o workflow em processo
await using Run run = await InProcessExecution.RunAsync(workflow, "Hello, World!");
Observe que o WithOutputFrom marca a saída de reverse como o resultado final do workflow. Nesse exemplo, os executors são classes C# comuns, o que mostra que o Microsoft Agent Framework orquestra também lógica determinística, e não só agentes.
Workflow concorrente com fan-out e fan-in
Esse padrão processa tarefas em paralelo, o que acelera o trabalho e combina diferentes perspectivas. Além disso, ele é útil quando as tarefas são independentes entre si e podem rodar ao mesmo tempo.
Por exemplo, você pode consultar vários especialistas de uma só vez.
No fan-out, um executor de partida envia a mesma entrada para vários executors com AddFanOutEdge. Já no fan-in, um executor de agregação espera todos os resultados e os consolida, configurado com AddFanInEdge.
No exemplo, uma pergunta vai ao mesmo tempo para um agente físico e um agente químico. O ConcurrentStartExecutor distribui a entrada, enquanto o ConcurrentAggregationExecutor reúne as respostas.
// Cria os agentes especialistas
ChatClientAgent physicist = new(chatClient, name: "Physicist", ...);
ChatClientAgent chemist = new(chatClient, name: "Chemist", ...);
// Cria os executors de início e de agregação
var startExecutor = new ConcurrentStartExecutor();
var aggregationExecutor = new ConcurrentAggregationExecutor();
// Monta o workflow com fan-out e fan-in
var workflow = new WorkflowBuilder(startExecutor)
.AddFanOutEdge(startExecutor, targets: [physicist, chemist])
.AddFanInEdge(aggregationExecutor, sources: [physicist, chemist])
.WithOutputFrom(aggregationExecutor)
.Build();
Lógica de ramificação
Para workflows que tomam decisões, o Microsoft Agent Framework oferece duas abordagens. A primeira são as arestas condicionais: o AddEdge aceita um parâmetro condition, uma Func<object?, bool> que avalia a saída do executor.
Se a função retornar true, a aresta é ativada. A segunda abordagem é o padrão switch-case, com o método AddSwitch, que encadeia casos com AddCase e define um caminho padrão com WithDefault.
O exemplo roteia um e-mail com base na classificação de um agente de detecção de spam. Esse é um caso clássico em que o Microsoft Agent Framework combina a decisão do LLM com regras explícitas de código.
// Define as funções de condição
Func<object?, bool> isNotSpamCondition = GetCondition(SpamDecision.NotSpam);
Func<object?, bool> isSpamCondition = GetCondition(SpamDecision.Spam);
// Monta o workflow usando switch-case
WorkflowBuilder builder = new(spamDetectionExecutor);
builder.AddSwitch(spamDetectionExecutor, switchBuilder =>
switchBuilder
.AddCase(isNotSpamCondition, emailAssistantExecutor)
.AddCase(isSpamCondition, handleSpamExecutor)
.WithDefault(handleUncertainExecutor)
);
// ... continue a construção
Confiabilidade e estado no Microsoft Agent Framework
Em aplicações corporativas, a confiabilidade não é opcional. Falhas de processo, reinícios de servidor e pausas para intervenção humana exigem uma estratégia sólida de gerenciamento de estado.
Por isso, o Microsoft Agent Framework traz mecanismos para persistir o estado de conversas e workflows. Nos workflows, os checkpoints salvam o estado ao fim de cada etapa de execução, permitindo retomar o processo depois.
Persistindo e retomando conversas
Salvar e restaurar uma conversa segue quatro etapas:
- Serializar:
thread.Serialize()converte o estado completo doAgentThread, incluindo histórico e memória, em umJsonElement. - Armazenar: grave o JSON em um banco de dados, no Azure Blob Storage ou em um arquivo local durante o desenvolvimento.
- Carregar: em outra sessão ou processo, recupere o JSON do armazenamento.
- Desserializar:
agent.DeserializeThread(jsonElement)recria oAgentThreada partir do JSON.
A desserialização precisa usar um agente do mesmo tipo que criou o thread original. Caso contrário, a compatibilidade não é garantida.
// ... após algumas interações com o agente no thread
// 1. Serializa o estado do thread
string serializedJson = thread.Serialize(JsonSerializerOptions.Web).GetRawText();
// 2. Salva em um arquivo, simulando armazenamento persistente
string filePath = Path.Combine(Path.GetTempPath(), "agent_thread.json");
await File.WriteAllTextAsync(filePath, serializedJson);
// ... mais tarde, em outra sessão
// 3. Carrega o JSON persistido
string loadedJson = await File.ReadAllTextAsync(filePath);
JsonElement reloaded = JsonSerializer.Deserialize<JsonElement>(loadedJson, JsonSerializerOptions.Web);
// 4. Desserializa o thread usando a mesma instância do agente
AgentThread resumedThread = agent.DeserializeThread(reloaded, JsonSerializerOptions.Web);
// 5. Continua a conversa
Console.WriteLine(await agent.RunAsync("Now tell that joke in the voice of a pirate.", resumedThread));
Trate o JSON serializado como dado confiável da aplicação. Afinal, ele contém o histórico completo da conversa e pode incluir informações sensíveis do usuário.
Conclusão
Neste guia, os agentes apareceram como blocos de construção. Começamos com um agente simples e o aprimoramos com ferramentas, aprovação humana e memória para conversas contextuais.
Em seguida, subimos o nível de abstração com workflows. Vimos como conectar agentes e código C# em pipelines sequenciais, paralelos e com ramificações.
Por fim, a persistência e os checkpoints fecham o quadro de confiabilidade. Com eles, o Microsoft Agent Framework suporta processos longos e tolerantes a falhas.
Para uma visão complementar, leia também uma visão geral do Agent Framework. Já a documentação oficial no Microsoft Learn acompanha a evolução do Microsoft Agent Framework desde o preview.
FAQ
O Microsoft Agent Framework substitui o Semantic Kernel?
Para construção de agentes, sim: ele é o sucessor direto, criado pelo mesmo time. O Semantic Kernel 1.x segue recebendo correções críticas e de segurança por pelo menos um ano após o fim do preview.
Quais linguagens o framework suporta?
No lançamento, o Microsoft Agent Framework suportava .NET e Python. Além disso, o mesmo modelo de agentes e workflows vale para as duas linguagens.
Qual a diferença entre agente e workflow?
O agente usa um LLM para decidir sozinho o que fazer, inclusive quando chamar ferramentas. O workflow define explicitamente a ordem de execução entre agentes e funções.
Como o agente lembra de conversas anteriores?
Por meio de um AgentThread que você passa em cada chamada de RunAsync. Para persistir, serialize o thread e desserialize-o depois com o mesmo tipo de agente.
Posso exigir aprovação humana antes de uma ferramenta rodar?
Sim. Basta envolver a função com ApprovalRequiredAIFunction e responder ao pedido de aprovação devolvido pelo agente.