Compartilhar via


Explorando o kernel semântico AzureAIAgent

Importante

Esse recurso está em estágio experimental. Os recursos nesta fase estão em desenvolvimento e sujeitos a alterações antes de avançar para a versão preliminar ou para o estágio de candidato a lançamento.

Dica

A documentação detalhada da API relacionada a esta discussão está disponível em:

Dica

A documentação detalhada da API relacionada a esta discussão está disponível em:

Recurso atualmente indisponível em Java.

O que é um AzureAIAgent?

Um AzureAIAgent é um agente especializado dentro da estrutura do Semantic Kernel, projetado para fornecer capacidades conversacionais avançadas com integração perfeita de ferramentas. Ele automatiza a chamada de ferramenta, eliminando a necessidade de análise manual e invocação. O agente também gerencia com segurança o histórico de conversas usando threads, reduzindo a sobrecarga de manutenção do estado. Além disso, o AzureAIAgent dá suporte a uma variedade de ferramentas internas, incluindo recuperação de arquivo, execução de código e interação de dados por meio do Bing, Azure AI Search, Azure Functions e OpenAPI.

Para utilizar um AzureAIAgent, é necessário usar um Projeto do Azure AI Foundry. Os artigos a seguir fornecem uma visão geral do Azure AI Foundry, como criar e configurar um projeto e o serviço do agente:

Preparando seu ambiente de desenvolvimento

Para continuar desenvolvendo um AzureAIAgent, configure seu ambiente de desenvolvimento com os pacotes apropriados.

Adicione o pacote de Microsoft.SemanticKernel.Agents.AzureAI ao seu projeto:

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

Talvez você também queira incluir o pacote Azure.Identity:

dotnet add package Azure.Identity

Instalar o pacote semantic-kernel:

pip install semantic-kernel

Recurso atualmente indisponível em Java.

Configurando o cliente de projeto de IA

Acessar um AzureAIAgent primeiro requer a criação de um cliente configurado para um Projeto Foundry específico, geralmente ao fornecer o endpoint do seu projeto (O SDK do Azure AI Foundry: Introdução aos Projetos).

PersistentAgentsClient client = AzureAIAgent.CreateAgentsClient("<your endpoint>", new AzureCliCredential());

Modifique o arquivo .env no diretório raiz para incluir:

AZURE_AI_AGENT_ENDPOINT = "<example-endpoint>"
AZURE_AI_AGENT_MODEL_DEPLOYMENT_NAME = "<example-model-deployment-name>"

Depois que a configuração for definida, o cliente poderá ser criado:

from semantic_kernel.agents import AzureAIAgent

async with (
    DefaultAzureCredential() as creds,
    AzureAIAgent.create_client(credential=creds) as client,
):
    # Your operational code here

O subjacente endpoint será captado pelas Pydantic Settings, se configurado. Caso contrário, você poderá passá-lo explicitamente para o create_client() método:

from semantic_kernel.agents import AzureAIAgent

async with (
    DefaultAzureCredential() as creds,
    AzureAIAgent.create_client(credential=creds, endpoint="<your-endpoint>") as client,
):
    # Your operational code here

Recurso atualmente indisponível em Java.

Criando um AzureAIAgent

Para criar um AzureAIAgent, comece configurando e inicializando o projeto foundry por meio do serviço do Agente do Azure e, em seguida, integre-o ao Kernel Semântico:

PersistentAgentsClient client = AzureAIAgent.CreateAgentsClient("<your endpoint>", new AzureCliCredential());

// 1. Define an agent on the Azure AI agent service
PersistentAgent definition = await agentsClient.Administration.CreateAgentAsync(
    "<name of the the model used by the agent>",
    name: "<agent name>",
    description: "<agent description>",
    instructions: "<agent instructions>");

// 2. Create a Semantic Kernel agent based on the agent definition
AzureAIAgent agent = new(definition, agentsClient);
from azure.identity.aio import DefaultAzureCredential
from semantic_kernel.agents import AzureAIAgent, AzureAIAgentSettings

