Utilizando Tools no Microsoft Agent Framework

As tools no Microsoft Agent Framework (MAF) formam o modelo de extensibilidade que permite a um agente de inteligência artificial chamar funções arbitrárias durante o processamento de uma requisição. Com elas, o agente deixa de depender apenas do conhecimento estático do modelo e passa a interagir com sistemas reais.

Esse mecanismo amplia bastante as capacidades de um agente. Ele pode consultar APIs externas, acessar bancos de dados, processar dados em tempo real e executar lógica de negócio, sem reescrever ou reconfigurar o modelo de linguagem.

Diagrama de tools no Microsoft Agent Framework mostrando o agente recebendo a pergunta, chamando uma função em C# e devolvendo a resposta
Fluxo geral de um agente que usa funções em C# para responder ao usuário.

Para se aprofundar no framework, conheça também a imersão em Microsoft Agent Framework do balta.io.

O conceito de ferramenta no MAF

No contexto do MAF, uma ferramenta é qualquer método que o agente pode invocar quando considera a chamada relevante. Em outras palavras, o modelo decide sozinho se precisa de dados externos para responder a uma pergunta ou executar uma tarefa.

O framework não exige que você registre as ferramentas em um catálogo separado. Qualquer método C# pode virar uma ferramenta funcional por meio da classe AIFunctionFactory, que vem da biblioteca Microsoft.Extensions.AI.

Esse design reduz o atrito no desenvolvimento. Além disso, ele favorece a coesão entre o código de domínio e o comportamento do agente, porque a ferramenta é o próprio método da aplicação.

Se você ainda não conhece o framework, comece pelo artigo de introdução ao Microsoft Agent Framework. Ele apresenta os conceitos de agente, provedor e execução que este texto assume.

Como funcionam as tools no Microsoft Agent Framework

A comunicação entre o agente e as tools no Microsoft Agent Framework passa pelo mecanismo de function calling do modelo de linguagem. Ou seja, o modelo não executa código; ele apenas pede que a aplicação execute uma função com certos argumentos.

O ciclo funciona em quatro etapas. Primeiro, o framework envia ao modelo a pergunta e a lista de funções disponíveis, com nome, descrição e esquema dos parâmetros.

Em seguida, o modelo responde com um pedido de chamada, indicando qual função usar e com quais argumentos. Depois, o framework executa o método C# correspondente e devolve o resultado ao modelo.

Por fim, o modelo usa esse resultado para montar a resposta final ao usuário. Esse ciclo pode se repetir várias vezes na mesma requisição, quando a tarefa exige mais de uma chamada.

Segundo a documentação oficial de function tools, nem todo tipo de agente aceita funções personalizadas. O tutorial da Microsoft usa um ChatClientAgent, que suporta function tools de forma completa.

Definindo tools no Microsoft Agent Framework com atributos de descrição

Para que o modelo decida com precisão quando e como invocar uma ferramenta, ele precisa de descrições claras. Por isso, você deve descrever tanto a função quanto os seus parâmetros.

O MAF usa o atributo [Description], do namespace System.ComponentModel, para esse propósito. O exemplo abaixo define uma ferramenta que retorna informações sobre o clima de uma localidade.

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.";

No método, o atributo descreve o propósito geral da função. Já o atributo no parâmetro orienta o modelo sobre o tipo de valor esperado.

Quanto mais precisa for a descrição, menor a ambiguidade. Isso pesa principalmente quando o modelo precisa escolher entre várias ferramentas parecidas.

Boas práticas de descrição

Escreva descrições curtas, no imperativo e focadas no resultado. Por exemplo, "Get the weather for a given location" diz exatamente o que a função entrega.

Também informe formatos esperados nos parâmetros, como "city name" ou "ISO 8601 date". Dessa forma, o modelo gera argumentos válidos com mais frequência.

Evite descrições genéricas como "Helper method". Afinal, o modelo só conhece a ferramenta pelo que está escrito no nome, na descrição e no esquema.

Registrando a ferramenta no agente

Depois de definir o método, o próximo passo é criar o agente e informar a quais ferramentas ele tem acesso. A criação do AIAgent parte de um AIProjectClient, que conecta a aplicação ao endpoint do projeto no Azure.

O método AsAIAgent recebe, entre outros parâmetros, a coleção de ferramentas disponíveis.

using System;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;

var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")
    ?? throw new InvalidOperationException("Set 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,
        instructions: "You are a helpful assistant.",
        tools: [AIFunctionFactory.Create(GetWeather)]);

