MentorAgent Docs
Menu

Questa pagina non è ancora tradotta in italiano: qui la trovi in inglese.

How-to guidePackage: Novior.MentorAgent

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.

  • Path A: options.ChatClient. Use it whenever the provider has an IChatClient: 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 an AIAgent, 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 a ChatClient that MentorAgent can call directly. The table shows which ones:
FeaturePath A: ChatClientPath B: Agent
Actions, Model Context Protocol (MCP) client tools, retrieval-augmented generation, Agent SkillsYesYes
Specialists, teams, remote Agent-to-Agent (A2A) agents, YAML agentsYesNo. 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 pageOne tool per actionOne generic invoke_ui_action tool
Safety checkYesOnly with ClassifierChatClient; without it, a warning when the coordinator is built
Model routing, tool filtering, hosted tools, structured outputsYesNo
Memory capture after each turnYesOnly with ClassifierChatClient, which then replaces the remember tool; without it, the remember tool saves the facts
Chat historySet through MentorOptionsSet on your agent

Set ChatClient or Agent, never both. Whatever the path, the model must support tool calling: every action is a tool.

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.

ProviderPathStatusHosted tools
Azure OpenAI, Responses APIATested live, with gpt-4.1, and o3 as the strong modelWeb search, code interpreter, file search, image generation and hosted MCP. The release tests ran web search live
Azure OpenAI, Chat CompletionsATested live, with gpt-4.1Web search only, and only on a deployment that supports it. The others are not available
OpenAIACompiled example, not tested live. It uses the same client library as Azure OpenAIAs for Azure OpenAI, by API: all of them with the Responses API, web search only with Chat Completions
Ollama and other local modelsACompiled example. Tried on a small local model during development, not in the release testsNot available
Foundry agentsBCompiled example, not tested liveMentorAgent'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 ClaudeACompiled example, not tested live. It uses Anthropic's official Anthropic SDKNot tested
Google Gemini and any other IChatClientAPossible, not testedNot 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.

.NET CLI

Terminal
dotnet add package Novior.MentorAgent

PackageReference

YourApp.csproj
<ItemGroup>
  <PackageReference Include="Novior.MentorAgent" Version="1.2.0" />
</ItemGroup>

Central Package Management

Directory.Packages.props
<ItemGroup>
  <PackageVersion Include="Novior.MentorAgent" Version="1.2.0" />
</ItemGroup>
YourApp.csproj
<ItemGroup>
  <PackageReference Include="Novior.MentorAgent" />
</ItemGroup>

File-based app

app.cs
#:package Novior.MentorAgent@1.2.0

Novior.MentorAgent does not include a model provider package. Add the ones that your provider needs:

ProviderPackages to add
OpenAI, and Ollama through its OpenAI-compatible endpointMicrosoft.Extensions.AI.OpenAI. It brings the OpenAI SDK and the AsIChatClient() method
Azure OpenAIAzure.AI.OpenAI and Microsoft.Extensions.AI.OpenAI
Azure OpenAI with Microsoft Entra IDAzure.Identity as well, for DefaultAzureCredential
A Foundry project (Path B)Microsoft.Agents.AI.Foundry: see Foundry agents (Path B)
Anthropic's ClaudeAnthropic, 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:

Terminal
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.0

Novior.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.

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:

Terminal
dotnet user-secrets set OpenAI:Key <your-key>
Program.cs
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();

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.

With an API key, read the endpoint and the key from configuration. The model name is the name of your deployment:

Program.cs
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();
JSON
{
  "AzureOpenAI": {
    "Endpoint": "https://<your-resource>.openai.azure.com/"
  }
}

Keep the key in user secrets while you develop:

Terminal
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:

Program.cs
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:

Program.cs
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's official SDK, the Anthropic package, gives you an IChatClient, so Claude goes on Path A. Keep the key in user secrets:

Terminal
dotnet user-secrets set Anthropic:Key <your-key>
Program.cs
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.
  • defaultMaxOutputTokens limits 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 exposes an OpenAI-compatible endpoint, so the OpenAI client talks to it:

Program.cs
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:

    Modelfile
    FROM llama3.2
    PARAMETER num_ctx 16384
    Terminal
    ollama create llama3.2-16k -f Modelfile
  • Time. A model on a CPU can take minutes on a long prompt: that is what NetworkTimeout in 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 with SafetyCheckTimeout, or point ClassifierChatClient at a faster model.

  • Other servers. A server with the OpenAI-compatible Chat Completions API is used the same way: change Endpoint and 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.

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:

XML
<PackageReference Include="Microsoft.Agents.AI.Foundry"
                  Version="[1.17.0-preview.260804.1]" />

Then build the agent and set Agent instead of ChatClient:

Program.cs
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.

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:

Program.cs
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.

OptionWhat it does
ChatClientPath A: the model MentorAgent builds its agent on
AgentPath B: a pre-built AIAgent. Never together with ChatClient
EmbeddingGeneratorThe embedding model for filtering, memory and routing
ClassifierChatClientThe 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, RoutingStrategyA stronger model for the hard questions: see Cost and model routing
UseServiceManagedHistoryPath A with a client whose service keeps the conversation, such as the Responses API
SafetyCheckTimeout, SafetyCheckFailureHow long the safety checks may take, and what happens when they give no answer
ConfigureChatClientPipelineAdds 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.

  • 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.
  • The build does not find OpenAIClient, AzureOpenAIClient, AnthropicClient or AsIChatClient. The provider packages are not in your project, because Novior.MentorAgent does not include a model provider package. Add them, as in Install the packages.
  • GetResponsesClient() throws MissingMethodException when it is called. OpenAI resolved to 2.11 or later. Pin Microsoft.Extensions.AI.OpenAI as in Azure OpenAI.
  • The build does not find AIProjectClient or the Azure.AI.Projects namespace. The Foundry package is not in your project, because Novior.MentorAgent does not include it. Add Microsoft.Agents.AI.Foundry with the pinned version, as in Foundry agents (Path B).
  • The build stops with OPENAI001 on GetResponsesClient. The Responses client is experimental in the OpenAI SDK: keep the #pragma around 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 SafetyCheckTimeout or set a faster ClassifierChatClient.
  • 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.