Как сделать: Агент завершения чата
Предупреждение
Платформа агента семантического ядра находится в предварительной версии и подлежит изменению.
Обзор
В этом примере мы рассмотрим настройку подключаемого модуля для доступа к API GitHub и предоставим шаблонные инструкции агенту завершения чата, чтобы ответить на вопросы о репозитории GitHub. Этот подход будет разбит на шаге, чтобы обеспечить высокий уровень освещения ключевых частей процесса программирования. В рамках задачи агент предоставит ссылки на документы в ответе.
Потоковая передача будет использоваться для доставки ответов агента. Это обеспечит обновления в режиме реального времени по мере выполнения задачи.
Начало работы
Прежде чем продолжить программирование компонентов, убедитесь, что среда разработки полностью настроена и настроена.
Начните с создания проекта консоли . Затем включите следующие ссылки на пакеты, чтобы убедиться, что доступны все необходимые зависимости.
Чтобы добавить зависимости пакета из командной строки, используйте dotnet
команду:
dotnet add package Azure.Identity
dotnet add package Microsoft.Extensions.Configuration
dotnet add package Microsoft.Extensions.Configuration.Binder
dotnet add package Microsoft.Extensions.Configuration.UserSecrets
dotnet add package Microsoft.Extensions.Configuration.EnvironmentVariables
dotnet add package Microsoft.SemanticKernel.Connectors.AzureOpenAI
dotnet add package Microsoft.SemanticKernel.Agents.Core --prerelease
При управлении пакетами NuGet в Visual Studio убедитесь, что
Include prerelease
установлен флажок.
Файл проекта (.csproj
) должен содержать следующие PackageReference
определения:
<ItemGroup>
<PackageReference Include="Azure.Identity" Version="<stable>" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="<stable>" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="<stable>" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="<stable>" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="<stable>" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Core" Version="<latest>" />
<PackageReference Include="Microsoft.SemanticKernel.Connectors.AzureOpenAI" Version="<latest>" />
</ItemGroup>
Платформа агента является экспериментальной и требует подавления предупреждений. Это может быть устранено в виде свойства в файле проекта (.csproj
):
<PropertyGroup>
<NoWarn>$(NoWarn);CA2007;IDE1006;SKEXP0001;SKEXP0110;OPENAI001</NoWarn>
</PropertyGroup>
Кроме того, скопируйте подключаемый модуль GitHub и модели (GitHubPlugin.cs
и) изGitHubModels.cs
семантического ядраLearnResources
. Добавьте эти файлы в папку проекта.
Начните с создания папки, в которую будут храниться скрипт (.py
файл) и примеры ресурсов. Включите следующие импорты в верхней части .py
файла:
import asyncio
import os
import sys
from datetime import datetime
from semantic_kernel.agents import ChatCompletionAgent
from semantic_kernel.connectors.ai.function_choice_behavior import FunctionChoiceBehavior
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion
from semantic_kernel.contents.chat_history import ChatHistory
from semantic_kernel.contents.chat_message_content import ChatMessageContent
from semantic_kernel.contents.utils.author_role import AuthorRole
from semantic_kernel.kernel import Kernel
from semantic_kernel.functions.kernel_arguments import KernelArguments
# Adjust the sys.path so we can use the GitHubPlugin and GitHubSettings classes
# This is so we can run the code from the samples/learn_resources/agent_docs directory
# If you are running code from your own project, you may not need need to do this.
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
from plugins.GithubPlugin.github import GitHubPlugin, GitHubSettings # noqa: E402
Кроме того, скопируйте подключаемый модуль GitHub и модели (github.py
) из LearnResources
. Добавьте эти файлы в папку проекта.
Агенты в настоящее время недоступны в Java.
Настройка
Этот пример требует настройки для подключения к удаленным службам. Вам потребуется определить параметры для Open AI или Azure Open AI , а также для GitHub.
Примечание. Сведения о Личных маркерах доступа GitHub см. в статье "Управление личными маркерами доступа".
# Open AI
dotnet user-secrets set "OpenAISettings:ApiKey" "<api-key>"
dotnet user-secrets set "OpenAISettings:ChatModel" "gpt-4o"
# Azure Open AI
dotnet user-secrets set "AzureOpenAISettings:ApiKey" "<api-key>" # Not required if using token-credential
dotnet user-secrets set "AzureOpenAISettings:Endpoint" "<model-endpoint>"
dotnet user-secrets set "AzureOpenAISettings:ChatModelDeployment" "gpt-4o"
# GitHub
dotnet user-secrets set "GitHubSettings:BaseUrl" "https://api.github.com"
dotnet user-secrets set "GitHubSettings:Token" "<personal access token>"
Следующий класс используется во всех примерах агента. Не забудьте включить его в проект, чтобы обеспечить правильную функциональность. Этот класс служит базовым компонентом для приведенных ниже примеров.
using System.Reflection;
using Microsoft.Extensions.Configuration;
namespace AgentsSample;
public class Settings
{
private readonly IConfigurationRoot configRoot;
private AzureOpenAISettings azureOpenAI;
private OpenAISettings openAI;
public AzureOpenAISettings AzureOpenAI => this.azureOpenAI ??= this.GetSettings<Settings.AzureOpenAISettings>();
public OpenAISettings OpenAI => this.openAI ??= this.GetSettings<Settings.OpenAISettings>();
public class OpenAISettings
{
public string ChatModel { get; set; } = string.Empty;
public string ApiKey { get; set; } = string.Empty;
}
public class AzureOpenAISettings
{
public string ChatModelDeployment { get; set; } = string.Empty;
public string Endpoint { get; set; } = string.Empty;
public string ApiKey { get; set; } = string.Empty;
}
public TSettings GetSettings<TSettings>() =>
this.configRoot.GetRequiredSection(typeof(TSettings).Name).Get<TSettings>()!;
public Settings()
{
this.configRoot =
new ConfigurationBuilder()
.AddEnvironmentVariables()
.AddUserSecrets(Assembly.GetExecutingAssembly(), optional: true)
.Build();
}
}
Самый быстрый способ начать работу с правильной конфигурацией для запуска примера кода — создать .env
файл в корне проекта (где выполняется скрипт).
Настройте следующие параметры в .env
файле для Azure OpenAI или OpenAI:
AZURE_OPENAI_API_KEY="..."
AZURE_OPENAI_ENDPOINT="https://..."
AZURE_OPENAI_CHAT_DEPLOYMENT_NAME="..."
AZURE_OPENAI_API_VERSION="..."
OPENAI_API_KEY="sk-..."
OPENAI_ORG_ID=""
OPENAI_CHAT_MODEL_ID=""
После настройки соответствующие классы служб ИИ будут собирать необходимые переменные и использовать их во время создания экземпляра.
Агенты в настоящее время недоступны в Java.
Написание кода
Процесс написания кода для этого примера включает в себя:
- Настройка — инициализация параметров и подключаемый модуль.
- Определение агента. Создание агента завершения чата с шаблонными инструкциями и подключаемым модулем.
- Цикл чата — запись цикла , который управляет взаимодействием пользователя или агента.
Полный пример кода представлен в заключительном разделе. См. этот раздел для полной реализации.
Настройка
Перед созданием агента завершения чата параметры конфигурации, подключаемые модули и ядро должны быть инициализированы.
Инициализировать класс, на который ссылается предыдущий Settings
раздел конфигурации .
Settings settings = new();
Агенты в настоящее время недоступны в Java.
Инициализировать подключаемый модуль с помощью его параметров.
Здесь отображается сообщение, указывающее ход выполнения.
Console.WriteLine("Initialize plugins...");
GitHubSettings githubSettings = settings.GetSettings<GitHubSettings>();
GitHubPlugin githubPlugin = new(githubSettings);
gh_settings = GitHubSettings(
token="<PAT value>"
)
kernel.add_plugin(GitHubPlugin(settings=gh_settings), plugin_name="github")
Агенты в настоящее время недоступны в Java.
Теперь инициализируйте Kernel
экземпляр с помощью созданного IChatCompletionService
ранее экземпляра GitHubPlugin
.
Console.WriteLine("Creating kernel...");
IKernelBuilder builder = Kernel.CreateBuilder();
builder.AddAzureOpenAIChatCompletion(
settings.AzureOpenAI.ChatModelDeployment,
settings.AzureOpenAI.Endpoint,
new AzureCliCredential());
builder.Plugins.AddFromObject(githubPlugin);
Kernel kernel = builder.Build();
kernel = Kernel()
# Add the AzureChatCompletion AI Service to the Kernel
service_id = "agent"
kernel.add_service(AzureChatCompletion(service_id=service_id))
settings = kernel.get_prompt_execution_settings_from_service_id(service_id=service_id)
# Configure the function choice behavior to auto invoke kernel functions
settings.function_choice_behavior = FunctionChoiceBehavior.Auto()
Агенты в настоящее время недоступны в Java.
Определение агента
Наконец, мы готовы создать экземпляр агента завершения чата со своими инструкциями, связанным ядром и параметрами выполнения по умолчанию. В этом случае мы хотим автоматически выполнять все функции подключаемого модуля.
Console.WriteLine("Defining agent...");
ChatCompletionAgent agent =
new()
{
Name = "SampleAssistantAgent",
Instructions =
"""
You are an agent designed to query and retrieve information from a single GitHub repository in a read-only manner.
You are also able to access the profile of the active user.
Use the current date and time to provide up-to-date details or time-sensitive responses.
The repository you are querying is a public repository with the following name: {{$repository}}
The current date and time is: {{$now}}.
""",
Kernel = kernel,
Arguments =
new KernelArguments(new AzureOpenAIPromptExecutionSettings() { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto() })
{
{ "repository", "microsoft/semantic-kernel" }
}
};
Console.WriteLine("Ready!");
agent = ChatCompletionAgent(
service_id="agent",
kernel=kernel,
name="SampleAssistantAgent",
instructions=f"""
You are an agent designed to query and retrieve information from a single GitHub repository in a read-only
manner.
You are also able to access the profile of the active user.
Use the current date and time to provide up-to-date details or time-sensitive responses.
The repository you are querying is a public repository with the following name: microsoft/semantic-kernel
The current date and time is: {{$now}}.
""",
arguments=KernelArguments(
settings=AzureAIPromptExecutionSettings(function_choice_behavior=FunctionChoiceBehavior.Auto()),
repository="microsoft/semantic-kernel",
),
)
Агенты в настоящее время недоступны в Java.
Цикл чата
Наконец, мы можем координировать взаимодействие между пользователем и агентом. Начните с создания объекта журнала чата для поддержания состояния беседы и создания пустого цикла.
ChatHistory history = [];
bool isComplete = false;
do
{
// processing logic here
} while (!isComplete);
history = ChatHistory()
is_complete: bool = False
while not is_complete:
# processing logic here
Агенты в настоящее время недоступны в Java.
Теперь давайте зафиксируем входные данные пользователя в предыдущем цикле. В этом случае пустые входные данные будут игнорироваться, и термин EXIT
будет сигнализировать о завершении беседы. Допустимые входные данные будут добавлены в журнал чата в виде сообщения пользователя.
Console.WriteLine();
Console.Write("> ");
string input = Console.ReadLine();
if (string.IsNullOrWhiteSpace(input))
{
continue;
}
if (input.Trim().Equals("EXIT", StringComparison.OrdinalIgnoreCase))
{
isComplete = true;
break;
}
history.Add(new ChatMessageContent(AuthorRole.User, input));
Console.WriteLine();
user_input = input("User:> ")
if not user_input:
continue
if user_input.lower() == "exit":
is_complete = True
break
history.add_message(ChatMessageContent(role=AuthorRole.USER, content=user_input))
Агенты в настоящее время недоступны в Java.
Чтобы создать ответ агента на входные данные пользователя, вызовите агент с помощью аргументов , чтобы предоставить окончательный параметр шаблона, указывающий текущую дату и время.
Затем ответ агента отображается пользователю.
DateTime now = DateTime.Now;
KernelArguments arguments =
new()
{
{ "now", $"{now.ToShortDateString()} {now.ToShortTimeString()}" }
};
await foreach (ChatMessageContent response in agent.InvokeAsync(history, arguments))
{
Console.WriteLine($"{response.Content}");
}
from datetime import datetime
arguments = KernelArguments(
now=datetime.now().strftime("%Y-%m-%d %H:%M")
)
async for response in agent.invoke(history, arguments):
print(f"{response.content}")
Агенты в настоящее время недоступны в Java.
Завершение
В этом примере приведен окончательный код для всех шагов. Полная реализация представлена ниже.
Попробуйте использовать эти предлагаемые входные данные:
- Что такое имя пользователя?
- Опишите репозиторий.
- Опишите новую проблему, созданную в репозитории.
- Перечислить первые 10 проблем, закрытых в течение последней недели.
- Как были помечены эти проблемы?
- Список последних открытых проблем с меткой "Агенты"
using System;
using System.Threading.Tasks;
using Azure.Identity;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.AzureOpenAI;
using Plugins;
namespace AgentsSample;
public static class Program
{
public static async Task Main()
{
// Load configuration from environment variables or user secrets.
Settings settings = new();
Console.WriteLine("Initialize plugins...");
GitHubSettings githubSettings = settings.GetSettings<GitHubSettings>();
GitHubPlugin githubPlugin = new(githubSettings);
Console.WriteLine("Creating kernel...");
IKernelBuilder builder = Kernel.CreateBuilder();
builder.AddAzureOpenAIChatCompletion(
settings.AzureOpenAI.ChatModelDeployment,
settings.AzureOpenAI.Endpoint,
new AzureCliCredential());
builder.Plugins.AddFromObject(githubPlugin);
Kernel kernel = builder.Build();
Console.WriteLine("Defining agent...");
ChatCompletionAgent agent =
new()
{
Name = "SampleAssistantAgent",
Instructions =
"""
You are an agent designed to query and retrieve information from a single GitHub repository in a read-only manner.
You are also able to access the profile of the active user.
Use the current date and time to provide up-to-date details or time-sensitive responses.
The repository you are querying is a public repository with the following name: {{$repository}}
The current date and time is: {{$now}}.
""",
Kernel = kernel,
Arguments =
new KernelArguments(new AzureOpenAIPromptExecutionSettings() { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto() })
{
{ "repository", "microsoft/semantic-kernel" }
}
};
Console.WriteLine("Ready!");
ChatHistory history = [];
bool isComplete = false;
do
{
Console.WriteLine();
Console.Write("> ");
string input = Console.ReadLine();
if (string.IsNullOrWhiteSpace(input))
{
continue;
}
if (input.Trim().Equals("EXIT", StringComparison.OrdinalIgnoreCase))
{
isComplete = true;
break;
}
history.Add(new ChatMessageContent(AuthorRole.User, input));
Console.WriteLine();
DateTime now = DateTime.Now;
KernelArguments arguments =
new()
{
{ "now", $"{now.ToShortDateString()} {now.ToShortTimeString()}" }
};
await foreach (ChatMessageContent response in agent.InvokeAsync(history, arguments))
{
// Display response.
Console.WriteLine($"{response.Content}");
}
} while (!isComplete);
}
}
import asyncio
import os
import sys
from datetime import datetime
from semantic_kernel.agents import ChatCompletionAgent
from semantic_kernel.connectors.ai.function_choice_behavior import FunctionChoiceBehavior
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion
from semantic_kernel.contents.chat_history import ChatHistory
from semantic_kernel.contents.chat_message_content import ChatMessageContent
from semantic_kernel.contents.utils.author_role import AuthorRole
from semantic_kernel.functions.kernel_arguments import KernelArguments
from semantic_kernel.kernel import Kernel
# Adjust the sys.path so we can use the GitHubPlugin and GitHubSettings classes
# This is so we can run the code from the samples/learn_resources/agent_docs directory
# If you are running code from your own project, you may not need need to do this.
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
from plugins.GithubPlugin.github import GitHubPlugin, GitHubSettings # noqa: E402
###################################################################
# The following sample demonstrates how to create a simple, #
# ChatCompletionAgent to use a GitHub plugin to interact #
# with the GitHub API. #
###################################################################
async def main():
kernel = Kernel()
# Add the AzureChatCompletion AI Service to the Kernel
service_id = "agent"
kernel.add_service(AzureChatCompletion(service_id=service_id))
settings = kernel.get_prompt_execution_settings_from_service_id(service_id=service_id)
# Configure the function choice behavior to auto invoke kernel functions
settings.function_choice_behavior = FunctionChoiceBehavior.Auto()
# Set your GitHub Personal Access Token (PAT) value here
gh_settings = GitHubSettings(token="<PAT value>")
kernel.add_plugin(plugin=GitHubPlugin(gh_settings), plugin_name="GithubPlugin")
# Create the agent
agent = ChatCompletionAgent(
service_id="agent",
kernel=kernel,
name="SampleAssistantAgent",
instructions=f"""
You are an agent designed to query and retrieve information from a single GitHub repository in a read-only
manner.
You are also able to access the profile of the active user.
Use the current date and time to provide up-to-date details or time-sensitive responses.
The repository you are querying is a public repository with the following name: microsoft/semantic-kernel
The current date and time is: {{$now}}.
""",
arguments=KernelArguments(settings=settings),
)
history = ChatHistory()
is_complete: bool = False
while not is_complete:
user_input = input("User:> ")
if not user_input:
continue
if user_input.lower() == "exit":
is_complete = True
break
history.add_message(ChatMessageContent(role=AuthorRole.USER, content=user_input))
arguments = KernelArguments(
now=datetime.now().strftime("%Y-%m-%d %H:%M")
)
async for response in agent.invoke(history=history, arguments):
print(f"{response.content}")
if __name__ == "__main__":
asyncio.run(main())
Агенты в настоящее время недоступны в Java.