Skip to main content
In this hands-on lab you’ll start with an agent that exposes two ambiguously described tools and observe how the model can pick the wrong one. Then you’ll apply three API design techniques—precise descriptions, strict parameter contracts, and input normalization—to make tool selection reliable and predictable.
A dark grid background features a pixelated magnifying-glass icon and a cyan label reading "HANDS-ON LAB" above large yellow pixelated text: "DESIGN BETTER TOOLS." Below is a white subtitle saying "Bad descriptions in · ACI principles out."

Setup

Create a file named better-tools.py with:
  • an OpenAI API client
  • a short system prompt
  • a loop that inspects model responses for function (tool) calls and dispatches them to handlers
Minimum agent skeleton:
(If you need the OpenAI API reference, see the official docs: https://platform.openai.com/docs/api-reference)

Demonstration: vague tool definitions

Begin with two intentionally vague tools so you can observe the problem:
Try the user prompt:
Because the tool descriptions are so vague, the model may be uncertain which tool to call. Running the agent multiple times often yields different tool choices.

Goals

Make the agent:
  • consistently choose the right tool for a given user intent
  • pass well-formed, normalized parameters that your backend expects
  • avoid brittle values that cause downstream failures
You can accomplish this using three API-level improvements:
  • Precise descriptions (teach the model when to call each tool)
  • Parameter constraints (enums, types, required fields)
  • Poka-yoke input normalization inside handlers (normalize inputs in code)

1) Precise descriptions (rename tools and explain when to use them)

Provide explicit tool names and descriptions that tell the model:
  • What the tool does
  • When to call it (in plain language)
  • The return shape or what the tool will return
Example improved tool definitions:
Why this helps: explicit naming plus “when to use” guidance gives the model a clear decision boundary, reducing ambiguity when the user asks for recommendations or searches.

2) Parameter constraints (use enums and clear parameter types)

Constrain parameter values so the model selects supported values only. Add descriptions, enums, and clear typing so your tool contract is unambiguous. Example: adding an enum to category ensures the model provides a supported category:
Benefits:
  • Prevents unsupported labels like dining or restaurant that your backend doesn’t expect
  • Produces consistent payloads to your handlers
  • Makes validation straightforward on the server side

3) Poka-yoke normalization (input normalization in handlers)

Handle small variations in inputs inside your tool implementation so the model doesn’t need to perfectly match your backend’s vocabulary. Normalization is a defensive, internal measure that reduces errors. Example handler with normalization:
Common normalizations:
  • Trim whitespace: " ITALIAN " → "italian"
  • Lowercase: "Italian" → "italian"
  • Map synonyms: "cheap", "$", "1" → "cheap"
Normalization ensures small input differences don’t break downstream logic.

Example: predictable end-to-end flow

After applying precise descriptions, parameter constraints, and input normalization, the same prompt:
will reliably result in a structured tool call such as:
and your handler will normalize and return predictable structured results for the assistant to present.

Summary: Quick reference

Next steps & references

  • Implement the exact tool definitions in your agent registration (as shown above).
  • Add server-side validation to catch unexpected values and return helpful errors.
  • Log model tool calls during testing to confirm the model chooses the intended tool consistently.
References:
Design tool descriptions to be explicit about purpose, expected inputs, and return shapes. Combine parameter constraints (enums, types, required fields) with internal input normalization to make tool usage reliable and robust.

Watch Video