async with (
    DefaultAzureCredential() as creds,
    AzureAIAgent.create_client(credential=creds) as client,
):
    # 1. Define an agent on the Azure AI agent service
    agent_definition = await client.agents.create_agent(
        model=AzureAIAgentSettings().model_deployment_name,
        name="<name>",
        instructions="<instructions>",
    )

    # 2. Create a Semantic Kernel agent based on the agent definition
    agent = AzureAIAgent(
        client=client,
        definition=agent_definition,
    )

Recurso atualmente indisponível em Java.

Interagindo com um AzureAIAgent

A interação com o AzureAIAgent é simples. O agente mantém o histórico de conversas automaticamente usando um thread.

As especificidades do thread do Agente de IA do Azure são abstraídas por meio da Microsoft.SemanticKernel.Agents.AzureAI.AzureAIAgentThread classe, que é uma implementação de Microsoft.SemanticKernel.Agents.AgentThread.

Importante

Observe que o SDK dos Agentes de IA do Azure tem a PersistentAgentThread classe. Ele não deve ser confundido com Microsoft.SemanticKernel.Agents.AgentThread, que é a abstração comum de Agentes do Kernel semântico para todos os tipos de thread.

O AzureAIAgent atualmente só dá suporte a threads do tipo AzureAIAgentThread.

AzureAIAgentThread agentThread = new(agent.Client);
try
{
    ChatMessageContent message = new(AuthorRole.User, "<your user input>");
    await foreach (ChatMessageContent response in agent.InvokeAsync(message, agentThread))
    {
        Console.WriteLine(response.Content);
    }
}
finally
{
    await agentThread.DeleteAsync();
    await agent.Client.DeleteAgentAsync(agent.Id);
}

As especificidades do thread do Agente de IA do Azure são abstraídas por meio da AzureAIAgentThread classe, que é uma implementação de AgentThread.

USER_INPUTS = ["Hello", "What's your name?"]

thread: AzureAIAgentThread = AzureAIAgentThread()

try:
    for user_input in USER_INPUTS:
        response = await agent.get_response(messages=user_inputs, thread=thread)
        print(response)
        thread = response.thread
finally:
    await thread.delete() if thread else None

Opcionalmente, um agente pode ser invocado como:

for user_input in USER_INPUTS:
    async for content in agent.invoke(messages=user_input, thread=thread):
        print(content.content)
        thread = response.thread

Você também pode passar uma lista de mensagens para o get_response(...), invoke(...)ou invoke_stream(...) métodos:

USER_INPUTS = ["Hello", "What's your name?"]

thread: AzureAIAgentThread = AzureAIAgentThread()

try:
    for user_input in USER_INPUTS:
        response = await agent.get_response(messages=USER_INPUTS, thread=thread)
        print(response)
        thread = response.thread
finally:
    await thread.delete() if thread else None

Um agente também pode produzir uma resposta transmitida em fluxo:

ChatMessageContent message = new(AuthorRole.User, "<your user input>");
await foreach (StreamingChatMessageContent response in agent.InvokeStreamingAsync(message, agentThread))
{
    Console.Write(response.Content);
}
for user_input in USER_INPUTS:
    await agent.add_chat_message(thread_id=thread.id, message=user_input)
    async for content in agent.invoke_stream(thread_id=thread.id):
        print(content.content, end="", flush=True)

Recurso atualmente indisponível em Java.

Usando plug-ins com um AzureAIAgent

O Kernel Semântico dá suporte à extensão de um AzureAIAgent com plug-ins personalizados para funcionalidade aprimorada:

KernelPlugin plugin = KernelPluginFactory.CreateFromType<YourPlugin>();
PersistentAgentsClient client = AzureAIAgent.CreateAgentsClient("<your endpoint>", new AzureCliCredential());

