Add a Function Tool to an Agent using the ADK

This tutorial covers the steps to add a function tool to an existing agent in Generative AI Agents.

Function tools allow the agent to use custom-written, locally-defined functions as tools. They're very flexible and particularly useful for enterprise cases due to its local processing, easy authentication, and seamless integration with existing functionality.

In this example, we have a weather agent equipped with a custom function tool. This is also known as a function calling agent.

Note

Function tools are executed locally on your side.

What is sent to a remote agent on OCI servers is the function definition (function name, function parameters, and their descriptions). OCI servers do not access the function implementation.

Overview

When a weather query is made, the remote agent effectively does the intent classification to use the get_weather tool. For example, based on the natural language query Is it cold in Seattle?, the remote agent fills the argument slot and makes the request.

The agent sends a request that contains the required actions for the client app. In this case, the required action for the client is to invoke the get_weather function tool with an argument location=Seattle.

The Agent Development Kit (ADK) does the following:

  • parses the required action
  • finds the local function registered
  • runs this function with the specific arguments
  • captures the function call output
  • submits the output back to the remote agent, so that the agent can use that output to generate an answer to the user prompt

Prerequisites

Before you create an agent app, perform these steps:
  1. On the machine running your code, set up an OCI API config file. Ensure the configuration refers to a region in which Generative AI Agents is hosted.
  2. Create a virtual environment:
    python3 -m venv <myenv>

    Activate the virtual environment.

    source <myenv>/bin/activate
  3. Install the ADK. Python ADK requires Python 3.10 or later.
    pip install "oci[adk]

Set up a Compartment for Development

To set up the compartment, follow these steps:
  1. Ask an administrator to add the following IAM policy for you:
    allow <a-group-your-user-name-belongs-to> to manage all-resources in compartment <your-compartment-name>
    Important

    Providing complete access to a compartment is convenient for a tutorial. However, in production, use more restrictive policies to limit access to the agent. See Getting Access to Generative AI Agents.
  2. Sign in to the Oracle Cloud Infrastructure Console.
  3. Open the navigation menu and select Identity & Security. Under Identity, select Compartments.
  4. Select Create Compartment.
  5. Fill in the following information:
    • Name: <your-compartment-name>
    • Description: Compartment for <your-description>.
    • Parent Compartment: <your-tenancy>(root)
  6. Select Create compartment.

Reference: Create a compartment

Create an Agent

  1. In the navigation bar of the Console, select the same region that you selected for the config file in the previous section.
  2. On the Agents list page, select Create agent. If you need help finding the list page, see Listing Agents.
  3. Enter the following information:
    • Name: <your-agent-name>
    • Compartment: Select a compartment that you have permission to work in.
    • Description: Agent with no initial tools. Adding tools with ADK.
    • Welcome message: Leave blank.
    • Routing instructions: Leave blank.
  4. Select Next to navigate to the Add Tool step. Skip this page and don't add any tools.
  5. Select Next.
  6. (Optional) Select Automatically create an endpoint for this agent to create an endpoint when the agent is created and keep all the other default options.
  7. Select Next and then select Create Agent.
    Note

    Accept license terms if requested.
  8. Wait for the agent to become active.

Gather Required Info

  1. In your environment, copy the region that you set up for the config file in a notepad. For example, us-chicago-1.
  2. In the Console, on the Agents list page, select the agent that you created in this tutorial. If you need help finding the list page, see Listing Agents.
  3. Copy the OCID for the agent and paste it in a notepad for the next section.

    Example agent OCID: ocid1.genaiagent.oc1.us-chicago-1.<unique-id>

  4. Select the Endpoint for this agent.
  5. Copy the OCID for the endpoint and paste it in a notepad for the next section.

    Example endpoint OCID: ocid1.genaiagentendpoint.oc1.us-chicago-1.<unique-id>

  6. Navigate to Identity and Security and select Compartments. Select the compartment with the agent. Copy the OCID for the compartment and paste it in a notepad.

    Example compartment OCID: ocid1.compartment.oc1..<unique-id>

Create a Local File

  1. From the terminal, go to your home directory.
  2. Create a directory called ADK.
  3. Change to the ADK directory.
  4. Create a file called, weather_agent.py.
  5. Paste the following code into weather-agent.py.
    Replace <region-where-agent-is-created> and <your-agent-endpoint> with the values that you gathered.
    from typing import Dict
    from adk import Agent, AgentClient, tool
    
    @tool
    def get_weather(location: str) -> Dict[str, str]:
        """Get the weather for a given location"""
        return {"location": location, "temperature": 72, "unit": "F"}
    
    
    def main():
        # Create a client with your authentication details
        client = AgentClient(
            auth_type="api_key",
            profile="DEFAULT",
            region="<region-where-agent-is-created>"
        )
    
        # Instantiate the agent with your agent endpoint ID and the tool
    
        agent = Agent(
            client=client,
            agent_endpoint_id="<your-agent-endpoint>",
            instructions="Perform weather queries using the given tools.",
            tools=[get_weather]
        )
    
        # Set up the agent (configures instructions and tools in the remote agent resource)
        agent.setup()
    
        # Run the agent with an input
        input = "Is it cold in Seattle?"
        response = agent.run(input)
    
        # Print the response
        response.pretty_print()
    
    if __name__ == "__main__":
        main()

