Skip to main content

What are Agents?

Agents are the core building blocks of AutoGen applications. Each agent is an autonomous entity that can:
  • Generate responses using language models
  • Execute functions and tools
  • Communicate with other agents
  • Maintain conversation history
  • Apply custom logic through middleware

Core Agent Types

AutoGen for .NET provides several built-in agent types:

AssistantAgent

An AI-powered agent that uses language models to generate intelligent responses.
using AutoGen;
using AutoGen.OpenAI;

var openAIKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY");
var gpt4Config = new OpenAIConfig(openAIKey, "gpt-4");

var assistant = new AssistantAgent(
    name: "assistant",
    systemMessage: "You are a helpful AI assistant that can write code and solve problems.",
    llmConfig: new ConversableAgentConfig
    {
        Temperature = 0.7,
        ConfigList = [gpt4Config],
        MaxToken = 2000
    });
Key Properties:
name
string
required
Unique identifier for the agent in conversations
systemMessage
string
default:"You are a helpful AI assistant"
Instructions that define the agent’s personality, role, and behavior
llmConfig
ConversableAgentConfig
required
Configuration for the language model, including API keys and parameters
humanInputMode
HumanInputMode
default:"NEVER"
When to request human input (NEVER, ALWAYS, TERMINATE)
isTermination
Func<IEnumerable<IMessage>, CancellationToken, Task<bool>>
Custom function to determine when to end the conversation

UserProxyAgent

Represents a human user or autonomous proxy in the conversation.
var userProxy = new UserProxyAgent(
    name: "user",
    humanInputMode: HumanInputMode.ALWAYS,
    defaultReply: "Proceed");
Human Input Modes:
// Prompts for user input before each message
var user = new UserProxyAgent(
    name: "user",
    humanInputMode: HumanInputMode.ALWAYS);

ConversableAgent Base Class

Both AssistantAgent and UserProxyAgent inherit from ConversableAgent, which provides:
  • Message generation and handling
  • Function execution capabilities
  • Middleware support
  • Conversation management

Agent Configuration

ConversableAgentConfig

Configures the language model behavior:
var config = new ConversableAgentConfig
{
    Temperature = 0,              // 0 = deterministic, 1 = creative
    MaxToken = 1024,              // Maximum tokens to generate
    ConfigList = [                // List of LLM configurations
        new OpenAIConfig(apiKey, "gpt-4"),
        new OpenAIConfig(apiKey, "gpt-3.5-turbo") // Fallback
    ],
    TimeoutInSeconds = 60,        // Request timeout
    StopSequence = ["END"]        // Sequences that stop generation
};

System Messages

Craft effective system messages to guide agent behavior:
var coder = new AssistantAgent(
    name: "coder",
    systemMessage: @"
        You are an expert C# developer.
        When writing code:
        - Use modern C# features and best practices
        - Include error handling
        - Add XML documentation comments
        - Format code between ```csharp and ``` markers
    ",
    llmConfig: config);

Message Generation

Basic Message Sending

using AutoGen.Core;

// Send a simple text message
var response = await assistant.SendAsync("What is 2 + 2?");
Console.WriteLine(response.GetContent());

// Send with message history
var history = new List<IMessage>
{
    new TextMessage(Role.User, "Hello"),
    new TextMessage(Role.Assistant, "Hi! How can I help?", from: "assistant")
};

var reply = await assistant.SendAsync(
    "Can you help me with math?",
    chatHistory: history);

Streaming Responses

Stream responses token-by-token for real-time output:
await foreach (var message in assistant.GenerateStreamingReplyAsync(
    new[] { new TextMessage(Role.User, "Write a story") }))
{
    Console.Write(message.GetContent());
}

Agent Communication

Two-Agent Chat

Direct conversation between two agents:
var assistant = new AssistantAgent(
    name: "assistant",
    systemMessage: "You are a helpful assistant.",
    llmConfig: config)
    .RegisterPrintMessage();

var user = new UserProxyAgent(
    name: "user",
    humanInputMode: HumanInputMode.ALWAYS)
    .RegisterPrintMessage();

// User initiates the conversation
await user.InitiateChatAsync(
    receiver: assistant,
    message: "Help me write a sorting algorithm",
    maxRound: 10);

GenerateReplyAsync

Lower-level method for custom conversation control:
var messages = new List<IMessage>
{
    new TextMessage(Role.User, "Hello")
};

// Generate a reply
var reply = await assistant.GenerateReplyAsync(messages);
messages.Add(reply);

