Что такое планировщик?
После того как у вас есть несколько подключаемых модулей, вам потребуется способ их совместного использования для решения необходимости пользователя. Вот где планируется.
На ранних этапах семантический ядро представило концепцию планировщиков, которые использовали запрос на запрос искусственного интеллекта, чтобы выбрать, какие функции следует вызывать. Поскольку семантический ядро было введено, однако 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 не решит, что она завершит задачу или нуждается в помощи от пользователя
В семантическом ядре мы упрощаем вызов функции, автоматизовав этот цикл для вас. Это позволяет сосредоточиться на создании подключаемых модулей, необходимых для решения потребностей пользователя.
Примечание.
Понимание того, как работает цикл вызова функции, является важным для создания выполняемых и надежных агентов ИИ. Подробный обзор работы цикла см. в статье о вызове функции.
Использование автоматического вызова функции
Чтобы использовать автоматический вызов функции в семантической ядре, необходимо выполнить следующее:
- Регистрация подключаемого модуля в ядре
- Создание объекта параметров выполнения, который сообщает ИИ автоматически вызывать функции
- Вызов службы завершения чата с журналом чата и ядром
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.functions import kernel_function
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion
from semantic_kernel.connectors.ai.function_choice_behavior import FunctionChoiceBehavior
from semantic_kernel.connectors.ai.chat_completion_client_base import ChatCompletionClientBase
from semantic_kernel.contents.chat_history import ChatHistory
from semantic_kernel.functions.kernel_arguments import KernelArguments
from semantic_kernel.connectors.ai.open_ai.prompt_execution_settings.azure_chat_prompt_execution_settings import (
AzureChatPromptExecutionSettings,
)
async def main():
# 1. Create the kernel with the Lights plugin
kernel = Kernel()
kernel.add_service(AzureChatCompletion(
deployment_name="your_models_deployment_name",
api_key="your_api_key",
base_url="your_base_url",
))
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_call_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_contents(
chat_history=history,
settings=execution_settings,
kernel=kernel,
arguments=KernelArguments(),
))[0]
# 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. Вместо этого используйте вызов функции, так как он более мощный и удобный для использования.
Следующие шаги
Теперь, когда вы понимаете, как планировщики работают в семантическом ядре, вы можете узнать больше о том, как повлиять на агент ИИ, чтобы они могли лучше планировать и выполнять задачи от имени пользователей.