M365 Agents Dotnet

作者 microsoft354361d83247MIT3K 個星標收錄於 2026年10月8日更新於 2026年10月8日儲存庫今天更新

Microsoft 365 Agents SDK for .NET. Build multichannel agents for Teams/M365/Copilot Studio with ASP.NET Core hosting, AgentApplication routing, and MSAL-based auth. Triggers: "Microsoft 365 Agents SDK", "Microsoft.Agents", "AddAgentApplicationOptions", "AgentApplication", "AddAgentAspNetAuthentication", "Copilot Studio client", "IAgentHttpAdapter".

AI 產生的概覽

指導使用 .NET 建置 Microsoft 365 代理,涵蓋 ASP.NET Core 裝載、AgentApplication 路由與 MSAL 驗證。

功能
此技能提供使用 Microsoft 365 Agents SDK for .NET 建置多通道代理的參考說明與程式碼範例。內容涵蓋 NuGet 套件安裝、appsettings.json 設定、含訊息路由的 ASP.NET Core 代理主機、AgentApplication 路由與錯誤處理,以及使用 MSAL 取得權杖的 Copilot Studio 直連引擎用戶端。它產出的是指引與範例程式碼,而非可執行的指令碼。
適用情境
適用於在 .NET 中實作 Microsoft 365、Teams 或 Copilot Studio 代理,且需要設定、裝載、路由或驗證模式的情境。也適用於串接 Copilot Studio 用戶端對話,或設定權杖驗證與連線。
執行需求
需要 .NET SDK,以及 Microsoft.Agents.Hosting.AspNetCore、Microsoft.Agents.Authentication.Msal、Microsoft.Agents.Storage、Microsoft.Agents.CopilotStudio.Client、Microsoft.Identity.Client.Extensions.Msal 等 NuGet 套件。需要 Microsoft 365 或 Copilot Studio 租用戶認證(用戶端識別碼、密碼、租用戶識別碼),並能存取 Microsoft 身分識別平台與 Bot Framework 端點。不隨附指令碼,僅為說明文件。

Microsoft 365 Agents SDK (.NET)

Overview

Build enterprise agents for Microsoft 365, Teams, and Copilot Studio using the Microsoft.Agents SDK with ASP.NET Core hosting, agent routing, and MSAL-based authentication.

Before implementation

  • Use the microsoft-docs MCP to verify the latest APIs for AddAgent, AgentApplication, and authentication options.
  • Confirm package versions in NuGet for the Microsoft.Agents.* packages you plan to use.

Installation

bash
dotnet add package Microsoft.Agents.Hosting.AspNetCoredotnet add package Microsoft.Agents.Authentication.Msaldotnet add package Microsoft.Agents.Storagedotnet add package Microsoft.Agents.CopilotStudio.Clientdotnet add package Microsoft.Identity.Client.Extensions.Msal

Configuration (appsettings.json)

json
{  "TokenValidation": {    "Enabled": true,    "Audiences": ["{{ClientId}}"],    "TenantId": "{{TenantId}}"  },  "AgentApplication": {    "StartTypingTimer": false,    "RemoveRecipientMention": false,    "NormalizeMentions": false  },  "Connections": {    "ServiceConnection": {      "Settings": {        "AuthType": "ClientSecret",        "ClientId": "{{ClientId}}",        "ClientSecret": "{{ClientSecret}}",        "AuthorityEndpoint": "https://login.microsoftonline.com/{{TenantId}}",        "Scopes": ["https://api.botframework.com/.default"]      }    }  },  "ConnectionsMap": [    {      "ServiceUrl": "*",      "Connection": "ServiceConnection"    }  ],  "CopilotStudioClientSettings": {    "DirectConnectUrl": "",    "EnvironmentId": "",    "SchemaName": "",    "TenantId": "",    "AppClientId": "",    "AppClientSecret": ""  }}

Core Workflow: ASP.NET Core agent host

csharp
using Microsoft.Agents.Builder;using Microsoft.Agents.Hosting.AspNetCore;using Microsoft.Agents.Storage;using Microsoft.AspNetCore.Builder;using Microsoft.AspNetCore.Http;using Microsoft.Extensions.DependencyInjection;using Microsoft.Extensions.Hosting;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpClient();builder.AddAgentApplicationOptions();builder.AddAgent<MyAgent>();builder.Services.AddSingleton<IStorage, MemoryStorage>();
builder.Services.AddControllers();builder.Services.AddAgentAspNetAuthentication(builder.Configuration);
WebApplication app = builder.Build();
app.UseAuthentication();app.UseAuthorization();
app.MapGet("/", () => "Microsoft Agents SDK Sample");
var incomingRoute = app.MapPost("/api/messages",    async (HttpRequest request, HttpResponse response, IAgentHttpAdapter adapter, IAgent agent, CancellationToken ct) =>    {        await adapter.ProcessAsync(request, response, agent, ct);    });
if (!app.Environment.IsDevelopment()){    incomingRoute.RequireAuthorization();}else{    app.Urls.Add("http://localhost:3978");}
app.Run();

