Compartilhar via


Criar ferramentas de agente de IA personalizadas com funções do Catálogo Unity

Use as funções do Catálogo do Unity para criar ferramentas de agente de IA que executam a lógica personalizada e executam tarefas específicas que estendem os recursos de LLMs além da geração de linguagem.

Requisitos

  • Uma conexão de computação sem servidor para criar funções do Catálogo do Unity escritas usando instruções de criação de função SQL com corpo. As funções do Python não exigem computação sem servidor.
  • Utilize o Databricks Runtime 15.0 ou mais recente.

Criar uma ferramenta de agente

Neste exemplo, você cria uma ferramenta do Catálogo do Unity, testa sua funcionalidade e a adiciona a um agente. Execute o código a seguir em um bloco de anotações do Databricks.

Instalar dependências

Instale pacotes de IA do Catálogo do Unity com o extra [databricks] e instale o pacote de integração Databricks-LangChain.

Este exemplo usa LangChain, mas uma abordagem semelhante pode ser aplicada a outras bibliotecas. Veja Integrar ferramentas do Unity Catalog com estruturas de IA generativa de terceiros.

# Install Unity Catalog AI integration packages with the Databricks extra
%pip install unitycatalog-ai[databricks]
%pip install unitycatalog-langchain[databricks]

# Install the Databricks LangChain integration package
%pip install databricks-langchain

dbutils.library.restartPython()

Inicializar o Cliente de Funções do Databricks

Inicialize o Cliente de Funções do Databricks, que é uma interface especializada para criar, gerenciar e executar funções do Catálogo do Unity no Databricks.

from unitycatalog.ai.core.databricks import DatabricksFunctionClient

client = DatabricksFunctionClient()

Definir a lógica da ferramenta

As ferramentas do Catálogo do Unity são, na verdade, apenas UDFs (funções definidas pelo usuário) do Catálogo do Unity sob o capô. Ao definir uma ferramenta de Catálogo do Unity, você está registrando uma função no Catálogo do Unity. Para saber mais sobre UDFs do Catálogo do Unity, consulte UDFs (funções definidas pelo usuário) no Catálogo do Unity.

Você pode criar funções do Catálogo do Unity usando uma das duas APIs:

  • create_python_function aceita um invocável Python.
  • create_function aceita uma instrução de criação de função SQL com corpo. Consulte Criar funções do Python.

Use a create_python_function API para criar a função.

Para tornar um Python callable reconhecível para o modelo de dados de funções do Unity Catalog, sua função precisa cumprir os seguintes requisitos:

  • Dicas de tipo: a assinatura de função deve definir dicas de tipo Python válidas. Os argumentos nomeados e o valor retornado devem ter seus tipos definidos.
  • Não use argumentos variáveis: argumentos variáveis como *args e **kwargs não têm suporte. Todos os argumentos devem ser definidos explicitamente.
  • Compatibilidade de tipos: nem todos os tipos de Python têm suporte no SQL. Consulte os tipos de dados com suporte do Spark.
  • Docstrings descritivos: O toolkit de funções do Unity Catalog lê, analisa e extrai informações importantes das suas docstrings.
    • Docstrings devem ser formatados de acordo com a sintaxe docstring do Google.
    • Escreva descrições claras para sua função e seus argumentos para ajudar o LLM a entender como e quando usar a função.
  • Importações de dependência: as bibliotecas devem ser importadas dentro do corpo da função. As importações fora da função não serão resolvidas ao executar a ferramenta.

Os trechos de código seguem utilizam o create_python_function para registrar o callable add_numbers do Python.


CATALOG = "my_catalog"
SCHEMA = "my_schema"

def add_numbers(number_1: float, number_2: float) -> float:
  """
  A function that accepts two floating point numbers adds them,
  and returns the resulting sum as a float.

  Args:
    number_1 (float): The first of the two numbers to add.
    number_2 (float): The second of the two numbers to add.

  Returns:
    float: The sum of the two input numbers.
  """
  return number_1 + number_2

