ライフサイクル・フック

ライフサイクル・フックを使用したエージェント実行の監視およびデバッグ。

ライフサイクル・フックを使用したエージェント実行の監視

ライフサイクル・フックを使用すると、ファンクション・コールやリモート・サービス相互作用などのagent.run()メソッド中に、主要なライフサイクル・イベントにカスタム・ロギングまたは処理ステップをプラグインできます。

この機能は、これらのイベントの詳細を人間が読める形式でWebアプリケーションのエンド・ユーザーに表示する場合や、顧客がエージェントを構築および監視するためのプラットフォームを提供している場合はエージェント開発者に特に役立ちます。

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();
    }
  }
}

現在、ADKは2つのライフサイクル・フックをサポートしています。

  • on_fulfilled_required_action: このフックは、ファンクション・ツールの起動など、必要なアクションの実行後にコールされます。
  • on_invoked_remote_service: このフックは、リモート・エージェント・サービスAPIが呼び出されたときにコールされます。