Поделиться через


Изучение семантического ядра OpenAIAssistantAgent

Это важно

Функции одного агента, такие как OpenAIAssistantAgent, находятся на стадии релиз-кандидата. Эти функции почти полностью и обычно стабильны, хотя они могут пройти незначительные уточнения или оптимизации, прежде чем достичь полной общедоступной доступности.

Подсказка

Подробная документация по API, связанная с этим обсуждением, доступна по адресу:

Подсказка

Подробная документация по API, связанная с этим обсуждением, доступна по адресу:

Функция в настоящее время недоступна в Java.

Что такое помощник?

API OpenAI Assistants — это специализированный интерфейс, предназначенный для более сложных и интерактивных возможностей ИИ, что позволяет разработчикам создавать персонализированные и многофакторные агенты, ориентированные на задачи. В отличие от API чат-сессии, который направлен на простые разговорные обмены, API помощника обеспечивает динамичные, целенаправленные взаимодействия с дополнительными функциями, такими как интерпретатор кода и поиск файлов.

Подготовка среды разработки

Чтобы продолжить разработку OpenAIAssistantAgent, настройте среду разработки с соответствующими пакетами.

Добавьте пакет Microsoft.SemanticKernel.Agents.OpenAI в проект:

dotnet add package Microsoft.SemanticKernel.Agents.OpenAI --prerelease

Также может потребоваться включить пакет Azure.Identity:

dotnet add package Azure.Identity

Установите пакет semantic-kernel.

pip install semantic-kernel

Функция в настоящее время недоступна в Java.

Создание объекта OpenAIAssistantAgent

Чтобы создать OpenAIAssistant, необходимо сначала создать клиента, чтобы иметь возможность общаться с удаленной службой.

AssistantClient client = OpenAIAssistantAgent.CreateAzureOpenAIClient(...).GetAssistantClient();
Assistant assistant =
    await client.CreateAssistantAsync(
        "<model name>",
        "<agent name>",
        instructions: "<agent instructions>");
OpenAIAssistantAgent agent = new(assistant, client);
from semantic_kernel.agents import AssistantAgentThread, AzureAssistantAgent, OpenAIAssistantAgent
from semantic_kernel.connectors.ai.open_ai import AzureOpenAISettings, OpenAISettings

# Set up the client and model using Azure OpenAI Resources
client = AzureAssistantAgent.create_client()

# Define the assistant definition
definition = await client.beta.assistants.create(
    model=AzureOpenAISettings().chat_deployment_name,
    instructions="<instructions>",
    name="<agent name>",
)

# Create the AzureAssistantAgent instance using the client and the assistant definition
agent = AzureAssistantAgent(
    client=client,
    definition=definition,
)

# or

# Set up the client and model using OpenAI Resources
client = OpenAIAssistantAgent.create_client()

# Define the assistant definition
definition = await client.beta.assistants.create(
    model=OpenAISettings().chat_model_id,
    instructions="<instructions>",
    name="<agent name>",
)

# Create the OpenAIAssistantAgent instance using the client and the assistant definition
agent = OpenAIAssistantAgent(
    client=client,
    definition=definition,
)

Функция в настоящее время недоступна в Java.

Получение объекта OpenAIAssistantAgent

После создания к помощнику можно получить доступ с помощью его идентификатора. Этот идентификатор можно использовать для создания OpenAIAssistantAgent из существующего определения ассистента.

Для .NET идентификатор агента предоставляется в виде string свойства, определенного любым агентом.

AssistantClient client = OpenAIAssistantAgent.CreateAzureOpenAIClient(...).GetAssistantClient();
Assistant assistant = await client.GetAssistantAsync("<assistant id>");
OpenAIAssistantAgent agent = new(assistant, client);
# Using Azure OpenAI Resources

# Create the client using Azure OpenAI resources and configuration
client = AzureAssistantAgent.create_client()

# Create the assistant definition
definition = await client.beta.assistants.create(
    model=AzureOpenAISettings().chat_deployment_name,
    name="<agent name>",
    instructions="<instructions>",
)

# Store the assistant ID
assistant_id = definition.id

# Retrieve the assistant definition from the server based on the assistant ID
new_asst_definition = await client.beta.assistants.retrieve(assistant_id)

# Create the AzureAssistantAgent instance using the client and the assistant definition
agent = AzureAssistantAgent(
    client=client,
    definition=new_asst_definition,
)

Функция в настоящее время недоступна в Java.

Использование OpenAIAssistantAgent

