Ganchos do Ciclo de Vida

Usando ganchos do ciclo de vida para monitorar e depurar a execução do agente.

Usando Ganchos do Ciclo de Vida para Monitorar a Execução do Agente

Os hooks do ciclo de vida permitem que você conecte suas etapas de log ou processamento personalizadas em eventos-chave do ciclo de vida durante o método agent.run(), como chamadas de função e interações de serviço remoto.

Esse recurso é particularmente útil quando você deseja exibir os detalhes desses eventos em um formato legível por humanos para seus usuários finais em seu aplicativo da Web ou para os desenvolvedores de seus agentes se você oferecer uma plataforma para que seus clientes criem e observem agentes.

Python

lifecycle_hook.py

import json

from rich.console import Console

from oci.addons.adk import Agent, AgentClient
from oci.addons.adk.tool.prebuilt import CalculatorToolkit
from oci.addons.adk.run.types import RequiredAction, PerformedAction

# A callback function that is called when a required action is fulfilled
def handle_fulfilled_required_action(required_action: RequiredAction, performed_action: PerformedAction):
    # Implement your custom logging or processing here
    # Access the required action and performed action objects to get the details
    pass

# A callback function that is called when a remote service is invoked
def handle_invoked_remote_service(chat_request, chat_response):
    # Implement your custom logging or processing here
    # Access the chat request and response objects to get the details
    pass

def main():

    client = AgentClient(
        auth_type="api_key",
        profile="DEFAULT",
        region="us-chicago-1"
    )

    agent = Agent(
        client=client,
        agent_endpoint_id="ocid1.genaiagentendpoint...",
        instructions="You're a helpful assistant that can perform calculations.",
        tools=[CalculatorToolkit()]
    )

    agent.setup()

    input = "What's the square root of 475695037565?"
    response = agent.run(
        input,
        max_steps=6,
        on_fulfilled_required_action=handle_fulfilled_required_action,
        on_invoked_remote_service=handle_invoked_remote_service,
    )

    response.pretty_print()

if __name__ == "__main__":
    main()

Java

LifecycleHookAgent.java


package demos;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.oracle.bmc.ConfigFileReader;
import com.oracle.bmc.auth.BasicAuthenticationDetailsProvider;
import com.oracle.bmc.auth.SessionTokenAuthenticationDetailsProvider;
import com.oracle.bmc.generativeaiagentruntime.model.FunctionCallingPerformedAction;
import com.oracle.bmc.generativeaiagentruntime.model.FunctionCallingRequiredAction;
import com.oracle.bmc.generativeaiagentruntime.model.PerformedAction;
import com.oracle.bmc.generativeaiagentruntime.model.RequiredAction;
import com.oracle.bmc.generativeaiagentruntime.responses.ChatResponse;
import com.oracle.bmc.adk.agent.Agent;
import com.oracle.bmc.adk.agent.RunOptions;
import com.oracle.bmc.adk.client.AgentClient;
import com.oracle.bmc.adk.tools.prebuilt.CalculatorToolkit;
import com.oracle.bmc.adk.run.RunResponse;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

public class LifecycleHookAgent {
  private static final ObjectMapper objectMapper = new ObjectMapper();

  public static void main(String[] args) throws Exception {
    final String AGENT_ENDPOINT_ID =
        "ocid1.genaiagentendpoint.oc1.us-chicago-1...";

    final String configLocation = "~/.oci/config";
    final String configProfile = "DEFAULT";
    BasicAuthenticationDetailsProvider authProvider =
            new SessionTokenAuthenticationDetailsProvider(
                    ConfigFileReader.parse(configLocation, configProfile));

    AgentClient agentClient = AgentClient.builder()
        .authProvider(authProvider)
        .region("us-chicago-1")
        .build();

    // Instantiate the local agent object (with the client, instructions, and tools to be
    // registered)
    Agent agent = Agent.builder()
            .client(agentClient)
            .agentEndpointId(WRITER_AGENT_ENDPOINT_ID)
            .instructions("You are a helpful assistant that can perform calculations.")
            .tools(List.of(new CalculatorToolkit()))
            .build();

    // Set up the agent (configures the instructions and tools in the remote agent resource)
    agent.setup();

    // Use the agent to process the end user request (automatically handles function calling)
    final String input = "What is the square root of 16?";
    final Integer maxStep = 6;
    final RunOptions runOptions = RunOptions.builder()
            .maxSteps(maxStep)
            .onFulfilledRequiredAction(LifecycleHookAgent::handleFulfilledRequiredAction)
            .onInvokedRemoteService(LifecycleHookAgent::handleInvokedRemoteService)
            .build();

    RunResponse response = agent.run(input, runOptions);

    response.prettyPrint();
  }

  public static void handleFulfilledRequiredAction(
      RequiredAction requiredAction, PerformedAction performedAction) {
    String toolCallName =
        ((FunctionCallingRequiredAction) requiredAction).getFunctionCall().getName();
    String toolCallArgs =
        ((FunctionCallingRequiredAction) requiredAction).getFunctionCall().getArguments();
    String toolCallOutput =
        ((FunctionCallingPerformedAction) performedAction).getFunctionCallOutput();

    // Format JSON strings with proper indentation
    String formattedArgs = formatJson(toolCallArgs);
    String formattedOutput = formatJson(toolCallOutput);

    String baseMessage = "Executed client-side function tool: **" + toolCallName + "**";
    String details =
        "Function Tool call arguments:\n```json\n"
            + formattedArgs
            + "\n```\nFunction Tool call output:\n```json\n"
            + formattedOutput
            + "\n```";

    System.out.println(baseMessage);
    System.out.println(details);
  }

  public static void handleInvokedRemoteService(
      Map<String, Object> chatRequest, ChatResponse chatResponse) {
    String label = "Invoked Agent Service API: ";
    if (chatResponse.getChatResult().getRequiredActions() != null) {
      List<RequiredAction> actions = chatResponse.getChatResult().getRequiredActions();
      label += " received " + actions.size() + " action(s) for client to take";
    } else {
      label += " received agent text message";
    }

    String content =
        "Agent Service call request:\n```json\n"
            + formatJson(chatRequest)
            + "\n```\nAgent Service call response:\n```json\n"
            + formatJson(chatResponse)
            + "\n```";

    System.out.println(label);
    System.out.println(content);
  }

  private static String formatJson(Object obj) {
    try {
      return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
    } catch (JsonProcessingException e) {
      return obj.toString();
    }
  }
}

Atualmente, o ADK suporta dois ganchos de ciclo de vida:

  • on_fulfilled_required_action: Este gancho é chamado depois que uma ação necessária é atendida, como uma ferramenta de função é chamada.
  • on_invoked_remote_service: Esse gancho é chamado quando a API do serviço de agente remoto é chamada.