Multi-Turn Context: Storage and Encryption
On this page
The Problem of Context Between Requests
In a multi-turn conversation with tools, context volume grows quickly. Each tool call adds its results to the message thread, and the model’s internal reasoning must be preserved for consistency. Two mechanisms solve this problem: remote storage and client-side encryption.
Method 1: store_messages and previous_response_id
Remote storage delegates context management to xAI servers. You enable store_messages=True in your first request, then chain subsequent requests with previous_response_id:
# First request: enable storage
response = await client.chat.completions.create(
model="grok-4.5",
messages=[{"role": "user", "content": "Analyze this sales dataset"}],
tools=my_tools,
store_messages=True
)
response_id = response.id # save the ID
# Next request: use stored context
response2 = await client.chat.completions.create(
model="grok-4.5",
messages=[{"role": "user", "content": "What are the top 3 selling products?"}],
previous_response_id=response_id,
store_messages=True
)
With this approach, you don’t need to resend the full message history. The xAI server keeps the context and attaches it automatically. This reduces request size and simplifies your code.
Advantages
- Lighter requests (no need to resend full history)
- Model internal reasoning is preserved automatically
- No complex state management on the client side
Limitations
- Messages are stored on xAI servers (privacy consideration)
- The
response_idmust be kept between requests - Storage has a limited retention period
Method 2: use_encrypted_content
Client-side encryption offers an alternative for cases where you want to retain control of the context without storing your data on xAI servers:
# Enable encrypted content
response = await client.chat.completions.create(
model="grok-4.5",
messages=[{"role": "user", "content": "Analyze this contract"}],
tools=my_tools,
use_encrypted_content=True
)
# Reasoning and tool outputs are returned encrypted
# You add them as-is to subsequent messages
messages = [
{"role": "user", "content": "Analyze this contract"},
response.choices[0].message, # contains encrypted content
{"role": "user", "content": "What are the termination clauses?"}
]
response2 = await client.chat.completions.create(
model="grok-4.5",
messages=messages,
use_encrypted_content=True
)
With use_encrypted_content=True, internal reasoning and tool results are returned in encrypted form. You can’t read them, but you resend them in subsequent requests. The server decrypts them to maintain reasoning continuity.
Advantages
- Context remains under your control (no remote storage)
- Internal reasoning is preserved without being exposed in plaintext
- Compatible with strict privacy policies
Limitations
- Requests are larger (encrypted content is included)
- You must manage message history on the client side
Choosing Between the Two Methods
The choice depends on your context:
- store_messages: preferable for chat applications, interactive assistants, and cases where simplicity comes first. Context is managed automatically.
- use_encrypted_content: preferable for sensitive applications, processing confidential documents, and cases where data must not leave your infrastructure (beyond API transit).
Combining with the Hybrid Workflow
Both methods integrate into the loop pattern seen in the previous lesson:
async def multi_turn_conversation(questions: list[str]) -> list[str]:
responses = []
previous_id = None
for question in questions:
kwargs = {
"model": "grok-4.5",
"messages": [{"role": "user", "content": question}],
"tools": my_tools,
"store_messages": True,
}
if previous_id:
kwargs["previous_response_id"] = previous_id
response = await client.chat.completions.create(**kwargs)
previous_id = response.id
responses.append(response.choices[0].message.content)
return responses
This pattern chains questions while preserving the full conversation context, including tool results and the model’s internal reasoning.
Key Takeaways
store_messages=True+previous_response_iddelegates context management to xAIuse_encrypted_content=Truepreserves reasoning without remote storage- The choice depends on your privacy and simplicity constraints
- Both methods are compatible with multi-turn workflows and hybrid tools
previous_response_ideliminates the need to resend the full message history