Как и во всех аспектах API помощника, беседы хранятся удаленно. Каждая беседа называется потоком и определяется уникальным string идентификатором. Взаимодействия с OpenAIAssistantAgent привязаны к данному идентификатору потока. Особенности потока API Помощника абстрагируются через OpenAIAssistantAgentThread класс, который является реализацией AgentThread.

В настоящее время OpenAIAssistantAgent поддерживает только потоки типа OpenAIAssistantAgentThread.

Можно вызвать OpenAIAssistantAgent без указания AgentThread, чтобы запустить новый поток, и в ответе на вызов будет возвращен новый AgentThread.


// Define agent
OpenAIAssistantAgent agent = ...;
AgentThread? agentThread = null;

// Generate the agent response(s)
await foreach (AgentResponseItem<ChatMessageContent> response in agent.InvokeAsync(new ChatMessageContent(AuthorRole.User, "<user input>")))
{
  // Process agent response(s)...
  agentThread = response.Thread;
}

// Delete the thread if no longer needed
if (agentThread is not null)
{
    await agentThread.DeleteAsync();
}

Вы также можете вызвать OpenAIAssistantAgent с AgentThread, который вы создали.

// Define agent
OpenAIAssistantAgent agent = ...;

// Create a thread with some custom metadata.
AgentThread agentThread = new OpenAIAssistantAgentThread(client, metadata: myMetadata);

// Generate the agent response(s)
await foreach (ChatMessageContent response in agent.InvokeAsync(new ChatMessageContent(AuthorRole.User, "<user input>"), agentThread))
{
  // Process agent response(s)...
}

// Delete the thread when it is no longer needed
await agentThread.DeleteAsync();

Вы также можете создать OpenAIAssistantAgentThread, который возобновляет более раннюю беседу по ID.

// Create a thread with an existing thread id.
AgentThread agentThread = new OpenAIAssistantAgentThread(client, "existing-thread-id");
from semantic_kernel.agents import AssistantAgentThread, AzureAssistantAgent

# Define agent
openai_agent = await ...

# Create a thread for the agent conversation
thread: AssistantAgentThread = None

# Generate the agent response(s)
async for response in agent.invoke(messages="user input", thread=thread):
  # process agent response(s)...
  thread = response.thread

# Delete the thread when it is no longer needed
await thread.delete() if thread else None

Функция в настоящее время недоступна в Java.

Удаление OpenAIAssistantAgent

Так как определение помощника хранится удаленно, оно будет сохраняться, если оно не удалено.
Удаление определения помощника может выполняться непосредственно с клиентом.

Примечание. Попытка использования экземпляра агента после удаления вызовет ошибку службы.

Для .NET идентификатор агента предоставляется как string через свойство Agent.Id, определенное любым агентом.

AssistantClient client = OpenAIAssistantAgent.CreateAzureOpenAIClient(...).GetAssistantClient();
await client.DeleteAssistantAsync("<assistant id>");
await client.beta.assistants.delete(agent.id)

Функция в настоящее время недоступна в Java.

Обработка промежуточных сообщений с помощью OpenAIAssistantAgent

Семантические ядра OpenAIAssistantAgent предназначены для вызова агента, выполняющего запросы пользователей или вопросы. Во время вызова агент может использовать инструменты для получения окончательного ответа. Чтобы получить доступ к промежуточным сообщениям, созданным во время этого процесса, вызывающие могут предоставить функцию обратного вызова, которая обрабатывает экземпляры FunctionCallContent или FunctionResultContent.

Документация по обратному вызову для OpenAIAssistantAgent будет доступна в ближайшее время.

Настройка обратного вызова on_intermediate_message в agent.invoke(...) или agent.invoke_stream(...) позволяет вызывающему объекту получать промежуточные сообщения, создаваемые в процессе формирования окончательного ответа агента.

import asyncio
from typing import Annotated

from semantic_kernel.agents import AssistantAgentThread, AzureAssistantAgent
from semantic_kernel.connectors.ai.open_ai import AzureOpenAISettings
from semantic_kernel.contents import AuthorRole, ChatMessageContent, FunctionCallContent, FunctionResultContent
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, FunctionResultContent):
            print(f"Function Result:> {item.result} for function: {item.name}")
        elif isinstance(item, FunctionCallContent):
            print(f"Function Call:> {item.name} with arguments: {item.arguments}")
        else:
            print(f"{item}")


