Share via


Quickstart: Create and test a basic agent using .NET

This example shows you how to download and run the QuickStart/Empty Agent sample from GitHub.

There are two main ways to get started with the Microsoft 365 Agents SDK:

  • Clone and run the QuickStart/Empty Agent agent sample available on GitHub

  • Use the Microsoft 365 Agents Toolkit. The Agents Toolkit has two built-in templates for Visual Studio and Visual Studio Code that use the Microsoft 365 Agents SDK for starting with an QuickStart/Empty Agent and a Weather Agent that uses Azure Foundry or OpenAI Services with either Semantic Kernel or LangChain.

Prerequisites

You need a few things before you get started. These steps use the QuickStart/Empty Agent sample at .NET quickstart, but you could also use any Agents SDK sample.

Open the solution

  1. Open the solution file QuickStart.csproj in Visual Studio.

  2. Run the project.

At this point, your agent is running locally using port 3978.

Test your agent locally

  1. Install the Agents Playground if you haven't already.

    winget install agentsplayground
    
  2. Start the agent in Visual Studio or Visual Studio Code

  3. Start the Teams App Tester. At a command prompt: agentsplayground

    • The tool opens a web browser showing the Teams App Test Tool, ready to send messages to your agent.
  4. Your running agent on port 3978 should connect automatically to the agent playground in your browser and you should be able to interact with your agent running locally

How does the agent work?

With the Agents SDK, an agent is built using AgentApplication and AgentApplicationOptions classes. This is built in the Program.cs file of the sample.

Build your agent

You can see in the sample, that as the agent is being built AgentApplicationOptions is loaded and your custom agent class MyAgent.cs that inherits from AgentApplication

// Add AgentApplicationOptions from appsettings section "AgentApplication".
builder.AddAgentApplicationOptions();

// Add the AgentApplication, which contains the logic for responding to
// user messages.
builder.AddAgent<MyAgent>();

Then the storage is loaded by default using the MemoryStorage class. This allows for context to be tracked across turns when using TurnState however should be switched out in production for more persistant storage such as BlobsStorage or CosmosDbPartitionedStorage.

builder.Services.AddSingleton<IStorage, MemoryStorage>();

The rest of the agent application uses standard .NET hosting patterns, and adds routes to accept messages at a specific endpoint. These routes use the IAgent interface to accept the agent activity, and provides developers with the AgentApplication object to work with the Activity payload that got passed to it from the channel/client. Learn more about the Activities and working with Activities

// This receives incoming messages from Azure Bot Service or other SDK Agents
var incomingRoute = app.MapPost("/api/messages", async (HttpRequest request, HttpResponse response, IAgentHttpAdapter adapter, IAgent agent, CancellationToken cancellationToken) =>
{
    await adapter.ProcessAsync(request, response, agent, cancellationToken);
});

Add new custom logic in a method

Developers add custom logic in the MyAgent.cs class that implements AgentApplication. This class uses the AgentApplicationOptions to configure any specific settings from your config and Program.cs and registers event listeners from the Agents SDK, available in the AgentApplication class that references your respective custom method when those events are triggered from the client.

In the following example, OnConversationUpdate triggers the WelcomeMessageAsync method and OnActivity triggers the method OnMessageAsync.

   public MyAgent(AgentApplicationOptions options) : base(options)
   {
      OnConversationUpdate(ConversationUpdateEvents.MembersAdded, WelcomeMessageAsync);
      OnActivity(ActivityTypes.Message, OnMessageAsync, rank: RouteRank.Last);
   }

Those events are routed via the endpoint configured in your MyProgram.cs and there are numerous events that you can use. The most common is OnActivity. To learn more about the events that the SDK implement, check out more about working with activities and the Activity protocol specification.

Once your method is triggered, for example OnMessageAsync to end the turn, you can choose in your custom logic to respond to send a message back to the client by using the methods available on and instance of the TurnContext class that should be a parameter in your method as shown in the following example:

private async Task OnMessageAsync(ITurnContext turnContext, ITurnState turnState, CancellationToken cancellationToken)
{
   await turnContext.SendActivityAsync($"You said: {turnContext.Activity.Text}", cancellationToken: cancellationToken);
}

Tip

Review the other TurnContext methods available to return to the client.

Now you know the basics, check out the next steps and work to add custom handler logic into your agent and sending back different events.

Next Steps

The Agents Playground is available by default if you're already using the Microsoft 365 Agents Toolkit. You can use one of the following guides if you want to get started with the toolkit: