首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >多Agent协作入门:AgentGroupChat

多Agent协作入门:AgentGroupChat

作者头像
郑子铭
发布2025-08-06 18:00:45
发布2025-08-06 18:00:45
5660
举报

大家好,我是Edison。

近日抽空学习了下Semantic Kernel提供的AgentGroupChat对象写了一个多Agent对话的Demo,总结一下分享与你。当然,多Agent协作还有其他的方式,就留到后续慢慢介绍给你。

AgentChat是什么鬼?

在Semantic Kernel中,AgentChat提供了一个框架,可以启用多个代理之间的交互,即使它们属于不同类型的代理。 这使得 ChatCompletionAgent和 OpenAIAssistantAgent 可以在同一对话中协同工作。 AgentChat还定义了用于启动代理之间协作的入口点,无论是通过多个响应还是单个代理响应。

在实现层面,AgentGroupChat 提供了 AgentChat 的具体实现,它是使用基于策略的方法来管理聊天的动态。

快速入门案例

这里我们来快速实现一个案例:Reviewer & Writer,让这两个不同功能的Agent能够相互配合协作,完成一个指定的功能:

(1)Reviewer 可以审核用户输入的文案并给出优化建议;

(2)Writer 则根据优化建议进行文案的优化创作;

为了简单地实现这个功能,我们创建一个.NET控制台项目,然后安装以下包:

代码语言:javascript
复制
Microsoft.Extensions.Configuration
Microsoft.Extensions.Configuration.Json
Microsoft.SemanticKernel.Agents.Core
Microsoft.SemanticKernel.Agents.OpenAI (Preview版本)

需要注意的是,由于Semantic Kernel的较多功能目前还处于实验预览阶段,所以建议在该项目的csproj文件中加入以下配置,统一取消警告:

代码语言:javascript
复制
<PropertyGroup>
  <NoWarn>$(NoWarn);CA2007;IDE1006;SKEXP0001;SKEXP0110;OPENAI001</NoWarn>
</PropertyGroup>

创建一个appsettings.json配置文件,填入以下关于LLM API的配置,其中API_KEY请输入你自己的:

代码语言:javascript
复制
{
  "LLM": 
  {
    "BASE_URL": "https://api.siliconflow.cn",
    "API_KEY": "******************************",
    "MODEL_ID": "Qwen/Qwen2.5-32B-Instruct"
  }
}

这里我们使用SiliconCloud提供的 Qwen2.5-32B-Instruct 模型,你可以通过这个URL注册账号:https://cloud.siliconflow.cn/i/DomqCefW 获取大量免费的Token来进行实验。

有了LLM API,我们可以创建一个Kernel供后续使用,这也是老面孔了:

代码语言:javascript
复制
Console.WriteLine("Now loading the configuration...");
var config = new ConfigurationBuilder()
    .AddJsonFile($"appsettings.json", optional: false, reloadOnChange: true)
    .Build();
Console.WriteLine("Now loading the chat client...");
var chattingApiConfiguration = new OpenAiConfiguration(
    config.GetSection("LLM:MODEL_ID").Value,
    config.GetSection("LLM:BASE_URL").Value,
    config.GetSection("LLM:API_KEY").Value);
var openAiChattingClient = new HttpClient(new OpenAiHttpHandler(chattingApiConfiguration.EndPoint));
var kernel = Kernel.CreateBuilder()
    .AddOpenAIChatCompletion(chattingApiConfiguration.ModelId, chattingApiConfiguration.ApiKey, httpClient: openAiChattingClient)
    .Build();

接下来,我们就一步一步地来看看核心的代码。

定义两个Agent

这里我们来定义两个Agent:Reviewer & Writer:

(1)Review

