Hirestack
Hirestack
Chapter 6

LLM Engineering · Structured output and tool use

📖 2 min read · 5 sections · May 2026

Why this matters

If your application parses LLM output with regex, you've already lost. Modern LLMs let you specify a JSON schema (OpenAI, Gemini) or pass an XML/tool-call structure (Claude) and guarantee the output validates. Use it.

Three mechanisms

MechanismHow it worksBest for
JSON mode / response_formatProvider constrains generation to valid JSONExtracting structured data from text
Function / tool callingYou define functions; LLM returns which one to call with what argsAgents, RAG with tools, action selection
Constrained decoding (open-source)Library forces token choices to match a grammarSelf-hosted models; libraries like Outlines, jsonformer

Function calling — the production pattern

Define a function (with a clear name, description, and parameter schema). Pass it to the LLM. The LLM decides whether to call it and with what arguments. Your code runs the function. You send the result back. Repeat.

sequenceDiagram
    participant User
    participant App
    participant LLM
    participant Tool as Weather API
    User->>App: What's the weather in Bangalore?
    App->>LLM: messages + tool definitions
    LLM-->>App: tool_call(get_weather, {city: "Bangalore"})
    App->>Tool: GET /weather?city=Bangalore
    Tool-->>App: { temp: 28, conditions: "humid" }
    App->>LLM: tool_result { temp: 28, conditions: "humid" }
    LLM-->>App: "It's 28°C and humid in Bangalore."
    App-->>User: "It's 28°C and humid in Bangalore."

Tool design rules

War story: an early agent kept calling delete_user by mistake instead of archive_user because both descriptions said "remove the user". Renamed to permanently_delete_user_irreversible with a warning in the description. Zero mistaken calls after that. Names matter to LLMs more than to humans.

Takeaway

Treat your tool schema as a public API contract. Document it like one. The LLM is the client, and clients with bad docs misuse APIs.