C.W.K.
Stream
Lesson 01 of 04 · published

Tool Declarations & Schema

~14 min · tools, function-calling, schema, openapi

Level 0Spark
0 XP0/35 lessons0/10 achievements
0/140 XP to next level140 XP to go0% complete

The model can't read your code

Function calling sounds like the model executes your functions. It doesn't. The model reads your declarations — names, descriptions, parameter schemas — and emits a structured request asking you to call them. You execute, you return the result, the model continues.

Which means: the description and schema you write are the only things the model knows about your tool. They're not documentation; they're the API contract.

OpenAPI subset, not full JSON Schema

Gemini's tool schema is a subset of OpenAPI 3.0. The differences from full JSON Schema matter:

FeatureGemini (OpenAPI subset)JSON Schema
Top-level typeAlways "object"Anything
$ref / $defsNot supportedSupported
anyOf / oneOfNot supportedSupported
additionalPropertiesNot recognizedSupported
EnumsUse enum arraySame
Nested objectsSupportedSupported

Translation: keep schemas flat, no refs, no union types. If your real-world tool needs polymorphism, expose it as separate tools instead.

Descriptions matter more than names

The model picks tools by reading the description. A function called do_thing with a great description outperforms a function called queryEnterpriseAccountManagementSystem with a vague one. Write descriptions like you're writing the docstring for a colleague who only has 30 seconds to skim.

Code

A clean tool declaration·python
from google.genai import types

set_lights = {
    'name': 'set_light_values',
    'description': (
        'Adjusts the brightness and color temperature of a smart light. '
        'Brightness is a 0-100 integer percentage. Color temperature is one '
        'of "daylight" (5000K), "cool" (4000K), or "warm" (2700K).'
    ),
    'parameters': {
        'type': 'object',
        'properties': {
            'brightness': {
                'type': 'integer',
                'description': 'Brightness percent, 0-100.',
            },
            'color_temp': {
                'type': 'string',
                'enum': ['daylight', 'cool', 'warm'],
                'description': 'Color temperature preset.',
            },
        },
        'required': ['brightness', 'color_temp'],
    },
}

tools = types.Tool(function_declarations=[set_lights])
TypeScript shape — same idea·typescript
import { Type } from '@google/genai';

const setLights = {
  name: 'set_light_values',
  description: 'Adjusts brightness (0-100) and color temperature (daylight/cool/warm).',
  parameters: {
    type: Type.OBJECT,
    properties: {
      brightness: {
        type: Type.INTEGER,
        description: 'Brightness percent, 0-100.',
      },
      color_temp: {
        type: Type.STRING,
        enum: ['daylight', 'cool', 'warm'],
        description: 'Color temperature preset.',
      },
    },
    required: ['brightness', 'color_temp'],
  },
};
Patterns that fail silently·python
# ❌ Top-level array — Gemini wants object
bad1 = {'name': 'log_events', 'parameters': {'type': 'array', 'items': {...}}}

# ❌ Union types via anyOf
bad2 = {
    'parameters': {
        'type': 'object',
        'properties': {
            'value': {'anyOf': [{'type': 'string'}, {'type': 'integer'}]}
        }
    }
}

# ❌ Refs
bad3 = {
    'parameters': {
        'type': 'object',
        '$defs': {'User': {...}},
        'properties': {'user': {'$ref': '#/$defs/User'}}
    }
}

# ✅ Flat the union into two tools instead
set_string_value = {'name': 'set_string_value', 'parameters': {'type': 'object', 'properties': {'value': {'type': 'string'}}, 'required': ['value']}}
set_int_value    = {'name': 'set_int_value',    'parameters': {'type': 'object', 'properties': {'value': {'type': 'integer'}}, 'required': ['value']}}

External links

Exercise

Pick an API you actually use (a calendar, weather service, GitHub) and write 2 tool declarations for it. Force yourself to write descriptions tight enough that a colleague could correctly call the tools without asking you. Then ask Flash to use them with a natural-language prompt. If it fumbles, your descriptions need work — not the schema.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.