时间:2026-03-26 09:03
人气:
作者:admin
本文演示如何用 Microsoft Agent Framework 用 Executor + Workflow(DAG)模式实现 SubAgent(子代理)架构。通过示例代码(来自项目的 txt)展示并发 Fan‑Out/Fan‑In 的实现、消息路由与聚合策略,最后讨论最佳实践与权衡。
假定读者等级: 熟悉 C#、异步编程与基本的 LLM/Agent 概念(如果不熟,先看基础 LLM/Agent 入门)。
为什么要用 SubAgents?
核心思路(简要)
示例架构
ConcurrentStartExecutor(广播)、ChatClientAgent(专业子代理)、ConcurrentAggregationExecutor(聚合)示例代码
初始化 OpenAI client & 两个 ChatClientAgent
OpenAIClient client = new OpenAIClient(Environment.GetEnvironmentVariable("OPENAI_API_KEY")!);
var chatClient = client.GetChatClient("gpt-4o-mini").AsIChatClient();
ChatClientAgent physicist = new(
chatClient,
name: "Physicist",
instructions: "You are an expert in physics. You answer questions from a physics perspective."
);
ChatClientAgent chemist = new(
chatClient,
name: "Chemist",
instructions: "You are an expert in chemistry. You answer questions from a chemistry perspective."
);
构建 Workflow
var startExecutor = new ConcurrentStartExecutor();
var aggregationExecutor = new ConcurrentAggregationExecutor();
var workflow = new WorkflowBuilder(startExecutor)
.AddFanOutEdge(startExecutor, new[] { physicist, chemist })
.AddFanInBarrierEdge(new[] { physicist, chemist }, aggregationExecutor)
.WithOutputFrom(aggregationExecutor)
.Build();
流式执行并监听输出
await using StreamingRun run = await InProcessExecution.RunStreamingAsync(workflow, input: "What is temperature?");
await foreach (WorkflowEvent evt in run.WatchStreamAsync())
{
if (evt is WorkflowOutputEvent output)
{
Console.WriteLine($"Workflow completed with results:\n{output.Data}");
}
}
ConcurrentStartExecutor(广播用户消息,再发 TurnToken 启动子代理)
[MessageHandler]
public async ValueTask HandleAsync(string message, IWorkflowContext context, CancellationToken cancellationToken = default)
{
await context.SendMessageAsync(new ChatMessage(ChatRole.User, message), cancellationToken: cancellationToken);
await context.SendMessageAsync(new TurnToken(emitEvents: true), cancellationToken: cancellationToken);
}
protected override ProtocolBuilder ConfigureProtocol(ProtocolBuilder protocolBuilder)
{
return protocolBuilder.ConfigureRoutes(r => r.AddHandler<string>(this.HandleAsync))
.SendsMessage<ChatMessage>()
.SendsMessage<TurnToken>();
}
ConcurrentAggregationExecutor(接收各 Agent 消息并在满足条件时产出聚合结果)
public override async ValueTask HandleAsync(List<ChatMessage> message, IWorkflowContext context, CancellationToken cancellationToken = default)
{
this._messages.AddRange(message);
if (this._messages.Count == 3) // 示例:等待 3 条回复再聚合
{
var formattedMessages = string.Join(Environment.NewLine, this._messages.Select(m => $"{m.AuthorName}: {m.Text}"));
await context.YieldOutputAsync(formattedMessages, cancellationToken);
}
}
逐步说明(快速教程风格)
OPENAI_API_KEY 环境变量instructions(prompt)与权限(可调用哪些工具)最佳实践与权衡
常见坑
结论 & 下一步
参考与进一步阅读
上一篇:多租户下的系统业务开发过程探讨