function_info = client.create_python_function(
  func=add_numbers,
  catalog=CATALOG,
  schema=SCHEMA,
  replace=True
)

Testar a função

Teste sua função para verificar se ela funciona conforme o esperado. Especifique um nome de função totalmente qualificado na execute_function API para executar a função:

result = client.execute_function(
  function_name=f"{CATALOG}.{SCHEMA}.add_numbers",
  parameters={"number_1": 36939.0, "number_2": 8922.4}
)

result.value # OUTPUT: '45861.4'

Encapsular a função usando o UCFunctionToolKit

Empacote a função usando UCFunctionToolkit para torná-la acessível às bibliotecas de criação de agentes. O kit de ferramentas garante a consistência em diferentes bibliotecas de IA generativa e adiciona recursos úteis, como o rastreamento automático para mecanismos de recuperação.

from databricks_langchain import UCFunctionToolkit

# Create a toolkit with the Unity Catalog function
func_name = f"{CATALOG}.{SCHEMA}.add_numbers"
toolkit = UCFunctionToolkit(function_names=[func_name])

tools = toolkit.tools

Usar a ferramenta em um agente

Adicione a ferramenta a um agente LangChain usando a propriedade tools de UCFunctionToolkit.

Este exemplo cria um agente simples usando a API LangChain AgentExecutor para simplificar. Para cargas de trabalho de produção, use o fluxo de trabalho de criação de agentes visto nos ChatAgent exemplos.

from langchain.agents import AgentExecutor, create_tool_calling_agent
from langchain.prompts import ChatPromptTemplate
from databricks_langchain import (
  ChatDatabricks,
  UCFunctionToolkit,
)
import mlflow

# Initialize the LLM (optional: replace with your LLM of choice)
LLM_ENDPOINT_NAME = "databricks-meta-llama-3-3-70b-instruct"
llm = ChatDatabricks(endpoint=LLM_ENDPOINT_NAME, temperature=0.1)

# Define the prompt
prompt = ChatPromptTemplate.from_messages(
  [
    (
      "system",
      "You are a helpful assistant. Make sure to use tools for additional functionality.",
    ),
    ("placeholder", "{chat_history}"),
    ("human", "{input}"),
    ("placeholder", "{agent_scratchpad}"),
  ]
)

# Enable automatic tracing
mlflow.langchain.autolog()

# Define the agent, specifying the tools from the toolkit above
agent = create_tool_calling_agent(llm, tools, prompt)

# Create the agent executor
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
agent_executor.invoke({"input": "What is 36939.0 + 8922.4?"})

Aprimorar o acionamento de ferramentas com documentação clara

Uma boa documentação ajuda seus agentes a saber quando e como usar cada ferramenta. Siga estas práticas recomendadas para documentar suas ferramentas:

  • Para funções do Catálogo do Unity, use a COMMENT cláusula para descrever a funcionalidade e os parâmetros da ferramenta.
  • Defina claramente as entradas e saídas esperadas.
  • Escreva descrições significativas para tornar as ferramentas mais fáceis de usar para agentes e humanos.

Exemplo: Documentação efetiva da ferramenta

O exemplo a seguir mostra cadeias de caracteres claras COMMENT para uma ferramenta que consulta uma tabela estruturada.

CREATE OR REPLACE FUNCTION main.default.lookup_customer_info(
  customer_name STRING COMMENT 'Name of the customer whose info to look up.'
)
RETURNS STRING
COMMENT 'Returns metadata about a specific customer including their email and ID.'
RETURN SELECT CONCAT(
    'Customer ID: ', customer_id, ', ',
    'Customer Email: ', customer_email
  )
  FROM main.default.customer_data
  WHERE customer_name = customer_name
  LIMIT 1;

Exemplo: documentação de ferramenta ineficaz

O exemplo a seguir não tem detalhes importantes, tornando mais difícil para os agentes usarem a ferramenta efetivamente:

