Payload anatomy

One real four-turn exchange with the model: request, tool_use, tool_result, answer. Every functional block is annotated. Tap a block to see its function and role in RAG.

The labelled payload works without JavaScript too: below is the same four-turn exchange as static JSON, and under it a list of all 17 functional blocks with their function and role in the RAG pipeline. Enable JavaScript to click the blocks right inside the JSON and zoom into each one.

>>Turn 1. Request: the question + a description of the search tool
{
  "model": "claude-sonnet-4-6",
  "max_tokens": 4096,
  "thinking": { "type": "enabled", "budget_tokens": 2048 },
  "system": "You are a support assistant. Answer ONLY from the text returned by the search_docs tool. If the answer is not in the found pieces, honestly say: this is not in the documents. Cite the source of each fact via the source field.",
  "tools": [
    {
      "name": "search_docs",
      "description": "Semantic search for the top-k chunks over the vector knowledge base.",
      "input_schema": {
        "type": "object",
        "properties": {
          "query": { "type": "string", "description": "The user's search query" },
          "top_k": { "type": "integer", "description": "How many nearest chunks to return", "default": 4 }
        },
        "required": ["query"]
      }
    }
  ],
  "tool_choice": { "type": "auto" },
  "messages": [
    { "role": "user", "content": "How many vacation days does an employee get after three years of service?" }
  ]
}
<<Turn 2. Response: the model reasons and asks to call the search
{
  "id": "msg_01XAbcRequestDemo",
  "type": "message",
  "role": "assistant",
  "model": "claude-sonnet-4-6",
  "content": [
    { "type": "thinking", "thinking": "A question about vacation days after three years of service...", "signature": "EqoBCkgDEMODEMOsignaturePLACEHOLDER==" },
    { "type": "tool_use", "id": "toolu_01A09q90qwDEMO", "name": "search_docs", "input": { "query": "vacation days length of service three years policy", "top_k": 4 } }
  ],
  "stop_reason": "tool_use",
  "stop_sequence": null,
  "usage": { "input_tokens": 412, "output_tokens": 76 }
}
>>Turn 3. Request with tool_result: returning the found chunks
{
  "model": "claude-sonnet-4-6",
  "max_tokens": 1024,
  "system": "You are a support assistant. Answer ONLY from the text returned by the search_docs tool...",
  "messages": [
    { "role": "user", "content": "How many vacation days does an employee get after three years of service?" },
    {
      "role": "assistant",
      "content": [
        { "type": "thinking", "thinking": "...", "signature": "EqoBCkgDEMODEMOsignaturePLACEHOLDER==" },
        { "type": "tool_use", "id": "toolu_01A09q90qwDEMO", "name": "search_docs", "input": { "query": "vacation days length of service three years policy", "top_k": 4 } }
      ]
    },
    {
      "role": "user",
      "content": [
        {
          "type": "tool_result",
          "tool_use_id": "toolu_01A09q90qwDEMO",
          "content": [
            { "type": "text", "text": "[chunk c-118 | source=hr-policy.md | section=Vacation | date=2026-01-10 | cosine=0.83 | rank=1] After 3 full years of service an employee is entitled to 28 calendar days of paid vacation per year." },
            { "type": "text", "text": "[chunk c-119 | source=hr-policy.md | section=Vacation | date=2026-01-10 | cosine=0.71 | rank=2] The base vacation for under 3 years of service is 24 calendar days." }
          ]
        }
      ]
    }
  ]
}
<<Turn 4. The model's grounded answer
{
  "id": "msg_01YDefResponseDemo",
  "type": "message",
  "role": "assistant",
  "model": "claude-sonnet-4-6",
  "content": [
    { "type": "text", "text": "After three full years of service an employee is entitled to 28 calendar days of paid vacation per year (source: hr-policy.md, section Vacation)." }
  ],
  "stop_reason": "end_turn",
  "stop_sequence": null,
  "usage": { "input_tokens": 638, "output_tokens": 41 }
}
  1. model model

    FunctionWhich model to call; the server echoes this id back in every response.

    Role in RAGChoice of the generator for the Generation stage; sets the context length limit and the cost.

    generation.html

  2. budget max_tokens

    FunctionCeiling on answer length in tokens.

    Role in RAGCost and latency control of the Generation stage.

    generation.html

  3. thinking-config thinking.type, thinking.budget_tokens

    FunctionEnables extended reasoning and sets its token budget.

    Role in RAGReasoning budget for the retrieve and generation stages.

    generation.html

  4. system system

    FunctionSystem instruction: answer only from what was found and honestly admit a gap.

    Role in RAGGrounding: the rules to answer from the context and cite the source - the instruction of the Generation stage.

    generation.html

  5. tools tools[].name, description, input_schema

    FunctionDescribes the available tools: name, description and input_schema of the search_docs function.

    Role in RAGDeclaration of the Retrieve step as a callable function (Lewis et al., 2020).

    search.html

  6. tool-choice tool_choice.type

    FunctionControls the tool call: auto leaves the decision to the model.

    Role in RAGControl over whether to run Retrieve.

    search.html

  7. messages-user messages[].role=user, content

    FunctionThe user's turn: the question or an array of content blocks (for example tool_result).

    Role in RAGThe question is the input of the whole pipeline: it becomes the query vector at the retrieve stage.

    search.html

  8. messages-assistant messages[].role=assistant, content[]

    FunctionThe model's turn, inserted back into messages: the saved thinking and tool_use.

    Role in RAGWithout the saved search request the next tool_result has nothing to bind to.

  9. response-id id, type, role, model

    FunctionIdentifier and type of the response message.

    Role in RAGBinding of the dialogue turn and request tracing in logs.

  10. thinking-block content[].type=thinking, thinking, signature

    FunctionThe model's visible reasoning before acting, plus a cryptographic signature.

    Role in RAGReasoning: the plan of the retrieve stage, not the final answer.

  11. tool-use content[].type=tool_use, id, name, input

    FunctionThe model's request to call a tool: name search_docs, input with query and top_k.

    Role in RAGThe Retrieve call: query and top_k go to the search stage.

    search.html

  12. tool-result content[].type=tool_result, tool_use_id, content[]

    FunctionReturning the tool result into the dialogue: linked by tool_use_id, carrying the chunks as text.

    Role in RAGThe Augmented step (Lewis et al., 2020): the found top-k chunks are slipped into the context.

    assemble-context.html

  13. chunk-meta source, section, date

    FunctionChunk metadata inside tool_result, glued to the text of the piece.

    Role in RAGProvenance of the chunk: source/section/date are set at the chunking stage.

    chunking.html

  14. retrieval-score cosine, rank

    FunctionCloseness score and position in the top-k: cosine (0..1) and rank of each chunk.

    Role in RAGRetrieve quality: cosine - meaning closeness to the query, rank - order in the top-k.

    search.html

  15. text-answer content[].type=text, text

    FunctionThe final answer text: one content block of type text with a link to source.

    Role in RAGGeneration: the grounded answer from the found chunks with an explicit link to the source.

    generation.html

  16. stop-reason stop_reason, stop_sequence

    FunctionWhy the model stopped: tool_use - waiting for the result; end_turn - finished on its own.

    Role in RAGControl signal: tool_use -> your code runs the search; end_turn -> the answer is ready.

  17. usage usage.input_tokens, usage.output_tokens

    FunctionToken spend per turn. In the example input grows from 412 (turn 2) to 638 (turn 4).

    Role in RAGCost and budget signal: a rise in input_tokens after tool_result is the price of the supplied context.

    assemble-context.html

