大家好,我是Edison。
上一篇我们学习了Semantic Kernel中的AgentGroupChat实现群聊的效果,但其实多Agent协作编排还有一些其他的模式。今天就来和你唠唠其他支持的编排模式,每篇介绍一个,持续更新完。
SK支持哪些编排模式?
传统的单Agent系统在处理复杂多面任务的能力方面受到较多限制,因此我们会有多Agent编排协作完成任务的需求。Semantic Kernel支持多种多Agent编排流程模式,每个模式都针对不同的协作方案而设计。这些模式作为框架的一部分提供出来,我们可以自己扩展。
目前,Semantic Kernel支持以下编排模式:

上面所有的编排模式都基于统一的构造和接口来实现,它抽象了Agent通信、协调和结果聚合的复杂性,如下代码所示,只需选择不同的编排模式类即可:
// 只需修改下面的编排模式类型即可
// or ConcurrentOrchestration, GroupChatOrchestration, HandoffOrchestration, MagenticOrchestration, ...
SequentialOrchestration orchestration = new(agentA, agentB)
{
LoggerFactory = this.LoggerFactory
};
InProcessRuntime runtime = new();
// Start the runtime
await runtime.StartAsync();
// Invoke the orchestration and get the result
OrchestrationResult<string> result = await orchestration.InvokeAsync(task, runtime);
string text = await result.GetValueAsync();
await runtime.RunUntilIdleAsync();
因此,我们无需学习新的API或重写Agent逻辑,可以专注于应用程序的编写,真的是很方便!
下面,我们就来看看第一种模式:并发编排。
并发编排模式简介
并发模式使用多个Agent并行处理同一个任务,每个Agent都可以独立处理输入,并收集并聚合结果。此模式比较适合多种观点或解决方案很有价值的场景,比如集思广益、群体推理以及其他投票系统。
下图展示了多个Agent生成同一问题的不同解决方案,并收集其响应以进一步分析或选择:

实现并发编排模式
这里我们来实现一个DEMO,定义两个Agent:Physicst(物理学大佬) 和 Chemist (化学大佬),它们可以对用户提出的同一个问题并行地进行思考并给出自己的解释。
为了简单地实现这个功能,我们创建一个.NET控制台项目,然后安装以下包:
Microsoft.SemanticKernel.Agents.Core
Microsoft.SemanticKernel.Agents.OpenAI (Preview版本)
Microsoft.SemanticKernel.Agents.Orchestration (Preview版本)
Microsoft.SemanticKernel.Agents.Runtime.InProcess (Preview版本)
需要注意的是,由于Semantic Kernel的较多功能目前还处于实验预览阶段,所以建议在该项目的csproj文件中加入以下配置,统一取消警告:
<PropertyGroup>
<NoWarn>$(NoWarn);CA2007;IDE1006;SKEXP0001;SKEXP0110;OPENAI001</NoWarn>
</PropertyGroup>
创建一个appsettings.json配置文件,填入以下关于LLM API的配置,其中API_KEY请输入你自己的:
{
"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供后续使用,这也是老面孔了:
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:Chemist & Physicst
(1)Chemist
var chemist = new ChatCompletionAgent()
{
Name = "ChemistryExpert",
Instructions = "You're an expert in chemistry, you can answer questions from a chemistry expert perspective.",
Description = "Chemistry expert agent for answering questions in the perspective of a chemist.",
Kernel = kernel
};
(2)Physicst
var physicist = new ChatCompletionAgent()
{
Name = "PhysicsExpert",
Instructions = "You're an expert in physics, you can answer questions from a physics expert perspective.",
Description = "Physics expert agent for answering questions in the perspective of a physicst.",
Kernel = kernel
};
选择编排模式
这里我们选择的是并发编排模式:ConcurrentOrchestration,将需要编排的两个Agent作为参数传递给它:
// Set up the Concurrent Orchestration
var orchestration = new ConcurrentOrchestration(physicist, chemist);
启动运行时
在Semantic Kernel中,需要运行时(Runtime)才能管理Agent的执行,因此这里我们需要在正式开始前使用InProcessRuntime并启动起来。
// Start the Runtime
var runtime = new InProcessRuntime();
await runtime.StartAsync();
调用编排 并 收集结果
准备工作差不多了,现在我们可以开始调用编排了。编排任务时它会将任务广播到所有Agent中,并发运行多个Agent进行任务处理,最后收集每个Agent的处理结果。
这里的案例就是将用户的问题传给多个Agent并发思考并给出自己的回答。
// Start the Chat
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))
{
// Stop the Runtime
await runtime.RunUntilIdleAsync();
break;
}
try
{
// Invoke the Orchestration
var result = await orchestration.InvokeAsync(input, runtime);
// Collect Results from multi Agents
var output = await result.GetValueAsync(TimeSpan.FromSeconds(10 * 2));
var texts = output.Select(text => $"{text}");
for (int i = 0; i < texts.Count(); i++)
{
Console.WriteLine($"# RESULT {i+1}:{Environment.NewLine}");
Console.WriteLine($"{texts.ElementAt(i).Trim()}{Environment.NewLine}");
}
}
catch (HttpOperationException ex)
{
Console.WriteLine($"Exception: {ex.Message}");
}
finally
{
Console.ResetColor();
Console.WriteLine();
}
}
需要注意的是:上面的代码示例中我手动使用了一个for循环将收集到的结果进行显示,期望显示格式为RESULT 1, RESULT 2等。
效果展示
用户输入问题:What is temperature?
NOTE:temperature中文意思为温度

可以看到,Chemist 和 Physicst 两个Agent并行思考并给出了从自己的视角出发的对于温度这个概念的解释。
因此,可以看出并发编排模式非常适合并行分析、独立子任务并集成决策的任务场景。
小结
本文介绍了Agent编排的概念以及Semantic Kernel支持的编排模式,最后通过一个案例介绍了如何实现一个并发编排模式,相信通过这个案例你能够有个感性的认识。
下一篇,我们将学习顺序编排模式,它按定义的顺序讲一个Agent的处理结果传递给下一个Agent,非常适合于工作流、管道、多阶段处理类任务。
示例源码
GitHub: https://github.com/EdisonTalk/MultiAgentOrchestration
参考资料
Microsoft Learn: https://learn.microsoft.com/zh-cn/semantic-kernel/frameworks/agent/agent-orchestration
推荐学习
圣杰:《.NET+AI | Semantic Kernel入门到精通》
作者:爱迪生
出处:https://edisontalk.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。