Tool/Function Schemas
Schemas for function calling.
Tool/Function Schemas is a free AI Prompt Engineering lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the AI Prompt Engineering learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Tools Are Schemas Plus Intent
Function calling lets a model request that your code execute an action. Each tool is declared with a name, a description (when to use it), and a JSON Schema for its parameters.
The model never runs code; it emits a structured call request that your runtime dispatches. The schema is what makes the arguments parseable.
Anatomy of a Tool Definition
A tool definition is a schema-wrapped capability declaration.
{
'type': 'function',
'function': {
'name': 'get_weather',
'description': 'Get current weather for a city. Use when the user asks about weather.',
'parameters': {
'type': 'object',
'properties': {
'city': {'type': 'string'},
'units': {'type': 'string', 'enum': ['celsius', 'fahrenheit']}
},
'required': ['city', 'units'],
'additionalProperties': False
}
}
}The Description Drives Selection
With many tools available, the model chooses based primarily on the description. Write descriptions as decision rules:
- State when to use it and when not.
- Disambiguate from sibling tools.
- Mention required preconditions.
Poor descriptions cause wrong-tool selection more often than poor schemas cause arg errors.
The Call-Execute-Return Loop
Function calling is multi-turn. The model emits a call, you execute, you append the result, and the model continues.
resp = client.chat.completions.create(model='gpt-4o', messages=msgs, tools=tools)
call = resp.choices[0].message.tool_calls[0]
args = json.loads(call.function.arguments)
result = dispatch(call.function.name, args)
msgs.append(resp.choices[0].message)
msgs.append({'role': 'tool', 'tool_call_id': call.id,
'content': json.dumps(result)})
# call the model again to continue with the tool resultParallel Tool Calls
Modern models can request multiple tool calls in one turn when actions are independent. Your runtime should iterate over all tool_calls, execute them (ideally concurrently), and return one tool message per tool_call_id.
Never assume a single call; always loop.
for call in resp.choices[0].message.tool_calls:
args = json.loads(call.function.arguments)
result = dispatch(call.function.name, args)
msgs.append({'role': 'tool', 'tool_call_id': call.id,
'content': json.dumps(result)})Forcing and Restricting Tool Use
Control selection with tool_choice:
auto— model decides.required— must call some tool.{name: ...}— force a specific tool.none— disable tools for this turn.
Forcing a specific tool turns function calling into pure structured extraction.
client.chat.completions.create(
model='gpt-4o', messages=msgs, tools=tools,
tool_choice={'type': 'function', 'function': {'name': 'get_weather'}}
)Validate Args Before Execution
Even with strict schemas, treat tool arguments as untrusted input. Re-validate against the schema and apply business rules before touching real systems (DBs, payments, file deletes).
def dispatch(name, args):
schema = TOOLS[name]['function']['parameters']
jsonschema.validate(args, schema) # defense in depth
if name == 'refund' and args['amount'] > MAX_AUTO_REFUND:
return {'error': 'requires human approval'}
return HANDLERS[name](**args)Tool Errors Are Part of the Protocol
When a tool fails, return a structured error as the tool result rather than throwing. The model can then apologize, retry with corrected args, or pick a different tool.
Make errors actionable: include a reason and, where safe, a hint for recovery.
{'status': 'error',
'code': 'CITY_NOT_FOUND',
'message': 'No city named Xyz. Ask the user to clarify the city.'}Keep the Tool Surface Small
Dozens of tools degrade selection accuracy and inflate token cost (every schema is in context every turn). Mitigations:
- Group related actions behind one tool with an
actionenum. - Dynamically expose only the tools relevant to the current state.
- Use namespacing to reduce confusion among similar tools.
Schema Hardening for Side Effects
For destructive actions, encode safety in the schema itself: require an explicit confirmation field, constrain ranges, and avoid free-text identifiers in favor of enums or validated patterns.
{
'name': 'delete_records',
'parameters': {
'type': 'object',
'properties': {
'table': {'type': 'string', 'enum': ['logs', 'temp_cache']},
'confirm': {'type': 'boolean'},
'max_rows': {'type': 'integer', 'minimum': 1, 'maximum': 1000}
},
'required': ['table', 'confirm', 'max_rows'],
'additionalProperties': False
}
}Testing Tool Definitions
Treat tool selection as a measurable behavior. Build an eval set of prompts mapped to the expected tool and args, then assert the model picks correctly. Track regression when you reword descriptions or add new tools.
cases = [
{'prompt': 'Whats it like in Paris?', 'expect_tool': 'get_weather'},
{'prompt': 'Convert 10 USD to EUR', 'expect_tool': 'fx_convert'}
]
for c in cases:
assert run(c['prompt']).tool_name == c['expect_tool']Quick Check
A model emits two independent tool_calls in one assistant turn. What must your runtime do?
Recap
Tool/function schemas in practice:
- Descriptions drive selection; schemas drive parseable args.
- Loop over all tool_calls; support parallel execution.
- Control behavior with tool_choice; force a tool for pure extraction.
- Re-validate args; return structured errors.
- Keep the tool surface small and harden destructive actions.
Next: repair and validation loops for when output still goes wrong.
Frequently asked questions
Is the “Tool/Function Schemas” lesson free?
Yes — the full text of “Tool/Function Schemas” is free to read here on the web, and the AI Prompt Engineering course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the AI Prompt Engineering course, upgrade to CoddyKit PRO.
What will I learn in “Tool/Function Schemas”?
Schemas for function calling. You practise AI Prompt Engineering with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start AI Prompt Engineering?
No prior experience is required. AI Prompt Engineering on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Tool/Function Schemas” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this AI Prompt Engineering lesson?
Yes. Every AI Prompt Engineering lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Why Structured Output
- JSON Schema in Prompts
- Tool/Function Schemas
- Repair and Validation Loops