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:
| Feature | Gemini (OpenAPI subset) | JSON Schema |
|---|---|---|
| Top-level type | Always "object" | Anything |
$ref / $defs | Not supported | Supported |
anyOf / oneOf | Not supported | Supported |
additionalProperties | Not recognized | Supported |
| Enums | Use enum array | Same |
| Nested objects | Supported | Supported |
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.