ai-agents-for-beginners

Como Projetar Bons Agentes de IA

(Clique na imagem acima para assistir ao vídeo desta lição)

Padrão de Design para Uso de Ferramentas

Ferramentas são interessantes porque permitem que agentes de IA tenham uma gama mais ampla de capacidades. Em vez de o agente ter um conjunto limitado de ações que pode executar, ao adicionar uma ferramenta, o agente pode realizar uma ampla variedade de ações. Neste capítulo, exploraremos o Padrão de Design para Uso de Ferramentas, que descreve como agentes de IA podem usar ferramentas específicas para alcançar seus objetivos.

Introdução

Nesta lição, buscamos responder às seguintes perguntas:

Objetivos de Aprendizado

Após concluir esta lição, você será capaz de:

O que é o Padrão de Design para Uso de Ferramentas?

O Padrão de Design para Uso de Ferramentas foca em dar aos LLMs a capacidade de interagir com ferramentas externas para alcançar objetivos específicos. Ferramentas são códigos que podem ser executados por um agente para realizar ações. Uma ferramenta pode ser uma função simples, como uma calculadora, ou uma chamada de API para um serviço de terceiros, como consulta de preços de ações ou previsão do tempo. No contexto de agentes de IA, ferramentas são projetadas para serem executadas por agentes em resposta a chamadas de função geradas pelo modelo.

Quais são os casos de uso aos quais ele pode ser aplicado?

Agentes de IA podem aproveitar ferramentas para realizar tarefas complexas, recuperar informações ou tomar decisões. O padrão de design para uso de ferramentas é frequentemente utilizado em cenários que exigem interação dinâmica com sistemas externos, como bancos de dados, serviços web ou interpretadores de código. Essa capacidade é útil para diversos casos de uso, incluindo:

Quais são os elementos/blocos de construção necessários para implementar o padrão de design para uso de ferramentas?

Esses blocos de construção permitem que o agente de IA realize uma ampla gama de tarefas. Vamos analisar os elementos-chave necessários para implementar o Padrão de Design para Uso de Ferramentas:

A seguir, vamos explorar o Chamado de Função/Ferramenta em mais detalhes.

Chamado de Função/Ferramenta

O chamado de função é a principal maneira de permitir que Modelos de Linguagem de Grande Escala (LLMs) interajam com ferramentas. Você frequentemente verá os termos ‘Função’ e ‘Ferramenta’ usados de forma intercambiável, porque ‘funções’ (blocos de código reutilizável) são as ‘ferramentas’ que os agentes utilizam para realizar tarefas. Para que o código de uma função seja invocado, um LLM deve comparar a solicitação do usuário com a descrição da função. Para isso, um esquema contendo as descrições de todas as funções disponíveis é enviado ao LLM. O LLM então seleciona a função mais apropriada para a tarefa e retorna seu nome e argumentos. A função selecionada é invocada, sua resposta é enviada de volta ao LLM, que usa as informações para responder à solicitação do usuário.

Para que os desenvolvedores implementem o chamado de função para agentes, será necessário:

  1. Um modelo LLM que suporte chamado de função
  2. Um esquema contendo descrições de funções
  3. O código para cada função descrita

