Questa pagina non è ancora tradotta in italiano: qui la trovi in inglese.
Model providers
Connect your .NET AI agent to OpenAI, Azure OpenAI, Ollama and other local models, or to your own Agent Framework AIAgent, and choose models with tool calling.
On this page
Use this page to connect your .NET AI agent to a model: OpenAI, Azure OpenAI, Anthropic's Claude, Ollama and other local models, or an agent you build with Agent Framework, such as a Foundry agent. MentorAgent calls the model through Microsoft.Extensions.AI. In AddMentorAgent you give it one of two things: an IChatClient, which is Path A, or an Agent Framework AIAgent that you have already built, which is Path B.
Choose a path
Section titled “Choose a path”- Path A:
options.ChatClient. Use it whenever the provider has anIChatClient: OpenAI, Azure OpenAI, Anthropic's Claude models, Ollama and any server with an OpenAI-compatible API. MentorAgent builds the agent, and every feature works. - Path B:
options.Agent. Use it for a provider that you reach only through anAIAgent, such as a Foundry project (Microsoft.Agents.AI.Foundry). You add the Agent Framework package yourself. On Path B the agent's instructions are yours, and some features need aChatClientthat MentorAgent can call directly. The table shows which ones:
| Feature | Path A: ChatClient | Path B: Agent |
|---|---|---|
| Actions, Model Context Protocol (MCP) client tools, retrieval-augmented generation, Agent Skills | Yes | Yes |
| Specialists, teams, remote Agent-to-Agent (A2A) agents, YAML agents | Yes | No. A warning in the log says which ones are skipped, and the cards of the remote agents are not fetched |
| UI actions of the current page | One tool per action | One generic invoke_ui_action tool |
| Safety check | Yes | Only with ClassifierChatClient; without it, a warning when the coordinator is built |
| Model routing, tool filtering, hosted tools, structured outputs | Yes | No |
| Memory capture after each turn | Yes | Only with ClassifierChatClient, which then replaces the remember tool; without it, the remember tool saves the facts |
| Chat history | Set through MentorOptions | Set on your agent |
Set ChatClient or Agent, never both. Whatever the path, the model must support tool calling: every action is a tool.
Which providers are tested
Section titled “Which providers are tested”MentorAgent works with any provider that offers an IChatClient or an Agent Framework AIAgent, but not every provider is tested. This table says how far each one is checked. Tested live means that the library's release tests ran the sample applications on that provider, with a real model. Compiled example means that the example on this page is built with every version of this documentation, and was not run on the provider. Hosted tools are the tools that run on the provider's side, such as web search.
| Provider | Path | Status | Hosted tools |
|---|---|---|---|
| Azure OpenAI, Responses API | A | Tested live, with gpt-4.1, and o3 as the strong model | Web search, code interpreter, file search, image generation and hosted MCP. The release tests ran web search live |
| Azure OpenAI, Chat Completions | A | Tested live, with gpt-4.1 | Web search only, and only on a deployment that supports it. The others are not available |
| OpenAI | A | Compiled example, not tested live. It uses the same client library as Azure OpenAI | As for Azure OpenAI, by API: all of them with the Responses API, web search only with Chat Completions |
| Ollama and other local models | A | Compiled example. Tried on a small local model during development, not in the release tests | Not available |
| Foundry agents | B | Compiled example, not tested live | MentorAgent's hosted tools do not apply on Path B: a warning at startup says so. Tools that you set on the Foundry agent itself are the agent's |
| Anthropic Claude | A | Compiled example, not tested live. It uses Anthropic's official Anthropic SDK | Not tested |
Google Gemini and any other IChatClient | A | Possible, not tested | Not available |
- A provider that is not tested live is at your risk. Try your actions, roles and confirmation boxes on it before you rely on it. The fake model of Test without a model checks your rules, not the provider.
- A hosted tool that the provider does not support makes the provider refuse the call. MentorAgent logs the hosted tools that it enables at startup. See Hosted tools.
- The model matters as much as the provider. It must support tool calling. On Ollama, also check the context window: see Ollama and other local models.
Install the packages
Section titled “Install the packages”.NET CLI
dotnet add package Novior.MentorAgentPackageReference
<ItemGroup>
<PackageReference Include="Novior.MentorAgent" Version="1.2.0" />
</ItemGroup>Central Package Management
<ItemGroup>
<PackageVersion Include="Novior.MentorAgent" Version="1.2.0" />
</ItemGroup><ItemGroup>
<PackageReference Include="Novior.MentorAgent" />
</ItemGroup>File-based app
#:package Novior.MentorAgent@1.2.0Novior.MentorAgent does not include a model provider package. Add the ones that your provider needs:
| Provider | Packages to add |
|---|---|
| OpenAI, and Ollama through its OpenAI-compatible endpoint | Microsoft.Extensions.AI.OpenAI. It brings the OpenAI SDK and the AsIChatClient() method |
| Azure OpenAI | Azure.AI.OpenAI and Microsoft.Extensions.AI.OpenAI |
| Azure OpenAI with Microsoft Entra ID | Azure.Identity as well, for DefaultAzureCredential |
| A Foundry project (Path B) | Microsoft.Agents.AI.Foundry: see Foundry agents (Path B) |
| Anthropic's Claude | Anthropic, Anthropic's official SDK. It brings AnthropicClient and the AsIChatClient() method |
Azure.AI.OpenAI 2.9.0-beta.1 is a prerelease, so dotnet add package needs a version for it. The examples on this page are compiled with these versions:
dotnet add package Microsoft.Extensions.AI.OpenAI --version 10.6.0
dotnet add package Azure.AI.OpenAI --version 2.9.0-beta.1
dotnet add package Azure.Identity --version 1.21.0
dotnet add package Anthropic --version 12.53.0Novior.MentorAgent brings System.ClientModel, so ApiKeyCredential needs no extra package. How the versions fit together, and the one combination that needs a pin, is in Provider package versions.
Minimal configuration
Section titled “Minimal configuration”Every example on this page is the model line inside AddMentorAgent(options => …), with the using directives that it needs at the top of Program.cs. Each example names only the namespaces of its own provider, so it compiles with the packages of that provider alone. The rest of the configuration stays as on the page of your host, such as Blazor Server app or Any front end.
With OpenAI, keep the key in user secrets and set the client:
dotnet user-secrets set OpenAI:Key <your-key>using Microsoft.Extensions.AI; // AsIChatClient
using OpenAI; // OpenAIClient
options.ChatClient = new OpenAIClient(
builder.Configuration["OpenAI:Key"]
?? throw new InvalidOperationException(
"Set OpenAI:Key with dotnet user-secrets."))
.GetChatClient("gpt-4o-mini")
.AsIChatClient();Complete configuration
Section titled “Complete configuration”This section connects the other providers: Azure OpenAI, Anthropic's Claude, Ollama and other local models, and Foundry agents. It also adds an embedding model and lists the options that matter on this page.
Azure OpenAI
Section titled “Azure OpenAI”With an API key, read the endpoint and the key from configuration. The model name is the name of your deployment:
using Azure; // AzureKeyCredential
using Azure.AI.OpenAI; // AzureOpenAIClient
using Microsoft.Extensions.AI; // AsIChatClient
options.ChatClient = new AzureOpenAIClient(
new Uri(builder.Configuration["AzureOpenAI:Endpoint"]!),
new AzureKeyCredential(builder.Configuration["AzureOpenAI:Key"]!))
.GetChatClient("gpt-4o-mini") // the deployment name
.AsIChatClient();{
"AzureOpenAI": {
"Endpoint": "https://<your-resource>.openai.azure.com/"
}
}Keep the key in user secrets while you develop:
dotnet user-secrets set AzureOpenAI:Key <your-key>Microsoft Entra ID needs no key. DefaultAzureCredential uses the managed identity when the app runs in Azure, and your developer sign-in on your machine. Give that identity access to the Azure OpenAI resource:
using Azure.AI.OpenAI; // AzureOpenAIClient
using Azure.Identity; // DefaultAzureCredential
using Microsoft.Extensions.AI; // AsIChatClient, AsIEmbeddingGenerator
options.ChatClient = new AzureOpenAIClient(
new Uri(builder.Configuration["AzureOpenAI:Endpoint"]!),
// The managed identity in Azure, your developer sign-in locally
new DefaultAzureCredential())
.GetChatClient("gpt-4o-mini")
.AsIChatClient();With the Responses API the service keeps the conversation, so MentorAgent must not keep its own history, and it installs no compaction either:
using Azure.AI.OpenAI; // AzureOpenAIClient
using Azure.Identity; // DefaultAzureCredential
using Microsoft.Extensions.AI; // AsIChatClient, AsIEmbeddingGenerator
// The Responses client is experimental in the OpenAI SDK:
// without the pragma the build fails with OPENAI001
#pragma warning disable OPENAI001
options.ChatClient = new AzureOpenAIClient(
new Uri(builder.Configuration["AzureOpenAI:Endpoint"]!),
new DefaultAzureCredential())
.GetResponsesClient()
.AsIChatClient("gpt-4o-mini"); // the deployment name goes here
#pragma warning restore OPENAI001
// The service keeps the conversation: MentorAgent must not keep its own history
options.UseServiceManagedHistory = true;Anthropic Claude
Section titled “Anthropic Claude”Anthropic's official SDK, the Anthropic package, gives you an IChatClient, so Claude goes on Path A. Keep the key in user secrets:
dotnet user-secrets set Anthropic:Key <your-key>using Anthropic; // AnthropicClient
using Microsoft.Extensions.AI; // AsIChatClient
options.ChatClient = new AnthropicClient
{
ApiKey = builder.Configuration["Anthropic:Key"]
?? throw new InvalidOperationException(
"Set Anthropic:Key with dotnet user-secrets."),
}
.AsIChatClient("claude-opus-5-5", defaultMaxOutputTokens: 16000);- The model name is an id from Anthropic's model list, such as
claude-opus-5-5. defaultMaxOutputTokenslimits the length of each answer. Anthropic's API needs a limit on every request, so set one that leaves room for long answers.- Not tested live. This example is compiled with every version of this documentation, and the provider is not part of the library's release tests. Try your actions and confirmation boxes on it before you rely on it.
Ollama and other local models
Section titled “Ollama and other local models”Ollama exposes an OpenAI-compatible endpoint, so the OpenAI client talks to it:
using System.ClientModel; // ApiKeyCredential
using Microsoft.Extensions.AI; // AsIChatClient
using OpenAI; // OpenAIClient, OpenAIClientOptions
// Ollama's OpenAI-compatible endpoint: same SDK, no extra package
options.ChatClient = new OpenAIClient(
new ApiKeyCredential("ollama"), // ignored by Ollama, required by the SDK
new OpenAIClientOptions
{
Endpoint = new Uri("http://localhost:11434/v1"),
// A CPU model can take minutes on a long prompt
NetworkTimeout = TimeSpan.FromMinutes(20),
})
.GetChatClient("llama3.2")
.AsIChatClient();
// The safety checks share the slow model: give them time,
// or point ClassifierChatClient at a faster one
options.SafetyCheckTimeout = TimeSpan.FromMinutes(2);Tool calling. Pick a model that supports tools. A model without them answers, but never runs your actions.
Context window. MentorAgent's prompt can be longer than Ollama (external site)'s default context, and Ollama cuts the start of the prompt without an error. Create a variant with a larger context and use its name in
GetChatClient:FROM llama3.2 PARAMETER num_ctx 16384ollama create llama3.2-16k -f ModelfileTime. A model on a CPU can take minutes on a long prompt: that is what
NetworkTimeoutin the snippet is for. It raises the HTTP time limit of the OpenAI client. The safety checks run on the same model, so give them time withSafetyCheckTimeout, or pointClassifierChatClientat a faster model.Other servers. A server with the OpenAI-compatible Chat Completions API is used the same way: change
Endpointand the model name.Tests. For automated tests, a fake model is faster than a local one and gives the same result every time: see Test without a model.
Foundry agents (Path B)
Section titled “Foundry agents (Path B)”A Foundry project gives you an AIAgent. Novior.MentorAgent does not include Agent Framework's Foundry package, so add Microsoft.Agents.AI.Foundry to your project. If the same project uses the Azure OpenAI Responses API, pin the Foundry package to this version: a newer one brings OpenAI 2.11 or later. The example on this page is compiled with this version:
<PackageReference Include="Microsoft.Agents.AI.Foundry"
Version="[1.17.0-preview.260804.1]" />Then build the agent and set Agent instead of ChatClient:
using Azure.AI.Projects; // AIProjectClient, from Microsoft.Agents.AI.Foundry
using Azure.Identity; // DefaultAzureCredential
// Path B: a pre-built AIAgent instead of a ChatClient
options.Agent = new AIProjectClient(
new Uri(builder.Configuration["Foundry:ProjectEndpoint"]!),
new DefaultAzureCredential())
.AsAIAgent(
model: "gpt-4o-mini",
instructions: "You are the assistant of a case management application.");On Path B the instructions you pass describe the agent's role and tone. MentorAgent adds the page, the user and your actions around them, but not its own coordinator prompt. The agent must be a ChatClientAgent, or another agent whose chat client invokes functions (FunctionInvokingChatClient), because that is where MentorAgent checks roles and confirmation. MentorAgent refuses any other agent when it builds the coordinator.
Embedding model
Section titled “Embedding model”An embedding model turns a text into a list of numbers that represents its meaning, so MentorAgent can find the texts closest to a message. It makes semantic tool filtering, semantic memory and semantic model routing possible. It uses a separate deployment:
using Azure.AI.OpenAI; // AzureOpenAIClient
using Azure.Identity; // DefaultAzureCredential
using Microsoft.Extensions.AI; // AsIChatClient, AsIEmbeddingGenerator
options.EmbeddingGenerator = new AzureOpenAIClient(
new Uri(builder.Configuration["AzureOpenAI:Endpoint"]!),
new DefaultAzureCredential())
.GetEmbeddingClient("text-embedding-3-small") // its own deployment
.AsIEmbeddingGenerator();Setting it does not turn on any feature. Each feature has its own option: EnableToolFiltering, MemoryRelevanceFiltering and RoutingStrategy = MentorRoutingStrategy.Semantic. If you turn one on without an embedding model, MentorAgent logs a warning and the feature stays off. RequireActionForChangeRequests needs it too, through tool filtering. RequireLookupForRecordQuestions does not.
Options for model providers
Section titled “Options for model providers”| Option | What it does |
|---|---|
ChatClient | Path A: the model MentorAgent builds its agent on |
Agent | Path B: a pre-built AIAgent. Never together with ChatClient |
EmbeddingGenerator | The embedding model for filtering, memory and routing |
ClassifierChatClient | The model for MentorAgent's own short decisions: the safety checks, the off-topic check (RefuseOutOfScope), the facts to remember, and the checks behind RequireLookupForRecordQuestions and RequireActionForChangeRequests. It defaults to ChatClient. A small, fast model shortens the wait before each answer |
StrongChatClient, RoutingStrategy | A stronger model for the hard questions: see Cost and model routing |
UseServiceManagedHistory | Path A with a client whose service keeps the conversation, such as the Responses API |
SafetyCheckTimeout, SafetyCheckFailure | How long the safety checks may take, and what happens when they give no answer |
ConfigureChatClientPipeline | Adds your own IChatClient middleware to the Path A pipeline. Only the coordinator's own calls go through it, and it is built once per coordinator, so a limit set there does not limit the whole process |
Every option is in Configuration options.
Security and roles
Section titled “Security and roles”- Keys stay on the server. Never put a key in the source code or in a client project. Use user secrets while you develop, and environment variables or a secret store in production. On Azure, Entra ID with a managed identity removes the key altogether.
- The provider does not decide what runs. Roles and confirmation are checked by MentorAgent around each action, whatever the model and whatever the path: see Roles, confirmation and governance.
- Data leaves with the prompt. The page context, the user's name and roles, memories, retrieved documents and action results are sent to the provider. A local model keeps them on your machine. Data that leaves your application lists everything that goes out.
Common errors
Section titled “Common errors”- The build does not find
OpenAIClient,AzureOpenAIClient,AnthropicClientorAsIChatClient. The provider packages are not in your project, becauseNovior.MentorAgentdoes not include a model provider package. Add them, as in Install the packages. GetResponsesClient()throwsMissingMethodExceptionwhen it is called.OpenAIresolved to 2.11 or later. PinMicrosoft.Extensions.AI.OpenAIas in Azure OpenAI.- The build does not find
AIProjectClientor theAzure.AI.Projectsnamespace. The Foundry package is not in your project, becauseNovior.MentorAgentdoes not include it. AddMicrosoft.Agents.AI.Foundrywith the pinned version, as in Foundry agents (Path B). - The build stops with
OPENAI001onGetResponsesClient. The Responses client is experimental in the OpenAI SDK: keep the#pragmaaround it. - Every turn fails with "Only ConversationId or ChatHistoryProvider may be used, but not both". The client keeps the conversation on the service: set
UseServiceManagedHistory = true. - The app stops at startup with "[MentorAgent] Set ChatClient OR Agent, not both." or "[MentorAgent] Configure ChatClient or Agent." Set exactly one of them. MentorAgent checks the options when the host starts. In a .NET MAUI app, which has no host start, the error comes the first time MentorAgent is used.
- The widget or your own client shows "The assistant could not start", and the log says "The pre-built agent in options.Agent … cannot carry MentorAgent's tool gate". The agent does not use a chat client that invokes functions (
FunctionInvokingChatClient). Build it from a chat client, or use Path A. - The model answers but never calls your actions. It does not support tool calling, or, on Ollama, the context window cut the prompt.
- The safety check is skipped with a timeout warning. The model is too slow for the default limit: raise
SafetyCheckTimeoutor set a fasterClassifierChatClient.
Vedi anche
Sezione “Vedi anche”- Prerequisites — The versions of .NET, hosts, Agent Framework, and model provider packages that MentorAgent is tested with, and how to install it.
- Blazor Server app — Configure MentorAgent in a Blazor Web App with Server interactivity: services, the options that matter, the widget and authentication.
- Production checklist — Settings to review before production: governance, safety check, rate limits, cost and routing, history, several instances, observability and outgoing data.
- Configuration options — Every MentorOptions property with its type, default and effect, grouped by area, plus the options of the WebAssembly client and the YAML loader.
