Implementation:Anthropics Anthropic sdk python ThinkingBlockParam Continuation
| Knowledge Sources | |
|---|---|
| Domains | Extended_Thinking, LLM, Reasoning |
| Last Updated | 2026-02-15 00:00 GMT |
Overview
ThinkingBlockParam and RedactedThinkingBlockParam are the input (request-side) counterparts of ThinkingBlock and RedactedThinkingBlock. They are TypedDict types used to echo back thinking blocks from prior responses when constructing multi-turn conversation histories. This page documents these param types and the pattern for using them to preserve reasoning context across conversation turns.
ThinkingBlockParam
Source: src/anthropic/types/thinking_block_param.py (Lines 10-15)
class ThinkingBlockParam(TypedDict, total=False):
signature: Required[str]
thinking: Required[str]
type: Required[Literal["thinking"]]
Import:
from anthropic.types import ThinkingBlockParam
Fields:
| Field | Type | Description |
|---|---|---|
signature |
Required[str] |
The cryptographic signature from the original ThinkingBlock. Must match the original exactly. The API uses this to verify that the thinking content has not been tampered with.
|
thinking |
Required[str] |
The thinking text from the original ThinkingBlock. Must match the original exactly. Any modification will cause signature verification to fail.
|
type |
Required[Literal["thinking"]] |
Discriminator field, must be "thinking".
|
RedactedThinkingBlockParam
Source: src/anthropic/types/redacted_thinking_block_param.py (Lines 10-13)
class RedactedThinkingBlockParam(TypedDict, total=False):
data: Required[str]
type: Required[Literal["redacted_thinking"]]
Import:
from anthropic.types import RedactedThinkingBlockParam
Fields:
| Field | Type | Description |
|---|---|---|
data |
Required[str] |
The opaque encrypted data from the original RedactedThinkingBlock. Must be preserved exactly. This data is not human-readable and should be treated as an opaque blob.
|
type |
Required[Literal["redacted_thinking"]] |
Discriminator field, must be "redacted_thinking".
|
Response-to-Param Mapping
The response and param types share the same field structure, enabling straightforward conversion:
| Response Type (Pydantic BaseModel) | Param Type (TypedDict) | Shared Fields |
|---|---|---|
ThinkingBlock |
ThinkingBlockParam |
signature, thinking, type
|
RedactedThinkingBlock |
RedactedThinkingBlockParam |
data, type
|
Multi-turn Continuation Pattern
The recommended pattern for multi-turn conversations with thinking is to pass the entire content list from the prior response as the assistant message content. The SDK handles the conversion from response block types to param block types automatically.
Basic Multi-turn Example
import anthropic
client = anthropic.Anthropic()
# First turn
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=16000,
thinking={"type": "enabled", "budget_tokens": 10000},
messages=[{"role": "user", "content": "What is the capital of France?"}]
)
# Preserve all content blocks (including thinking) for multi-turn
messages = [
{"role": "user", "content": "What is the capital of France?"},
{"role": "assistant", "content": response.content},
{"role": "user", "content": "And what about Germany?"},
]
# Second turn - thinking blocks are echoed back automatically
response2 = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=16000,
thinking={"type": "enabled", "budget_tokens": 10000},
messages=messages,
)
The key line is "content": response.content, which passes the entire content list (including ThinkingBlock and potentially RedactedThinkingBlock objects) directly into the next request. The SDK's serialization layer converts these Pydantic model instances into the appropriate TypedDict format for the API request.
Manual Block Conversion
If you need to construct thinking block params manually (for example, when loading from a database):
from anthropic.types import ThinkingBlockParam, RedactedThinkingBlockParam
# Manually constructing a thinking block param
thinking_param: ThinkingBlockParam = {
"type": "thinking",
"thinking": original_thinking_text, # Must be exact
"signature": original_signature, # Must be exact
}
# Manually constructing a redacted thinking block param
redacted_param: RedactedThinkingBlockParam = {
"type": "redacted_thinking",
"data": original_opaque_data, # Must be exact
}
Handling Mixed Content Blocks
A response may contain a mix of thinking, redacted thinking, and text blocks. All must be preserved:
# The response content might look like:
# [ThinkingBlock(...), RedactedThinkingBlock(...), TextBlock(...)]
# When constructing the next turn, include everything:
messages = [
{"role": "user", "content": "First question"},
{"role": "assistant", "content": response.content}, # All blocks preserved
{"role": "user", "content": "Follow-up question"},
]
Integrity Constraints
The following constraints must be satisfied when echoing thinking blocks back:
- Signature exactness: The
signaturefield inThinkingBlockParammust be identical to thesignaturereturned in the originalThinkingBlock. Character-for-character match is required. - Thinking text exactness: The
thinkingfield inThinkingBlockParammust be identical to thethinkingreturned in the originalThinkingBlock. No trimming, reformatting, or encoding changes are permitted. - Redacted data exactness: The
datafield inRedactedThinkingBlockParammust be identical to thedatareturned in the originalRedactedThinkingBlock. - Block ordering: Thinking and redacted thinking blocks should appear before text blocks in the content list, matching the order from the original response.
Failure to meet these constraints will result in an API error.
Dependencies
typing_extensions.TypedDict: Base class for both param types.typing_extensions.Required: Marks all fields as required (sincetotal=Falseis set on the TypedDict).typing_extensions.Literal: Used for the discriminatortypefield.