Nos últimos anos, a maioria das integrações com IA em aplicações corporativas se resumiu a enviar um prompt para um modelo e exibir a resposta. Isso resolve parte do problema, mas não entrega o que o negócio realmente precisa: uma IA capaz de consultar dados reais, executar ações e manter o contexto de uma conversa de forma segura e monitorada.
É exatamente esse o papel dos agentes de IA. E no ecossistema .NET, a Microsoft consolidou suas iniciativas nessa área em uma única ferramenta: o Microsoft Agent Framework.
Neste artigo, vamos construir um agente de atendimento para uma empresa de logística, capaz de consultar pedidos, calcular prazos de entrega e manter o histórico da conversa, com observabilidade via OpenTelemetry. Tudo com exemplos práticos e explicações detalhadas.
O que é o Microsoft Agent Framework?
O Microsoft Agent Framework é um SDK open source (licença MIT) para criar agentes de IA e fluxos com múltiplos agentes em .NET e Python. Ele é o sucessor do Semantic Kernel e do AutoGen, unindo a base corporativa do primeiro com as orquestrações do segundo.
A versão 1.0 foi lançada em abril de 2026, com APIs estáveis e compromisso de suporte de longo prazo. Por ser construído sobre o Microsoft.Extensions.AI, ele segue os padrões que já conhecemos no .NET: injeção de dependência, middleware e configuração.
Com o Agent Framework, é possível:
- Criar agentes conectados a diferentes provedores: Microsoft Foundry, Azure OpenAI, OpenAI, Anthropic Claude, Amazon Bedrock, Google Gemini e Ollama.
- Expor métodos C# como ferramentas que o agente decide quando chamar.
- Manter o histórico de conversas com sessões.
- Orquestrar múltiplos agentes (sequencial, concorrente, handoff e group chat).
- Consumir ferramentas via MCP e conversar com agentes de outros frameworks via A2A.
- Monitorar tudo com OpenTelemetry.
Se você já usa o Semantic Kernel, a Microsoft disponibiliza um guia de migração. Para projetos novos, o Agent Framework é o caminho recomendado.
Instalando o Agent Framework
Para este exemplo, você vai precisar de um projeto no Microsoft Foundry com um modelo publicado (por exemplo, gpt-4o-mini) e do Azure CLI autenticado com az login.
Crie um novo projeto .NET 10 (Console Application) e adicione os pacotes:
dotnet new console -n Logistica.Agente
cd Logistica.Agente
dotnet add package Microsoft.Agents.AI.Foundry --prerelease
dotnet add package Azure.Identity
dotnet add package OpenTelemetry.Exporter.ConsoleO pacote Microsoft.Agents.AI (núcleo do framework) já está em versão estável, mas o conector do Foundry ainda é publicado como prerelease, por isso o parâmetro --prerelease.
Em seguida, configure as variáveis de ambiente com o endpoint do seu projeto e o nome do modelo:
export AZURE_OPENAI_ENDPOINT="https://seu-projeto.services.ai.azure.com"
export AZURE_OPENAI_DEPLOYMENT_NAME="gpt-4o-mini"Criando o primeiro agente
Na classe Program.cs, crie o agente com o código abaixo:
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")
?? throw new InvalidOperationException("Configure a variável AZURE_OPENAI_ENDPOINT");
var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-4o-mini";
AIAgent agent = new AIProjectClient(new Uri(endpoint), new DefaultAzureCredential())
.AsAIAgent(
model: deploymentName,
name: "AgenteLogistica",
instructions: "Você é um assistente de atendimento de uma empresa de logística. Responda de forma breve e objetiva.");
Console.WriteLine(await agent.RunAsync("Quais informações você precisa para rastrear um pedido?"));O método AsAIAgent transforma o cliente do Foundry em um AIAgent, a abstração central do framework. As instructions funcionam como o system prompt: definem o papel e os limites do agente.
Para uma experiência de chat mais fluida, você também pode receber a resposta em streaming:
await foreach (var update in agent.RunStreamingAsync("Explique em uma frase o que é logística reversa."))
{
Console.Write(update);
}Até aqui, temos apenas um chatbot. O que transforma isso em um agente é a capacidade de agir, e é isso que vamos fazer a seguir.
Adicionando ferramentas ao agente
Ferramentas (function tools) são métodos C# que o agente pode chamar quando julgar necessário. O modelo não executa código: ele decide qual ferramenta chamar e com quais parâmetros, e o framework faz a invocação e devolve o resultado para o modelo.
Vamos considerar o seguinte cenário para o nosso agente de logística:
ConsultarPedido: retorna o status de um pedido.CalcularPrazoEntrega: estima o prazo de entrega para um CEP de destino.
Crie a classe PedidoTools.cs:
using System.ComponentModel;
public class PedidoTools
{
private static readonly Dictionary<string, (string Status, string Destino)> _pedidos = new()
{
["PED-1001"] = ("Em trânsito", "Vitória/ES"),
["PED-1002"] = ("Entregue", "São Paulo/SP"),
["PED-1003"] = ("Aguardando coleta", "Belo Horizonte/MG")
};
[Description("Consulta o status atual de um pedido pelo número.")]
public string ConsultarPedido(
[Description("Número do pedido no formato PED-0000.")] string numeroPedido)
{
return _pedidos.TryGetValue(numeroPedido.ToUpperInvariant(), out var pedido)
? $"Pedido {numeroPedido}: {pedido.Status}, destino {pedido.Destino}."
: $"Pedido {numeroPedido} não encontrado.";
}
[Description("Calcula o prazo estimado de entrega em dias úteis para um CEP de destino.")]
public int CalcularPrazoEntrega(
[Description("CEP de destino, somente números.")] string cep)
{
// Regra simplificada: CEPs da região Sudeste (0 a 3) têm prazo menor
return cep.Length > 0 && cep[0] is >= '0' and <= '3' ? 2 : 5;
}
}O atributo [Description] é fundamental: é a partir dele que o modelo entende para que serve cada ferramenta e cada parâmetro. Descrições vagas geram chamadas erradas.
Agora registre as ferramentas no agente com o AIFunctionFactory:
using Microsoft.Extensions.AI;
var tools = new PedidoTools();
AIAgent agent = new AIProjectClient(new Uri(endpoint), new DefaultAzureCredential())
.AsAIAgent(
model: deploymentName,
name: "AgenteLogistica",
instructions: """
Você é um assistente de atendimento de uma empresa de logística.
Use as ferramentas disponíveis para consultar pedidos e prazos.
Nunca invente informações sobre pedidos.
""",
tools:
[
AIFunctionFactory.Create(tools.ConsultarPedido),
AIFunctionFactory.Create(tools.CalcularPrazoEntrega)
]);
Console.WriteLine(await agent.RunAsync("Qual o status do pedido PED-1001? E qual o prazo para o CEP 29100000?"));Neste exemplo, o agente identifica que precisa de duas informações, chama as duas ferramentas e monta uma resposta única com o resultado. Em um projeto real, a classe PedidoTools consultaria seu repositório ou sua API via injeção de dependência.
Mantendo o contexto da conversa
Por padrão, cada chamada ao RunAsync é independente. Para que o agente lembre o que foi dito anteriormente, utilizamos uma AgentSession:
AgentSession session = await agent.CreateSessionAsync();
Console.WriteLine("Agente de logística iniciado. Digite 'sair' para encerrar.");
while (true)
{
Console.Write("\nVocê: ");
var mensagem = Console.ReadLine();
if (string.IsNullOrWhiteSpace(mensagem) || mensagem.Equals("sair", StringComparison.OrdinalIgnoreCase))
break;
Console.Write("Agente: ");
await foreach (var update in agent.RunStreamingAsync(mensagem, session))
{
Console.Write(update);
}
Console.WriteLine();
}Com a sessão, um diálogo como este passa a funcionar naturalmente:
Você: Qual o status do pedido PED-1003?
Agente: O pedido PED-1003 está aguardando coleta, com destino a Belo Horizonte/MG.
Você: E qual o prazo de entrega para o CEP 30110000?
Agente: Para o CEP 30110000, o prazo estimado é de 2 dias úteis após a coleta.Na segunda pergunta, o agente sabe que ainda estamos falando do mesmo pedido. Em aplicações web, a sessão pode ser serializada e persistida (por exemplo, no Redis ou no Cosmos DB) para manter o histórico entre requisições. Os detalhes estão na documentação de sessões.
Monitoramento e Observabilidade
Um agente em produção sem observabilidade é uma caixa preta: você não sabe quais ferramentas foram chamadas, quantos tokens foram consumidos nem por que uma resposta saiu errada. O Agent Framework emite traces, logs e métricas seguindo as convenções semânticas de GenAI do OpenTelemetry.
Para habilitar, envolva o agente com o UseOpenTelemetry e configure o tracer provider:
using OpenTelemetry;
using OpenTelemetry.Trace;
const string SourceName = "Logistica.Agente";
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddSource(SourceName)
.AddSource("*Microsoft.Extensions.Agents*")
.AddConsoleExporter() // Em produção: AddOtlpExporter() ou Azure Monitor
.Build();
AIAgent agentMonitorado = agent
.AsBuilder()
.UseOpenTelemetry(sourceName: SourceName, configure: cfg => cfg.EnableSensitiveData = false)
.Build();Com isso:
- Cada execução do agente gera um trace com a duração e o modelo utilizado.
- As chamadas de ferramentas aparecem como spans filhos, facilitando identificar gargalos.
- O consumo de tokens fica disponível para acompanhar custos.
- Os dados podem ser enviados para o Application Insights, Jaeger, Grafana ou para o próprio painel de observabilidade do Foundry.
Atenção ao EnableSensitiveData: quando true, os prompts e as respostas completas são registrados no trace. Isso ajuda no desenvolvimento, mas em produção pode expor dados pessoais de clientes e gerar problemas com a LGPD. Mantenha false fora do ambiente local.
Cuidados para levar o agente para produção
O exemplo acima funciona bem localmente, mas alguns pontos merecem atenção antes do deploy:
- Credenciais: o
DefaultAzureCredentialé prático no desenvolvimento, mas em produção prefira oManagedIdentityCredential, evitando latência e tentativas desnecessárias de autenticação. - Ferramentas de escrita: ferramentas que alteram dados (cancelar pedido, emitir reembolso) devem exigir aprovação humana. O framework oferece suporte nativo a aprovação de ferramentas.
- Menos é mais: quanto mais ferramentas o agente tem, maior a chance de escolher a errada. Prefira agentes especializados com poucas ferramentas bem descritas.
- Valide os parâmetros: trate tudo que vem do modelo como entrada de usuário. Valide formatos, permissões e limites dentro da própria ferramenta.
- Dados antes da IA: um agente só é tão bom quanto as APIs e os dados que ele consulta. Se o processo ou a base estiverem desorganizados, o agente vai apenas automatizar o problema.
Vantagens de usar o Microsoft Agent Framework
- Totalmente integrado ao ecossistema .NET, com os mesmos padrões do ASP.NET Core.
- Independente de provedor: troque o modelo sem reescrever o agente.
- APIs estáveis desde a versão 1.0, com suporte de longo prazo.
- Observabilidade nativa com OpenTelemetry.
- Suporte a MCP, A2A e orquestração de múltiplos agentes.
- Open source e com suporte ativo da Microsoft.
Conclusão
O Microsoft Agent Framework simplifica a construção de agentes de IA no .NET. Com poucas linhas de código, conseguimos um agente que consulta dados reais, mantém o contexto da conversa e pode ser monitorado em produção.
Se você ainda está usando o Semantic Kernel ou integrando modelos de IA “na mão” com chamadas HTTP, vale a pena dar uma chance ao Agent Framework. Nos próximos artigos, vamos evoluir este exemplo com orquestração de múltiplos agentes e integração com servidores MCP.
Os detalhes completos deste exemplo você encontra no meu GitHub: https://github.com/hgmauri/sample-agent-framework
