Function Calling with SDKs in Generative AI Agents
Use this guide to become familiar with using the OCI Java SDK to integrate function calling into an application. The following steps show an OCI Java SDK example for creating a function calling tool and then using chat to invoke the function calling tool.
Prerequisites
Before you begin, ensure that you have set up the following resources:
- An agent. See Creating an Agent in Generative AI Agents.
- An agent endpoint. See Creating an Endpoint in Generative AI Agents.
- The necessary OCI SDK and dependencies installed in your development environment. See Setup and Prerequisites.
Creating a Function Calling Tool
The following steps show how to use OCI Java SDK to create a function calling tool for an agent.
-
Configure the client. For example:
GenerativeAiAgentRuntimeClient agentClient = GenerativeAiAgentRuntimeClient.builder() .endpoint(endpoint) .configuration(clientConfiguration) .build(provider);
-
Define a function and then embed the function in the
ToolConfig
. For example, here is a function that creates an OCI Object Storage bucket:private static Function prepareFunction() { return Function.builder() .name("create_object") .description("A function to create an object storage bucket") .parameters("{\n" + " \"displayName\": \"Create Object Storage Bucket\",\n" + " \"description\": \"Create a new bucket in OCI Object Storage.\",\n" + " \"toolConfig\": {\n" + " \"toolConfigType\": \"FUNCTION_CALLING_TOOL_CONFIG\",\n" + " \"function\": {\n" + " \"name\": \"create_object_storage_bucket\",\n" + " \"description\": \"Creates a new bucket in OCI Object Storage within a specified compartment.\",\n" + " \"parameters\": {\n" + " \"type\": \"object\",\n" + " \"properties\": {\n" + " \"bucket_name\": {\n" + " \"type\": \"string\",\n" + " \"description\": \"The name of the bucket to create.\"\n" + " },\n" + " \"compartment_ocid\": {\n" + " \"type\": \"string\",\n" + " \"description\": \"The OCID of the compartment where the bucket will be created.\"\n" + " },\n" + " \"storage_tier\": {\n" + " \"type\": \"string\",\n" + " \"enum\": [\"Standard\", \"Archive\"],\n" + " \"description\": \"The storage tier for the bucket.\"\n" + " }\n" + " },\n" + " \"required\": [\"bucket_name\", \"compartment_ocid\"],\n" + " \"additionalProperties\": false\n" + " }\n" + " }\n" + " }\n" + "}") .build(); } private static ToolConfig createFunctionToolConfig() { return FunctionCallingToolConfig.builder() .function(prepareFunction()) .build(); }
-
Create a tool request and then create the tool using the client. For example:
CreateToolDetails createToolDetails = CreateToolDetails.builder() .agentId(agentId) .compartmentId(COMPARTMENT_ID) .toolConfig(toolConfig) .displayName("tool-sdk") .description("tool description") .build(); CreateToolRequest toolRequest = CreateToolRequest.builder() .createToolDetails(createToolDetails) .build(); client.createTool(toolRequest);
Chatting with an Agent
-
Create a session. For example:
GenerativeAiAgentRuntimeClient agentClient = GenerativeAiAgentRuntimeClient.builder() .endpoint(endpoint) .configuration(clientConfiguration) .build(provider); // Create a new chat session request CreateSessionRequest request = CreateSessionRequest.builder() .agentEndpointId(<agentEndpointId>) .createSessionDetails(CreateSessionDetails.builder() .description("description") .displayName("display_name") .build()) .build(); String sessionId = agentClient.createSession(request) .getSession() .getId();
Replace <agentEndpointId> with the OCID of the agent endpoint from the prerequisite section.
-
Use the session to make a chat call that invokes the function. This example sends a message to the agent and expects a response that includes a function call
String message = "Create an Object Store."; // Create Chat request final ChatDetails chatDetails = ChatDetails.builder() .shouldStream(shouldStream) .userMessage(message) .sessionId(sessionId) .build(); final ChatRequest chatRequest = ChatRequest.builder() .chatDetails(chatDetails) .agentEndpointId(agentEndpointId) .build(); final ChatResult chatResult = agentClient.chat(chatRequest);
The response from the agent includes a
required-actions
field, which contains the details of the function to be invoked.chatResult(message=null, traces=[], usageDetails=null, requiredActions=[FunctionCallingRequiredAction(super=RequiredAction(super=BmcModel (__explicitlySet__=[functionCall, actionId]) actionId=<some-action-id>), functionCall=FunctionCall(super=BmcModel(__explicitlySet__=[name, arguments])name=object_storage, arguments= {"bucket_name": "my_object_store", "compartment_ocid": "ocid1.compartment.oc1..xxx", "storage_tier": "Standard" }))], toolResults=null)
From the response, extract the
action-id
that's associated with the function call. This ID is used in the next step to perform the action.String actionId = "<some-action-id>";
-
Perform the action. The response contains the final response from the agent, which includes the result of the function call. For example:
String actionId = chatResponse.getChatResult().getRequiredActions().get(0).getActionId(); String functionCallOutput = "{"bucket_name": "test_bucket", "compartment_ocid": "
<compartment_OCID>
", "storage_tier":"Standard"}"; PerformedAction performedAction = FunctionCallingPerformedAction.builder() .actionId(actionId) .functionCallOutput(functionCallOutput) .build(); // Execute the chat session with the performed action final ChatDetails chatDetails = ChatDetails.builder() .shouldStream(shouldStream) .userMessage(userMessage) .performedActions(List.of(performedAction)) .sessionId(sessionId) .build(); final ChatRequest chatRequest = ChatRequest.builder() .chatDetails(chatDetails) .agentEndpointId(agentEndpointId) .build(); ChatResult chatResult = agentClient.chat(chatRequest); # Chat Result: # ChatResult(message=The object store 'my_object_store' has been successfully created in the specified compartment with the 'Standard' storage tier., traces=[], usageDetails=null, toolResults=null)