CREATE OR REPLACE FUNCTION main.default.lookup_customer_info(
  customer_name STRING COMMENT 'Name of the customer.'
)
RETURNS STRING
COMMENT 'Returns info about a customer.'
RETURN SELECT CONCAT(
    'Customer ID: ', customer_id, ', ',
    'Customer Email: ', customer_email
  )
  FROM main.default.customer_data
  WHERE customer_name = customer_name
  LIMIT 1;

Executando funções usando o modo local ou sem servidor

Quando um serviço de IA generativa determina que uma chamada de ferramenta é necessária, os pacotes de integração (UCFunctionToolkit instâncias) executam a DatabricksFunctionClient.execute_function API.

A execute_function chamada pode executar funções em dois modos de execução: sem servidor ou local. Esse modo determina qual recurso executa a função.

Modo sem servidor para produção

O modo sem servidor é a opção padrão e recomendada para casos de uso de produção. Ele executa funções remotamente usando um ponto de extremidade SQL Sem servidor, garantindo que o processo do seu agente permaneça seguro e livre dos riscos de execução de código arbitrário localmente.

# Defaults to serverless if `execution_mode` is not specified
client = DatabricksFunctionClient(execution_mode="serverless")

Quando o agente solicita uma execução de ferramenta no modo sem servidor , acontece o seguinte:

  1. Envia DatabricksFunctionClient uma solicitação ao Catálogo do Unity para recuperar a definição de função se a definição não tiver sido armazenada em cache localmente.
  2. O DatabricksFunctionClient extrai a definição de função e valida os nomes e tipos de parâmetro.
  3. O DatabricksFunctionClient envia a execução como uma UDF para uma instância sem servidor.

Modo local para desenvolvimento

O modo local é projetado para desenvolvimento e depuração. Ele executa funções em um subprocesso local em vez de fazer solicitações para um endpoint do Serverless SQL. Isso permite que você resolva problemas de chamadas de ferramenta com mais eficiência, fornecendo rastreamentos de pilha locais.

Quando o agente solicita a execução de uma ferramenta no modo local, o DatabricksFunctionClient faz o seguinte:

  1. Envia uma solicitação ao Catálogo do Unity para recuperar a definição de função se a definição não tiver sido armazenada em cache localmente.
  2. Extrai a definição de função chamável de Python, armazena em cache a função localmente e valida os nomes e tipos de parâmetro.
  3. Chama o invocável com os parâmetros especificados em um subprocesso restrito com proteção contra tempo limite.
# Defaults to serverless if `execution_mode` is not specified
client = DatabricksFunctionClient(execution_mode="local")

A execução no "local" modo fornece os seguintes recursos:

  • Limite de tempo da CPU: Restringe o runtime total da CPU para execução callable para evitar cargas computacionais excessivas.

    O limite de tempo da CPU baseia-se no uso real da CPU, não no tempo do relógio de parede. Devido ao agendamento do sistema e a processos simultâneos, o tempo de CPU pode exceder o tempo de relógio em cenários reais.

  • Limite de memória: Restringe a memória virtual alocada ao processo.

  • Proteção de tempo limite: Impõe um tempo limite total do relógio de parede para executar funções.

Personalize esses limites usando variáveis de ambiente (leia mais).

Variáveis de ambiente

Configure como as DatabricksFunctionClient funções são executadas usando as seguintes variáveis de ambiente:

Variável de ambiente Valor padrão Descrição
EXECUTOR_MAX_CPU_TIME_LIMIT 10 Segundos Tempo máximo de execução da CPU permitido (somente no modo local).
EXECUTOR_MAX_MEMORY_LIMIT 100 MB Alocação máxima de memória virtual permitida para o processo (somente no modo local).
EXECUTOR_TIMEOUT 20 Segundos Tempo máximo total do relógio de parede (somente no modo local).
UCAI_DATABRICKS_SESSION_RETRY_MAX_ATTEMPTS 5 O número máximo de tentativas de tentar atualizar novamente o cliente de sessão em caso de expiração do token.
UCAI_DATABRICKS_SERVERLESS_EXECUTION_RESULT_ROW_LIMIT 100 O número máximo de linhas a serem retornadas ao executar funções usando computação sem servidor e databricks-connect.

Próximas etapas