O método AIFunctionFactory.Create converte o método estático em uma instância de AIFunction. Esse é o tipo que o framework reconhece como ferramenta funcional.

A lista passada no parâmetro tools pode conter várias funções. Assim, o agente seleciona automaticamente a mais adequada conforme o contexto da conversa.

Executando o agente com tools no Microsoft Agent Framework

Uma vez configurado, você invoca o agente normalmente com o método RunAsync. Quando a pergunta exige uma das ferramentas registradas, o agente faz a chamada sozinho, sem intervenção do seu código.

Console.WriteLine(await agent.RunAsync("What is the weather like in Amsterdam?"));

Nesse exemplo, o agente percebe que a resposta depende de dados externos. Então, ele pede a execução de GetWeather com o argumento "Amsterdam", recebe o retorno e incorpora o valor à resposta final.

Esse modelo de orquestração é transparente para quem consome o agente. Com isso, as tools no Microsoft Agent Framework eliminam a necessidade de lógica condicional explícita no código de chamada.

Para manter o histórico entre várias perguntas, use sessões. O artigo sobre conversas multi-turnos no Microsoft Agent Framework detalha esse recurso.

Ferramentas assíncronas e tratamento de erros

Na prática, a maior parte das tools no Microsoft Agent Framework faz I/O. Por exemplo, elas chamam APIs HTTP, consultam bancos de dados ou leem arquivos.

Nesses casos, implemente a ferramenta como método assíncrono. O AIFunctionFactory.Create aceita métodos que retornam Task<T>, e o framework aguarda o resultado antes de devolvê-lo ao modelo.

using System.ComponentModel;
using System.Net.Http.Json;

public sealed record ExchangeRate(string From, string To, decimal Rate);

public sealed class CurrencyTools(HttpClient httpClient)
{
    [Description("Get the current exchange rate between two currencies.")]
    public async Task<string> GetExchangeRateAsync(
        [Description("Source currency code, for example USD.")] string from,
        [Description("Target currency code, for example BRL.")] string to)
    {
        try
        {
            // Chamada externa que pode falhar por rede ou indisponibilidade
            var rate = await httpClient.GetFromJsonAsync<ExchangeRate>($"rates/{from}/{to}");
            return rate is null
                ? "Exchange rate not found."
                : $"1 {rate.From} = {rate.Rate} {rate.To}";
        }
        catch (HttpRequestException)
        {
            // Retorna uma mensagem estruturada em vez de propagar a exceção
            return "The exchange rate service is unavailable. Try again later.";
        }
    }
}

Quando uma ferramenta lança uma exceção, o FunctionInvokingChatClient da Microsoft.Extensions.AI captura o erro e avisa o modelo. Por padrão, o modelo recebe apenas uma mensagem genérica, porque a propriedade IncludeDetailedErrors vale false.

Além disso, a propriedade MaximumConsecutiveErrorsPerRequest limita as falhas seguidas, com padrão de 3. Quando o limite é atingido, a exceção volta para quem chamou o agente.

Mesmo assim, a recomendação continua válida: trate exceções dentro da ferramenta e retorne mensagens claras. Dessa forma, o modelo entende o problema e pode responder ao usuário de forma útil.

Credenciais e considerações de produção

O DefaultAzureCredential é conveniente durante o desenvolvimento local. Ele percorre automaticamente vários provedores de credencial disponíveis no ambiente, como a CLI do Azure e o Visual Studio.

No entanto, a própria documentação do MAF alerta para o uso em produção. Essa varredura pode adicionar latência e expõe o sistema a mecanismos de fallback que representam riscos de segurança.

Para cenários produtivos, prefira credenciais específicas e com escopo bem definido. Um exemplo é o ManagedIdentityCredential, que autentica direto com a identidade gerenciada atribuída ao recurso no Azure.

// Em produção, use uma credencial explícita
var credential = new ManagedIdentityCredential(ManagedIdentityId.SystemAssigned);

AIAgent agent = new AIProjectClient(new Uri(endpoint), credential)
    .AsAIAgent(
        model: deploymentName,
        instructions: "You are a helpful assistant.",
        tools: [AIFunctionFactory.Create(GetWeather)]);

Várias tools no Microsoft Agent Framework em uma única classe

Em cenários mais complexos, várias ferramentas compartilham estado ou dependências. Por exemplo, elas podem usar o mesmo cliente HTTP, as mesmas feature flags ou os mesmos dados em cache.