// Continue the conversation
messages.Add(new TextMessage(Role.User, "Tell me a joke"));
reply = await assistant.GenerateReplyAsync(messages);

Middleware and Extensions

Enhance agents with middleware: Format and display messages:
var agent = new AssistantAgent(/*...*/);
    .RegisterPrintMessage(); // Adds console output

Custom Middleware

Create custom message processing logic:
var agent = new AssistantAgent(/*...*/)
    .RegisterMiddleware(async (messages, options, agent, ct) =>
    {
        Console.WriteLine($"[{DateTime.Now}] Processing {messages.Count()} messages");
        
        // Call the next middleware/agent
        var reply = await agent.GenerateReplyAsync(messages, options, ct);
        
        Console.WriteLine($"[{DateTime.Now}] Generated reply");
        return reply;
    });

Message Connector Middleware

Convert between different message formats:
using AutoGen.OpenAI.Extension;

var agent = new OpenAIChatAgent(/*...*/)
    .RegisterMessageConnector() // Converts AutoGen messages to OpenAI format
    .RegisterPrintMessage();

Termination Conditions

Default Termination

Conversations end when:
  • Maximum rounds reached
  • Termination message received
  • Custom termination condition met

Custom Termination

var assistant = new AssistantAgent(
    name: "assistant",
    systemMessage: "You are a helpful assistant.",
    llmConfig: config,
    isTermination: async (messages, ct) =>
    {
        var lastMessage = messages.LastOrDefault();
        if (lastMessage == null) return false;
        
        var content = lastMessage.GetContent()?.ToLower();
        
        // Terminate if message contains "goodbye" or "done"
        return content?.Contains("goodbye") == true ||
               content?.Contains("done") == true;
    });

Provider-Specific Agents

OpenAIChatAgent

using AutoGen.OpenAI;
using AutoGen.OpenAI.Extension;
using OpenAI;

var openAIClient = new OpenAIClient(apiKey);
var agent = new OpenAIChatAgent(
    chatClient: openAIClient.GetChatClient("gpt-4"),
    name: "assistant",
    systemMessage: "You are a helpful assistant")
    .RegisterMessageConnector()
    .RegisterPrintMessage();

AnthropicClientAgent

using AutoGen.Anthropic;
using AutoGen.Anthropic.Extensions;

var anthropicClient = new AnthropicClient(
    new HttpClient(),
    AnthropicConstants.Endpoint,
    apiKey);

var agent = new AnthropicClientAgent(
    anthropicClient,
    "assistant",
    AnthropicConstants.Claude3Haiku)
    .RegisterMessageConnector()
    .RegisterPrintMessage();

ChatCompletionsClientAgent (Azure AI)

using AutoGen.AzureAIInference;
using AutoGen.AzureAIInference.Extension;
using Azure.AI.Inference;

var client = new ChatCompletionsClient(
    new Uri(endpoint),
    new AzureKeyCredential(apiKey));

var agent = new ChatCompletionsClientAgent(
    chatCompletionsClient: client,
    name: "assistant",
    modelName: "gpt-4",
    systemMessage: "You are a helpful assistant")
    .RegisterMessageConnector();

SemanticKernelAgent

using AutoGen.SemanticKernel;
using AutoGen.SemanticKernel.Extension;
using Microsoft.SemanticKernel;

var kernel = Kernel.CreateBuilder()
    .AddOpenAIChatCompletion("gpt-4", apiKey)
    .Build();

var agent = new SemanticKernelAgent(
    kernel: kernel,
    name: "assistant",
    systemMessage: "You are a helpful assistant")
    .RegisterMessageConnector()
    .RegisterPrintMessage();

Best Practices

  • Be specific about the agent’s role and responsibilities
  • Include output format requirements
  • Specify constraints and limitations
  • Use examples when needed
  • Keep it concise but complete
  • Use descriptive, unique names
  • Avoid special characters
  • Keep names short and memorable
  • Use lowercase for consistency
  • Set Temperature = 0 for deterministic output
  • Use Temperature = 0.7-1.0 for creative tasks
  • Set appropriate token limits to control costs
  • Configure timeouts for long-running operations
try
{
    var reply = await assistant.SendAsync(message);
}
catch (Exception ex)
{
    Console.WriteLine($"Error: {ex.Message}");
    // Handle retry logic or fallback
}

Next Steps

Group Chat

Create multi-agent conversations

Function Calling

Add custom functions to agents

Code Execution

Execute code dynamically

OpenAI Integration

Learn about OpenAI-specific features

Build docs developers (and LLMs) love