Lesson 19 / 27

Tool Use and Structured Output

Let the model call functions and return machine-readable results.

The model asks, your code acts

With tool use (function calling) you describe functions (name, purpose, JSON schema of arguments). The model may respond with a request to call one, your code executes it and returns the result, and the model continues with that information. This is how LLMs search, query databases or send emails; chains of such steps form agents. For reliable parsing, ask for structured output (JSON matching a schema) and validate it in code. Treat tool arguments as untrusted input: check permissions, limit what each tool can do, and require human confirmation for risky actions.

A tool definition and validation

The schema tells the model what arguments are allowed; your code must still validate before acting. Illustrative; not run here.

tool = {
    "name": "get_order_status",
    "description": "Look up the status of an order by id",
    "input_schema": {
        "type": "object",
        "properties": {"order_id": {"type": "string", "pattern": "^[0-9]{6}$"}},
        "required": ["order_id"],
    },
}

def run_tool(args):
    oid = args.get("order_id", "")
    if not (len(oid) == 6 and oid.isdigit()):
        return {"error": "invalid order_id"}
    return {"order_id": oid, "status": "shipped"}   # real code: query your system

Log every tool call

Record the arguments, result and who triggered it. Logs make debugging and security reviews possible; remove personal data first.

Quick check: Who actually executes a tool call?

  • The user's browser only
  • The model itself
  • The tokenizer
  • Your application code
Answer

Your application code — The model only proposes the call; your code decides whether and how to run it.