Use Gemini function calling and ADK-style orchestration patterns.
Function calling bridges natural language to application code.
Learners understand Gemini function calling as structured intent.
Why this matters: This prevents treating model-produced calls as already authorized actions.
Problem anchor: a user asks “Schedule a project review with Maya tomorrow.” Gemini function calling can return a structured request such as schedule_meeting(attendees, time), but the app must validate calendar access, time zone, conflicts, and approval.
Official Gemini docs frame function calling as connecting models to external tools and APIs. The model determines when to call a function and supplies parameters; client code performs the real action.
The model may return a meeting function with attendee and time fields. The app parses the call, validates required fields, checks policy, then either executes or asks the user to confirm.
If the model invents an attendee email or vague time, the app should request clarification rather than guessing.
ADK turns a model-plus-tools pattern into an agent object.
Learners map ADK agent objects to product behavior.
Why this matters: This distinguishes direct Gemini API calls from ADK agent runtime structure.
Google ADK docs show LlmAgent configured with a model, name, description, instruction, and tools. Python can accept a native function directly as a tool, while other languages may use explicit FunctionTool wrappers or annotations.
The LLM uses tool names, descriptions, docstrings, and parameter schemas to decide which tool to call. That means tool naming and docstrings are behavioral design, not decoration.
A simple agent answers capital-city questions with a function. In a product setting, the same pattern becomes a support agent with tools for KB search, ticket lookup, and draft reply creation.
The risk rises with tools: a search tool is low risk; a ticket update tool needs policy and approval.
ADK state and workflows are application control surfaces.
Learners understand ADK session state and workflow patterns.
Why this matters: State and loops can create subtle bugs without stop rules and ownership.
ADK session state can be injected into LlmAgent instructions with template keys such as {topic}. This is powerful for context-aware behavior, but values should be controlled product state, not random transcript leftovers.
ADK also documents workflow-style agents such as sequential, parallel, and loop patterns. Loop workflows need explicit termination mechanisms or max iterations.
| Option | Choice | Use when | Risk | When to choose | Cost | Complexity |
|---|---|---|---|---|---|---|
| Direct function call | Single model request with declared functions. | One-shot tool use is enough. | App owns more orchestration. | Use for small integrations. | Low | Low |
| LlmAgent with tools | Reusable agent with instructions and tools. | Behavior and toolset repeat across sessions. | Tool descriptions shape behavior. | Use for product agents. | Medium | Medium |
| Workflow/multi-agent pattern | Sequential, parallel, loop, or delegated agents. | Control flow has real structure. | Loops need termination and eval. | Use after simple agent is insufficient. | Medium | High |
The useful example validates the call before the side effect.
Learners write a concrete ADK/Gemini-style tool example.
Why this matters: Runnable-looking examples make the model/runtime boundary tangible.
For teaching, use a harmless function such as looking up a capital or checking availability. For product work, wrap side effects in policy and approval.
Spaced recall: from structured outputs, schemas help shape arguments but do not prove intent. Keep executor validation close to the function.
from google.adk.agents import LlmAgent def get_capital_city(country: str) -> str: """Retrieves the capital city for a supported country.""" capitals = {"france": "Paris", "japan": "Tokyo", "canada": "Ottawa"} return capitals.get(country.lower(), f"Unknown country: {country}") capital_agent = LlmAgent( model="gemini-flash-latest", name="capital_agent", description="Answers capital-city questions for supported countries.", instruction="Use the tool for capital-city lookups. Do not invent unsupported capitals.", tools=[get_capital_city], ) # In a real app, inspect the tool call and result in the ADK event stream. print(get_capital_city("Japan"))
It prints Tokyo because the function lowercases the country and finds japan in the dictionary.
Tool-calling quality lives in the call trace.
Learners define production checks for ADK tool use.
Why this matters: A final answer can hide wrong tool selection or unsafe arguments.
For Gemini function calling and ADK agents, evaluation should inspect whether the model chose the right tool, produced valid arguments, handled tool errors, respected session state, and avoided tools when it should answer directly.
For side effects, test approval gates and idempotency. For workflows, test loop termination and state updates. For integrations, date-stamp API assumptions because ADK versions and supported languages can evolve.
Review the event or tool trace with the final answer.
Retrieval prompt: reconstruct Google ADK by naming Gemini function calling, FunctionTool, LlmAgent, session state, AgentTool, workflow agents, and host execution policy.
Build a small Gemini/ADK design for a calendar assistant: one function declaration, one LlmAgent, session state key, approval rule before scheduling, and a test for malformed arguments. Next rung: compare ADK workflows with LangGraph.
When Gemini decides to call a tool, what does it actually return to your code?
Gemini only produces a structured call request (name + args); your application code is responsible for actually running the function and returning the result.
You want to give an LlmAgent a Python function called check_inventory. Which of the following correctly makes it available to the agent?
ADK's FunctionTool wrapping happens automatically when you pass a plain Python function in the tools list — you don't need to subclass or manually wrap it.
An agent's instruction string contains the placeholder {user_budget}. Where does the value for user_budget come from at runtime?
ADK reads matching keys from session.state and substitutes them into the instruction template at runtime, letting context change turn-by-turn without rebuilding the agent.
Name ONE key difference between a SequentialAgent and a LoopAgent in ADK, and give a one-sentence example of when you would choose a LoopAgent over a SequentialAgent.
SequentialAgent is for a fixed pipeline; LoopAgent is for repeated execution with a dynamic exit condition — a critical design choice when building multi-step workflows.
When writing tests for a FunctionTool-style agent, which of the following is the MOST important thing to assert — beyond checking the agent's final text reply?
Tool-call evaluation means asserting which tool was invoked (or skipped), what arguments were passed, and whether downstream validation and approval logic fired correctly — the final reply alone can mask bugs in all of these.