The problem you came with

You walked the whole route - chunks, embeddings, search, context assembly, generation. Each chapter showed its stage in isolation. But in a live system they all converge into one thing: an HTTP request to the LLM and a response from it. This is ordinary JSON. And until you see this JSON in full, with every field in its place, RAG stays a set of separate ideas rather than one mechanism.

Here we take apart one real exchange with the model: the request you send and the response that comes back. The fields are real - this is the format of the Anthropic Messages API (platform.claude.com/docs/en/api/messages). Each functional block is labelled twice: what it does technically and what role it plays in the RAG pipeline. This is that same retrieve-augment-generate assembly from the paper Lewis et al., 2020 (arxiv.org/abs/2005.11401), but no longer on a diagram - in the bytes that go over the wire.

One payload through the whole pipeline

A RAG request to the Anthropic Messages API is arranged like this: you put the grounding instructions in system, the assembled context and the question in messages, and you express the search itself as a tool call (tools plus tool_choice) (platform.claude.com/docs/en/api/messages). The model answers not with a single text but with an array of content blocks: reasoning (thinking), a search request (tool_use), and the final text. The stop_reason field tells why the model stopped, and usage - how many tokens it cost (platform.claude.com/docs/en/api/messages).

Below is a real exchange of four turns: you send the question with a description of the search tool, the model asks to call the search (tool_use), you return the found chunks (tool_result), the model writes a grounded answer.