代码语言:javascript
复制
public class ReviewerAgent
{
    public const string AgentName = "Reviewer";
    public static ChatCompletionAgent Build(Kernel kernel)
    {
        var toolKernel = kernel.Clone();
        toolKernel.Plugins.AddFromType<ClipboardAccessPlugin>();
        var reviewerAgent = new ChatCompletionAgent()
        {
            Name = AgentName,
            Instructions =
                """
                Your responsibility is to review and identify how to improve user provided content.
                If the user has providing input or direction for content already provided, specify how to address this input.
                Never directly perform the correction or provide example.
                Once the content has been updated in a subsequent response, you will review the content again until satisfactory.
                Always copy satisfactory content to the clipboard using available tools and inform user.
                RULES:
                - Only identify suggestions that are specific and actionable.
                - Verify previous suggestions have been addressed.
                - Never repeat previous suggestions.
                """,
            Kernel = toolKernel,
            Arguments = new KernelArguments(
                new OpenAIPromptExecutionSettings()
                {
                    FunctionChoiceBehavior = FunctionChoiceBehavior.Auto()
                })
        };
        return reviewerAgent;
    }
}

(2)Writer

代码语言:javascript
复制
public class WriterAgent
{
    public const string AgentName = "Writer";
    public static ChatCompletionAgent Build(Kernel kernel)
    {
        var writerAgent = new ChatCompletionAgent()
        {
            Name = AgentName,
            Instructions =
                """
                Your sole responsibility is to rewrite content according to review suggestions.
                - Always apply all review direction.
                - Always revise the content in its entirety without explanation.
                - Never address the user.
                """,
            Kernel = kernel
        };
        return writerAgent;
    }
}

这里可以通过静态方法直接Build出来两个Agent实例:

代码语言:javascript
复制
// Initialize Reviewer Agent
Console.WriteLine("Now loading the Reviewer Agent...");
var reviewerAgent = ReviewerAgent.Build(kernel);
// Initialize Writer Agent
Console.WriteLine("Now loading the Writer Agent...");
var writerAgent = WriterAgent.Build(kernel);

定义选择策略 和 终止策略

对于多Agent协作,在AgentGroupChat中需要定义选择Agent轮次的策略(即SelectionStrategy)和 终止聊天循环的策略(即TerminationStrategy)。我们可以通过使用 AgentGroupChat.CreatePromptFunctionForStrategy 来轻松地实现,它提供了一种方便的机制,避免了对消息参数进行HTML编码:

(1)SelectionStrategy

代码语言:javascript
复制
// Define Selection Policy
var selectionFunction =
    AgentGroupChat.CreatePromptFunctionForStrategy(
        $$$"""
        Examine the provided RESPONSE and choose the next participant.
        State only the name of the chosen participant without explanation.
        Never choose the participant named in the RESPONSE.
        Choose only from these participants:
        - {{{ReviewerAgent.AgentName}}}
        - {{{WriterAgent.AgentName}}}
        Always follow these rules when choosing the next participant:
        - If RESPONSE is user input, it is {{{ReviewerAgent.AgentName}}}'s turn.
        - If RESPONSE is by {{{ReviewerAgent.AgentName}}}, it is {{{WriterAgent.AgentName}}}'s turn.
        - If RESPONSE is by {{{WriterAgent.AgentName}}}, it is {{{ReviewerAgent.AgentName}}}'s turn.
        RESPONSE:
        {{${{{KernelFunctionTerminationStrategy.DefaultHistoryVariableName}}}}}
        """);

(2)TerminationStrategy

这个策略至关重要,它定义了如何评估什么时候退出聊天循环。对于这个案例来说,就是评估Writer优化的内容是否满足用户的需求了。

代码语言:javascript
复制
// Define Termination Policy
const string TerminationToken = "yes";
var terminationFunction =
    AgentGroupChat.CreatePromptFunctionForStrategy(
        $$$"""
        Examine the RESPONSE and determine whether the content has been deemed satisfactory.
        If content is satisfactory, respond with a single word without explanation: {{{TerminationToken}}}.
        If specific suggestions are being provided, it is not satisfactory.
        If no correction is suggested, it is satisfactory.
        RESPONSE:
        {{${{{KernelFunctionTerminationStrategy.DefaultHistoryVariableName}}}}}
        """);

两种策略都只需要了解最新的聊天消息,因此可以使用下面的代码来定一个HistoryReducer,它可以只将最近的1条消息作为历史记录传递给下一个聊天参与者。这将减少Token消耗 也能 一定程度上提高性能。

代码语言:javascript
复制
var historyReducer = new ChatHistoryTruncationReducer(1);

初始化AgentGroupChat