AgentApplication routing

csharp
using Microsoft.Agents.Builder;using Microsoft.Agents.Builder.App;using Microsoft.Agents.Builder.State;using Microsoft.Agents.Core.Models;using System;using System.Threading;using System.Threading.Tasks;
public sealed class MyAgent : AgentApplication{    public MyAgent(AgentApplicationOptions options) : base(options)    {        OnConversationUpdate(ConversationUpdateEvents.MembersAdded, WelcomeAsync);        OnActivity(ActivityTypes.Message, OnMessageAsync, rank: RouteRank.Last);        OnTurnError(OnTurnErrorAsync);    }
    private static async Task WelcomeAsync(ITurnContext turnContext, ITurnState turnState, CancellationToken ct)    {        foreach (ChannelAccount member in turnContext.Activity.MembersAdded)        {            if (member.Id != turnContext.Activity.Recipient.Id)            {                await turnContext.SendActivityAsync(                    MessageFactory.Text("Welcome to the agent."),                    ct);            }        }    }
    private static async Task OnMessageAsync(ITurnContext turnContext, ITurnState turnState, CancellationToken ct)    {        await turnContext.SendActivityAsync(            MessageFactory.Text($"You said: {turnContext.Activity.Text}"),            ct);    }
    private static async Task OnTurnErrorAsync(        ITurnContext turnContext,        ITurnState turnState,        Exception exception,        CancellationToken ct)    {        await turnState.Conversation.DeleteStateAsync(turnContext, ct);
        var endOfConversation = Activity.CreateEndOfConversationActivity();        endOfConversation.Code = EndOfConversationCodes.Error;        endOfConversation.Text = exception.Message;        await turnContext.SendActivityAsync(endOfConversation, ct);    }}

Copilot Studio direct-to-engine client

DelegatingHandler for token acquisition (interactive flow)

csharp
using System.Net.Http.Headers;using Microsoft.Agents.CopilotStudio.Client;using Microsoft.Identity.Client;
internal sealed class AddTokenHandler : DelegatingHandler{    private readonly SampleConnectionSettings _settings;
    public AddTokenHandler(SampleConnectionSettings settings) : base(new HttpClientHandler())    {        _settings = settings;    }
    protected override async Task<HttpResponseMessage> SendAsync(        HttpRequestMessage request,        CancellationToken cancellationToken)    {        if (request.Headers.Authorization is null)        {            string[] scopes = [CopilotClient.ScopeFromSettings(_settings)];
            IPublicClientApplication app = PublicClientApplicationBuilder                .Create(_settings.AppClientId)                .WithAuthority(AadAuthorityAudience.AzureAdMyOrg)                .WithTenantId(_settings.TenantId)                .WithRedirectUri("http://localhost")                .Build();
            AuthenticationResult authResponse;            try            {                var account = (await app.GetAccountsAsync()).FirstOrDefault();                authResponse = await app.AcquireTokenSilent(scopes, account).ExecuteAsync(cancellationToken);            }            catch (MsalUiRequiredException)            {                authResponse = await app.AcquireTokenInteractive(scopes).ExecuteAsync(cancellationToken);            }
            request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authResponse.AccessToken);        }
        return await base.SendAsync(request, cancellationToken);    }}

Console host with CopilotClient

csharp
using Microsoft.Agents.CopilotStudio.Client;using Microsoft.Extensions.DependencyInjection;using Microsoft.Extensions.Hosting;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
var settings = new SampleConnectionSettings(    builder.Configuration.GetSection("CopilotStudioClientSettings"));
builder.Services.AddHttpClient("mcs").ConfigurePrimaryHttpMessageHandler(() =>{    return new AddTokenHandler(settings);});
builder.Services    .AddSingleton(settings)    .AddTransient<CopilotClient>(sp =>    {        var logger = sp.GetRequiredService<ILoggerFactory>().CreateLogger<CopilotClient>();        return new CopilotClient(settings, sp.GetRequiredService<IHttpClientFactory>(), logger, "mcs");    });
IHost host = builder.Build();var client = host.Services.GetRequiredService<CopilotClient>();
await foreach (var activity in client.StartConversationAsync(emitStartConversationEvent: true)){    Console.WriteLine(activity.Type);}
await foreach (var activity in client.AskQuestionAsync("Hello!", null)){    Console.WriteLine(activity.Type);}

Best Practices

  1. Use AgentApplication subclasses to centralize routing and error handling.
  2. Use MemoryStorage only for development; use persisted storage in production.
  3. Enable TokenValidation in production and require authorization on /api/messages.
  4. Keep auth secrets in configuration providers (Key Vault, managed identity, env vars).
  5. Reuse HttpClient from IHttpClientFactory and cache MSAL tokens.
  6. Prefer async handlers and pass CancellationToken to SDK calls.

Reference Links

來源與署名

來源:microsoft/skills位於.github/plugins/azure-sdk-dotnet/skills/m365-agents-dotnet提交354361d

授權條款: MIT

內容歸原作者所有。SourceWeft 從公開儲存庫中收錄這些內容。

檢舉或申請下架