Turn 1. Request: the question plus a description of the search tool

system is the grounding layer: a firm instruction to answer only from what was found and to honestly admit a gap (platform.claude.com/docs/en/api/messages). In RAG terms this is exactly the instruction of the generation stage from generation.html. tools describes search as a function the model can call - this is the declaration of the retrieve step from the paper Lewis et al., 2020 (arxiv.org/abs/2005.11401), expressed in the tool-use schema (platform.claude.com/docs/en/docs/build-with-claude/tool-use/overview). tool_choice: auto leaves the model to decide whether search is needed (platform.claude.com/docs/en/docs/build-with-claude/tool-use/overview). thinking enables extended reasoning with a token budget (platform.claude.com/docs/en/docs/build-with-claude/extended-thinking).

Turn 2. Response: the model reasons and asks to call the search

The thinking block is the model's reasoning before acting; in RAG this is the visible plan of the retrieve stage, not the final answer (platform.claude.com/docs/en/docs/build-with-claude/extended-thinking). The tool_use block is exactly the search request: the model asks to call search_docs with a concrete query and top_k (platform.claude.com/docs/en/docs/build-with-claude/tool-use/overview). stop_reason: tool_use is a control signal: the model stopped not because it finished but because it is waiting for the tool result; your code must run the search and return the result (platform.claude.com/docs/en/api/messages). usage is a budget and cost signal: input_tokens and output_tokens for this turn (platform.claude.com/docs/en/api/messages); in RAG a bloated input_tokens is the first sign that the assembled context is too large (see assemble-context.html).

Turn 3. Request with tool_result: returning the found chunks

Your code runs the search (the retrieve stage: query -> vector -> top-k by cosine, as in search.html), then continues the same conversation, appending the assistant's response and a tool_result block with the found chunks. The vector shape and the cosine metric are from the OpenAI Embeddings guide (developers.openai.com/api/docs/guides/embeddings).

tool_result is the return of the retrieve stage into the conversation: linked to the request by tool_use_id, carrying the found chunks as text (platform.claude.com/docs/en/docs/build-with-claude/tool-use/overview). Inside each chunk are pipeline-stage metadata: source/section/date come from chunking (chunking.html), while cosine/rank come from search (search.html, the cosine metric per the OpenAI Embeddings guide, developers.openai.com/api/docs/guides/embeddings). This block is exactly the Augmented step from Lewis et al., 2020: what was found is slipped into the model's context before generation (arxiv.org/abs/2005.11401).

Turn 4 (final answer). The model's grounded answer

Here content is one text block: the final grounded answer with a link to source, as the instruction in system required. This is the Generation stage from Lewis et al., 2020 (arxiv.org/abs/2005.11401); the link to the concrete fields is described in generation.html. stop_reason: end_turn is a control signal that the model finished on its own, not because of a limit (platform.claude.com/docs/en/api/messages). usage.input_tokens grew from 412 to 638 - this is the price of the supplied context: that same budget signal by which assemble-context.html decides what to trim.