AgentGroupChat对象会将之前定义的所有内容聚集在一起,相当于创建了一个群聊,添加了群聊的对象(Reviewer + Writer),以及告诉群主/群管理选择Agent的策略 和 终止循环的策略。

代码语言:javascript
复制
// Initialize AgentGroupChat
var groupChat = new AgentGroupChat(reviewerAgent, writerAgent)
{
    ExecutionSettings = new AgentGroupChatSettings()
    {
        SelectionStrategy = new KernelFunctionSelectionStrategy(selectionFunction, kernel)
        {
            InitialAgent = reviewerAgent,
            HistoryReducer = historyReducer,
            HistoryVariableName = KernelFunctionTerminationStrategy.DefaultHistoryVariableName,
            ResultParser = (result) =>
            {
                var val = result.GetValue<string>() ?? ReviewerAgent.AgentName;
                return val.ReplaceLineEndings("\n").Trim();
            }
        },
        TerminationStrategy = new KernelFunctionTerminationStrategy(terminationFunction, kernel)
        {
            Agents = [reviewerAgent],
            HistoryReducer = historyReducer,
            HistoryVariableName = KernelFunctionTerminationStrategy.DefaultHistoryVariableName,
            MaximumIterations = 10,
            ResultParser = (result) =>
            {
                var val = result.GetValue<string>() ?? string.Empty;
                return val.Contains(TerminationToken, StringComparison.OrdinalIgnoreCase);
            }
        }
    }
};

开始聊天循环

下面的代码也是老面孔了,就不过多介绍了:

代码语言:javascript
复制
// Start Working!
Console.WriteLine("----------Agents are Ready. Let's Start Working!----------");
while (true)
{
    Console.WriteLine("User> ");
    var input = Console.ReadLine();
    if (string.IsNullOrWhiteSpace(input))
        continue;
    input = input.Trim();
    if (input.Equals("EXIT", StringComparison.OrdinalIgnoreCase))
        break;
    if (input.Equals("RESET", StringComparison.OrdinalIgnoreCase))
    {
        await groupChat.ResetAsync();
        Console.ResetColor();
        Console.WriteLine("System> Conversation has been reset!");
        continue;
    }
    groupChat.AddChatMessage(new ChatMessageContent(AuthorRole.User, input));
    groupChat.IsComplete = false;
    try
    {
        await foreach (var response in groupChat.InvokeAsync())
        {
            if (string.IsNullOrWhiteSpace(response.Content))
                continue;
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine();
            Console.WriteLine($"{response.AuthorName} ({response.Role})> ");
            Console.WriteLine($"{response.Content.ReplaceLineEndings("\n").Trim()}");
        }
        Console.ResetColor();
        Console.WriteLine();
    }
    catch (HttpOperationException ex)
    {
        Console.ResetColor();
        Console.WriteLine(ex.Message);
        if (ex.InnerException != null)
        {
            Console.WriteLine(ex.InnerException.Message);
            if (ex.InnerException.Data.Count > 0)
                Console.WriteLine(JsonSerializer.Serialize(ex.InnerException.Data, new JsonSerializerOptions() { WriteIndented = true }));
        }
    }
}
Console.ResetColor();
Console.WriteLine("----------See you next time!----------");
Console.ReadKey();

效果展示

第一轮:给了它一段待优化的文本段落

第二轮:让Agent帮忙将其拆分为两个段落

第三轮:提出更高的要求,需要更加学术化以便大学教授能够欣赏

可以看到,Reviewer 和 Writer 的配合还是不错,准确完成了我给它们的Task。

小结

本文介绍了如何通过Semantic Kernel提供的AgentGroupChat来实现多Agent的协作,其中最要的部分就是定义选择轮次策略 和 终止聊天策略,相信通过这个案例你能够有个感性的认识。

当然,多Agent协作还有很多其他的方式和框架实现,这就留到后面一一介绍给你,因为我也还在学。

示例源码

Github: https://github.com/EdisonTalk/MultiAgentSamples

参考资料

Microsoft Learn: https://learn.microsoft.com/en-us/semantic-kernel/support/archive/agent-chat-example?wt.mc_id=MVP_397012

推荐学习

圣杰:《.NET+AI | Semantic Kernel入门到精通》in 极客时间

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-08-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DotNet NB 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档