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.
Exploration du noyau sémantique
Conseil / Astuce
La documentation détaillée de l’API relative à cette discussion est disponible à l’adresse suivante :
Conseil / Astuce
La documentation détaillée de l’API relative à cette discussion est disponible à l’adresse suivante :
Conseil / Astuce
La documentation détaillée de l’API relative à cette discussion est disponible à l’adresse suivante :
Complétion de conversation dans le noyau sémantique
L’achèvement de la conversation est fondamentalement un protocole pour une interaction basée sur la conversation avec un modèle IA où l’historique des conversations est conservé et présenté au modèle avec chaque requête. Les services AI du noyau sémantique offrent une infrastructure unifiée permettant d’intégrer les fonctionnalités d’achèvement de conversation de différents modèles IA.
Un ChatCompletionAgent peut tirer parti de l’un de ces services IA pour générer des réponses, qu’ils soient dirigés vers un utilisateur ou un autre agent.
Préparation de votre environnement de développement
Pour poursuivre le développement d’un ChatCompletionAgent, configurez votre environnement de développement avec les packages appropriés.
Ajoutez le package Microsoft.SemanticKernel.Agents.Core à votre projet :
dotnet add package Microsoft.SemanticKernel.Agents.Core --prerelease
Installez le package semantic-kernel :
pip install semantic-kernel
Important
Selon le service IA que vous utilisez dans le cadre du ChatCompletionAgent, vous devrez peut-être installer des paquets supplémentaires. Vérifiez la valeur supplémentaire requise sur la page suivante
<dependency>
<groupId>com.microsoft.semantic-kernel</groupId>
<artifactId>semantickernel-agents-core</artifactId>
<version>[LATEST]</version>
</dependency>
Création d’un ChatCompletionAgent
Un ChatCompletionAgent est fondamentalement basé sur un service IA. Par conséquent, la création d’un ChatCompletionAgent commence par créer une instance Kernel qui contient un ou plusieurs services d'achèvement de chat, puis en instanciant l’agent avec une référence à cette instance Kernel.
// Initialize a Kernel with a chat-completion service
IKernelBuilder builder = Kernel.CreateBuilder();
builder.AddAzureOpenAIChatCompletion(/*<...configuration parameters>*/);
Kernel kernel = builder.Build();
// Create the agent
ChatCompletionAgent agent =
new()
{
Name = "SummarizationAgent",
Instructions = "Summarize user input",
Kernel = kernel
};
Il existe deux façons de créer un ChatCompletionAgent:
1. En fournissant directement le service d’achèvement de conversation
from semantic_kernel.agents import ChatCompletionAgent
# Create the agent by directly providing the chat completion service
agent = ChatCompletionAgent(
service=AzureChatCompletion(), # your chat completion service instance
name="<agent name>",
instructions="<agent instructions>",
)
2. En créant d’abord un noyau, en y ajoutant le service, puis en fournissant le noyau
# Define the kernel
kernel = Kernel()
# Add the chat completion service to the kernel
kernel.add_service(AzureChatCompletion())
# Create the agent using the kernel
agent = ChatCompletionAgent(
kernel=kernel,
name="<agent name>",
instructions="<agent instructions>",
)
La première méthode est utile lorsque vous disposez déjà d’un service d’achèvement de conversation prêt. La deuxième méthode est bénéfique lorsque vous avez besoin d’un noyau qui gère plusieurs services ou fonctionnalités supplémentaires.
// Initialize a Kernel with a chat-completion service
var chatCompletion = OpenAIChatCompletion.builder()
.withOpenAIAsyncClient(client) // OpenAIAsyncClient with configuration parameters
.withModelId(MODEL_ID)
.build();
var kernel = Kernel.builder()
.withAIService(ChatCompletionService.class, chatCompletion)
.build();
// Create the agent
var agent = ChatCompletionAgent.builder()
.withKernel(kernel)
.build();
Sélection de services d'IA
Il n'est pas différent d'utiliser directement les services d’IA du noyau sémantique ; un ChatCompletionAgent prend en charge la spécification d’un sélecteur de service. Un sélecteur de service identifie le service d'IA à cibler quand le Kernel en contient plus d'un.
Remarque
Si plusieurs services IA sont présents et qu’aucun sélecteur de service n’est fourni, la même logique par défaut est appliquée pour l’agent que vous trouverez lors de l’utilisation d’un service IA en dehors du Agent Framework
IKernelBuilder builder = Kernel.CreateBuilder();
// Initialize multiple chat-completion services.
builder.AddAzureOpenAIChatCompletion(/*<...service configuration>*/, serviceId: "service-1");
builder.AddAzureOpenAIChatCompletion(/*<...service configuration>*/, serviceId: "service-2");
Kernel kernel = builder.Build();
ChatCompletionAgent agent =
new()
{
Name = "<agent name>",
Instructions = "<agent instructions>",
Kernel = kernel,
Arguments = // Specify the service-identifier via the KernelArguments
new KernelArguments(
new OpenAIPromptExecutionSettings()
{
ServiceId = "service-2" // The target service-identifier.
})
};
from semantic_kernel.connectors.ai.open_ai import (
AzureChatCompletion,
AzureChatPromptExecutionSettings,
)
# Define the Kernel
kernel = Kernel()
# Add the AzureChatCompletion AI Service to the Kernel
kernel.add_service(AzureChatCompletion(service_id="service1"))
kernel.add_service(AzureChatCompletion(service_id="service2"))
settings = AzureChatPromptExecutionSettings(service_id="service2")
# Create the agent
agent = ChatCompletionAgent(
kernel=kernel,
name="<agent name>",
instructions="<agent instructions>",
arguments=KernelArguments(settings=settings)
)
Fonctionnalité actuellement indisponible en Java.
Conversation avec ChatCompletionAgent
La conversation avec votre ChatCompletionAgent est basée sur une instance de ChatHistory, pas différente de l’interaction avec un service d'achèvement de tâche de conversation par intelligence artificielle.
Vous pouvez simplement appeler l’agent avec votre message utilisateur.
// Define agent
ChatCompletionAgent agent = ...;
// Generate the agent response(s)
await foreach (ChatMessageContent response in agent.InvokeAsync(new ChatMessageContent(AuthorRole.User, "<user input>")))
{
// Process agent response(s)...
}
Vous pouvez également utiliser un AgentThread pour avoir une conversation avec votre agent.
Ici, nous utilisons un ChatHistoryAgentThread.
Le ChatHistoryAgentThread peut également prendre un objet facultatif ChatHistory comme entrée, via son constructeur, lors de la reprise d'une conversation précédente. (non affiché)
// Define agent
ChatCompletionAgent agent = ...;
AgentThread thread = new ChatHistoryAgentThread();
// Generate the agent response(s)
await foreach (ChatMessageContent response in agent.InvokeAsync(new ChatMessageContent(AuthorRole.User, "<user input>"), thread))
{
// Process agent response(s)...
}
Il existe plusieurs façons de converser avec un ChatCompletionAgent.
Le plus simple est d’appeler et d’attendre get_response:
# Define agent
agent = ChatCompletionAgent(...)
# Generate the agent response
response = await agent.get_response(messages="user input")
# response is an `AgentResponseItem[ChatMessageContent]` object
Si vous souhaitez que l’agent conserve l’historique des conversations entre les appels, vous pouvez le transmettre ChatHistoryAgentThread suit :
# Define agent
agent = ChatCompletionAgent(...)
# Generate the agent response(s)
response = await agent.get_response(messages="user input")
# Generate another response, continuing the conversation thread from the first response.
response2 = await agent.get_response(messages="user input", thread=response.thread)
# process agent response(s)
L’appel de la méthode invoke retourne une valeur AsyncIterable de AgentResponseItem[ChatMessageContent].
# Define agent
agent = ChatCompletionAgent(...)
# Define the thread
thread = ChatHistoryAgentThread()
# Generate the agent response(s)
async for response in agent.invoke(messages="user input", thread=thread):
# process agent response(s)
La ChatCompletionAgent prend également en charge la transmission en continu dans laquelle la méthode invoke_stream retourne une AsyncIterable de StreamingChatMessageContent:
# Define agent
agent = ChatCompletionAgent(...)
# Define the thread
thread = ChatHistoryAgentThread()
# Generate the agent response(s)
async for response in agent.invoke_stream(messages="user input", thread=thread):
# process agent response(s)
ChatCompletionAgent agent = ...;
// Generate the agent response(s)
agent.invokeAsync(new ChatMessageContent<>(AuthorRole.USER, "<user input>")).block();
Vous pouvez également utiliser un AgentThread pour avoir une conversation avec votre agent.
Ici, nous utilisons un ChatHistoryAgentThread.
Le ChatHistoryAgentThread peut également prendre un objet ChatHistory comme entrée via son constructeur, pour reprendre une conversation précédente. (non affiché)
// Define agent
ChatCompletionAgent agent = ...;
AgentThread thread = new ChatHistoryAgentThread();
// Generate the agent response(s)
agent.invokeAsync(new ChatMessageContent<>(AuthorRole.USER, "<user input>"), thread).block();
Gestion des messages intermédiaires avec un ChatCompletionAgent
Le noyau ChatCompletionAgent sémantique est conçu pour appeler un agent qui répond aux requêtes utilisateur ou aux questions. Pendant l’appel, l’agent peut exécuter des outils pour dériver la réponse finale. Pour accéder aux messages intermédiaires générés pendant ce processus, les appelants peuvent fournir une fonction de rappel qui gère les instances de FunctionCallContent ou FunctionResultContent.
La documentation du callback pour
ChatCompletionAgentsera bientôt disponible.
La configuration du on_intermediate_message rappel dans agent.invoke(...) ou agent.invoke_stream(...) permet à l’appelant de recevoir des messages intermédiaires générés pendant le processus de formulation de la réponse finale de l’agent.
import asyncio
from typing import Annotated
from semantic_kernel.agents.chat_completion.chat_completion_agent import ChatCompletionAgent, ChatHistoryAgentThread
from semantic_kernel.connectors.ai.open_ai.services.azure_chat_completion import AzureChatCompletion
from semantic_kernel.contents import FunctionCallContent, FunctionResultContent
from semantic_kernel.contents.chat_message_content import ChatMessageContent
from semantic_kernel.functions import kernel_function
# Define a sample plugin for the sample
class MenuPlugin:
"""A sample Menu Plugin used for the concept sample."""
@kernel_function(description="Provides a list of specials from the menu.")
def get_specials(self) -> Annotated[str, "Returns the specials from the menu."]:
return """
Special Soup: Clam Chowder
Special Salad: Cobb Salad
Special Drink: Chai Tea
"""
@kernel_function(description="Provides the price of the requested menu item.")
def get_item_price(
self, menu_item: Annotated[str, "The name of the menu item."]
) -> Annotated[str, "Returns the price of the menu item."]:
return "$9.99"
# This callback function will be called for each intermediate message
# Which will allow one to handle FunctionCallContent and FunctionResultContent
# If the callback is not provided, the agent will return the final response
# with no intermediate tool call steps.
async def handle_intermediate_steps(message: ChatMessageContent) -> None:
for item in message.items or []:
if isinstance(item, FunctionCallContent):
print(f"Function Call:> {item.name} with arguments: {item.arguments}")
elif isinstance(item, FunctionResultContent):
print(f"Function Result:> {item.result} for function: {item.name}")
else:
print(f"{message.role}: {message.content}")
async def main() -> None:
agent = ChatCompletionAgent(
service=AzureChatCompletion(),
name="Assistant",
instructions="Answer questions about the menu.",
plugins=[MenuPlugin()],
)
# Create a thread for the agent
# If no thread is provided, a new thread will be
# created and returned with the initial response
thread: ChatHistoryAgentThread = None
user_inputs = [
"Hello",
"What is the special soup?",
"How much does that cost?",
"Thank you",
]
for user_input in user_inputs:
print(f"# User: '{user_input}'")
async for response in agent.invoke(
messages=user_input,
thread=thread,
on_intermediate_message=handle_intermediate_steps,
):
print(f"# {response.role}: {response}")
thread = response.thread
if __name__ == "__main__":
asyncio.run(main())
Voici un exemple de résultat du processus d'invocation de l'agent :
User: 'Hello'
AuthorRole.ASSISTANT: Hi there! How can I assist you today?
User: 'What is the special soup?'
Function Call:> MenuPlugin-get_specials with arguments: {}
Function Result:>
Special Soup: Clam Chowder
Special Salad: Cobb Salad
Special Drink: Chai Tea
for function: MenuPlugin-get_specials
AuthorRole.ASSISTANT: The special soup today is Clam Chowder. Would you like to know anything else from the menu?
User: 'How much does that cost?'
Function Call:> MenuPlugin-get_item_price with arguments: {"menu_item":"Clam Chowder"}
Function Result:> $9.99 for function: MenuPlugin-get_item_price
AuthorRole.ASSISTANT: The Clam Chowder costs $9.99. Would you like to know more about the menu or anything else?
User: 'Thank you'
AuthorRole.ASSISTANT: You're welcome! If you have any more questions, feel free to ask. Enjoy your day!
Fonctionnalité actuellement indisponible en Java.
Spécification déclarative
La documentation sur l’utilisation de spécifications déclaratives sera bientôt disponible.
Important
Cette fonctionnalité est à l’étape expérimentale. Les fonctionnalités à ce stade sont en cours de développement et soumises à des modifications avant de passer à la phase de préversion ou de version candidate.
Le ChatCompletionAgent peut être instancié directement à partir d'une spécification YAML déclarative. Cette approche vous permet de définir les principales propriétés, instructions et fonctions disponibles de l’agent (plug-ins) de manière structurée et portable. En utilisant YAML, vous pouvez décrire le nom, la description, l’invite d’instructions, l’ensemble d’outils et les paramètres de modèle dans un document unique, ce qui rend la configuration de l’agent facilement auditable et reproductible.
Remarque
Tous les outils ou fonctions spécifiés dans le YAML déclaratif doivent déjà exister dans l’instance du noyau au moment de la création de l’agent. Le chargeur d’agent ne crée pas de nouvelles fonctions à partir de la spécification ; Au lieu de cela, il recherche les plug-ins et fonctions référencés par leurs identificateurs dans le noyau. Si un plug-in ou une fonction requis n’est pas présent dans le noyau, une erreur est générée pendant la construction de l’agent.
Exemple : création d’un ChatCompletionAgent à partir d'une spécification YAML
import asyncio
from typing import Annotated
from semantic_kernel import Kernel
from semantic_kernel.agents import AgentRegistry, ChatHistoryAgentThread
from semantic_kernel.agents.chat_completion.chat_completion_agent import ChatCompletionAgent
from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion
from semantic_kernel.functions import kernel_function
# Define a plugin with kernel functions
class MenuPlugin:
@kernel_function(description="Provides a list of specials from the menu.")
def get_specials(self) -> Annotated[str, "Returns the specials from the menu."]:
return """
Special Soup: Clam Chowder
Special Salad: Cobb Salad
Special Drink: Chai Tea
"""
@kernel_function(description="Provides the price of the requested menu item.")
def get_item_price(
self, menu_item: Annotated[str, "The name of the menu item."]
) -> Annotated[str, "Returns the price of the menu item."]:
return "$9.99"
# YAML spec for the agent
AGENT_YAML = """
type: chat_completion_agent
name: Assistant
description: A helpful assistant.
instructions: Answer the user's questions using the menu functions.
tools:
- id: MenuPlugin.get_specials
type: function
- id: MenuPlugin.get_item_price
type: function
model:
options:
temperature: 0.7
"""
USER_INPUTS = [
"Hello",
"What is the special soup?",
"What does that cost?",
"Thank you",
]
async def main():
kernel = Kernel()
kernel.add_plugin(MenuPlugin(), plugin_name="MenuPlugin")
agent: ChatCompletionAgent = await AgentRegistry.create_from_yaml(
AGENT_YAML, kernel=kernel, service=OpenAIChatCompletion()
)
thread: ChatHistoryAgentThread | None = None
for user_input in USER_INPUTS:
print(f"# User: {user_input}")
response = await agent.get_response(user_input, thread=thread)
print(f"# {response.name}: {response}")
thread = response.thread
await thread.delete() if thread else None
if __name__ == "__main__":
asyncio.run(main())
Cette fonctionnalité n’est pas disponible.
Comment faire
Pour obtenir un exemple de bout en bout pour un ChatCompletionAgent, consultez :
- guide pratique :
ChatCompletionAgent