Zenaique

Describe the JSON shape of a Claude Opus 4.7 assistant message that calls a tool

Short answer·Medium·4.0 · 0·~3 min·Asked atAccentureAnthropicOpenAI·Relevant atCoreweaveFireworks AiLambda LabsRunway
Attempt it

Walk through what an assistant message looks like at the JSON level when Claude Opus 4.7 calls a tool during a turn, and what the next user turn must contain. Be specific about field names and the block typed content array.

Free · 2 AI evals / day
TL;DR

Assistant content is a typed-block array mixing text and tool_use blocks; the next user turn replies with tool_result blocks linked by tool_use_id. No separate tool role.

Memory aid
Sign in to see the mnemonic that makes this stick.
Easy to grasp

Picture a conversation where each speaker can hand over more than one slip of paper per turn. The assistant might pass a slip with words on it and another slip that says please run this calculation, with a unique sticker number on the calculation slip. On the next turn, the user hands back a slip with the calculation result and the same sticker number, so it is obvious which request the result answers. Nothing is glued together as one long sentence. Each kind of slip has its own format, and the sticker number is what keeps the call and the result linked across turns. That is exactly how the message shape works under the hood.

Concept explanation~2 min read

Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.

Tool calling is the most common reason teams fine-tune in 2026, and the schema details are where teams quietly ship broken behaviour. Anthropic's messages API has a specific, opinionated shape for tool calls that differs from the OpenAI chat completions convention, and conflating the two is a frequent source of training-time bugs that pass tests but fail under production load.

The core idea is that assistant content is not a string. It is a list of typed blocks, and the API treats each block as a first-class structural unit. A tool call is one specific block type, with its own required fields and its own protocol for how the result returns on the next turn. Getting the shape right at training time means the model learns to emit valid block-typed output at inference time. Getting it wrong means the model learns to emit flat text that looks like JSON, which no runtime can dispatch.

The rest of this section walks the assistant turn structure, the tool_use block fields, the tool_result reply protocol, the id linkage that enables parallel tool calls, and the specific failure modes that hit fine-tuning datasets when teams accidentally flatten the structure.

The block-typed content array

Every message in the Anthropic messages API has two top-level fields: role (one of 'user', 'assistant', or 'system') and content. The content field is the source of all the schema-level interest. For simple text messages it can be a string, but for any structured interaction including tool calls, it must be an array of typed blocks.

The relevant block types for tool calls are text, tool_use, and tool_result. A text block looks like {"type": "text", "text": "..."} and carries natural-language content. A tool_use block, valid only inside an assistant turn, looks like {"type": "tool_use", "id": "...", "name": "...", "input": {...}}. A tool_result block, valid only inside a user turn, looks like {"type": "tool_result", "tool_use_id": "...", "content": ...}.

The array structure is what lets a single turn carry multiple blocks. The assistant can emit a text block of reasoning followed by a tool_use block, or several tool_use blocks for parallel calls, or a text block then a tool_use block then another text block. The order matters: the runtime preserves it, and the model's training data should preserve it too. Flattening the array into a single string at any stage of data preparation destroys the type information and the boundary between blocks, which is the supervision signal that teaches the model to emit valid structured output.

The tool_use block in detail
The tool_result reply and the role choice
Fine-tuning implications and failure modes
Sign in to unlock the full deep dive.

Situations where this technique stops working.

Sign in to see when this approach fails.

2–4 min · Everything important, quickly.

Sign in to see the quick scan of the deep dive.
python
from anthropic import Anthropic

client = Anthropic()

resp = client.messages.create(
    model="claude-opus-4-7-20260101",
    max_tokens=1024,
    tools=[{
        "name": "get_weather",
        "description": "Lookup current weather for a city",
        "input_schema": {
            "type": "object",
            "properties": {"city": {"type": "string"}},
            "required": ["city"],
        },
    }],
    messages=[
        {"role": "user", "content": "Weather in Tokyo?"},
    ],
)

# resp.content is the block-typed array.
# For a tool call, you will see something like:
#   [TextBlock(text="Let me check..."),
#    ToolUseBlock(id="toolu_01...", name="get_weather",
#                 input={"city": "Tokyo"})]
for block in resp.content:
    if block.type == "tool_use":
        result = run_tool(block.name, block.input)
        # Reply with a tool_result block under role 'user'
        followup = client.messages.create(
            model="claude-opus-4-7-20260101",
            max_tokens=1024,
            messages=[
                {"role": "user", "content": "Weather in Tokyo?"},
                {"role": "assistant", "content": resp.content},
                {"role": "user", "content": [
                    {"type": "tool_result",
                     "tool_use_id": block.id,
                     "content": result},
                ]},
            ],
        )
AspectAnthropic messages APIOpenAI chat completions
Assistant contentTyped-block array (text, tool_use)String plus tool_calls field
Tool-call locationInline tool_use block in contentSeparate tool_calls field on message
Result role'user' with tool_result block'tool' role with content string
Call-to-result linkagetool_use_id matches tool_use.idtool_call_id matches tool_calls[].id
Parallel callsMultiple tool_use blocks in one turnMultiple entries in tool_calls array

Real products, models, and research that use this idea.

  • Claude Opus 4.7 production deployments at Anthropic customers use this exact block-typed shape for tool-augmented agents calling search, calculator, and code-execution tools.
  • Anthropic's official SDKs (TypeScript, Python) construct typed-block content automatically when you pass tools to the messages.create call.
Sign in to see more production examples.

What an interviewer would ask next. Try answering before peeking at the approach.

QHow does the message shape support parallel tool calls in one assistant turn?
A

The assistant emits multiple tool_use blocks in one content array, each with its own id. The runtime executes all calls and returns a user message whose content array carries one tool_result per call, linked by tool_use_id. The model can then reason over all results in the next assistant turn.

2 more follow-ups an interviewer would ask next. Sign in to reveal them.

Red flags & common mistakes

The phrases that signal junior thinking. Click to expand.

Most common mistake

Treating assistant content as a single string and putting a tool call into JSON inside that string. The API expects a list of typed blocks; flat strings drop the structured schema and break the model's tool-call grounding.

Sign in to see all red flags and common mistakes.

60 second bullets to scan on the way to the call.

  • The typed-block structure of assistant content

  • The three required fields on a tool_use block

Sign in to unlock the revision sheet.

Primary sources. Browse if you want the original framing.

Similar questions

Same topic, related formats. Practice these next.

4 curated
Next question
What is RLHF, and why is it used after pretraining?
MCQ·Easy