An AI agent is a language model in a loop: it's given a goal and a set of tools, and it repeatedly decides what to do, calls a tool, looks at the result, and decides again — until the goal is met. Every one of those decisions and results is JSON. Understand the shapes and an agent stops being a black box and becomes something you can log, debug, and trust.
This guide walks the JSON that flows through an agent, from the tools you expose to the trace you record. Each stage links to a copy-ready example you can open, format, or turn into TypeScript types.
> They all live in the AI & LLM category of the JSON Examples Library.
The agent loop
goal + tools → model decides → tool call → run tool → observation
▲ │
└────────────────── repeat until done ◄─────────────────┘Three JSON artifacts make this work: the tool registry (what the agent can do), the tool call + observation (one step), and the trace (the whole run). Let's take them in turn.
1. The tool registry: what the agent can do
Before an agent can act, you declare the tools it may call — each with a name, a plain-language description, and a JSON Schema for its arguments. The model reads this to decide which tool fits the task.
- AI Agent Tool Registry — an array of tools with
name,description, andparameters(JSON Schema), plus a pattern for flaggingdangeroustools that need confirmation.
The descriptions are effectively prompts: clear, specific wording is the single biggest factor in the model picking the right tool. Treat them like product copy, not code comments.
2. The tool call: one step of action
When the model chooses a tool, it emits a tool call — the function name plus arguments. You run the function and return the result, referencing the call's id.
- LLM Tool / Function Call — the call the model returns and the result you send back. Remember the
argumentsarrive as a JSON-encoded string, soJSON.parse()and validate them before executing.
Always gate irreversible actions (refunds, deletes, sends) behind a human confirmation — never let an agent run them autonomously off an unvalidated tool call.
3. MCP: standardizing tool access
Rather than hard-wiring tools into every app, the Model Context Protocol (MCP) lets an agent host discover and call tools from any MCP server over a uniform JSON-RPC interface.
- MCP Message (Model Context Protocol) — the JSON-RPC 2.0 messages (
tools/list,tools/call, and the error shape) behind MCP servers.
4. The run trace: recording what happened
The trace is the agent's flight recorder. Capturing each step as JSON — the thought, the action, the observation — makes runs reproducible and debuggable, and is the foundation of agent observability.
- AI Agent Run Trace — the ReAct-style
stepsarray (thought / action / observation), a final answer, aggregateusage(tokens, tool calls, duration), and a failed-run variant.
Logging the thought field is what makes failures explainable: you can see *why* the agent chose a tool or went off-track. Redact or truncate thoughts in production if needed, but keep them during development.
5. State & memory
Agents need to remember context across turns. In a chat agent, that's the conversation; in a long task, it's a running summary plus a scratchpad.
- Chat Conversation History — the
messagesarray, including a summarized-memory variant for keeping long runs under the context window.
6. Constraining decisions with structured output
When you want an agent to make a discrete choice — route a ticket, pick the next action, emit a plan — constrain the output to a JSON Schema so you can act on it reliably.
- LLM Structured Output (JSON Schema) — a
response_formatrequest withstrict: trueand a guaranteed-valid result.
Debugging agents with JSON tools
Agent bugs hide in the JSON between steps:
- Replay the trace. Drop a run trace into the JSON Tree Explorer to walk
steps[].actionandsteps[].observationand see exactly where it went wrong. - Validate tool arguments. Malformed or hallucinated arguments are a top failure mode — validate them against the tool's schema with the JSON Schema Validator.
- Type your tool I/O. Paste a tool's argument and result shapes into JSON to TypeScript so your handlers are type-safe.