Nesses casos, você pode encapsular as tools no Microsoft Agent Framework em uma única classe. Depois, registra cada método individualmente no agente.

using System.ComponentModel;

public class WeatherTools
{
    private readonly bool _useMetric;

    public WeatherTools(bool useMetric = true)
    {
        _useMetric = useMetric;
    }

    [Description("Get the current weather for a location.")]
    public string GetCurrentWeather(
        [Description("The city name.")] string city)
        => _useMetric
            ? $"The weather in {city} is 15°C."
            : $"The weather in {city} is 59°F.";

    [Description("Get the weather forecast for the next 3 days.")]
    public string GetForecast(
        [Description("The city name.")] string city)
        => $"The forecast for {city} shows rain tomorrow and sun the day after.";
}

Para registrar, crie a instância e passe cada método ao AIFunctionFactory.Create. Assim, todos os métodos compartilham o mesmo estado da instância.

var weatherTools = new WeatherTools(useMetric: true);

AIAgent agent = new AIProjectClient(new Uri(endpoint), new DefaultAzureCredential())
    .AsAIAgent(
        model: deploymentName,
        instructions: "You are a helpful weather assistant.",
        tools:
        [
            AIFunctionFactory.Create(weatherTools.GetCurrentWeather),
            AIFunctionFactory.Create(weatherTools.GetForecast)
        ]);

Essa abordagem organiza melhor o código e evita duplicar a lógica de inicialização. Além disso, valores que o modelo não deve fornecer, como clientes de serviço, ficam no construtor, longe dos parâmetros da ferramenta.

Aprovação humana nas tools no Microsoft Agent Framework

Algumas tools no Microsoft Agent Framework têm efeitos irreversíveis ou exigem consentimento explícito do usuário. Para esses casos, o MAF oferece suporte nativo ao padrão human-in-the-loop.

Nesse modelo, o agente não executa a função logo que o modelo a solicita. Em vez disso, ele termina a execução com um pedido de aprovação e aguarda a decisão do usuário.

A implementação exige envolver a AIFunction em uma instância de ApprovalRequiredAIFunction.

AIFunction weatherFunction = AIFunctionFactory.Create(GetWeather);
AIFunction approvalRequiredWeatherFunction = new ApprovalRequiredAIFunction(weatherFunction);

AIAgent agent = new AIProjectClient(new Uri(endpoint), new DefaultAzureCredential())
    .AsAIAgent(
        model: deploymentName,
        instructions: "You are a helpful assistant.",
        tools: [approvalRequiredWeatherFunction]);

Ao executar o agente, a resposta pode conter instâncias de ToolApprovalRequestContent. Elas sinalizam que uma chamada de função está pendente de aprovação.

AgentSession session = await agent.CreateSessionAsync();
AgentResponse response = await agent.RunAsync("What is the weather like in Amsterdam?", session);

var toolApprovalRequests = response.Messages
    .SelectMany(x => x.Contents)
    .OfType<ToolApprovalRequestContent>()
    .ToList();

Versões anteriores do framework usavam o nome FunctionApprovalRequestContent para esse tipo. Por isso, confira qual nome existe no pacote instalado no seu projeto.

Enviando a decisão do usuário

Você é responsável por mostrar os dados da chamada ao usuário e coletar a decisão. A propriedade ToolCall traz o nome da função e os argumentos.

ToolApprovalRequestContent requestContent = toolApprovalRequests.First();
var functionCall = (FunctionCallContent)requestContent.ToolCall;

// Apresenta ao usuário o nome da função e os argumentos
Console.WriteLine($"Approval required to execute '{functionCall.Name}'");

var approvalMessage = new ChatMessage(ChatRole.User, [requestContent.CreateResponse(true)]);
Console.WriteLine(await agent.RunAsync(approvalMessage, session));

Passar true para CreateResponse aprova a execução, enquanto false a rejeita. Toda a lógica de apresentação e coleta da decisão fica sob responsabilidade da aplicação.

A documentação recomenda verificar novos pedidos de aprovação após cada execução. Isso porque o agente pode solicitar outras chamadas até concluir a tarefa.

Sessões e gerenciamento de contexto em aprovações

O uso de sessões é fundamental quando há tools no Microsoft Agent Framework com aprovação. A instância de AgentSession mantém o histórico da conversa entre as rodadas necessárias para completar o fluxo.