Vamos usar o exemplo de obter a hora atual em uma cidade para ilustrar:

  1. Inicializar um LLM que suporte chamado de função:

    Nem todos os modelos suportam chamado de função, então é importante verificar se o LLM que você está usando suporta. Azure OpenAI suporta chamado de função. Podemos começar iniciando o cliente Azure OpenAI.

     # Initialize the Azure OpenAI client
     client = AzureOpenAI(
         azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT"), 
         api_key=os.getenv("AZURE_OPENAI_API_KEY"),  
         api_version="2024-05-01-preview"
     )
    
  2. Criar um Esquema de Função:

    Em seguida, definiremos um esquema JSON que contém o nome da função, descrição do que a função faz e os nomes e descrições dos parâmetros da função. Passaremos este esquema ao cliente criado anteriormente, junto com a solicitação do usuário para encontrar a hora em São Francisco. É importante notar que o que é retornado é uma chamada de ferramenta, não a resposta final à pergunta. Como mencionado anteriormente, o LLM retorna o nome da função que selecionou para a tarefa e os argumentos que serão passados a ela.

     # Function description for the model to read
     tools = [
         {
             "type": "function",
             "function": {
                 "name": "get_current_time",
                 "description": "Get the current time in a given location",
                 "parameters": {
                     "type": "object",
                     "properties": {
                         "location": {
                             "type": "string",
                             "description": "The city name, e.g. San Francisco",
                         },
                     },
                     "required": ["location"],
                 },
             }
         }
     ]
    
      
     # Initial user message
     messages = [{"role": "user", "content": "What's the current time in San Francisco"}] 
      
     # First API call: Ask the model to use the function
       response = client.chat.completions.create(
           model=deployment_name,
           messages=messages,
           tools=tools,
           tool_choice="auto",
       )
      
       # Process the model's response
       response_message = response.choices[0].message
       messages.append(response_message)
      
       print("Model's response:")  
    
       print(response_message)
      
    
     Model's response:
     ChatCompletionMessage(content=None, role='assistant', function_call=None, tool_calls=[ChatCompletionMessageToolCall(id='call_pOsKdUlqvdyttYB67MOj434b', function=Function(arguments='{"location":"San Francisco"}', name='get_current_time'), type='function')])
    
  3. O código da função necessário para realizar a tarefa:

    Agora que o LLM escolheu qual função precisa ser executada, o código que realiza a tarefa precisa ser implementado e executado. Podemos implementar o código para obter a hora atual em Python. Também precisaremos escrever o código para extrair o nome e os argumentos da resposta_message para obter o resultado final.

       def get_current_time(location):
         """Get the current time for a given location"""
         print(f"get_current_time called with location: {location}")  
         location_lower = location.lower()
            
         for key, timezone in TIMEZONE_DATA.items():
             if key in location_lower:
                 print(f"Timezone found for {key}")  
                 current_time = datetime.now(ZoneInfo(timezone)).strftime("%I:%M %p")
                 return json.dumps({
                     "location": location,
                     "current_time": current_time
                 })
          
         print(f"No timezone data found for {location_lower}")  
         return json.dumps({"location": location, "current_time": "unknown"})
    
      # Handle function calls
       if response_message.tool_calls:
           for tool_call in response_message.tool_calls:
               if tool_call.function.name == "get_current_time":
         
                   function_args = json.loads(tool_call.function.arguments)
         
                   time_response = get_current_time(
                       location=function_args.get("location")
                   )
         
                   messages.append({
                       "tool_call_id": tool_call.id,
                       "role": "tool",
                       "name": "get_current_time",
                       "content": time_response,
                   })
       else:
           print("No tool calls were made by the model.")  
      
       # Second API call: Get the final response from the model
       final_response = client.chat.completions.create(
           model=deployment_name,
           messages=messages,
       )
      
       return final_response.choices[0].message.content
    
       get_current_time called with location: San Francisco
       Timezone found for san francisco
       The current time in San Francisco is 09:24 AM.
    

O chamado de função está no centro da maioria, se não de todos os designs de uso de ferramentas por agentes, porém implementá-lo do zero pode ser desafiador. Como aprendemos na Lição 2, frameworks agentivos nos fornecem blocos de construção pré-definidos para implementar o uso de ferramentas.

Exemplos de Uso de Ferramentas com Frameworks Agentivos

Aqui estão alguns exemplos de como você pode implementar o Padrão de Design para Uso de Ferramentas usando diferentes frameworks agentivos:

Semantic Kernel

Semantic Kernel é um framework de IA de código aberto para desenvolvedores .NET, Python e Java que trabalham com Modelos de Linguagem de Grande Escala (LLMs). Ele simplifica o processo de uso de chamado de função ao descrever automaticamente suas funções e seus parâmetros para o modelo por meio de um processo chamado serialização. Ele também gerencia a comunicação entre o modelo e seu código. Outra vantagem de usar um framework agentivo como o Semantic Kernel é que ele permite acessar ferramentas pré-construídas como Busca de Arquivos e Interpretador de Código.

O diagrama a seguir ilustra o processo de chamado de função com Semantic Kernel:

chamado de função

No Semantic Kernel, funções/ferramentas são chamadas de Plugins. Podemos converter a função get_current_time que vimos anteriormente em um plugin transformando-a em uma classe com a função dentro dela. Também podemos importar o decorador kernel_function, que recebe a descrição da função. Quando você cria um kernel com o GetCurrentTimePlugin, o kernel automaticamente serializa a função e seus parâmetros, criando o esquema para enviar ao LLM no processo.

from semantic_kernel.functions import kernel_function

class GetCurrentTimePlugin:
    async def __init__(self, location):
        self.location = location

    @kernel_function(
        description="Get the current time for a given location"
    )
    def get_current_time(location: str = ""):
        ...

from semantic_kernel import Kernel

# Create the kernel
kernel = Kernel()