PersistentAgent definition = await agentsClient.Administration.CreateAgentAsync(
    "<name of the the model used by the agent>",
    name: "<agent name>",
    description: "<agent description>",
    instructions: "<agent instructions>");

AzureAIAgent agent = new(definition, agentsClient, plugins: [plugin]);
from semantic_kernel.functions import kernel_function

class SamplePlugin:
    @kernel_function(description="Provides sample data.")
    def get_data(self) -> str:
        return "Sample data"

async with (
        DefaultAzureCredential() as creds,
        AzureAIAgent.create_client(credential=creds) as client,
    ):
        agent_definition = await client.agents.create_agent(
            model=AzureAIAgentSettings().model_deployment_name,
        )

        agent = AzureAIAgent(
            client=client,
            definition=agent_definition,
            plugins=[SamplePlugin()]
        )

Recurso atualmente indisponível em Java.

Recursos avançados

Um AzureAIAgent pode aproveitar ferramentas avançadas como:

Interpretador de Código

O Interpretador de Código permite que os agentes escrevam e executem código Python em um ambiente de execução isolado (Interpretador de Código do Serviço de Agente de IA do Azure).

PersistentAgentsClient client = AzureAIAgent.CreateAgentsClient("<your endpoint>", new AzureCliCredential());

PersistentAgent definition = await agentsClient.CreateAgentAsync(
    "<name of the the model used by the agent>",
    name: "<agent name>",
    description: "<agent description>",
    instructions: "<agent instructions>",
    tools: [new CodeInterpreterToolDefinition()],
    toolResources:
        new()
        {
            CodeInterpreter = new()
            {
                FileIds = { ... },
            }
        }));

AzureAIAgent agent = new(definition, agentsClient);
from azure.ai.agents.models import CodeInterpreterTool

async with (
        DefaultAzureCredential() as creds,
        AzureAIAgent.create_client(credential=creds) as client,
    ):
        code_interpreter = CodeInterpreterTool()
        agent_definition = await client.agents.create_agent(
            model=ai_agent_settings.model_deployment_name,
            tools=code_interpreter.definitions,
            tool_resources=code_interpreter.resources,
        )

Recurso atualmente indisponível em Java.

A pesquisa de arquivos oferece aos agentes conhecimentos externos ao seu modelo (Ferramenta de Pesquisa de Arquivos do Serviço de Agente de IA do Azure).

PersistentAgentsClient client = AzureAIAgent.CreateAgentsClient("<your endpoint>", new AzureCliCredential());

PersistentAgent definition = await agentsClient.CreateAgentAsync(
    "<name of the the model used by the agent>",
    name: "<agent name>",
    description: "<agent description>",
    instructions: "<agent instructions>",
    tools: [new FileSearchToolDefinition()],
    toolResources:
        new()
        {
            FileSearch = new()
            {
                VectorStoreIds = { ... },
            }
        });

AzureAIAgent agent = new(definition, agentsClient);
from azure.ai.agents.models import FileSearchTool

async with (
        DefaultAzureCredential() as creds,
        AzureAIAgent.create_client(credential=creds) as client,
    ):
        file_search = FileSearchTool(vector_store_ids=[vector_store.id])
        agent_definition = await client.agents.create_agent(
            model=ai_agent_settings.model_deployment_name,
            tools=file_search.definitions,
            tool_resources=file_search.resources,
        )

Recurso atualmente indisponível em Java.

Integração do OpenAPI

Conecta seu agente a uma API externa (Como usar o Serviço de Agente de IA do Azure com Ferramentas Especificadas no OpenAPI).

PersistentAgentsClient client = AzureAIAgent.CreateAgentsClient("<your endpoint>", new AzureCliCredential());

string apiJsonSpecification = ...; // An Open API JSON specification