A map of the blocks: function and role in RAG

A greppable table: each functional block of the payload, its fields, its technical function, and its domain role in the RAG pipeline. This is the map of blocks for the drill interaction above; with JS off it doubles as a static list under the payload.

  • model (model) - which model to call; choice of the generator for the Generation stage, affects the length limit and cost.
  • budget (max_tokens) - ceiling on answer length; cost and latency control of the Generation stage.
  • thinking-config (thinking.type, thinking.budget_tokens) - enable extended reasoning and its budget; reasoning budget for the retrieve and generation stages.
  • system (system) - the model's system instruction; grounding: answer only from the context plus cite the source (generation.html).
  • tools (tools[].name, description, input_schema) - description of the available tools; declaration of the Retrieve step as a callable function (Lewis et al., 2020).
  • tool-choice (tool_choice.type) - allow or force a tool call; control over whether to run retrieve.
  • messages-user (messages[].role=user, content) - the user's turn; the question - the input of the whole pipeline.
  • messages-assistant (messages[].role=assistant, content[]) - the model's turn in the history; saved reasoning and search request to continue the dialogue.
  • response-id (id, type, role, model) - identifier and type of the response message; binding of the dialogue turn, request tracing.
  • thinking-block (content[].type=thinking, thinking, signature) - the model's visible reasoning; reasoning: the plan of the retrieve stage, not the final answer.
  • tool-use (content[].type=tool_use, id, name, input) - the model's request to call a tool; the Retrieve call: query and top_k go to the search (search.html).
  • tool-result (tool_result.tool_use_id, content[]) - returning the tool result into the dialogue; Augmented: the found top-k chunks are slipped into the context (assemble-context.html).
  • chunk-meta (source, section, date) - chunk metadata; provenance: set at the chunking stage (chunking.html).
  • retrieval-score (cosine, rank) - closeness score and position in the top-k; retrieve quality: cosine 0..1, ranking (search.html).
  • text-answer (content[].type=text, text) - the final answer text; Generation: the grounded answer with a link to source.
  • stop-reason (stop_reason, stop_sequence) - why the model stopped; control signal: tool_use -> run the search; end_turn -> done.
  • usage (usage.input_tokens, usage.output_tokens) - token spend per turn; cost and budget signal: a rise in input_tokens = bloated context (assemble-context.html).

Interaction: drill across the payload blocks

The rendered payload is not a picture but a map. At the top level (zoom 0) you see the whole exchange of four turns: request, tool_use, tool_result, answer. Each functional block from the table above highlights on hover. One click or Enter on a block is a semantic zoom inside it (zoom 1): the block takes the stage, and beside it unfolds its annotation card with two lines - what it does technically and what role it plays in RAG, plus a link to the owning chapter (for example, tool_use -> search.html, usage -> assemble-context.html). This is exactly two zoom levels: the whole payload -> one block up close. Going back (Esc or the back button) pulls the camera out to the full payload.

With JS off, the block map works as the static labelled table above plus the JSON itself with captions - the reader loses nothing.

Sources

Try it yourself

  • Open the drill on the tool_use block (zoom 1) and trace how input.query and top_k go into the retrieve stage; check against search.html.
  • Expand the tool_result block and find inside the chunk the fields source/section/date (from chunking) and cosine/rank (from search) - one block carries the traces of two pipeline stages at once.
  • Compare usage.input_tokens in turn 2 (412) and in turn 4 (638): expand the usage block and confirm that the growth is the price of the supplied context, that same budget signal from assemble-context.html.

What is next

This payload is not a separate chapter of the route but a cross-section through the whole pipeline: it is referenced by generation.html (how the system/content/stop_reason fields produce a grounded answer) and assemble-context.html (how usage and tool_result show the context budget). Go back to either of them to see your stage already in the bytes of a live request.

Back to the route map

About this recipe