Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
После того как у вас есть несколько подключаемых модулей, вашему AI-агенту потребуется способ их совместного использования для решения задачи пользователя. Вот где вступает планирование.
На ранних этапах семантическое ядро представило концепцию планировщиков, которые использовали подсказки, чтобы попросить ИИ выбрать, какие функции следует вызывать. С тех пор как было введено семантическое ядро, OpenAI, однако, представил собственный способ для модели вызывать или "вызова" функции: вызов функции. Другие модели искусственного интеллекта, такие как Gemini, Claude и Mistral, с тех пор приняли вызов функций в качестве основной функции, что делает её функцией, поддерживаемой различными моделями.
Из-за этих улучшений семантический ядро развивалось, чтобы использовать вызов функции в качестве основного способа планирования и выполнения задач.
Это важно
Вызов функций доступен только в моделях OpenAI версии 0613 или более поздней. Если вы используете старую модель (например, 0314), эта функция вернет ошибку. Мы рекомендуем использовать последние модели OpenAI, чтобы воспользоваться этой функцией.
Как вызов функции создает «план»?
В самом простом случае вызов функции — это всего лишь способ вызвать функцию с правильными параметрами. Например, пользователь хочет включить лампочку. Предположим, у искусственного интеллекта есть правильный плагин, он может вызвать функцию для включения света.
Должность | Сообщение |
---|---|
🔵 пользователя | Включите свет #1 |
🔴 помощник (вызов функции) | Lights.change_state(1, { "isOn": true }) |
🟢 средство | { "id": 1, "name": "Table Lamp", "isOn": true, "brightness": 100, "hex": "FF0000" } |
🔴 помощник | Лампа в настоящее время включена |
Но что делать, если пользователь не знает идентификатор света? Или что делать, если пользователь хочет включить все световые индикаторы? Вот здесь и требуется планирование. Современные модели LLM способны итеративно вызывать функции для решения необходимости пользователя. Это достигается путем создания цикла обратной связи, в котором ИИ может вызывать функцию, проверять результат, а затем решать, что делать дальше.
Например, пользователь может попросить ИИ переключить лампочку. ИИ сначала потребуется проверить состояние лампочки, прежде чем решить, следует ли включить или отключить его.
Должность | Сообщение |
---|---|
🔵 пользователя | Переключите все световые индикаторы |
🔴 помощник (вызов функции) | Lights.get_lights() |
🟢 средство | { "lights": [ { "id": 1, "name": "Table Lamp", "isOn": true, "brightness": 100, "hex": "FF0000" }, { "id": 2, "name": "Ceiling Light", "isOn": false, "brightness": 0, "hex": "FFFFFF" } ] } |
🔴 помощник (вызов функции) |
Lights.change_state(1, { "isOn": false })
Lights.change_state(2, { "isOn": true })
|
🟢 средство | { "id": 1, "name": "Table Lamp", "isOn": false, "brightness": 0, "hex": "FFFFFF" } |
🟢 средство | { "id": 2, "name": "Ceiling Light", "isOn": true, "brightness": 100, "hex": "FF0000" } |
🔴 помощник | Свет был переключлен |
Замечание
В этом примере вы также увидели параллельные вызовы функций. В этом случае ИИ может одновременно вызывать несколько функций. Это мощная функция, которая помогает ИИ решать сложные задачи быстрее. Он был добавлен в модели OpenAI в 1106 году.
Цикл автоматического планирования
Поддержка вызова функций без семантического ядра является относительно сложным. Необходимо написать цикл, который будет выполнять следующие действия:
- Создание схем JSON для каждой функции
- Предоставьте LLM предыдущую историю чата и схемы функций.
- Выполните анализ ответа LLM, чтобы определить, хочет ли он предоставить сообщение или вызвать функцию
- Если LLM хочет вызвать функцию, необходимо проанализировать имя функции и параметры из ответа LLM.
- Вызов функции с правильными параметрами
- Возвращает результаты функции, чтобы LLM смог определить, что он должен делать дальше.
- Повторите шаги 2-6, пока LLM не решит, что она завершит задачу или нуждается в помощи от пользователя
В семантическом ядре мы упрощаем вызов функции, автоматизовав этот цикл для вас. Это позволяет сосредоточиться на создании подключаемых модулей, необходимых для решения потребностей пользователя.
Замечание
Понимание того, как работает цикл вызова функции, необходимо для создания эффективных и надежных агентов ИИ. Подробный обзор работы цикла см. в статье о вызове функции .
Использование автоматического вызова функции
Чтобы использовать автоматический вызов функции в семантической ядре, необходимо выполнить следующее:
- Регистрация подключаемого модуля в ядре
- Создание объекта параметров выполнения, который сообщает ИИ автоматически вызывать функции
- Вызовите службу завершения чата, используя журнал чата и ядро.
Подсказка
В следующем примере кода используется LightsPlugin
, определенный здесь.
using System.ComponentModel;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.OpenAI;
// 1. Create the kernel with the Lights plugin
var builder = Kernel.CreateBuilder().AddAzureOpenAIChatCompletion(modelId, endpoint, apiKey);
builder.Plugins.AddFromType<LightsPlugin>("Lights");
Kernel kernel = builder.Build();
var chatCompletionService = kernel.GetRequiredService<IChatCompletionService>();
// 2. Enable automatic function calling
OpenAIPromptExecutionSettings openAIPromptExecutionSettings = new()
{
FunctionChoiceBehavior = FunctionChoiceBehavior.Auto()
};
var history = new ChatHistory();
string? userInput;
do {
// Collect user input
Console.Write("User > ");
userInput = Console.ReadLine();
// Add user input
history.AddUserMessage(userInput);
// 3. Get the response from the AI with automatic function calling
var result = await chatCompletionService.GetChatMessageContentAsync(
history,
executionSettings: openAIPromptExecutionSettings,
kernel: kernel);
// Print the results
Console.WriteLine("Assistant > " + result);
// Add the message from the agent to the chat history
history.AddMessage(result.Role, result.Content ?? string.Empty);
} while (userInput is not null)
import asyncio
from semantic_kernel import Kernel
from semantic_kernel.connectors.ai import FunctionChoiceBehavior
from semantic_kernel.connectors.ai.chat_completion_client_base import ChatCompletionClientBase
from semantic_kernel.connectors.ai.open_ai import (
AzureChatCompletion,
AzureChatPromptExecutionSettings,
)
from semantic_kernel.contents import ChatHistory
from semantic_kernel.functions import kernel_function
async def main():
# 1. Create the kernel with the Lights plugin
kernel = Kernel()
kernel.add_service(AzureChatCompletion())
kernel.add_plugin(
LightsPlugin(),
plugin_name="Lights",
)
chat_completion: AzureChatCompletion = kernel.get_service(type=ChatCompletionClientBase)
# 2. Enable automatic function calling
execution_settings = AzureChatPromptExecutionSettings()
execution_settings.function_choice_behavior = FunctionChoiceBehavior.Auto()
# Create a history of the conversation
history = ChatHistory()
userInput = None
while True:
# Collect user input
userInput = input("User > ")
# Terminate the loop if the user says "exit"
if userInput == "exit":
break
# Add user input to the history
history.add_user_message(userInput)
# 3. Get the response from the AI with automatic function calling
result = await chat_completion.get_chat_message_content(
chat_history=history,
settings=execution_settings,
kernel=kernel,
)
# Print the results
print("Assistant > " + str(result))
# Add the message from the agent to the chat history
history.add_message(result)
# Run the main function
if __name__ == "__main__":
asyncio.run(main())
OpenAIAsyncClient client = new OpenAIClientBuilder()
.credential(new AzureKeyCredential(AZURE_CLIENT_KEY))
.endpoint(CLIENT_ENDPOINT)
.buildAsyncClient();
// Import the LightsPlugin
KernelPlugin lightPlugin = KernelPluginFactory.createFromObject(new LightsPlugin(),
"LightsPlugin");
// Create your AI service client
ChatCompletionService chatCompletionService = OpenAIChatCompletion.builder()
.withModelId(MODEL_ID)
.withOpenAIAsyncClient(client)
.build();
// Create a kernel with Azure OpenAI chat completion and plugin
Kernel kernel = Kernel.builder()
.withAIService(ChatCompletionService.class, chatCompletionService)
.withPlugin(lightPlugin)
.build();
// Add a converter to the kernel to show it how to serialise LightModel objects into a prompt
ContextVariableTypes
.addGlobalConverter(
ContextVariableTypeConverter.builder(LightModel.class)
.toPromptString(new Gson()::toJson)
.build());
// Enable planning
InvocationContext invocationContext = new InvocationContext.Builder()
.withReturnMode(InvocationReturnMode.LAST_MESSAGE_ONLY)
.withToolCallBehavior(ToolCallBehavior.allowAllKernelFunctions(true))
.build();
// Create a history to store the conversation
ChatHistory history = new ChatHistory();
// Initiate a back-and-forth chat
Scanner scanner = new Scanner(System.in);
String userInput;
do {
// Collect user input
System.out.print("User > ");
userInput = scanner.nextLine();
// Add user input
history.addUserMessage(userInput);
// Prompt AI for response to users input
List<ChatMessageContent<?>> results = chatCompletionService
.getChatMessageContentsAsync(history, kernel, invocationContext)
.block();
for (ChatMessageContent<?> result : results) {
// Print the results
if (result.getAuthorRole() == AuthorRole.ASSISTANT && result.getContent() != null) {
System.out.println("Assistant > " + result);
}
// Add the message from the agent to the chat history
history.addMessage(result);
}
} while (userInput != null && !userInput.isEmpty());
При использовании автоматического вызова функции все шаги в цикле автоматического планирования обрабатываются для вас и добавляются в ChatHistory
объект. После завершения цикла вызова функции можно проверить ChatHistory
объект, чтобы просмотреть все вызовы функций и результаты, предоставляемые семантическим ядром.
Что случилось с планировщиками Stepwise и Handlebars?
Планировщики stepwise и Handlebars устарели и удалены из пакета семантического ядра. Эти планировщики больше не поддерживаются в Python, .NET или Java.
Мы рекомендуем использовать вызов функции, который является более мощным и удобным для большинства сценариев.
Чтобы обновить существующие решения, следуйте нашему руководству по пошаговой миграции планировщика.
Подсказка
Для новых агентов ИИ используйте вызов функции вместо устаревших планировщиков. Он обеспечивает более высокую гибкость, поддержку встроенных средств и более простой возможности разработки.
Дальнейшие шаги
Теперь, когда вы понимаете, как планировщики работают в семантическом ядре, вы можете узнать больше о том, как повлиять на агент ИИ, чтобы они могли лучше планировать и выполнять задачи от имени пользователей.