PersistentAgent definition = await agentsClient.CreateAgentAsync(
    "<name of the the model used by the agent>",
    name: "<agent name>",
    description: "<agent description>",
    instructions: "<agent instructions>",
    tools: [
        new OpenApiToolDefinition(
            "<api name>", 
            "<api description>", 
            BinaryData.FromString(apiJsonSpecification), 
            new OpenApiAnonymousAuthDetails())
    ]
);

AzureAIAgent agent = new(definition, agentsClient);
from azure.ai.agents.models import OpenApiTool, OpenApiAnonymousAuthDetails

async with (
    DefaultAzureCredential() as creds,
    AzureAIAgent.create_client(credential=creds) as client,
):
    openapi_spec_file_path = "sample/filepath/..."
    with open(os.path.join(openapi_spec_file_path, "spec_one.json")) as file_one:
        openapi_spec_one = json.loads(file_one.read())
    with open(os.path.join(openapi_spec_file_path, "spec_two.json")) as file_two:
        openapi_spec_two = json.loads(file_two.read())

    # Note that connection or managed identity auth setup requires additional setup in Azure
    auth = OpenApiAnonymousAuthDetails()
    openapi_tool_one = OpenApiTool(
        name="<name>",
        spec=openapi_spec_one,
        description="<description>",
        auth=auth,
    )
    openapi_tool_two = OpenApiTool(
        name="<name>",
        spec=openapi_spec_two,
        description="<description>",
        auth=auth,
    )

    agent_definition = await client.agents.create_agent(
        model=ai_agent_settings.model_deployment_name,
        tools=openapi_tool_one.definitions + openapi_tool_two.definitions,
    )

Recurso atualmente indisponível em Java.

Integração do AzureAI Search

Usar um índice existente do Azure AI Search com seu agente (Usar um índice existente do AI Search).

PersistentAgentsClient client = AzureAIAgent.CreateAgentsClient("<your endpoint>", new AzureCliCredential());

PersistentAgent definition = await agentsClient.CreateAgentAsync(
    "<name of the the model used by the agent>",
    name: "<agent name>",
    description: "<agent description>",
    instructions: "<agent instructions>",
    tools: [new AzureAISearchToolDefinition()],
    toolResources: new()
    {
        AzureAISearch = new()
        {
            IndexList = { new AISearchIndexResource("<your connection id>", "<your index name>") }
        }
    });

AzureAIAgent agent = new(definition, agentsClient);
from azure.ai.agents.models import AzureAISearchTool, ConnectionType

async with (
    DefaultAzureCredential() as creds,
    AzureAIAgent.create_client(credential=creds) as client,
):
    conn_list = await client.connections.list()

    ai_search_conn_id = ""
    for conn in conn_list:
        if conn.connection_type == ConnectionType.AZURE_AI_SEARCH:
            ai_search_conn_id = conn.id
            break

    ai_search = AzureAISearchTool(
        index_connection_id=ai_search_conn_id, 
        index_name=AZURE_AI_SEARCH_INDEX_NAME,
    )

    agent_definition = await client.agents.create_agent(
        model=ai_agent_settings.model_deployment_name,
        instructions="Answer questions using your index.",
        tools=ai_search.definitions,
        tool_resources=ai_search.resources,
        headers={"x-ms-enable-preview": "true"},
    )

Recurso atualmente indisponível em Java.

Fundamentação do Bing

Exemplo em breve.

from azure.ai.agents.models import BingGroundingTool
from azure.identity.aio import DefaultAzureCredential

from semantic_kernel.agents import AzureAIAgent, AzureAIAgentSettings

async with (
    DefaultAzureCredential() as creds,
    AzureAIAgent.create_client(credential=creds) as client,
):
    # 1. Enter your Bing Grounding Connection Name
    bing_connection = await client.connections.get(connection_name="<your-bing-grounding-connection-name>")
    conn_id = bing_connection.id

    # 2. Initialize agent bing tool and add the connection id
    bing_grounding = BingGroundingTool(connection_id=conn_id)

    # 3. Create an agent with Bing grounding on the Azure AI agent service
    agent_definition = await client.agents.create_agent(
        name="BingGroundingAgent",
        instructions="Use the Bing grounding tool to answer the user's question.",
        model=AzureAIAgentSettings().model_deployment_name,
        tools=bing_grounding.definitions,
    )

    # 4. Create a Semantic Kernel agent for the Azure AI agent
    agent = AzureAIAgent(
        client=client,
        definition=agent_definition,
    )