async def main():
    # Create the client using Azure OpenAI resources and configuration
    client = AzureAssistantAgent.create_client()

    # Define the assistant definition
    definition = await client.beta.assistants.create(
        model=AzureOpenAISettings().chat_deployment_name,
        name="Host",
        instructions="Answer questions about the menu.",
    )

    # Create the AzureAssistantAgent instance using the client and the assistant definition and the defined plugin
    agent = AzureAssistantAgent(
        client=client,
        definition=definition,
        plugins=[MenuPlugin()],
    )

    # Create a new thread for use with the assistant
    # If no thread is provided, a new thread will be
    # created and returned with the initial response
    thread: AssistantAgentThread = None

    user_inputs = [
        "Hello",
        "What is the special soup?",
        "What is the special drink?",
        "How much is that?",
        "Thank you",
    ]

    try:
        for user_input in user_inputs:
            print(f"# {AuthorRole.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
    finally:
        await thread.delete() if thread else None
        await client.beta.assistants.delete(assistant_id=agent.id)


if __name__ == "__main__":
    asyncio.run(main())

Ниже приведен пример выходных данных из процесса вызова агента:

AuthorRole.USER: 'Hello'
AuthorRole.ASSISTANT: Hello! How can I assist you today?
AuthorRole.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 is Clam Chowder. Would you like to know more about the specials or 
    anything else?
AuthorRole.USER: 'What is the special drink?'
AuthorRole.ASSISTANT: The special drink is Chai Tea. If you have any more questions, feel free to ask!
AuthorRole.USER: 'How much is that?'
Function Call:> MenuPlugin-get_item_price with arguments: {"menu_item":"Chai Tea"}
Function Result:> $9.99 for function: MenuPlugin-get_item_price
AuthorRole.ASSISTANT: The Chai Tea is priced at $9.99. If there's anything else you'd like to know, 
    just let me know!
AuthorRole.USER: 'Thank you'
AuthorRole.ASSISTANT: You're welcome! If you have any more questions or need further assistance, feel free to 
    ask. Enjoy your day!

Функция в настоящее время недоступна в Java.

Декларативная спецификация

В ближайшее время будет представлена документация по использованию декларативных спецификаций.

Это важно

Эта функция находится на экспериментальном этапе. Функции на этом этапе находятся в стадии разработки и могут измениться перед переходом к этапу предварительного просмотра или релиз-кандидата.

Элемент OpenAIAssistantAgent поддерживает создание экземпляров из декларативной спецификации YAML. Декларативный подход позволяет определить свойства агента, инструкции, конфигурацию модели, средства и другие параметры в одном, проверяемом документе. Это делает состав агента переносимым и легко управляемым в разных средах.

Замечание

Все средства, функции или подключаемые модули, перечисленные в декларативном YAML, должны быть доступны агенту во время строительства. Для плагинов на основе ядра это означает, что они должны быть зарегистрированы в ядре. Для встроенных инструментов, таких как интерпретатор кода или поиск файлов, необходимо указать правильную конфигурацию и учетные данные. Загрузчик агента не создаст функции с нуля. Если обязательный компонент отсутствует, создание агента не удастся.

Как использовать декларативную спецификацию

Вместо перечисления каждой возможной конфигурации YAML в этом разделе описываются основные принципы и приводятся ссылки на примеры концепций, показывающие полный код для каждого типа инструмента. Ознакомьтесь с этими примерами концепции для комплексных реализаций OpenAIAssistantAgent декларативных спецификаций:

AzureAssistantAgent Образцы:

OpenAIAssistantAgent Образцы:

Пример. Создание AzureAIAgent из YAML

Минимальное декларативное представление YAML может выглядеть следующим образом:

type: openai_assistant
name: Host
instructions: Respond politely to the user's questions.
model:
  id: ${OpenAI:ChatModelId}
tools:
  - id: MenuPlugin.get_specials
    type: function
  - id: MenuPlugin.get_item_price
    type: function

Дополнительные сведения о подключении агента можно найти в приведённых выше полных образцах кода.

Основные моменты

  • Декларативные спецификации позволяют определять структуру агента, средства и поведение в YAML.
  • Все указанные средства и подключаемые модули должны быть зарегистрированы или доступны во время выполнения.
  • Встроенные средства, такие как Bing, поиск файлов и интерпретатор кода, требуют надлежащей настройки и учетных данных (часто через переменные среды или явные аргументы).
  • Полные примеры см. в приведенных примерах ссылок, демонстрирующих практические сценарии, включая регистрацию подключаемых модулей, конфигурацию удостоверений Azure и расширенное использование средств.

Эта функция недоступна.

Инструкции

Полный пример для OpenAIAssistantAgentсм. здесь:

Дальнейшие шаги