概述

AgentGroupChat 是 Semantic Kernel 中用于管理多个 Agent 之间对话的核心组件。它提供了灵活的机制来控制哪个 Agent 在什么时候发言,以及如何终止对话。

核心组件

1. AgentGroupChat 类

AgentGroupChat 是多Agent对话的主要管理器,位于 Microsoft.SemanticKernel.Agents 命名空间中。

public sealed class AgentGroupChat : AgentChat
{
    // 参与聊天的Agent列表
    public IReadOnlyList<Agent> Agents { get; }
    
    // 执行设置,控制Agent选择和终止策略
    public AgentGroupChatSettings ExecutionSettings { get; set; }
    
    // 指示对话是否完成
    public bool IsComplete { get; set; }
}

2. AgentGroupChatSettings 配置

控制AgentGroupChat行为的核心配置类:

public class AgentGroupChatSettings
{
    // Agent选择策略 - 决定下一个发言的Agent
    public SelectionStrategy SelectionStrategy { get; init; } = new SequentialSelectionStrategy();
    
    // 终止策略 - 决定何时结束对话
    public TerminationStrategy TerminationStrategy { get; init; } = new DefaultTerminationStrategy();
}

Agent选择策略 (SelectionStrategy)

1. SequentialSelectionStrategy (顺序选择策略)

默认策略,按照Agent加入聊天的顺序轮流发言。

// 创建Agent
ChatCompletionAgent agent1 = new() { Name = "Agent1", Instructions = "..." };
ChatCompletionAgent agent2 = new() { Name = "Agent2", Instructions = "..." };

// 创建群组聊天,使用默认的顺序选择策略
AgentGroupChat chat = new(agent1, agent2)
{
    ExecutionSettings = new()
    {
        SelectionStrategy = new SequentialSelectionStrategy(), // 可选,这是默认值
        TerminationStrategy = new KernelFunctionTerminationStrategy(...)
    }
};

特点:

  • Agent按加入顺序轮流发言

  • 简单可预测的发言顺序

  • 适用于结构化对话场景

2. KernelFunctionSelectionStrategy (函数选择策略)

智能策略,使用AI函数根据对话历史动态选择下一个发言的Agent。

// 定义选择函数
KernelFunction selectionFunction = KernelFunctionFactory.CreateFromPrompt(
    """
    根据对话历史选择下一个发言的参与者。
    
    参与者列表:
    - ReviewerName (审核者)
    - CopyWriterName (文案写手)
    
    选择规则:
    - 用户输入后,轮到 CopyWriterName
    - CopyWriterName 回复后,轮到 ReviewerName
    - ReviewerName 提供反馈后,轮到 CopyWriterName
    
    对话历史:
    {{$history}}
    """);

// 应用选择策略
AgentGroupChat chat = new(agentWriter, agentReviewer)
{
    ExecutionSettings = new()
    {
        SelectionStrategy = new KernelFunctionSelectionStrategy(selectionFunction, kernel)
        {
            // 结果解析器 - 从函数结果中提取Agent名称
            ResultParser = (result) => result.GetValue<string>() ?? "DefaultAgent",
            // 变量名配置
            AgentsVariableName = "agents",      // Agent列表的变量名
            HistoryVariableName = "history",    // 对话历史的变量名
        }
    }
};

特点:

  • 基于AI智能决策

  • 可根据对话内容动态调整

  • 支持复杂的选择逻辑

  • 高度可定制

发言控制的具体方法

1. 自动发言控制

使用 InvokeAsync() 方法让AgentGroupChat自动管理Agent发言:

// 添加用户消息
chat.AddChatMessage(new ChatMessageContent(AuthorRole.User, "请帮我写一个广告文案"));

// 自动执行对话,根据SelectionStrategy选择Agent
await foreach (ChatMessageContent content in chat.InvokeAsync())
{
    Console.WriteLine($"# {content.Role} - {content.AuthorName}: '{content.Content}'");
}

2. 手动指定Agent发言

使用 InvokeAsync(Agent agent) 方法手动指定特定Agent发言:

// 手动让特定Agent发言,忽略SelectionStrategy
await foreach (ChatMessageContent content in chat.InvokeAsync(specificAgent))
{
    Console.WriteLine($"# {content.Role} - {content.AuthorName}: '{content.Content}'");
}

3. 控制Agent是否加入聊天

// 让Agent发言并加入聊天(默认行为)
await chat.InvokeAsync(newAgent, isJoining: true);

// 让Agent发言但不加入聊天
await chat.InvokeAsync(guestAgent, isJoining: false);

终止策略 (TerminationStrategy)

1. 基于关键词的终止

// 自定义终止策略
public class ApprovalTerminationStrategy : TerminationStrategy
{
    public List<Agent> Agents { get; set; } = new(); // 可以触发终止的Agent
    
    protected override Task<bool> ShouldAgentTerminateAsync(
        Agent agent, 
        IReadOnlyList<ChatMessageContent> history, 
        CancellationToken cancellationToken)
    {
        // 只有指定的Agent可以触发终止
        if (!Agents.Contains(agent))
            return Task.FromResult(false);
            
        // 检查最后一条消息是否包含"approve"
        var lastMessage = history.LastOrDefault();
        bool shouldTerminate = lastMessage?.Content?.Contains("approve", StringComparison.OrdinalIgnoreCase) ?? false;
        
        return Task.FromResult(shouldTerminate);
    }
}