Ao usar a ferramenta de Aterramento do Bing, o retorno de chamada FunctionCallContent passado para o on_intermediate_message terá seu nome de função definido como "bing_grounding". Após a conclusão da execução, a lista ChatMessageContent.items incluirá AnnotationContent ou StreamingAnnotationContent, dependendo se a invocação for padrão ou streaming. Esses itens de anotação contêm informações sobre os links que o agente visitou durante a resposta, semelhantes às informações presentes no FunctionCallContent.

Para obter mais informações, consulte os seguintes exemplos de conceito:

Recurso atualmente indisponível em Java.

Recuperação de um AzureAIAgent existente

Um agente existente pode ser recuperado e reutilizado ao especificar o ID do assistente:

PersistentAgent definition = await agentsClient.Administration.GetAgentAsync("<your agent id>");
AzureAIAgent agent = new(definition, agentsClient);
agent_definition = await client.agents.get_agent(assistant_id="your-agent-id")
agent = AzureAIAgent(client=client, definition=agent_definition)

Recurso atualmente indisponível em Java.

Excluindo um AzureAIAgent

Os agentes e seus threads associados podem ser excluídos quando não forem mais necessários:

await agentThread.DeleteAsync();
await agentsClient.Administration.DeleteAgentAsync(agent.Id);
await client.agents.delete_thread(thread.id)
await client.agents.delete_agent(agent.id)

Se estiver trabalhando com um repositório de vetores ou arquivos, eles também poderão ser excluídos:

await agentsClient.VectorStores.DeleteVectorStoreAsync("<your store id>");
await agentsClient.Files.DeleteFileAsync("<your file id>");
await client.agents.files.delete(file_id=file.id)
await client.agents.vector_stores.delete(vector_store_id=vector_store.id)

Recurso atualmente indisponível em Java.

Mais informações sobre a ferramenta de pesquisa de arquivos são descritas no artigo ferramenta de pesquisa de arquivos do Serviço do Agente de IA do Azure.

Como Fazer

Para obter exemplos práticos de como usar um AzureAIAgent, consulte nossos exemplos de código no GitHub:

Recurso atualmente indisponível em Java.

Gerenciando mensagens intermediárias com um AzureAIAgent

O Kernel AzureAIAgent Semântico foi projetado para invocar um agente que atende a consultas ou perguntas do usuário. Durante a invocação, o agente pode executar ferramentas para derivar a resposta final. Para acessar mensagens intermediárias produzidas durante este processo, os chamadores podem fornecer uma função de callback que lida com instâncias de FunctionCallContent ou FunctionResultContent.

A documentação de callback para o AzureAIAgent estará disponível em breve.

Configurar o on_intermediate_message retorno de chamada dentro de agent.invoke(...) ou agent.invoke_stream(...) permite que o chamador receba mensagens intermediárias geradas durante o processo de formulação da resposta final do agente.

import asyncio
from typing import Annotated

from azure.identity.aio import DefaultAzureCredential

