Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Important
Les fonctionnalités d’orchestration d’agent dans l’infrastructure d’agent sont à l’étape expérimentale. Ils sont en cours de développement actif et peuvent changer considérablement avant de passer à la phase de version préliminaire ou de candidat à la version finale.
L’orchestration de transfert permet aux agents de transférer le contrôle les uns aux autres en fonction du contexte ou de la demande utilisateur. Chaque agent peut « remettre » la conversation à un autre agent avec l’expertise appropriée, ce qui garantit que l’agent approprié gère chaque partie de la tâche. Cela est particulièrement utile dans le support client, les systèmes experts ou tout scénario nécessitant une délégation dynamique.
Pour en savoir plus sur le modèle, par exemple quand utiliser le modèle ou quand éviter le modèle dans votre charge de travail, consultez l’orchestration de handoff.
Cas d’usage courants
Un agent de support client gère une enquête générale, puis se remet à un agent d’experts techniques pour la résolution des problèmes, ou à un agent de facturation si nécessaire :
Ce que vous allez apprendre
- Comment définir des agents et leurs relations de transfert
- Comment configurer une orchestration de passation pour le routage dynamique des agents
- Comment impliquer un humain dans la boucle de conversation
Définir des agents spécialisés
Chaque agent est responsable d’une zone spécifique. Dans cet exemple, nous définissons un agent de triage, un agent de remboursement, un agent d’état de commande et un agent de retour de commande. Certains agents utilisent des plug-ins pour gérer des tâches spécifiques.
Conseil / Astuce
Il ChatCompletionAgent est utilisé ici, mais vous pouvez utiliser n’importe quel type d’agent.
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
using Microsoft.SemanticKernel.Agents.Orchestration;
using Microsoft.SemanticKernel.Agents.Orchestration.Handoff;
using Microsoft.SemanticKernel.Agents.Runtime.InProcess;
using Microsoft.SemanticKernel.ChatCompletion;
// Plugin implementations
public sealed class OrderStatusPlugin {
[KernelFunction]
public string CheckOrderStatus(string orderId) => $"Order {orderId} is shipped and will arrive in 2-3 days.";
}
public sealed class OrderReturnPlugin {
[KernelFunction]
public string ProcessReturn(string orderId, string reason) => $"Return for order {orderId} has been processed successfully.";
}
public sealed class OrderRefundPlugin {
[KernelFunction]
public string ProcessReturn(string orderId, string reason) => $"Refund for order {orderId} has been processed successfully.";
}
// Helper function to create a kernel with chat completion
public static Kernel CreateKernelWithChatCompletion(...)
{
...
}
ChatCompletionAgent triageAgent = new ChatCompletionAgent {
Name = "TriageAgent",
Description = "Handle customer requests.",
Instructions = "A customer support agent that triages issues.",
Kernel = CreateKernelWithChatCompletion(...),
};
ChatCompletionAgent statusAgent = new ChatCompletionAgent {
Name = "OrderStatusAgent",
Description = "A customer support agent that checks order status.",
Instructions = "Handle order status requests.",
Kernel = CreateKernelWithChatCompletion(...),
};
statusAgent.Kernel.Plugins.Add(KernelPluginFactory.CreateFromObject(new OrderStatusPlugin()));
ChatCompletionAgent returnAgent = new ChatCompletionAgent {
Name = "OrderReturnAgent",
Description = "A customer support agent that handles order returns.",
Instructions = "Handle order return requests.",
Kernel = CreateKernelWithChatCompletion(...),
};
returnAgent.Kernel.Plugins.Add(KernelPluginFactory.CreateFromObject(new OrderReturnPlugin()));
ChatCompletionAgent refundAgent = new ChatCompletionAgent {
Name = "OrderRefundAgent",
Description = "A customer support agent that handles order refund.",
Instructions = "Handle order refund requests.",
Kernel = CreateKernelWithChatCompletion(...),
};
refundAgent.Kernel.Plugins.Add(KernelPluginFactory.CreateFromObject(new OrderRefundPlugin()));
Configurer des relations de passation
Utilisez OrchestrationHandoffs pour spécifier quel agent peut transférer la tâche à quel autre agent, et dans quelles circonstances.
var handoffs = OrchestrationHandoffs
.StartWith(triageAgent)
.Add(triageAgent, statusAgent, returnAgent, refundAgent)
.Add(statusAgent, triageAgent, "Transfer to this agent if the issue is not status related")
.Add(returnAgent, triageAgent, "Transfer to this agent if the issue is not return related")
.Add(refundAgent, triageAgent, "Transfer to this agent if the issue is not refund related");
Observer les réponses de l’agent
Vous pouvez créer un rappel pour capturer les réponses de l’agent à mesure que la conversation progresse via la ResponseCallback propriété.
ChatHistory history = [];
ValueTask responseCallback(ChatMessageContent response)
{
history.Add(response);
return ValueTask.CompletedTask;
}
Human in the Loop
Une caractéristique clé de la gestion du processus de transfert est la capacité pour un humain de participer à la conversation. Cela est obtenu en fournissant un InteractiveCallback, qui est appelé chaque fois qu’un agent a besoin d’une entrée de l’utilisateur. Dans une application réelle, cela invite l’utilisateur à entrer ; dans un exemple, vous pouvez utiliser une file d’attente de réponses.
// Simulate user input with a queue
Queue<string> responses = new();
responses.Enqueue("I'd like to track the status of my order");
responses.Enqueue("My order ID is 123");
responses.Enqueue("I want to return another order of mine");
responses.Enqueue("Order ID 321");
responses.Enqueue("Broken item");
responses.Enqueue("No, bye");
ValueTask<ChatMessageContent> interactiveCallback()
{
string input = responses.Dequeue();
Console.WriteLine($"\n# INPUT: {input}\n");
return ValueTask.FromResult(new ChatMessageContent(AuthorRole.User, input));
}
Configurer l’orchestration de transfert
Créez un HandoffOrchestration en renseignant les agents, les relations de transfert et les rappels.
HandoffOrchestration orchestration = new HandoffOrchestration(
handoffs,
triageAgent,
statusAgent,
returnAgent,
refundAgent)
{
InteractiveCallback = interactiveCallback,
ResponseCallback = responseCallback,
};
Démarrer le runtime
Un runtime est nécessaire pour gérer l’exécution des agents. Ici, nous utilisons InProcessRuntime et démarrons avant d’invoquer l’orchestration.
InProcessRuntime runtime = new InProcessRuntime();
await runtime.StartAsync();
Appeler l’orchestration
Appelez l’orchestration avec votre tâche initiale (par exemple, « Je suis un client qui a besoin d’aide avec mes commandes »). Les agents achemineront la conversation en fonction des besoins, impliquant l’humain quand cela est nécessaire.
string task = "I am a customer that needs help with my orders";
var result = await orchestration.InvokeAsync(task, runtime);
Collecter les résultats
Attendez que l'orchestration se termine et récupérez la sortie finale.
string output = await result.GetValueAsync(TimeSpan.FromSeconds(300));
Console.WriteLine($"\n# RESULT: {output}");
Console.WriteLine("\n\nORCHESTRATION HISTORY");
foreach (ChatMessageContent message in history)
{
// Print each message
Console.WriteLine($"# {message.Role} - {message.AuthorName}: {message.Content}");
}
Facultatif : arrêter le runtime
Une fois le traitement terminé, arrêtez le runtime pour nettoyer les ressources.
await runtime.RunUntilIdleAsync();
Exemple de sortie
# RESULT: Handled order return for order ID 321 due to a broken item, and successfully processed the return.
ORCHESTRATION HISTORY
# Assistant - TriageAgent: Could you please specify what kind of help you need with your orders? Are you looking to check the order status, return an item, or request a refund?
# Assistant - OrderStatusAgent: Could you please tell me your order ID?
# Assistant - OrderStatusAgent: Your order with ID 123 has been shipped and will arrive in 2-3 days. Anything else I can assist you with?
# Assistant - OrderReturnAgent: I can help you with that. Could you please provide the order ID and the reason you'd like to return it?
# Assistant - OrderReturnAgent: Please provide the reason for returning the order with ID 321.
# Assistant - OrderReturnAgent: The return for your order with ID 321 has been successfully processed due to the broken item. Anything else I can assist you with?
Conseil / Astuce
L’exemple de code complet est disponible ici
Définir des agents spécialisés
Chaque agent est responsable d’une zone spécifique. Par exemple:
- TriageAgent : gère les demandes initiales des clients et décide quel spécialiste impliquer.
- RefundAgent : gère les demandes de remboursement.
- OrderStatusAgent : vérifie l’état de la commande.
- OrderReturnAgent : gère les retours de commande.
Plug-ins
Tout d’abord, nous devons définir les plug-ins qui seront utilisés dans les agents. Ces plug-ins contiennent la logique de gestion des tâches spécifiques.
from semantic_kernel.functions import kernel_function
class OrderStatusPlugin:
@kernel_function
def check_order_status(self, order_id: str) -> str:
"""Check the status of an order."""
# Simulate checking the order status
return f"Order {order_id} is shipped and will arrive in 2-3 days."
class OrderRefundPlugin:
@kernel_function
def process_refund(self, order_id: str, reason: str) -> str:
"""Process a refund for an order."""
# Simulate processing a refund
print(f"Processing refund for order {order_id} due to: {reason}")
return f"Refund for order {order_id} has been processed successfully."
class OrderReturnPlugin:
@kernel_function
def process_return(self, order_id: str, reason: str) -> str:
"""Process a return for an order."""
# Simulate processing a return
print(f"Processing return for order {order_id} due to: {reason}")
return f"Return for order {order_id} has been processed successfully."
Agents
Ensuite, nous définissons les agents qui utiliseront ces plug-ins.
Conseil / Astuce
Il ChatCompletionAgent est utilisé ici avec Azure OpenAI, mais vous pouvez utiliser n’importe quel type d’agent ou service de modèle.
from semantic_kernel.agents import ChatCompletionAgent
from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion
support_agent = ChatCompletionAgent(
name="TriageAgent",
description="A customer support agent that triages issues.",
instructions="Handle customer requests.",
service=OpenAIChatCompletion(),
)
refund_agent = ChatCompletionAgent(
name="RefundAgent",
description="A customer support agent that handles refunds.",
instructions="Handle refund requests.",
service=OpenAIChatCompletion(),
plugins=[OrderRefundPlugin()],
)
order_status_agent = ChatCompletionAgent(
name="OrderStatusAgent",
description="A customer support agent that checks order status.",
instructions="Handle order status requests.",
service=OpenAIChatCompletion(),
plugins=[OrderStatusPlugin()],
)
order_return_agent = ChatCompletionAgent(
name="OrderReturnAgent",
description="A customer support agent that handles order returns.",
instructions="Handle order return requests.",
service=OpenAIChatCompletion(),
plugins=[OrderReturnPlugin()],
)
Définir les relations de transfert
Utilisez OrchestrationHandoffs pour spécifier quel agent peut transférer la tâche à quel autre agent, et dans quelles circonstances.
from semantic_kernel.agents import OrchestrationHandoffs
handoffs = (
OrchestrationHandoffs()
.add_many( # Use add_many to add multiple handoffs to the same source agent at once
source_agent=support_agent.name,
target_agents={
refund_agent.name: "Transfer to this agent if the issue is refund related",
order_status_agent.name: "Transfer to this agent if the issue is order status related",
order_return_agent.name: "Transfer to this agent if the issue is order return related",
},
)
.add( # Use add to add a single handoff
source_agent=refund_agent.name,
target_agent=support_agent.name,
description="Transfer to this agent if the issue is not refund related",
)
.add(
source_agent=order_status_agent.name,
target_agent=support_agent.name,
description="Transfer to this agent if the issue is not order status related",
)
.add(
source_agent=order_return_agent.name,
target_agent=support_agent.name,
description="Transfer to this agent if the issue is not order return related",
)
)
Observer les réponses de l’agent
Vous pouvez définir un rappel pour imprimer le message de chaque agent à mesure que la conversation progresse.
from semantic_kernel.contents import ChatMessageContent
def agent_response_callback(message: ChatMessageContent) -> None:
print(f"{message.name}: {message.content}")
Human in the Loop
Une caractéristique clé de la gestion du processus de transfert est la capacité pour un humain de participer à la conversation. Pour ce faire, vous devez fournir un human_response_function rappel, qui est appelé chaque fois qu’un agent a besoin d’une entrée de l’utilisateur.
from semantic_kernel.contents import AuthorRole, ChatMessageContent
def human_response_function() -> ChatMessageContent:
user_input = input("User: ")
return ChatMessageContent(role=AuthorRole.USER, content=user_input)
Configurer l’orchestration de transfert
Créez un HandoffOrchestration en renseignant les agents, les relations de transfert et les rappels.
from semantic_kernel.agents import HandoffOrchestration
handoff_orchestration = HandoffOrchestration(
members=[
support_agent,
refund_agent,
order_status_agent,
order_return_agent,
],
handoffs=handoffs,
agent_response_callback=agent_response_callback,
human_response_function=human_response_function,
)
Démarrer le runtime
Démarrez le runtime pour gérer l’exécution de l’agent.
from semantic_kernel.agents.runtime import InProcessRuntime
runtime = InProcessRuntime()
runtime.start()
Appeler l’orchestration
Appelez l’orchestration avec votre tâche initiale (par exemple, « Un client est sur la ligne »). Les agents achemineront la conversation en fonction des besoins, impliquant l’humain quand cela est nécessaire.
orchestration_result = await handoff_orchestration.invoke(
task="A customer is on the line.",
runtime=runtime,
)
Collecter les résultats
Attendez que l’orchestration se termine.
value = await orchestration_result.get()
print(value)
Facultatif : arrêter le runtime
Une fois le traitement terminé, arrêtez le runtime pour nettoyer les ressources.
await runtime.stop_when_idle()
Exemple de sortie
TriageAgent: Hello! Thank you for reaching out. How can I assist you today?
User: I'd like to track the status of my order
OrderStatusAgent: Sure, I can help you with that. Could you please provide me with your order ID?
User: My order ID is 123
OrderStatusAgent: Your order with ID 123 has been shipped and is expected to arrive in 2-3 days. Is there anything else I can assist you with?
User: I want to return another order of mine
OrderReturnAgent: I can help you with returning your order. Could you please provide the order ID for the return and the reason you'd like to return it?
User: Order ID 321
OrderReturnAgent: Please provide the reason for returning the order with ID 321.
User: Broken item
OrderReturnAgent: The return for your order with ID 321 has been successfully processed due to the broken item. Is there anything else I can assist you with?
User: No, bye
Task is completed with summary: Handled order return for order ID 321 due to a broken item, and successfully processed the return.
Conseil / Astuce
L’exemple de code complet est disponible ici.
Remarque
L’orchestration de l’agent n’est pas encore disponible dans le Kit de développement logiciel (SDK) Java.