// 应用终止策略
AgentGroupChat chat = new(agentWriter, agentReviewer)
{
    ExecutionSettings = new()
    {
        TerminationStrategy = new ApprovalTerminationStrategy()
        {
            Agents = [agentReviewer], // 只有审核者可以批准
            MaximumIterations = 10,   // 最大轮次限制
        }
    }
};

2. 基于函数的终止策略

KernelFunction terminationFunction = KernelFunctionFactory.CreateFromPrompt(
    """
    判断文案是否已被批准。如果是,回复单词:yes
    
    对话历史:
    {{$history}}
    """);

var terminationStrategy = new KernelFunctionTerminationStrategy(terminationFunction, kernel)
{
    Agents = [agentReviewer],
    ResultParser = (result) => result.GetValue<string>()?.Contains("yes", StringComparison.OrdinalIgnoreCase) ?? false,
    HistoryVariableName = "history",
    MaximumIterations = 10,
};

完整示例

示例1:简单的文案审核流程

public async Task SimpleReviewWorkflowAsync()
{
    // 创建Agent
    ChatCompletionAgent writerAgent = new()
    {
        Name = "CopyWriter",
        Instructions = "你是一个有10年经验的文案写手,以简洁和幽默著称。",
        Kernel = CreateKernelWithChatCompletion(),
    };

    ChatCompletionAgent reviewerAgent = new()
    {
        Name = "ArtDirector", 
        Instructions = "你是艺术总监,负责审核文案是否可以发布。",
        Kernel = CreateKernelWithChatCompletion(),
    };

    // 创建群组聊天
    AgentGroupChat chat = new(writerAgent, reviewerAgent)
    {
        ExecutionSettings = new()
        {
            // 使用顺序选择策略
            SelectionStrategy = new SequentialSelectionStrategy(),
            // 自定义终止策略
            TerminationStrategy = new ApprovalTerminationStrategy()
            {
                Agents = [reviewerAgent],
                MaximumIterations = 10,
            }
        }
    };

    // 开始对话
    chat.AddChatMessage(new ChatMessageContent(AuthorRole.User, "概念:用鸡蛋盒制作的地图"));
    
    await foreach (ChatMessageContent content in chat.InvokeAsync())
    {
        Console.WriteLine($"# {content.Role} - {content.AuthorName}: '{content.Content}'");
    }
}

示例2:智能选择策略

public async Task SmartSelectionWorkflowAsync()
{
    // 定义智能选择函数
    KernelFunction selectionFunction = KernelFunctionFactory.CreateFromPrompt(
        """
        根据最近参与者的行为选择下一个发言者。
        只能从以下参与者中选择:
        - CopyWriter
        - ArtDirector
        
        选择规则:
        - 用户输入后 → CopyWriter
        - CopyWriter回复后 → ArtDirector  
        - ArtDirector反馈后 → CopyWriter
        
        对话历史:
        {{$history}}
        """);

    AgentGroupChat chat = new(writerAgent, reviewerAgent)
    {
        ExecutionSettings = new()
        {
            SelectionStrategy = new KernelFunctionSelectionStrategy(selectionFunction, kernel)
            {
                ResultParser = (result) => result.GetValue<string>() ?? "CopyWriter",
                HistoryVariableName = "history",
            },
            TerminationStrategy = new KernelFunctionTerminationStrategy(terminationFunction, kernel)
            {
                Agents = [reviewerAgent],
                ResultParser = (result) => result.GetValue<string>()?.Contains("yes", StringComparison.OrdinalIgnoreCase) ?? false,
                MaximumIterations = 10,
            }
        }
    };
}

最佳实践

1. Agent命名

  • 为每个Agent设置清晰的名称

  • 名称应该反映Agent的角色和职责

  • 在选择策略中使用Agent名称进行识别

2. 选择策略设计

  • 简单场景:使用 SequentialSelectionStrategy

  • 复杂逻辑:使用 KernelFunctionSelectionStrategy

  • 在函数中明确定义选择规则

  • 提供默认选择以处理异常情况

3. 终止条件

  • 设置合理的 MaximumIterations 避免无限循环

  • 明确定义终止条件

  • 考虑多种终止场景(成功完成、错误、超时等)

4. 错误处理

  • 在选择函数中处理边界情况

  • 提供默认Agent选择

  • 监控对话状态和Agent响应

5. 性能优化

  • 避免过于复杂的选择逻辑

  • 合理设置最大迭代次数

  • 考虑使用缓存优化重复计算

总结

AgentGroupChat 提供了强大而灵活的多Agent对话控制机制:

  1. SelectionStrategy 控制Agent发言顺序

    • SequentialSelectionStrategy:简单轮流

    • KernelFunctionSelectionStrategy:智能选择

  2. TerminationStrategy 控制对话终止

    • 基于条件的自动终止

    • 最大迭代次数限制

  3. 手动控制 支持直接指定Agent发言

  4. 灵活配置 通过 AgentGroupChatSettings 自定义行为

通过合理组合这些机制,可以实现从简单轮流对话到复杂智能协作的各种多Agent交互场景。

更多AIGC文章

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