from semantic_kernel.agents import AzureAIAgent, AzureAIAgentSettings, AzureAIAgentThread
from semantic_kernel.contents import FunctionCallContent, FunctionResultContent
from semantic_kernel.contents.chat_message_content import ChatMessageContent
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() -> None:
    ai_agent_settings = AzureAIAgentSettings()

    async with (
        DefaultAzureCredential() as creds,
        AzureAIAgent.create_client(credential=creds, endpoint=ai_agent_settings.endpoint) as client,
    ):
        AGENT_NAME = "Host"
        AGENT_INSTRUCTIONS = "Answer questions about the menu."

        # Create agent definition
        agent_definition = await client.agents.create_agent(
            model=ai_agent_settings.deployment_name,
            name=AGENT_NAME,
            instructions=AGENT_INSTRUCTIONS,
        )

        # Create the AzureAI Agent
        agent = AzureAIAgent(
            client=client,
            definition=agent_definition,
            plugins=[MenuPlugin()],  # add the sample plugin to the agent
        )

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

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

        try:
            for user_input in user_inputs:
                print(f"# User: '{user_input}'")
                async for response in agent.invoke(
                    messages=user_input,
                    thread=thread,
                    on_intermediate_message=handle_intermediate_steps,
                ):
                    print(f"# Agent: {response}")
                    thread = response.thread
        finally:
            # Cleanup: Delete the thread and agent
            await thread.delete() if thread else None
            await client.agents.delete_agent(agent.id)


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

O seguinte demonstra a saída de exemplo do processo de invocação do agente:

User: 'Hello'
Agent: Hi there! How can I assist you today?
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
Agent: The special soup is Clam Chowder. Would you like to know anything else about the menu?
User: 'How much does that cost?'
Function Call:> MenuPlugin-get_item_price with arguments: {"menu_item":"Clam Chowder"}
Function Result:> $9.99 for function: MenuPlugin-get_item_price
Agent: The Clam Chowder costs $9.99. Let me know if you would like assistance with anything else!
User: 'Thank you'
Agent: You're welcome! Enjoy your meal! 😊

Recurso atualmente indisponível em Java.

Especificação declarativa

A documentação sobre como usar especificações declarativas será fornecida em breve.

Importante

Esse recurso está em estágio experimental. Os recursos nesta fase estão em desenvolvimento e sujeitos a alterações antes de avançar para a versão preliminar ou para o estágio de candidato a lançamento.

O AzureAIAgent permite a instanciação a partir de uma especificação declarativa YAML. A abordagem declarativa permite definir as propriedades, as instruções, a configuração do modelo, as ferramentas e outras opções do agente em um único documento auditável. Isso torna a composição do agente portátil e facilmente gerenciada entre ambientes.

Observação

Todas as ferramentas, funções ou plug-ins listados no YAML declarativo devem estar disponíveis para o agente no momento da construção. Para plug-ins baseados em kernel, isso significa que eles devem ser registrados no Kernel. Para ferramentas internas, como Bing Grounding, Pesquisa de Arquivos, ou ferramentas OpenAPI, a configuração e as credenciais corretas devem ser fornecidas. O carregador do agente não criará funções do zero. Se um componente necessário estiver ausente, a criação do agente falhará.

Como usar a especificação declarativa

Em vez de enumerar todas as configurações possíveis do YAML, esta seção descreve os principais princípios e fornece links para exemplos de conceito que mostram código completo para cada tipo de ferramenta. Consulte estes exemplos de conceito para implementações de ponta a ponta de um AzureAIAgent com especificações declarativas:

Exemplo: criando um AzureAIAgent a partir do YAML

Uma especificação declarativa mínima do YAML pode ser semelhante à seguinte:

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

Para obter detalhes sobre como conectar o agente, consulte os exemplos de código completos acima.

Pontos Principais

  • As especificações declarativas permitem definir a estrutura, as ferramentas e o comportamento do agente no YAML.
  • Todas as ferramentas e plug-ins referenciados devem ser registrados ou acessíveis em tempo de execução.
  • Ferramentas internas como Bing, Pesquisa de Arquivos e Interpretador de Código exigem configuração e credenciais adequadas (geralmente por meio de variáveis de ambiente ou argumentos explícitos).
  • Para obter exemplos abrangentes, consulte os links de exemplo fornecidos que demonstram cenários práticos, incluindo registro de plug-in, configuração de identidade do Azure e uso avançado de ferramentas.

Esse recurso não está disponível.

Próximas etapas