In the previous post “Learning AI function calling in C# with Llama 3.2 SLM and Ollama running on your machine“, we wrapped our head around the concept of tool calling and implemented a C# source generator enabling our functions to be called by Llama 3.2 SLM using Ollama.

In this post, we will explore how to use Microsoft Extensions AI for tool calling in a simple .NET CLI application. We will leverage the power of Ollama and Llama 3.2 SLM to call functions and interact with the AI model using C#.

Introduction

Tool calling in AI, often referred to as function calling, is a feature that allows AI models, particularly Language Models (LMs), to perform tasks beyond simple text generation by invoking predefined functions. This capability significantly enhances the interaction between humans and AI applications, allowing for more complex and structured outputs.

In essence, tool calling enables an AI model to use external tools, such as APIs and functions, to respond to prompts with more than just text. For example, an AI could be prompted to retrieve the weather forecast for a specific location. Instead of generating a text-based guess, the model can invoke a function that interacts with a weather API to provide accurate, real-time data.

The process involves two main components: the function name and a structured set of arguments, usually defined using JSONSchema. These arguments are essential for executing the specified function. The beauty of tool calling lies in its simplicity and efficiency. It offloads the responsibility of parsing structured output to the model providers, such as OpenAI, allowing for more accurate and reliable responses.

Tool calling is particularly useful for creating modular and scalable AI systems. It provides a way to structure outputs consistently, simplifies the interaction by embedding the concept directly into the model, and offers a secure method to prevent users from manipulating the model’s output in unintended ways.

Requirements

  • Llama 3.2 SLM, a model supporting function calling
  • Ollama to run the SLM and deal with the integration
  • A .NET CLI application using Microsoft.Extensions.AI

Setting Up Your Environment

To get started with AI function calling in C#, you need to

  • Install Ollama to run the SLM and handle the integration
  • Pull Llama 3.2 SLM model on your machine ollama pull llama3.2:3b

Creating a .NET CLI Application

We create a simple .NET CLI application that interacts with the AI model using Microsoft.Extensions.AI. This library provides a unified set of AI building blocks for .NET applications, making it easy to integrate AI capabilities into your projects.

1
2
3
dotnet new console -n OllamaToolCallingMicrosoftExtensions
cd OllamaToolCallingMicrosoftExtensions
dotnet add package Microsoft.Extensions.AI

Implementing Tool Calling using Microsoft.Extensions.AI

This is how simple it is to implement tool calling using Microsoft.Extensions.AI in a .NET CLI application. We define two functions, GetCurrentTime and GetCurrentWeather, and use them as tools in the chat client. The chat client is configured to use Ollama as the chat client and wraps the function invocation client with logging.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
using System.ComponentModel;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Logging;

Console.WriteLine("Hello, Microsoft.Extensions.AI with Ollama & Tool calling!");
var message = "What time is it in Illzach, France?";
Console.WriteLine(message);

using var factory = LoggerFactory.Create(builder =>
builder.AddConsole().SetMinimumLevel(LogLevel.Trace));

// 👇🏼 Use Ollama as the chat client
var ollamaChatClient =
new OllamaChatClient(new Uri("http://localhost:11434/"), "llama3.2:3b");
var client = new ChatClientBuilder(ollamaChatClient)
// 👇🏼 Add logging to the chat client, wrapping the function invocation client
.UseLogging(factory)
// 👇🏼 Add function invocation to the chat client, wrapping the Ollama client
.UseFunctionInvocation()
.Build();

var chatOptions = new ChatOptions
{
// 👇🏼 Define tools that can be used by the chat client
Tools =
[
AIFunctionFactory.Create(GetCurrentTime),
AIFunctionFactory.Create(GetCurrentWeather)
]
};

var response = await client.CompleteAsync(message, chatOptions);

Console.Write(response);

// 👇🏼 Define a time tool
[Description("Get the current time for a city")]
string GetCurrentTime(string city)
{
return $"It is {DateTime.Now.Hour}:{DateTime.Now.Minute} in {city}.";
}

// 👇🏼 Define a weather tool
[Description("Get the current weather for a city")]
string GetCurrentWeather(string city)
{
return $"The weather in {city} is sunny.";
}

Result

Running the code will output the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
 ❯  dotnet run
Hello, Microsoft.Extensions.AI with Ollama & Tool calling!
What time is it in Illzach, France?
trce: Microsoft.Extensions.AI.LoggingChatClient[805843669]
CompleteAsync invoked: [
{
"role": "user",
"contents": [
{
"$type": "text",
"text": "What time is it in Illzach, France?"
}
]
}
]. Options: {
"toolMode": {
"$type": "auto"
}
}. Metadata: {
"providerName": "ollama",
"providerUri": "http://localhost:11434/",
"modelId": "llama3.2:3b"
}.
trce: Microsoft.Extensions.AI.LoggingChatClient[384896670]
CompleteAsync completed: {
"choices": [
{
"role": "assistant",
"contents": [
{
"$type": "text",
"text": "The current time in Illzach, France is 10:45."
}
]
}
],
"completionId": "2025-01-26T09:45:18.8271931Z",
"modelId": "llama3.2:3b",
"createdAt": "2025-01-26T09:45:18.8271931+00:00",
"finishReason": "stop",
"usage": {
"inputTokenCount": 368,
"outputTokenCount": 45,
"totalTokenCount": 413,
"additionalCounts": {
"load_duration": 42408700,
"total_duration": 805363100,
"prompt_eval_duration": 108000000,
"eval_duration": 652000000
}
}
}.
The current time in Illzach, France is 10:45.

As we added the logging with trace level, we can see the trace of chat client’s interactions with Ollama. The chat client sends the message “What time is it in Illzach, France?” to Ollama, which invokes the GetCurrentTime function and returns the current time in Illzach, France. The logging also provides additional information about the completion like token usage. I think it could be useful to see the function invocation in the trace.

Conclusion

We explored how to leverage Microsoft.Extensions.AI for tool calling in a .NET CLI application using Ollama and Llama 3.2 SLM. We demonstrated the setup process, created a simple application, and implemented tool calling to interact with AI models. By integrating these technologies, developers can enhance their applications with advanced AI capabilities, enabling more complex and structured interactions. This approach provides a robust framework for building modular AI systems.

References

Get the source code on GitHub laurentkempe/aiPlayground/OllamaToolCallingMicrosoftExtensions.