# Create the plugin
get_current_time_plugin = GetCurrentTimePlugin(location)

# Add the plugin to the kernel
kernel.add_plugin(get_current_time_plugin)

Azure AI Agent Service

Azure AI Agent Service é um framework agentivo mais recente, projetado para capacitar desenvolvedores a construir, implantar e escalar agentes de IA de alta qualidade e extensíveis de forma segura, sem precisar gerenciar os recursos subjacentes de computação e armazenamento. Ele é particularmente útil para aplicações empresariais, pois é um serviço totalmente gerenciado com segurança de nível empresarial.

Comparado ao desenvolvimento direto com a API do LLM, o Azure AI Agent Service oferece algumas vantagens, incluindo:

As ferramentas disponíveis no Azure AI Agent Service podem ser divididas em duas categorias:

  1. Ferramentas de Conhecimento:
  2. Ferramentas de Ação:

O Agent Service nos permite usar essas ferramentas juntas como um toolset. Ele também utiliza threads, que acompanham o histórico de mensagens de uma conversa específica.

Imagine que você é um agente de vendas em uma empresa chamada Contoso. Você deseja desenvolver um agente conversacional que possa responder a perguntas sobre seus dados de vendas.

A imagem a seguir ilustra como você poderia usar o Azure AI Agent Service para analisar seus dados de vendas:

Agentic Service em Ação

Para usar qualquer uma dessas ferramentas com o serviço, podemos criar um cliente e definir uma ferramenta ou conjunto de ferramentas. Para implementar isso na prática, podemos usar o seguinte código Python. O LLM será capaz de olhar para o conjunto de ferramentas e decidir se usa a função criada pelo usuário, fetch_sales_data_using_sqlite_query, ou o Interpretador de Código pré-construído, dependendo da solicitação do usuário.

import os
from azure.ai.projects import AIProjectClient
from azure.identity import DefaultAzureCredential
from fetch_sales_data_functions import fetch_sales_data_using_sqlite_query # fetch_sales_data_using_sqlite_query function which can be found in a fetch_sales_data_functions.py file.
from azure.ai.projects.models import ToolSet, FunctionTool, CodeInterpreterTool

project_client = AIProjectClient.from_connection_string(
    credential=DefaultAzureCredential(),
    conn_str=os.environ["PROJECT_CONNECTION_STRING"],
)

# Initialize function calling agent with the fetch_sales_data_using_sqlite_query function and adding it to the toolset
fetch_data_function = FunctionTool(fetch_sales_data_using_sqlite_query)
toolset = ToolSet()
toolset.add(fetch_data_function)

# Initialize Code Interpreter tool and adding it to the toolset. 
code_interpreter = code_interpreter = CodeInterpreterTool()
toolset = ToolSet()
toolset.add(code_interpreter)

agent = project_client.agents.create_agent(
    model="gpt-4o-mini", name="my-agent", instructions="You are helpful agent", 
    toolset=toolset
)

Quais são as considerações especiais para usar o Padrão de Design para Uso de Ferramentas na construção de agentes de IA confiáveis?

Uma preocupação comum com SQL gerado dinamicamente por LLMs é a segurança, particularmente o risco de injeção de SQL ou ações maliciosas, como excluir ou alterar o banco de dados. Embora essas preocupações sejam válidas, elas podem ser mitigadas de forma eficaz configurando corretamente as permissões de acesso ao banco de dados. Para a maioria dos bancos de dados, isso envolve configurá-los como somente leitura. Para serviços de banco de dados como PostgreSQL ou Azure SQL, o aplicativo deve ser atribuído a uma função de somente leitura (SELECT).

Executar o aplicativo em um ambiente seguro aumenta ainda mais a proteção. Em cenários empresariais, os dados geralmente são extraídos e transformados de sistemas operacionais em um banco de dados somente leitura ou data warehouse com um esquema amigável ao usuário. Essa abordagem garante que os dados sejam seguros, otimizados para desempenho e acessibilidade, e que o aplicativo tenha acesso restrito e somente leitura.

Tem mais perguntas sobre o Padrão de Design para Uso de Ferramentas?

Junte-se ao Azure AI Foundry Discord para conhecer outros aprendizes, participar de horários de atendimento e tirar suas dúvidas sobre AI Agents.

Recursos Adicionais

Aula Anterior

Entendendo Padrões de Design Agentes

Próxima Aula

Agentic RAG


Aviso Legal:
Este documento foi traduzido utilizando o serviço de tradução por IA Co-op Translator. Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automatizadas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte autoritativa. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações equivocadas decorrentes do uso desta tradução.