交接协调允许代理根据上下文或用户请求将控制权转移给另一个代理。 每个代理都可以通过适当的专业知识将对话“移交”到另一个代理,确保正确的代理处理任务的每个部分。 这在客户支持、专家系统或任何需要动态委派的方案中特别有用。
Handoff 与工具化代理之间的差异
虽然代理作为工具通常被视为多代理模式,乍一看可能与转换类似,但两者之间存在根本差异:
- 控制流:在移交业务流程中,根据定义的规则在代理之间显式传递控制。 每个代理都可以决定将整个任务移交给另一个代理。 没有中央权威管理工作流。 相比之下,代理即工具涉及将子任务委托给其他代理的主代理,一旦代理完成子任务,控制就会返回到主代理。
- 任务所有权:在交接中,接收移交的代理拥有任务的完全所有权。 在代理即工具中,主代理将保留任务的总体责任,而其他代理则被视为辅助特定子任务的工具。
- 上下文管理:在交接业务流程中,对话完全移交给另一个代理。 接收代理对到目前为止已完成的工作有完整的了解。 在代理即工具中,主代理管理整个上下文,并且可能仅根据需要向工具代理提供相关信息。
学习内容
- 如何为不同的域创建专用代理
- 如何配置代理之间的移交规则
- 如何使用动态代理路由生成交互式工作流
- 如何使用代理切换处理多轮次对话
在交接业务流程中,代理可以基于上下文将控制权传输到彼此,从而允许动态路由和专业知识处理。
设置 Azure OpenAI 客户端
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.Workflows;
using Microsoft.Extensions.AI;
using Microsoft.Agents.AI;
// 1) Set up the Azure OpenAI client
var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") ??
throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-4o-mini";
var client = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetChatClient(deploymentName)
.AsIChatClient();
定义专用代理
创建领域专用代理和用于路由的分诊代理:
// 2) Create specialized agents
ChatClientAgent historyTutor = new(client,
"You provide assistance with historical queries. Explain important events and context clearly. Only respond about history.",
"history_tutor",
"Specialist agent for historical questions");
ChatClientAgent mathTutor = new(client,
"You provide help with math problems. Explain your reasoning at each step and include examples. Only respond about math.",
"math_tutor",
"Specialist agent for math questions");
ChatClientAgent triageAgent = new(client,
"You determine which agent to use based on the user's homework question. ALWAYS handoff to another agent.",
"triage_agent",
"Routes messages to the appropriate specialist agent");
配置交接规则
定义哪些代理可以移交给其他代理:
// 3) Build handoff workflow with routing rules
var workflow = AgentWorkflowBuilder.StartHandoffWith(triageAgent)
.WithHandoff(triageAgent, [mathTutor, historyTutor]) // Triage can route to either specialist
.WithHandoff(mathTutor, triageAgent) // Math tutor can return to triage
.WithHandoff(historyTutor, triageAgent) // History tutor can return to triage
.Build();
运行交互式移交工作流
使用动态代理切换处理多轮次对话:
// 4) Process multi-turn conversations
List<ChatMessage> messages = new();
while (true)
{
Console.Write("Q: ");
string userInput = Console.ReadLine()!;
messages.Add(new(ChatRole.User, userInput));
// Execute workflow and process events
StreamingRun run = await InProcessExecution.StreamAsync(workflow, messages);
await run.TrySendMessageAsync(new TurnToken(emitEvents: true));
List<ChatMessage> newMessages = new();
await foreach (WorkflowEvent evt in run.WatchStreamAsync().ConfigureAwait(false))
{
if (evt is AgentRunUpdateEvent e)
{
Console.WriteLine($"{e.ExecutorId}: {e.Data}");
}
else if (evt is WorkflowCompletedEvent completed)
{
newMessages = (List<ChatMessage>)completed.Data!;
break;
}
}
// Add new messages to conversation history
messages.AddRange(newMessages.Skip(messages.Count));
}
示例交互
Q: What is the derivative of x^2?
triage_agent: This is a math question. I'll hand this off to the math tutor.
math_tutor: The derivative of x^2 is 2x. Using the power rule, we bring down the exponent (2) and multiply it by the coefficient (1), then reduce the exponent by 1: d/dx(x^2) = 2x^(2-1) = 2x.
Q: Tell me about World War 2
triage_agent: This is a history question. I'll hand this off to the history tutor.
history_tutor: World War 2 was a global conflict from 1939 to 1945. It began when Germany invaded Poland and involved most of the world's nations. Key events included the Holocaust, Pearl Harbor attack, D-Day invasion, and ended with atomic bombs on Japan.
Q: Can you help me with calculus integration?
triage_agent: This is another math question. I'll route this to the math tutor.
math_tutor: I'd be happy to help with calculus integration! Integration is the reverse of differentiation. The basic power rule for integration is: ∫x^n dx = x^(n+1)/(n+1) + C, where C is the constant of integration.
关键概念
- 动态路由:代理可以决定哪个代理应根据上下文处理下一次交互
- AgentWorkflowBuilder.StartHandoffWith():定义启动工作流的初始代理
- WithHandoff():配置特定代理之间的移交规则
- 上下文保存:在所有交接中维护完整对话历史记录
- 多轮次支持:支持使用无缝代理切换的持续对话
- 专业知识:每个代理专注于自己的领域,同时通过交接进行协作