Sem o objeto de sessão, o agente perde o contexto das iterações anteriores. Consequentemente, ele pode não associar a resposta de aprovação à chamada de função pendente.

Por isso, sempre envie a resposta de aprovação com a mesma sessão usada na primeira execução. O artigo sobre memória e provedores de contexto no Microsoft Agent Framework aprofunda o armazenamento desse histórico.

Segurança das tools no Microsoft Agent Framework

Adicionar tools no Microsoft Agent Framework sem critério expande a superfície de ataque do sistema. Cada ferramenta é uma porta que o modelo pode abrir com argumentos que você não controla diretamente.

Funções com efeitos colaterais devem sempre usar o modo de aprovação. Por exemplo, escrita em banco de dados, envio de e-mails ou chamadas a APIs financeiras se encaixam nesse grupo.

Já ferramentas apenas de leitura, sem impacto externo, podem rodar sem aprovação. Ainda assim, descreva-as com precisão para evitar chamadas desnecessárias, que consomem tokens e aumentam a latência.

O princípio do menor privilégio se aplica diretamente aqui. Ou seja, cada agente deve acessar apenas as ferramentas estritamente necessárias para as suas tarefas.

Também valide os argumentos dentro de cada ferramenta. Afinal, o modelo pode gerar valores fora do esperado, e o seu código precisa rejeitá-los antes de tocar em qualquer sistema.

Se você está decidindo entre expor funções locais ou servidores externos, vale ler a comparação entre agents e MCP.

Quando usar tools no Microsoft Agent Framework

Use tools no Microsoft Agent Framework sempre que a resposta depender de informação que o modelo não tem. Dados do cliente, estoque, preços atuais e status de pedidos são exemplos típicos.

Também faz sentido usar ferramentas quando o agente precisa agir, e não apenas responder. Por exemplo, abrir um chamado, agendar uma reunião ou atualizar um cadastro.

Por outro lado, evite criar ferramentas para tarefas que o próprio modelo resolve bem. Resumir um texto, traduzir uma frase ou reescrever um parágrafo não exigem código adicional.

Outro critério é o custo. Cada ferramenta registrada aumenta o tamanho do contexto enviado ao modelo, porque o esquema de cada função vai junto em todas as requisições.

Portanto, mantenha a lista enxuta e coesa. Se um agente começa a acumular dezenas de funções, provavelmente vale dividi-lo em agentes menores e especializados.

Nesse cenário, o artigo sobre orquestrar agentes com workflows no Microsoft Agent Framework mostra como coordenar vários agentes, cada um com o seu próprio conjunto de tools no Microsoft Agent Framework.

Conclusão

O mecanismo de tools no Microsoft Agent Framework é uma das extensões mais poderosas para agentes baseados em LLMs no ecossistema .NET. Ele permite que o agente supere o conhecimento estático do modelo e interaja com sistemas reais por meio de código C# comum.

A integração entre o atributo [Description], a classe AIFunctionFactory e o suporte a aprovações forma um modelo completo. Com isso, as tools no Microsoft Agent Framework ajudam a construir agentes ao mesmo tempo capazes e seguros.

Por fim, adote boas práticas desde o início: descrições precisas, credenciais específicas em produção e aprovação para operações sensíveis. Esse é o caminho para agentes que entregam valor real com riscos controlados.

FAQ

O agente sempre chama a ferramenta quando ela está disponível?

Não. O modelo decide quando invocar uma ferramenta com base na relevância para a pergunta e responde direto quando não precisa de nenhuma função.

É possível registrar várias ferramentas com o mesmo nome?

Não é recomendado. Cada ferramenta deve ter um nome único no agente, porque conflitos de nome confundem o modelo na hora de escolher a função.

O que acontece se uma ferramenta lançar uma exceção?

O FunctionInvokingChatClient captura o erro e envia ao modelo uma mensagem genérica, a menos que IncludeDetailedErrors esteja ativo. Após falhas consecutivas acima do limite configurado, a exceção volta para quem chamou o agente.

Ferramentas assíncronas são suportadas?

Sim. O AIFunctionFactory.Create aceita métodos assíncronos, e operações de rede ou banco de dados devem usar async e await.

O modo de aprovação é definido por ferramenta ou por chamada?

Na composição básica, ele é definido por ferramenta, com ApprovalRequiredAIFunction. O Harness Agent do MAF adiciona regras de aprovação automática configuráveis, para quem precisa de políticas mais flexíveis.