Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Esplorazione del kernel semantico
Suggerimento
La documentazione dettagliata dell'API relativa a questa discussione è disponibile all'indirizzo:
Suggerimento
La documentazione dettagliata dell'API relativa a questa discussione è disponibile all'indirizzo:
Suggerimento
La documentazione dettagliata dell'API relativa a questa discussione è disponibile all'indirizzo:
Completamento della chat nel kernel semantico
Il completamento della chat è fondamentalmente un protocollo per un'interazione basata su chat con un modello di intelligenza artificiale in cui la cronologia delle chat viene mantenuta e presentata al modello con ogni richiesta. Il Semantic Kernel offre un framework unificato per integrare le funzionalità di completamento della chat di vari modelli di intelligenza artificiale.
Un ChatCompletionAgent
può sfruttare uno di questi servizi di intelligenza artificiale per generare risposte, sia indirizzate a un utente che a un altro agente.
Preparazione dell'ambiente di sviluppo
Per procedere con lo sviluppo di un ChatCompletionAgent
, è necessario configurare l'ambiente di sviluppo con i pacchetti appropriati.
Aggiungere il pacchetto Microsoft.SemanticKernel.Agents.Core
al progetto:
dotnet add package Microsoft.SemanticKernel.Agents.Core --prerelease
Installare il pacchetto semantic-kernel
:
pip install semantic-kernel
Importante
A seconda del servizio di intelligenza artificiale usato come parte di ChatCompletionAgent
, potrebbe essere necessario installare pacchetti aggiuntivi. Verificare la presenza degli elementi aggiuntivi necessari nella pagina seguente
<dependency>
<groupId>com.microsoft.semantic-kernel</groupId>
<artifactId>semantickernel-agents-core</artifactId>
<version>[LATEST]</version>
</dependency>
Creazione di un ChatCompletionAgent
Un ChatCompletionAgent
è fondamentalmente basato su servizi di intelligenza artificiale . Di conseguenza, la creazione di un ChatCompletionAgent
inizia con l'inizializzazione di un'istanza di Kernel
che contiene uno o più servizi di completamento chat, seguita dall'instanziazione dell'agente con un riferimento a quell'istanza di 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
};
Esistono due modi per creare un ChatCompletionAgent
:
1. Fornendo direttamente il servizio di completamento della chat
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. Creando prima un kernel, aggiungendo il servizio, quindi fornendo il kernel
# 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>",
)
Il primo metodo è utile quando si dispone già di un servizio di completamento della chat pronto. Il secondo metodo è utile quando è necessario un kernel che gestisce più servizi o funzionalità aggiuntive.
// 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();
Selezione del servizio di intelligenza artificiale
Non è diverso dall'uso diretto dei servizi di intelligenza artificiale del kernel semantico; un ChatCompletionAgent
supporta la specifica di un selettore di servizio. Un selettore di servizi identifica quale servizio di intelligenza artificiale indirizzare quando il Kernel
contiene più di uno.
Annotazioni
Se sono presenti più servizi di intelligenza artificiale e non viene fornito alcun selettore di servizio, viene applicata la stessa logica predefinita per l'agente che si trova quando si usa un servizio di intelligenza artificiale all'esterno di 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)
)
Funzionalità attualmente non disponibile in Java.
Conversare con ChatCompletionAgent
Conversare con il tuo ChatCompletionAgent
si basa su un'istanza di ChatHistory
, non è diverso dall'interagire con un servizio di intelligenza artificiale per il completamento delle chat.
È sufficiente richiamare l'agente con il messaggio dell'utente.
// 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)...
}
È anche possibile usare un AgentThread
per avere conversazione con l'agente.
In questo caso viene usato un oggetto ChatHistoryAgentThread
.
Il ChatHistoryAgentThread
può anche accettare un oggetto facoltativo ChatHistory
come input, attraverso il suo costruttore, nel caso si riprenda una conversazione precedente. (non visualizzato)
// 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)...
}
Esistono diversi modi per conversare con un ChatCompletionAgent
.
Il modo più semplice consiste nel chiamare e attendere get_response
:
# Define agent
agent = ChatCompletionAgent(...)
# Generate the agent response
response = await agent.get_response(messages="user input")
# response is an `AgentResponseItem[ChatMessageContent]` object
Se si vuole che l'agente mantenga la cronologia delle conversazioni tra le chiamate, è possibile passarla come ChatHistoryAgentThread
segue:
# 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)
La chiamata al metodo invoke
restituisce un AsyncIterable
di 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)
Il ChatCompletionAgent
supporta anche lo streaming in cui il metodo invoke_stream
restituisce un AsyncIterable
di 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();
È anche possibile usare un AgentThread
per avere conversazione con l'agente.
In questo caso viene usato un oggetto ChatHistoryAgentThread
.
Il ChatHistoryAgentThread
può anche accettare un ChatHistory
oggetto come input, tramite il relativo costruttore, se si riprende una conversazione precedente. (non visualizzato)
// Define agent
ChatCompletionAgent agent = ...;
AgentThread thread = new ChatHistoryAgentThread();
// Generate the agent response(s)
agent.invokeAsync(new ChatMessageContent<>(AuthorRole.USER, "<user input>"), thread).block();
Gestione dei messaggi intermedi con un ChatCompletionAgent
Il kernel ChatCompletionAgent
semantico è progettato per richiamare un agente che soddisfa le query o le domande degli utenti. Durante la chiamata, l'agente può eseguire strumenti per derivare la risposta finale. Per accedere ai messaggi intermedi generati durante questo processo, i chiamanti possono fornire una funzione di callback che gestisce le istanze di FunctionCallContent
o FunctionResultContent
.
La documentazione per il callback di
ChatCompletionAgent
sarà presto disponibile.
La configurazione del on_intermediate_message
callback all'interno agent.invoke(...)
o agent.invoke_stream(...)
consente al chiamante di ricevere messaggi intermedi generati durante il processo di simulazione della risposta finale dell'agente.
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())
Di seguito viene illustrato l'output di esempio del processo di chiamata dell'agente:
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!
Funzionalità attualmente non disponibile in Java.
Specifica dichiarativa
La documentazione sull'uso delle specifiche dichiarative sarà presto disponibile.
Importante
Questa funzionalità si trova nella fase sperimentale. Le funzionalità in questa fase sono in fase di sviluppo e soggette a cambiamenti prima di passare alla fase di anteprima o alla versione candidata al rilascio.
L'ChatCompletionAgent
può essere istanziato direttamente da una specifica dichiarativa YAML. Questo approccio consente di definire le proprietà principali dell'agente, le istruzioni e le funzioni disponibili (plug-in) in modo strutturato e portabile. Usando YAML è possibile descrivere il nome, la descrizione, la richiesta di istruzioni, il set di strumenti e i parametri del modello dell'agente in un singolo documento, rendendo facilmente controllabile e riproducibile la configurazione dell'agente.
Annotazioni
Tutti gli strumenti o le funzioni specificati nel file YAML dichiarativo devono esistere già nell'istanza del kernel al momento della creazione dell'agente. Il caricatore dell'agente non crea nuove funzioni dalla specifica; cerca invece i plug-in e le funzioni a cui si fa riferimento in base ai relativi identificatori nel kernel. Se un plug-in o una funzione richiesta non è presente nel kernel, durante la costruzione dell'agente verrà generato un errore.
Esempio: Creazione di un oggetto ChatCompletionAgent
da una specifica 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())
Questa funzionalità non è disponibile.
Guida pratica
Per un esempio completo per un ChatCompletionAgent
, consultare:
- Guida pratica :
ChatCompletionAgent