Add the Tool

Important

If you chose an existing agent instead of creating a new one for this tutorial, before you run this file ensure the remote agent has no tools. This program deletes all the tools on the remote agent, unless it's the tool is named get_weather tool. If it finds a remote get_weather tool it updates the remote tool to be synchronized with the local one.
  1. In the Console, navigate to the agent's detail page and note the values for.
    • Routing instructions: Should be blank.
    • Select Tools. The tool list should be empty.
  2. Run the Python file, get_weather
    python3 weather-agent.py
  3. In the output, review the local and remote function names and ensure that the get_weather tool is being added to the remote agent. Example output:
    Waiting for agent to be active...
    ╭─ Local and remote function tools found ─╮
    │ Local function tools (1):               │
    │ ['get_weather']                         │
    │                                         │
    │ Remote function tools (0):              │
    │ []                                      │
    ╰─────────────────────────────────────────╯
    Found local tool not in remote tools: get_weather. Adding it to the remote agent...
    Waiting for tool to be active...
    Checking synchronization of local and remote RAG tools...                                                             
    No active remote RAG tools found. No local RAG tool to add.                                                                                                                                                        
  4. In the Console, navigate to the agent's detail page and watch the updates.
    • In the agent detail page, the Routing instructions changes from blank to Perform weather queries using the given tools.
    • Select Tools. The tool, get_weather appears in the list of tools.
    • Select get_weather and under work requests, see that the CREATE_TOOL operation succeeded.

Read the Outputs

  1. In the output, read the user message. Example output:
    
                                                          
    ╭──────────────────────────────────── Chat request to remote agent ─────────────────────────────────────╮
    │ (Local --> Remote)                                                                                    │
    │                                                                                                       │
    │ user message:                                                                                         │
    │ Is it cold in Seattle?                                                                                │
    │                                                                                                       │
    │ performed actions by client:                                                                          │
    │ []                                                                                                    │
    │                                                                                                       │
    │ session id:                                                                                           │
    │ ocid1.genaiagentsession.<unique-id>                                                          │
    ╰───────────────────────────────────────────────────────────────────────────────────────────────────────╯           
  2. Read the chat response. Example output:
    
    ╭────────────────── Chat response from remote agent ──────────────────╮
    │ (Local <-- Remote)                                                  │
    │                                                                     │
    │ agent message:                                                      │
    │ null                                                                │
    │                                                                     │
    │ required actions for client to take:                                │
    │ [                                                                   │
    │     {                                                               │
    │         "action_id": "<unique-id>",        │
    │         "required_action_type": "FUNCTION_CALLING_REQUIRED_ACTION", │
    │         "function_call": {                                          │
    │             "name": "get_weather",                                  │
    │             "arguments": "{\"location\": \"Seattle\"}"              │
    │         }                                                           │
    │     }                                                               │
    │ ]                                                                   │
    ╰─────────────────────────────────────────────────────────────────────╯                                                                           
  3. Read the function call requested by the agent. Example output:
    
    ╭─ Function call requested by agent and mapped local handler function ─╮
    │ Agent function tool name:                                            │
    │ get_weather                                                          │
    │                                                                      │
    │ Agent function tool call arguments:                                  │
    │ {'location': 'Seattle'}                                              │
    │                                                                      │
    │ Mapped local handler function name:                                  │
    │ get_weather                                                          │
    ╰──────────────────────────────────────────────────────────────────────╯                                                              
  4. Read the function execution result. Example output:
    
    ╭─────── Obtained local function execution result ────────╮
    │ {'location': 'Seattle', 'temperature': 72, 'unit': 'F'} │
    ╰─────────────────────────────────────────────────────────╯                                                           
  5. Read the chat request to the remote agent example output:
    
    ╭──────────────────────────────────── Chat request to remote agent ─────────────────────────────────────╮
    │ (Local --> Remote)                                                                                    │
    │                                                                                                       │
    │ user message:                                                                                         │
    │ null                                                                                                  │
    │                                                                                                       │
    │ performed actions by client:                                                                          │
    │ [                                                                                                     │
    │     {                                                                                                 │
    │         "action_id": "<unique-id>",                                          │
    │         "performed_action_type": "FUNCTION_CALLING_PERFORMED_ACTION",                                 │
    │         "function_call_output": "{\"location\": \"Seattle\", \"temperature\": 72, \"unit\": \"F\"}"   │
    │     }                                                                                                 │
    │ ]                                                                                                     │
    │                                                                                                       │
    │ session id:                                                                                           │
    │ ocid1.genaiagentsession.oc1.us-chicago-1.xxx                                                          │
    ╰───────────────────────────────────────────────────────────────────────────────────────────────────────╯                                                         
  6. Read the chat response from the remote agent example output:
    
    ╭─────────────────────────────── Chat response from remote agent ────────────────────────────────╮
    │ (Local <-- Remote)                                                                             │
    │                                                                                                │
    │ agent message:                                                                                 │
    │ {                                                                                              │
    │     "role": "AGENT",                                                                           │
    │     "content": {                                                                               │
    │         "text": "It's not cold in Seattle. The current temperature is 72 degrees Fahrenheit.", │
    │         "citations": null,                                                                     │
    │         "paragraph_citations": null                                                            │
    │     },                                                                                         │
    │     "time_created": "2025-04-10T18:47:33.617000+00:00"                                         │
    │ }                                                                                              │
    │                                                                                                │
    │ required actions for client to take:                                                           │
    │ null                                                                                           │
    ╰────────────────────────────────────────────────────────────────────────────────────────────────╯                                                      
  7. Read the agent run response that's in natural language. Example output:
    
    ╭──────────────────────────────────────────────── Agent run response ────────────────────────────────────────────────╮
    │ agent text message:                                                                                                │
    │ It's not cold in Seattle. The current temperature is 72 degrees Fahrenheit.                                        │
    ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
                                                   

Remove the Tool

  1. In your local environment, create a file called list_agent_tools.py with the following content. Also update the all the ID variables with your OCID information.
    import json
    from adk import AgentClient
    
    
    
    def main():
    
        agent_id = "ocid1.genaiagent.<unique-id>"
        agent_compartment_id = "<your-compartment-ocid>"
        region_id = "<your-region-id>"
        # Enter an OCI region such as "us-chicago-1" or airport code such as "ORD"
    
        # Create a client with your authentication details
        client = AgentClient(
            auth_type="api_key",
            profile="DEFAULT",
            region=region_id
        )
    
    
        # Find the tools of the following agent in the following compartment
        tool_list = client.find_tools(agent_compartment_id, agent_id)
    
        json_str = json.dumps(tool_list, indent=4)
    
        
    
        print(json_str)
    
        for item in tool_list:
            print(f"Tool Name: {item.get('display_name')}  \nTool OCID: {item.get('id')}")
    
    
    if __name__ == "__main__":
        main()

    This script calls the client's find_tool operation and returns all the tools for a specified agent in a specified compartment.

  2. Review the output:
    [
        {
        "id": "ocid1.genaiagenttool.<unique-id>",
            "lifecycle_state": "ACTIVE",
            "time_created": "2025-04-10T21:49:19.350000+00:00",
            "time_updated": "2025-04-10T21:49:42.132000+00:00",
            "display_name": "get_weather",
            "description": "Get the weather for a given location created by ADK",
            "compartment_id": "<your-compartment-ocid>",
                                    "agent_id": "ocid1.genaiagent.<unique-id>",
            "tool_config": {
                "tool_config_type": "FUNCTION_CALLING_TOOL_CONFIG",
                "function": {
                    "name": "get_weather",
                    "description": "Get the weather for a given location",
                    "parameters": {
                        "type": "object",
                        "properties": "{\"location\": {\"type\": \"string\"}}",
                        "required": "['location']"
                    }
                }
            },
            "metadata": null,
            "freeform_tags": {
                "ModifiedBy": "ADK",
                "CreatedBy": "ADK"
            },
            "defined_tags": {
                "Oracle-Tags": {
                    "CreatedBy": "john.doe@example.com",
                    "CreatedOn": "2025-04-10T21:49:19.277Z"
                }
            },
            "system_tags": {}
        }
    ]
    Tool Name: get_weather  
    Tool OCID: ocid1.genaiagenttool.oc1.us-chicago-1.amaa<your-ocid>
  3. Create a file called delete_tools.py and copy the following information to use the delete_tool operation to delete the weather_tool. Also update the all the ID variables with your OCID information.
    import json
    from adk import AgentClient
    
    
    
    def main():
    
    agent_id = "ocid1.genaiagent.<unique-id>"
        agent_compartment_id = "<your-compartment-ocid>"
        endpoint_id = "ocid1.genaiagentendpoint.<unique-id>"
        region_id = "<your-region-id>"
    
        # Create a client with your authentication details
        client = AgentClient(
            auth_type="api_key",
            profile="DEFAULT",
            region=region_id
        )
    
    
        # Find the tools of the following agent in the following compartment
        tool_list = client.find_tools(agent_compartment_id, agent_id)
    
        json_str = json.dumps(tool_list, indent=4)
    
        
    
        print(json_str)
    
        for item in tool_list:
            print(f"Tool Name: {item.get('display_name')}  \nTool OCID: {item.get('id')}")
    
        for item in tool_list:
            print(f"Deleting tool {item.get('display_name')} with tool OCID: {item.get('id')}")
            client.delete_tool(item.get('id'))
    
        print ("Tool deleted!")
    
    if __name__ == "__main__":
        main()
  4. In the Console, go to the agent's detail page and see that the tool is deleted.
  5. Deactivate the virtual environment.
    decativate