Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Importante
Esse recurso está em estágio experimental. Os recursos estão em fase de desenvolvimento ativo e podem mudar significativamente antes de avançar para o estágio de pré-visualização ou de candidato a lançamento.
Visão geral
A Seleção de Função Contextual é uma funcionalidade avançada no Framework de Agentes de Kernel Semântico que permite que os agentes selecionem e anunciem dinamicamente apenas as funções mais relevantes com base no contexto atual da conversa. Em vez de expor todas as funções disponíveis ao modelo de IA, esse recurso usa Retrieval-Augmented Geração (RAG) para filtrar e apresentar apenas essas funções mais pertinentes à solicitação do usuário.
Essa abordagem aborda o desafio da seleção de função ao lidar com um grande número de funções disponíveis, em que os modelos de IA podem ter dificuldades para escolher a função apropriada, levando a confusão e desempenho abaixo do ideal.
Como funciona a seleção de função contextual
Quando um agente é configurado com a seleção de função contextual, ele aproveita um repositório de vetores e um gerador de inserção para corresponder semanticamente ao contexto de conversa atual (incluindo mensagens anteriores e entrada do usuário) com as descrições e nomes de funções disponíveis. As funções mais relevantes, até o limite especificado, são anunciadas para o modelo de IA para invocação.
Esse mecanismo é especialmente útil para agentes que têm acesso a um amplo conjunto de plug-ins ou ferramentas, garantindo que apenas ações contextualmente apropriadas sejam consideradas em cada etapa.
Exemplo de uso
O exemplo a seguir demonstra como um agente pode ser configurado para usar a seleção de função contextual. O agente é configurado para resumir as revisões do cliente, mas apenas as funções mais relevantes são anunciadas para o modelo de IA para cada invocação. O GetAvailableFunctions
método inclui intencionalmente funções relevantes e irrelevantes para realçar os benefícios da seleção contextual.
// Create an embedding generator for function vectorization
var embeddingGenerator = new AzureOpenAIClient(new Uri("<endpoint>"), new ApiKeyCredential("<api-key>"))
.GetEmbeddingClient("<deployment-name>")
.AsIEmbeddingGenerator();
// Create kernel and register AzureOpenAI chat completion service
var kernel = Kernel.CreateBuilder()
.AddAzureOpenAIChatCompletion("<deployment-name>", "<endpoint>", "<api-key>");
.Build();
// Create a chat completion agent
ChatCompletionAgent agent = new()
{
Name = "ReviewGuru",
Instructions = "You are a friendly assistant that summarizes key points and sentiments from customer reviews. For each response, list available functions.",
Kernel = kernel,
Arguments = new(new PromptExecutionSettings { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto(options: new FunctionChoiceBehaviorOptions { RetainArgumentTypes = true }) })
};
// Create the agent thread and register the contextual function provider
ChatHistoryAgentThread agentThread = new();
agentThread.AIContextProviders.Add(
new ContextualFunctionProvider(
vectorStore: new InMemoryVectorStore(new InMemoryVectorStoreOptions() { EmbeddingGenerator = embeddingGenerator }),
vectorDimensions: 1536,
functions: AvailableFunctions(),
maxNumberOfFunctions: 3, // Only the top 3 relevant functions are advertised
loggerFactory: LoggerFactory
)
);
// Invoke the agent
ChatMessageContent message = await agent.InvokeAsync("Get and summarize customer review.", agentThread).FirstAsync();
Console.WriteLine(message.Content);
// Output
/*
Customer Reviews:
-----------------
1. John D. - ★★★★★
Comment: Great product and fast shipping!
Date: 2023-10-01
Summary:
--------
The reviews indicate high customer satisfaction,
highlighting product quality and shipping speed.
Available functions:
--------------------
- Tools-GetCustomerReviews
- Tools-Summarize
- Tools-CollectSentiments
*/
IReadOnlyList<AIFunction> GetAvailableFunctions()
{
// Only a few functions are directly related to the prompt; the majority are unrelated to demonstrate the benefits of contextual filtering.
return new List<AIFunction>
{
// Relevant functions
AIFunctionFactory.Create(() => "[ { 'reviewer': 'John D.', 'date': '2023-10-01', 'rating': 5, 'comment': 'Great product and fast shipping!' } ]", "GetCustomerReviews"),
AIFunctionFactory.Create((string text) => "Summary generated based on input data: key points include customer satisfaction.", "Summarize"),
AIFunctionFactory.Create((string text) => "The collected sentiment is mostly positive.", "CollectSentiments"),
// Irrelevant functions
AIFunctionFactory.Create(() => "Current weather is sunny.", "GetWeather"),
AIFunctionFactory.Create(() => "Email sent.", "SendEmail"),
AIFunctionFactory.Create(() => "The current stock price is $123.45.", "GetStockPrice"),
AIFunctionFactory.Create(() => "The time is 12:00 PM.", "GetCurrentTime")
};
}
Armazenamento Vetorial
O provedor foi projetado principalmente para trabalhar com repositórios de vetores na memória, que oferecem simplicidade. No entanto, se outros tipos de repositórios de vetores forem usados, é importante observar que a responsabilidade de lidar com a sincronização e consistência de dados recai sobre o aplicativo de hospedagem.
A sincronização é necessária sempre que a lista de funções é alterada ou quando a origem das inserções de função é modificada. Por exemplo, se um agente tiver inicialmente três funções (f1, f2, f3) vetorizadas e armazenadas em um repositório de vetores de nuvem e, posteriormente, f3 for removida da lista de funções do agente, o repositório de vetores deverá ser atualizado para refletir apenas as funções atuais que o agente tem (f1 e f2). A falha ao atualizar o repositório de vetores pode resultar em funções irrelevantes retornadas como resultados. Da mesma forma, se os dados usados para vetorização, como nomes de função, descrições etc. forem alterados, o repositório de vetores deverá ser limpo e repovoado com novas inserções com base nas informações atualizadas.
O gerenciamento da sincronização de dados em repositórios de vetores externos ou distribuídos pode ser complexo e propenso a erros, especialmente em aplicativos distribuídos em que diferentes serviços ou instâncias podem operar de forma independente e exigir acesso consistente aos mesmos dados. Por outro lado, o uso de um repositório na memória simplifica esse processo: quando a lista de funções ou a fonte de vetorização é alterada, o repositório na memória pode ser facilmente recriado com o novo conjunto de funções e suas inserções, garantindo consistência com esforço mínimo.
Especificando funções
O provedor de funções contextuais deve ser fornecido com uma lista de funções das quais pode selecionar as mais relevantes com base no contexto atual. Isso é feito fornecendo uma lista de funções para o functions
parâmetro do ContextualFunctionProvider
construtor.
Além das funções, você também deve especificar o número máximo de funções relevantes a serem retornadas usando o maxNumberOfFunctions
parâmetro.
Esse parâmetro determina quantas funções o provedor considerará ao selecionar as mais relevantes para o contexto atual.
O número especificado não deve ser preciso; em vez disso, ele serve como um limite superior que depende do cenário específico.
Definir esse valor muito baixo pode impedir que o agente acesse todas as funções necessárias para um cenário, potencialmente levando à falha do cenário. Por outro lado, defini-lo muito alto pode sobrecarregar o agente com muitas funções, o que pode resultar em alucinações, consumo excessivo de token de entrada e desempenho abaixo do ideal.
// Create the provider with a list of functions and a maximum number of functions to return
ContextualFunctionProvider provider = new (
vectorStore: new InMemoryVectorStore(new InMemoryVectorStoreOptions { EmbeddingGenerator = embeddingGenerator }),
vectorDimensions: 1536,
functions: [AIFunctionFactory.Create((string text) => $"Echo: {text}", "Echo"), <other functions>]
maxNumberOfFunctions: 3 // Only the top 3 relevant functions are advertised
);
Opções de provedor de funções contextuais
O provedor pode ser configurado usando a classe, o ContextualFunctionProviderOptions
que permite personalizar vários aspectos de como o provedor opera:
// Create options for the contextual function provider
ContextualFunctionProviderOptions options = new ()
{
...
};
// Create the provider with options
ContextualFunctionProvider provider = new (
...
options: options // Pass the options
);
Tamanho do contexto
O tamanho do contexto determina quantas mensagens recentes de invocações de agente anteriores são incluídas ao formar o contexto para uma nova invocação. O provedor coleta todas as mensagens de invocações anteriores, até o número especificado e as prepara para as novas mensagens para formar o contexto.
Usar mensagens recentes junto com novas mensagens é especialmente útil para tarefas que exigem informações de etapas anteriores em uma conversa. Por exemplo, se um agente provisionar um recurso em uma invocação e implantá-lo na próxima, a etapa de implantação poderá acessar detalhes da etapa de provisionamento para obter informações de recursos provisionadas para a implantação.
O valor padrão para o número de mensagens recentes no contexto é 2, mas isso pode ser configurado conforme necessário especificando a NumberOfRecentMessagesInContext
propriedade no ContextualFunctionProviderOptions
:
ContextualFunctionProviderOptions options = new ()
{
NumberOfRecentMessagesInContext = 1 // Only the last message will be included in the context
};
Valor de origem da inserção de contexto
Para executar a seleção de função contextual, o provedor precisa vetorizar o contexto atual para que ele possa ser comparado com as funções disponíveis no repositório de vetores. Por padrão, o provedor cria essa inserção de contexto concatenando todas as mensagens recentes e novas não vazias em uma única cadeia de caracteres, que é então vetorizada e usada para pesquisar funções relevantes.
Em alguns cenários, talvez você queira personalizar esse comportamento para:
- Concentre-se em tipos de mensagem específicos (por exemplo, somente mensagens de usuário)
- Excluir determinadas informações do contexto
- Pré-processar ou resumir o contexto antes da vetorização (por exemplo, reescrever o prompt)
Para fazer isso, você pode atribuir um delegado personalizado a ContextEmbeddingValueProvider
. Esse delegado recebe as mensagens recentes e novas e retorna um valor de cadeia de caracteres a ser usado como uma fonte para a inserção de contexto:
ContextualFunctionProviderOptions options = new()
{
ContextEmbeddingValueProvider = async (recentMessages, newMessages, cancellationToken) =>
{
// Example: Only include user messages in the embedding
var allUserMessages = recentMessages.Concat(newMessages)
.Where(m => m.Role == "user")
.Select(m => m.Content)
.Where(content => !string.IsNullOrWhiteSpace(content));
return string.Join("\n", allUserMessages);
}
};
Personalizar a inserção de contexto pode melhorar a relevância da seleção de função, especialmente em cenários de agente complexos ou altamente especializados.
Valor da origem da inserção de função
O provedor precisa vetorizar cada função disponível para compará-la com o contexto e selecionar as mais relevantes. Por padrão, o provedor cria uma inserção de função concatenando o nome e a descrição da função em uma única cadeia de caracteres, que é então vetorizada e armazenada no repositório de vetores.
Você pode personalizar esse comportamento usando a EmbeddingValueProvider
propriedade de ContextualFunctionProviderOptions
. Essa propriedade permite que você especifique um retorno de chamada que recebe a função e um token de cancelamento e retorna uma cadeia de caracteres a ser usada como a origem da inserção de função. Isso é útil se você quiser:
- Adicionar metadados de função adicionais à fonte de inserção
- Pré-processar, filtrar ou reformatar as informações da função antes da vetorização
ContextualFunctionProviderOptions options = new()
{
EmbeddingValueProvider = async (function, cancellationToken) =>
{
// Example: Use only the function name for embedding
return function.Name;
}
};
Personalizar o valor de origem da inserção de função pode melhorar a precisão da seleção de função, especialmente quando suas funções têm metadados avançados e relevantes para contexto ou quando você deseja concentrar a pesquisa em aspectos específicos de cada função.
Próximas etapas
Em breve
Mais informações em breve.
Em breve
Mais informações em breve.