Microsoft Agent Framework Tools Created: 19 Feb 2026 Updated: 19 Feb 2026

Function Tools with Microsoft Agent Framework

This lesson shows how to extend an AI agent with custom C# methods called function tools. When a user sends a message that requires real data or side-effects, the agent automatically invokes the right tool, receives the result, and incorporates it into its reply — all without any extra orchestration code on your side.

What is a Function Tool?

A function tool is any ordinary C# method that you expose to the agent via AIFunctionFactory.Create(). The framework captures the method name, its XML/attribute description, and the names and descriptions of its parameters. This metadata is sent to the model alongside the user message so the model can decide whether — and how — to call the method.

Not all agent types support caller-supplied function tools. The ChatClientAgent produced by .AsAIAgent() does support them.

Key API Surface

APIPurpose
AIFunctionFactory.Create(method)Wraps a C# method as an AIFunction. Captures [Description] attributes and parameter metadata.
[System.ComponentModel.Description("…")]Applied to the method and its parameters. Gives the model the context it needs to decide when and how to call the tool.
.AsAIAgent(instructions, tools: [...])Registers one or more AIFunction instances with the agent at creation time.
agent.RunAsync(prompt, session?)Runs a full agent turn. Internally handles the tool-call loop: call model → invoke requested tools → feed results back → produce reply.
agent.CreateSessionAsync()Creates an AgentSession that preserves conversation history across multiple RunAsync calls.

How the Tool-Call Loop Works

  1. User sends a message. You call agent.RunAsync(prompt).
  2. Model responds with a tool-call request. Instead of a text reply, the model returns the name of the tool and the argument values it computed from the conversation.
  3. Framework invokes your C# method. The agent runtime calls your method with the provided arguments and serializes the return value.
  4. Result is sent back to the model. The framework appends a tool result message to the conversation and calls the model again.
  5. Model produces a final text reply. The AgentResponse.Text you receive contains the grounded answer.

This loop is fully automatic. If the model decides to call multiple tools in one turn, the framework handles all of them before returning control to your code.

Demo 1 – Single Function Tool

File: Lesson8/Demo1_FunctionTools.cs

Registers a single GetWeather method as a function tool. The agent calls it when the user asks about weather.

using System.ComponentModel;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using OpenAI;

[Description("Get the current weather for a given location.")]
static string GetWeather(
[Description("The city or location to get the weather for.")] string location)
=> $"The weather in {location} is cloudy with a high of 15°C.";

AIFunction weatherTool = AIFunctionFactory.Create(GetWeather);

AIAgent agent = new OpenAIClient(apiKey)
.GetChatClient("gpt-4o")
.AsIChatClient()
.AsAIAgent(
instructions: "You are a helpful assistant. Use available tools when needed.",
tools: [weatherTool]);

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

What happens at runtime

  1. The user asks about the weather in Amsterdam.
  2. The model identifies GetWeather as the relevant tool and requests a call with location = "Amsterdam".
  3. The framework invokes GetWeather("Amsterdam").
  4. The result is fed back and the model returns a natural-language reply.

Demo 2 – Multiple Function Tools

File: Lesson8/Demo2_MultipleFunctionTools.cs

Registers three tools at once. The agent selects the correct tool for each user message. An AgentSession is used to preserve conversation history across turns.

using System.ComponentModel;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using OpenAI;

[Description("Get the current weather for a given location.")]
static string GetWeather(
[Description("The city or location to get the weather for.")] string location)
=> $"The weather in {location} is partly cloudy with a high of 18°C.";

[Description("Convert an amount from one currency to another.")]
static string ConvertCurrency(
[Description("The monetary amount to convert.")] double amount,
[Description("The source currency code, e.g. USD.")] string from,
[Description("The target currency code, e.g. EUR.")] string to)
=> $"{amount} {from} = {amount * 0.92:F2} {to}";

[Description("Get the current local date and time.")]
static string GetCurrentDateTime()
=> $"The current date and time is {DateTime.Now:f}.";

AIFunction[] tools =
[
AIFunctionFactory.Create(GetWeather),
AIFunctionFactory.Create(ConvertCurrency),
AIFunctionFactory.Create(GetCurrentDateTime),
];

AIAgent agent = new OpenAIClient(apiKey)
.GetChatClient("gpt-4o")
.AsIChatClient()
.AsAIAgent(
instructions: "You are a helpful assistant. Use available tools when needed.",
tools: tools);

AgentSession session = await agent.CreateSessionAsync();

// Turn 1 – calls GetWeather
AgentResponse r1 = await agent.RunAsync("What is the weather like in London?", session);

// Turn 2 – calls ConvertCurrency
AgentResponse r2 = await agent.RunAsync("How much is 250 USD in EUR?", session);

// Turn 3 – calls GetCurrentDateTime
AgentResponse r3 = await agent.RunAsync("What day and time is it right now?", session);

Tool selection per turn

User messageTool called
What is the weather like in London?GetWeather("London")
How much is 250 USD in EUR?ConvertCurrency(250, "USD", "EUR")
What day and time is it right now?GetCurrentDateTime()

Best Practices

  1. Always provide a [Description] on both the method and its parameters. The model uses this text to decide when and how to call the tool. Vague descriptions lead to incorrect or missed tool calls.
  2. Keep tools focused and single-purpose. One tool per action (get weather, convert currency) helps the model reason about which tool to use without ambiguity.
  3. Return simple, structured strings. The model reads the return value as a tool result message. A concise, human-readable string is easier for the model to incorporate than raw JSON.
  4. Use AgentSession for multi-turn conversations. A session carries conversation history, enabling follow-up questions and context-aware tool selection across several turns.

Prerequisites

  1. Install the NuGet packages: Microsoft.Agents.AI, Microsoft.Extensions.AI.OpenAI.
  2. Set the OPEN_AI_KEY environment variable with a valid OpenAI API key.


Share this lesson: