An agent without tools is just a chatbot. ADK gives your Vertex AI agent five ways to connect to APIs - function tools, OpenAPI tools, MCP tools, built-in tools, and agent-as-tool. Here's how to wire them up with Terraform provisioning the infrastructure.
In the previous post, we deployed a Vertex AI agent with ADK and Agent Engine. It can reason and hold conversations, but without tools it can only generate text. Ask it to check a stock price or create a ticket, and it describes what it would do instead of doing it.
ADK's tool ecosystem is where GCP agents shine. Unlike AWS where action groups require Lambda functions and OpenAPI schemas as separate resources, ADK lets you define tools as Python functions, OpenAPI specs, MCP servers, or even other agents - all in the same codebase. The agent decides which tool to use based on the user's request, and ADK handles the execution. Terraform provisions the infrastructure; Python defines the capabilities. π―
π§ Five Tool Types in ADK
| Tool Type | What It Does | Best For |
|---|---|---|
| Function Tool | Plain Python function | Custom logic, calculations, internal APIs |
| OpenAPI Tool | Auto-generated from OpenAPI spec | Existing REST APIs with documentation |
| MCP Tool | Connects to MCP servers | Third-party services (GitHub, Slack, DBs) |
| Built-in Tool | Google Search, Code Execution | Web search, running generated code |
| Agent Tool | Uses another agent as a tool | Delegation, specialized sub-tasks |
This post focuses on function tools and OpenAPI tools - the two patterns that connect your agent to your own APIs.
π§ Function Tools: Python Functions as Agent Capabilities
The simplest way to give an agent a capability. Write a Python function with a docstring, and ADK makes it available as a tool:
# agent_source/tools.py
import urllib.request
import json
def get_exchange_rate(
currency_from: str,
currency_to: str,
) -> dict:
"""Get the current exchange rate between two currencies.
Use this when the user asks about currency conversion or exchange rates.
Args:
currency_from: The source currency code (e.g., USD, EUR, GBP).
currency_to: The target currency code (e.g., USD, EUR, GBP).
Returns:
A dictionary with the exchange rate.
"""
url = f"https://api.frankfurter.dev/v1/latest?base={currency_from}&symbols={currency_to}"
req = urllib.request.Request(url)
with urllib.request.urlopen(req) as resp:
data = json.loads(resp.read())
rate = data["rates"].get(currency_to, "N/A")
return {"rate": rate, "from": currency_from, "to": currency_to}
The docstring is the schema. ADK uses type hints for parameter types and the docstring for descriptions. The agent reads these to decide when and how to call the function. Clear docstrings drive better tool selection, just like OpenAPI descriptions in AWS action groups.
Wire Tools to the Agent
# agent_source/agent.py
import json
from google.adk.agents import Agent
from google.adk.models.vertexai import VertexAi
from tools import get_exchange_rate
with open("config.json") as f:
config = json.load(f)
model = VertexAi(model=config["model_id"])
agent = Agent(
name=config["agent_name"],
model=model,
instruction=config["instruction"],
tools=[get_exchange_rate], # Register tools here
)
That's it. No Lambda function, no OpenAPI schema file, no IAM permissions for tool invocation. The function runs in the same process as the agent.
Multiple Function Tools
Add as many tools as needed. The agent decides which to call:
from tools import get_exchange_rate, get_weather, create_ticket
agent = Agent(
name=config["agent_name"],
model=model,
instruction="""You are a helpful assistant.
Use get_exchange_rate for currency questions.
Use get_weather for weather queries.
Use create_ticket for support requests.""",
tools=[get_exchange_rate, get_weather, create_ticket],
)
Instruction quality matters. Tell the agent when to use each tool. Without guidance, the model guesses based on docstrings alone - explicit instructions improve tool selection accuracy.
π§ OpenAPI Tools: Auto-Generate from API Specs
For existing REST APIs with OpenAPI documentation, ADK can generate tools automatically:
# agent_source/agent_with_openapi.py
from google.adk.agents import Agent
from google.adk.models.vertexai import VertexAi
from google.adk.tools.openapi_tool.openapi_spec_parser.openapi_toolset import OpenAPIToolset
model = VertexAi(model=config["model_id"])
# Load OpenAPI spec and generate tools
petstore_toolset = OpenAPIToolset(
spec_str=open("petstore_openapi.yaml").read(),
spec_str_type="yaml",
)
agent = Agent(
name="api-agent",
model=model,
instruction="You manage the pet store. Use the API tools to list, create, and look up pets.",
tools=[petstore_toolset],
)
OpenAPIToolset parses the spec and creates one RestApiTool per operation. The agent sees list_pets, create_pet, get_pet_by_id as separate callable tools. When the agent decides to call one, ADK handles the HTTP request automatically.
OpenAPI Tool with Authentication
For APIs requiring auth, pass credentials to the toolset:
from google.adk.tools.openapi_tool.auth.auth_helpers import token_to_scheme_credential
toolset = OpenAPIToolset(
spec_str=open("my_api.yaml").read(),
spec_str_type="yaml",
auth_scheme_credential=token_to_scheme_credential(
"bearer", "my-api-token"
),
)
π§ Terraform: Infrastructure for Tool-Connected Agents
Terraform provisions the APIs, IAM, and any GCP services your tools need. The tool logic stays in Python.
APIs for External Connectivity
# agent/apis.tf
resource "google_project_service" "agent_tools" {
for_each = toset([
"aiplatform.googleapis.com",
"cloudfunctions.googleapis.com",
"secretmanager.googleapis.com", # For API keys
"run.googleapis.com", # For Agent Engine
])
project = var.project_id
service = each.value
}
Store API Keys in Secret Manager
# agent/secrets.tf
resource "google_secret_manager_secret" "api_keys" {
for_each = var.tool_api_keys
secret_id = "${var.environment}-${each.key}-api-key"
project = var.project_id
replication {
auto {}
}
}
resource "google_secret_manager_secret_version" "api_keys" {
for_each = var.tool_api_keys
secret = google_secret_manager_secret.api_keys[each.key].id
secret_data = each.value
}
# Grant agent SA access to secrets
resource "google_secret_manager_secret_iam_member" "agent_access" {
for_each = var.tool_api_keys
secret_id = google_secret_manager_secret.api_keys[each.key].id
role = "roles/secretmanager.secretAccessor"
member = "serviceAccount:${google_service_account.agent.email}"
}
Config with Tool Settings
# agent/config.tf
resource "local_file" "agent_config" {
filename = "${path.module}/agent_source/config.json"
content = jsonencode({
project_id = var.project_id
location = var.region
model_id = var.agent_model.id
agent_name = "${var.environment}-${var.agent_name}"
instruction = var.agent_instruction
tool_config = {
api_key_secret = "${var.environment}-exchange-rate-api-key"
}
})
}
π Sequential Tool Use
ADK supports chaining tools where one tool's output feeds another. Describe the sequence in the agent's instructions:
agent = Agent(
name="research-agent",
model=model,
instruction="""You are a research assistant.
When the user asks for analysis:
1. First use search_documents to find relevant data
2. Then use summarize_data to create a summary
3. Finally use create_report to format the output""",
tools=[search_documents, summarize_data, create_report],
)
The agent follows the sequence, passing results between tools automatically. No orchestration code needed.
β οΈ Gotchas and Tips
Docstrings are your schema. ADK infers tool descriptions from Python docstrings and type hints. Missing or vague docstrings mean the agent can't properly select or parameterize the tool.
Tool limitations. Some built-in tools (Google Search, Code Execution) can't be combined with other tools in the same agent. Check ADK documentation for compatibility.
Long-running tools. For operations that take more than a few seconds, use LongRunningFunctionTool which supports async execution with polling.
Testing locally. ADK's CLI (adk run) and dev UI let you test tool interactions locally before deploying to Agent Engine. Always test tool selection with varied prompts.
βοΈ What's Next
This is Post 2 of the GCP AI Agents with Terraform series.
- Post 1: Deploy First Vertex AI Agent π€
- Post 2: Agent Tools - Connect to APIs (you are here) π
- Post 3: Multi-Agent with Agent Engine
- Post 4: Agent + Google Search Grounding
Your agent can now take action. Function tools, OpenAPI tools, MCP integrations - ADK makes your Python functions into agent capabilities. The model reasons; your code executes. π
Found this helpful? Follow for the full AI Agents with Terraform series! π¬
Top comments (0)