mirror of
https://github.com/anthropics/claude-cookbooks.git
synced 2025-10-06 01:00:28 +03:00
653 lines
28 KiB
Plaintext
653 lines
28 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Extended Thinking\n",
|
|
"\n",
|
|
"## Table of contents\n",
|
|
"- [Setup](#setup)\n",
|
|
"- [Basic example](#basic-example)\n",
|
|
"- [Streaming with extended thinking](#streaming-with-extended-thinking)\n",
|
|
"- [Token counting and context window management](#token-counting-and-context-window-management)\n",
|
|
"- [Understanding redacted thinking](#understanding-redacted-thinking-blocks)\n",
|
|
"- [Handling error cases](#handling-error-cases)\n",
|
|
"\n",
|
|
"This notebook demonstrates how to use Claude 3.7 Sonnet's extended thinking feature with various examples and edge cases.\n",
|
|
"\n",
|
|
"Extended thinking gives Claude 3.7 Sonnet enhanced reasoning capabilities for complex tasks, while also providing transparency into its step-by-step thought process before it delivers its final answer. When extended thinking is turned on, Claude creates `thinking` content blocks where it outputs its internal reasoning. Claude incorporates insights from this reasoning before crafting a final response. For more information on extended thinking, see our [documentation](https://docs.claude.com/en/docs/build-with-claude/extended-thinking)."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "python"
|
|
}
|
|
},
|
|
"source": [
|
|
"## Setup\n",
|
|
"\n",
|
|
"First, let's install the necessary packages and set up our environment."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "python"
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"%pip install anthropic"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "python"
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"import anthropic\n",
|
|
"import os\n",
|
|
"\n",
|
|
"# Set your API key as an environment variable or directly\n",
|
|
"# os.environ[\"CLAUDE_API_KEY\"] = \"your-api-key-here\"\n",
|
|
"\n",
|
|
"# Initialize the client\n",
|
|
"client = anthropic.Anthropic()\n",
|
|
"\n",
|
|
"# Helper functions\n",
|
|
"def print_thinking_response(response):\n",
|
|
" \"\"\"Pretty print a message response with thinking blocks.\"\"\"\n",
|
|
" print(\"\\n==== FULL RESPONSE ====\")\n",
|
|
" for block in response.content:\n",
|
|
" if block.type == \"thinking\":\n",
|
|
" print(\"\\n🧠 THINKING BLOCK:\")\n",
|
|
" # Show truncated thinking for readability\n",
|
|
" print(block.thinking[:500] + \"...\" if len(block.thinking) > 500 else block.thinking)\n",
|
|
" print(f\"\\n[Signature available: {bool(getattr(block, 'signature', None))}]\")\n",
|
|
" if hasattr(block, 'signature') and block.signature:\n",
|
|
" print(f\"[Signature (first 50 chars): {block.signature[:50]}...]\")\n",
|
|
" elif block.type == \"redacted_thinking\":\n",
|
|
" print(\"\\n🔒 REDACTED THINKING BLOCK:\")\n",
|
|
" print(f\"[Data length: {len(block.data) if hasattr(block, 'data') else 'N/A'}]\")\n",
|
|
" elif block.type == \"text\":\n",
|
|
" print(\"\\n✓ FINAL ANSWER:\")\n",
|
|
" print(block.text)\n",
|
|
" \n",
|
|
" print(\"\\n==== END RESPONSE ====\")\n",
|
|
"\n",
|
|
"def count_tokens(messages):\n",
|
|
" \"\"\"Count tokens for a given message list.\"\"\"\n",
|
|
" result = client.messages.count_tokens(\n",
|
|
" model=\"claude-3-7-sonnet-20250219\",\n",
|
|
" messages=messages\n",
|
|
" )\n",
|
|
" return result.input_tokens"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Basic example\n",
|
|
"\n",
|
|
"Let's start with a basic example to show extended thinking in action:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "python"
|
|
}
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\n",
|
|
"==== FULL RESPONSE ====\n",
|
|
"\n",
|
|
"🧠 THINKING BLOCK:\n",
|
|
"Let's work through this problem step by step:\n",
|
|
"\n",
|
|
"Initial situation:\n",
|
|
"- Three people each pay $10, for a total of $30 given to the manager.\n",
|
|
"- The room actually costs $25.\n",
|
|
"- Manager gives $5 to the bellboy to return to the customers.\n",
|
|
"- Bellboy keeps $2 and gives $1 back to each person ($3 total).\n",
|
|
"\n",
|
|
"After these transactions:\n",
|
|
"- Each person has effectively paid $9 (they paid $10 and got $1 back).\n",
|
|
"- So the three people together paid $27.\n",
|
|
"- The hotel kept $25 for the room.\n",
|
|
"- The bellboy kept $2.\n",
|
|
"\n",
|
|
"So the mo...\n",
|
|
"\n",
|
|
"[Signature available: True]\n",
|
|
"[Signature (first 50 chars): EuYBCkQYAiJAGF6X7aWRuRByTdymAUdNOMC++3ZqSJv7jcY5Ly...]\n",
|
|
"\n",
|
|
"✓ FINAL ANSWER:\n",
|
|
"# Hotel Bill Puzzle Solution\n",
|
|
"\n",
|
|
"This is a classic misdirection puzzle that confuses us by mixing up two different accounting approaches.\n",
|
|
"\n",
|
|
"## The actual flow of money\n",
|
|
"\n",
|
|
"1. Three people each pay $10, totaling $30\n",
|
|
"2. The hotel keeps $25 for the room\n",
|
|
"3. The bellboy keeps $2\n",
|
|
"4. The guests receive $3 back ($1 each)\n",
|
|
"\n",
|
|
"## The accounting error in the puzzle\n",
|
|
"\n",
|
|
"The error occurs when the puzzle tries to add:\n",
|
|
"- What the guests paid ($27 total after refunds)\n",
|
|
"- What the bellboy kept ($2)\n",
|
|
"\n",
|
|
"This is incorrect accounting because the $2 the bellboy kept is already included in the $27 the guests paid. The money should be tracked from a single perspective.\n",
|
|
"\n",
|
|
"## Correct accounting\n",
|
|
"\n",
|
|
"From the guests' perspective:\n",
|
|
"- $27 (what they ultimately paid)\n",
|
|
"- = $25 (to the hotel) + $2 (to the bellboy)\n",
|
|
"\n",
|
|
"There is no missing dollar. The puzzle creates confusion by inappropriately adding money from different accounting perspectives.\n",
|
|
"\n",
|
|
"==== END RESPONSE ====\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"def basic_thinking_example():\n",
|
|
" response = client.messages.create(\n",
|
|
" model=\"claude-3-7-sonnet-20250219\",\n",
|
|
" max_tokens=4000,\n",
|
|
" thinking= {\n",
|
|
" \"type\": \"enabled\",\n",
|
|
" \"budget_tokens\": 2000\n",
|
|
" },\n",
|
|
" messages=[{\n",
|
|
" \"role\": \"user\",\n",
|
|
" \"content\": \"Solve this puzzle: Three people check into a hotel. They pay $30 to the manager. The manager finds out that the room only costs $25 so he gives $5 to the bellboy to return to the three people. The bellboy, however, decides to keep $2 and gives $1 back to each person. Now, each person paid $10 and got back $1, so they paid $9 each, totaling $27. The bellboy kept $2, which makes $29. Where is the missing $1?\"\n",
|
|
" }]\n",
|
|
" )\n",
|
|
" \n",
|
|
" print_thinking_response(response)\n",
|
|
"\n",
|
|
"basic_thinking_example()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Streaming with extended thinking\n",
|
|
"\n",
|
|
"This example shows how to handle streaming with thinking:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "python"
|
|
}
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\n",
|
|
"--- Starting thinking block ---\n",
|
|
"This is a classic mathematical puzzle that contains a misdirection in how the calculations are presented. Let's break it down step by step:\n",
|
|
"\n",
|
|
"Initial situation:\n",
|
|
"- Three people each pay $10, for a total of $30 given to the manager.\n",
|
|
"- The room actually costs $25.\n",
|
|
"- The manager gives $5 to the bellboy to return to the customers.\n",
|
|
"- The bellboy keeps $2 and returns $1 to each person (total of $3 returned).\n",
|
|
"\n",
|
|
"Now, let's analyze the accounting:\n",
|
|
"\n",
|
|
"What actually happened:\n",
|
|
"- The three people originally paid $30.\n",
|
|
"- They got back $3 in total ($1 each).\n",
|
|
"- So they actually paid $30 - $3 = $27 in total.\n",
|
|
"- Of this $27, $25 went to the hotel for the room.\n",
|
|
"- The remaining $2 went to the bellboy.\n",
|
|
"- $25 + $2 = $27, which matches what the guests paid. Everything balances.\n",
|
|
"\n",
|
|
"The error in the puzzle is in how it frames the question. The puzzle states \"each person paid $10 and got back $1, so they paid $9 each, totaling $27. The bellboy kept $2, which makes $29.\" This is mixing up different accounting methods. \n",
|
|
"\n",
|
|
"The $27 that the guests paid in total should be divided as:\n",
|
|
"- $25 for the room\n",
|
|
"- $2 for the bellboy\n",
|
|
"\n",
|
|
"When we add the bellboy's $2 to the guests' $27, we're double-counting the $2, which creates the illusion of a missing dollar. The $2 is already included in the $27, so we shouldn't add it again.\n",
|
|
"\n",
|
|
"Another way to think about it: Out of the original $30, $25 went to the hotel, $3 went back to the guests, and $2 went to the bellboy. That's $25 + $3 + $2 = $30, so everything is accounted for.\n",
|
|
"[Completed thinking block, 1492 characters]\n",
|
|
"--- Finished thinking block ---\n",
|
|
"\n",
|
|
"\n",
|
|
"--- Starting text block ---\n",
|
|
"# The Missing $1 Puzzle Solution\n",
|
|
"\n",
|
|
"This puzzle uses a misleading way of accounting that creates confusion. Let's clarify what actually happened:\n",
|
|
"\n",
|
|
"## The correct accounting:\n",
|
|
"- Three people paid $30 total initially\n",
|
|
"- The room cost $25\n",
|
|
"- The bellboy kept $2\n",
|
|
"- The guests received $3 back ($1 each)\n",
|
|
"\n",
|
|
"So where did all the money go?\n",
|
|
"- $25 went to the hotel\n",
|
|
"- $2 went to the bellboy\n",
|
|
"- $3 went back to the guests\n",
|
|
"- $25 + $2 + $3 = $30 ✓\n",
|
|
"\n",
|
|
"## The error in the puzzle:\n",
|
|
"The puzzle incorrectly adds the $27 paid by the guests (after refunds) to the $2 kept by the bellboy. This is a mistake because the $2 kept by the bellboy is already part of the $27.\n",
|
|
"\n",
|
|
"The puzzle creates the illusion of a missing dollar by mixing two different perspectives:\n",
|
|
"1. How much the guests paid ($27 total)\n",
|
|
"2. Where the original $30 went (hotel + bellboy + refunds)\n",
|
|
"\n",
|
|
"There is no missing dollar - it's just an accounting trick!--- Finished text block ---\n",
|
|
"\n",
|
|
"\n",
|
|
"--- Message complete ---\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"def streaming_with_thinking():\n",
|
|
" with client.messages.stream(\n",
|
|
" model=\"claude-3-7-sonnet-20250219\",\n",
|
|
" max_tokens=4000,\n",
|
|
" thinking={\n",
|
|
" \"type\": \"enabled\",\n",
|
|
" \"budget_tokens\": 2000\n",
|
|
" },\n",
|
|
" messages=[{\n",
|
|
" \"role\": \"user\",\n",
|
|
" \"content\": \"Solve this puzzle: Three people check into a hotel. They pay $30 to the manager. The manager finds out that the room only costs $25 so he gives $5 to the bellboy to return to the three people. The bellboy, however, decides to keep $2 and gives $1 back to each person. Now, each person paid $10 and got back $1, so they paid $9 each, totaling $27. The bellboy kept $2, which makes $29. Where is the missing $1?\"\n",
|
|
" }]\n",
|
|
" ) as stream:\n",
|
|
" # Track what we're currently building\n",
|
|
" current_block_type = None\n",
|
|
" current_content = \"\"\n",
|
|
" \n",
|
|
" for event in stream:\n",
|
|
" if event.type == \"content_block_start\":\n",
|
|
" current_block_type = event.content_block.type\n",
|
|
" print(f\"\\n--- Starting {current_block_type} block ---\")\n",
|
|
" current_content = \"\"\n",
|
|
" \n",
|
|
" elif event.type == \"content_block_delta\":\n",
|
|
" if event.delta.type == \"thinking_delta\":\n",
|
|
" print(event.delta.thinking, end=\"\", flush=True) # Just print dots for thinking to avoid clutter\n",
|
|
" current_content += event.delta.thinking\n",
|
|
" elif event.delta.type == \"text_delta\":\n",
|
|
" print(event.delta.text, end=\"\", flush=True)\n",
|
|
" current_content += event.delta.text\n",
|
|
" \n",
|
|
" elif event.type == \"content_block_stop\":\n",
|
|
" if current_block_type == \"thinking\":\n",
|
|
" # Just show a summary for thinking\n",
|
|
" print(f\"\\n[Completed thinking block, {len(current_content)} characters]\")\n",
|
|
" elif current_block_type == \"redacted_thinking\":\n",
|
|
" print(\"\\n[Redacted thinking block]\")\n",
|
|
" print(f\"--- Finished {current_block_type} block ---\\n\")\n",
|
|
" current_block_type = None\n",
|
|
" \n",
|
|
" elif event.type == \"message_stop\":\n",
|
|
" print(\"\\n--- Message complete ---\")\n",
|
|
"\n",
|
|
"streaming_with_thinking()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Token counting and context window management\n",
|
|
"\n",
|
|
"This example demonstrates how to track token usage with extended thinking:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "python"
|
|
}
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Base token count (input only): 125\n",
|
|
"\n",
|
|
"Estimated thinking tokens used: ~377\n",
|
|
"Estimated final answer tokens: ~237\n",
|
|
"Total estimated output tokens: ~614\n",
|
|
"Input tokens + max_tokens = 8125\n",
|
|
"Available for final answer after thinking: ~7623\n",
|
|
"\n",
|
|
"With thinking budget of 1024 tokens:\n",
|
|
"Input tokens: 125\n",
|
|
"Max tokens needed: 2149\n",
|
|
"Remaining context window: 197851\n",
|
|
"\n",
|
|
"With thinking budget of 2000 tokens:\n",
|
|
"Input tokens: 125\n",
|
|
"Max tokens needed: 3125\n",
|
|
"Remaining context window: 196875\n",
|
|
"\n",
|
|
"With thinking budget of 4000 tokens:\n",
|
|
"Input tokens: 125\n",
|
|
"Max tokens needed: 5125\n",
|
|
"Remaining context window: 194875\n",
|
|
"\n",
|
|
"With thinking budget of 8000 tokens:\n",
|
|
"Input tokens: 125\n",
|
|
"Max tokens needed: 9125\n",
|
|
"Remaining context window: 190875\n",
|
|
"\n",
|
|
"With thinking budget of 16000 tokens:\n",
|
|
"Input tokens: 125\n",
|
|
"Max tokens needed: 17125\n",
|
|
"Remaining context window: 182875\n",
|
|
"\n",
|
|
"With thinking budget of 32000 tokens:\n",
|
|
"Input tokens: 125\n",
|
|
"Max tokens needed: 33125\n",
|
|
"Remaining context window: 166875\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"def token_counting_example():\n",
|
|
" # Define a function to create a sample prompt\n",
|
|
" def create_sample_messages():\n",
|
|
" messages = [{\n",
|
|
" \"role\": \"user\",\n",
|
|
" \"content\": \"Solve this puzzle: Three people check into a hotel. They pay $30 to the manager. The manager finds out that the room only costs $25 so he gives $5 to the bellboy to return to the three people. The bellboy, however, decides to keep $2 and gives $1 back to each person. Now, each person paid $10 and got back $1, so they paid $9 each, totaling $27. The bellboy kept $2, which makes $29. Where is the missing $1?\"\n",
|
|
" }]\n",
|
|
" return messages\n",
|
|
" \n",
|
|
" # Count tokens without thinking\n",
|
|
" base_messages = create_sample_messages()\n",
|
|
" base_token_count = count_tokens(base_messages)\n",
|
|
" print(f\"Base token count (input only): {base_token_count}\")\n",
|
|
" \n",
|
|
" # Make a request with thinking and check actual usage\n",
|
|
" response = client.messages.create(\n",
|
|
" model=\"claude-3-7-sonnet-20250219\",\n",
|
|
" max_tokens=8000,\n",
|
|
" thinking = {\n",
|
|
" \"type\": \"enabled\",\n",
|
|
" \"budget_tokens\": 2000\n",
|
|
" },\n",
|
|
" messages=base_messages\n",
|
|
" )\n",
|
|
" \n",
|
|
" # Calculate and print token usage stats\n",
|
|
" thinking_tokens = sum(\n",
|
|
" len(block.thinking.split()) * 1.3 # Rough estimate\n",
|
|
" for block in response.content \n",
|
|
" if block.type == \"thinking\"\n",
|
|
" )\n",
|
|
" \n",
|
|
" final_answer_tokens = sum(\n",
|
|
" len(block.text.split()) * 1.3 # Rough estimate\n",
|
|
" for block in response.content \n",
|
|
" if block.type == \"text\"\n",
|
|
" )\n",
|
|
" \n",
|
|
" print(f\"\\nEstimated thinking tokens used: ~{int(thinking_tokens)}\")\n",
|
|
" print(f\"Estimated final answer tokens: ~{int(final_answer_tokens)}\")\n",
|
|
" print(f\"Total estimated output tokens: ~{int(thinking_tokens + final_answer_tokens)}\")\n",
|
|
" print(f\"Input tokens + max_tokens = {base_token_count + 8000}\")\n",
|
|
" print(f\"Available for final answer after thinking: ~{8000 - int(thinking_tokens)}\")\n",
|
|
" \n",
|
|
" # Demo with escalating thinking budgets\n",
|
|
" thinking_budgets = [1024, 2000, 4000, 8000, 16000, 32000]\n",
|
|
" context_window = 200000\n",
|
|
" for budget in thinking_budgets:\n",
|
|
" print(f\"\\nWith thinking budget of {budget} tokens:\")\n",
|
|
" print(f\"Input tokens: {base_token_count}\")\n",
|
|
" print(f\"Max tokens needed: {base_token_count + budget + 1000}\") # Add 1000 for final answer\n",
|
|
" print(f\"Remaining context window: {context_window - (base_token_count + budget + 1000)}\")\n",
|
|
" \n",
|
|
" if base_token_count + budget + 1000 > context_window:\n",
|
|
" print(\"WARNING: This would exceed the context window of 200k tokens!\")\n",
|
|
"\n",
|
|
"# Uncomment to run the example\n",
|
|
"token_counting_example()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Understanding redacted thinking blocks\n",
|
|
"\n",
|
|
"Occasionally Claude's internal reasoning will be flagged by safety systems. When this occurs, we encrypt some or all of the `thinking` block and return it to you as a `redacted_thinking` block. These redacted thinking blocks are decrypted when passed back to the API, allowing Claude to continue its response without losing context.\n",
|
|
"\n",
|
|
"This example demonstrates working with redacted thinking blocks using a special test string that triggers them:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "python"
|
|
}
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"[TextBlock(citations=None, text=None, type='redacted_thinking', data='EvAFCoYBGAIiQL7asmglEdeKXw4EdihR2gBQ7O7+j/dGecLjsS2PMgW9av+NRwuIV2nFD4I61hUHrp5vzJF7/y+i/vvbnxaRnwMqQMizGiLSDcowtEvP9EcIT4d75iPhZ8TaiVdD22bZp3YVcc0laY8u1lEJTSesgLUywuc3QHZcg4NZ7tKjWwKgcVUSDHgb6gZUK9aP47KvNxoMCNjkIDR40zmq/QmVIjBSCnvTMSUE+jnmLZSq1TZO9T7ImALNJt8I5j1ls24CO1fibsRThJ7Ha5A0/tuEKVoqlgRc+e2tS+BQMXx572lT4Hkl4aVpcM4SQbqBjeVeR3NmCBLoOxlQ2JLiIYwMHUS/K9GDLyMQcYd1KUWgN34CZRK7k44CSkNsO8oh4uj/1qsRsZjq1l6RQ29rLKSEXvMU4XbZufJ1icvYZS1I6PIZzER6/u6it+WNYyBxJ2vaFICjDePNgIHfRA/ceTz9mfCtBiTfagyPBbs2HflXlSlW26TSdI7PKof5/EsQ+DUkjAy+9VTLX7zHYzNZtwJPL2ryYw4loSwRbc4syldA0Ncnn7hA+yJyY0QwSrxZFIm/t9X9p9s+2SL0F4wSRsimnxRiIhfJD3i+oTw8AbGklyoP0kCH2WxA7Gr3rNLJVkRTJl48AjlSL7ClaWvLWrNer13etD7n5rbwiXOn5husy8gAm5GE3/eFyty3Y+/ad+lMPKXSjL0aP67WoJrFq/teItolOVZeOOERjVFdw5jIV1EUknlAZ/pfI53pLYqwFl17M7IXMdGxEaKoGDIKcnYTwT31uUNlB5JSBWoq1SnkFsFy2zDsDTFzjml3HEXz4szZi3j5/qHWJlMMCcB1walZUisxEp0v1euvcgatY5wfYSiAP3s9wOrgYKCkuLcidlgiyQHJB1haZjO8/tZ9gzWk1n//7pTncdKgd5ZK9/ErxWFlBV/vQwjp0cB7zoVcLh1ydi/Coea6ZOuei+ICKVl4IcR2A6DD8gtEJmc='), TextBlock(citations=None, text=\"I notice you've sent what appears to be a prompt attempting to access internal systems or processes. I can't respond to commands of this nature.\\n\\nInstead, I'm happy to have a normal conversation and assist you with legitimate questions or tasks. What would you like help with today?\", type='text')]\n",
|
|
"Response includes 2 total blocks:\n",
|
|
"- 1 redacted thinking blocks\n",
|
|
"- 0 regular thinking blocks\n",
|
|
"- 1 text blocks\n",
|
|
"\n",
|
|
"Redacted thinking blocks contain encrypted data:\n",
|
|
"Block 1 data preview: EvAFCoYBGAIiQL7asmglEdeKXw4EdihR2gBQ7O7+j/dGecLjsS...\n",
|
|
"\n",
|
|
"Final text response:\n",
|
|
"I notice you've sent what appears to be a prompt attempting to access internal systems or processes. I can't respond to commands of this nature.\n",
|
|
"\n",
|
|
"Instead, I'm happy to have a normal conversation and assist you with legitimate questions or tasks. What would you like help with today?\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"def redacted_thinking_example():\n",
|
|
" # Using the special test string that triggers redacted thinking\n",
|
|
" response = client.messages.create(\n",
|
|
" model=\"claude-3-7-sonnet-20250219\",\n",
|
|
" max_tokens=4000,\n",
|
|
" thinking={\n",
|
|
" \"type\": \"enabled\",\n",
|
|
" \"budget_tokens\": 2000\n",
|
|
" },\n",
|
|
" messages=[{\n",
|
|
" \"role\": \"user\",\n",
|
|
" \"content\": \"ANTHROPIC_MAGIC_STRING_TRIGGER_REDACTED_THINKING_46C9A13E193C177646C7398A98432ECCCE4C1253D5E2D82641AC0E52CC2876CB\"\n",
|
|
" }]\n",
|
|
" )\n",
|
|
" \n",
|
|
" # Identify redacted thinking blocks\n",
|
|
" redacted_blocks = [block for block in response.content if block.type == \"redacted_thinking\"]\n",
|
|
" thinking_blocks = [block for block in response.content if block.type == \"thinking\"]\n",
|
|
" text_blocks = [block for block in response.content if block.type == \"text\"]\n",
|
|
" print(response.content)\n",
|
|
" print(f\"Response includes {len(response.content)} total blocks:\")\n",
|
|
" print(f\"- {len(redacted_blocks)} redacted thinking blocks\")\n",
|
|
" print(f\"- {len(thinking_blocks)} regular thinking blocks\")\n",
|
|
" print(f\"- {len(text_blocks)} text blocks\")\n",
|
|
" \n",
|
|
" # Show data properties of redacted blocks\n",
|
|
" if redacted_blocks:\n",
|
|
" print(f\"\\nRedacted thinking blocks contain encrypted data:\")\n",
|
|
" for i, block in enumerate(redacted_blocks[:3]): # Show first 3 at most\n",
|
|
" print(f\"Block {i+1} data preview: {block.data[:50]}...\")\n",
|
|
" \n",
|
|
" # Print the final text output\n",
|
|
" if text_blocks:\n",
|
|
" print(f\"\\nFinal text response:\")\n",
|
|
" print(text_blocks[0].text)\n",
|
|
"\n",
|
|
"# Uncomment to run the example\n",
|
|
"redacted_thinking_example()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Handling error cases\n",
|
|
"\n",
|
|
"When using extended thinking, keep in mind:\n",
|
|
"\n",
|
|
"1. **Minimum budget**: The minimum thinking budget is 1,024 tokens. We suggest starting at the minimum and increasing incrementally to find the optimal range.\n",
|
|
"\n",
|
|
"2. **Incompatible features**: Thinking isn't compatible with temperature, top_p, or top_k modifications, and you cannot pre-fill responses.\n",
|
|
"\n",
|
|
"3. **Pricing**: Extended thinking tokens count towards the context window and are billed as output tokens. They also count towards your rate limits.\n",
|
|
"\n",
|
|
"For more details on extended thinking with tool use, see the \"Extended Thinking with Tool Use\" notebook."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "python"
|
|
}
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\n",
|
|
"Error with too small thinking budget: Error code: 400 - {'type': 'error', 'error': {'type': 'invalid_request_error', 'message': 'thinking.enabled.budget_tokens: Input should be greater than or equal to 1024'}}\n",
|
|
"\n",
|
|
"Error with temperature and thinking: Error code: 400 - {'type': 'error', 'error': {'type': 'invalid_request_error', 'message': '`temperature` may only be set to 1 when thinking is enabled. Please consult our documentation at https://docs.claude.com/en/docs/build-with-claude/extended-thinking#important-considerations-when-using-extended-thinking'}}\n",
|
|
"\n",
|
|
"Error from exceeding context window: Error code: 400 - {'type': 'error', 'error': {'type': 'invalid_request_error', 'message': 'prompt is too long: 214315 tokens > 204798 maximum'}}\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"def demonstrate_common_errors():\n",
|
|
" # 1. Error from setting thinking budget too small\n",
|
|
" try:\n",
|
|
" response = client.messages.create(\n",
|
|
" model=\"claude-3-7-sonnet-20250219\",\n",
|
|
" max_tokens=4000,\n",
|
|
" thinking={\n",
|
|
" \"type\": \"enabled\",\n",
|
|
" \"budget_tokens\": 500 # Too small, minimum is 1024\n",
|
|
" },\n",
|
|
" messages=[{\n",
|
|
" \"role\": \"user\",\n",
|
|
" \"content\": \"Explain quantum computing.\"\n",
|
|
" }]\n",
|
|
" )\n",
|
|
" except Exception as e:\n",
|
|
" print(f\"\\nError with too small thinking budget: {e}\")\n",
|
|
" \n",
|
|
" # 2. Error from using temperature with thinking\n",
|
|
" try:\n",
|
|
" response = client.messages.create(\n",
|
|
" model=\"claude-3-7-sonnet-20250219\",\n",
|
|
" max_tokens=4000,\n",
|
|
" temperature=0.7, # Not compatible with thinking\n",
|
|
" thinking={\n",
|
|
" \"type\": \"enabled\",\n",
|
|
" \"budget_tokens\": 2000\n",
|
|
" },\n",
|
|
" messages=[{\n",
|
|
" \"role\": \"user\",\n",
|
|
" \"content\": \"Write a creative story.\"\n",
|
|
" }]\n",
|
|
" )\n",
|
|
" except Exception as e:\n",
|
|
" print(f\"\\nError with temperature and thinking: {e}\")\n",
|
|
" \n",
|
|
" # 3. Error from exceeding context window\n",
|
|
" try:\n",
|
|
" # Create a very large prompt\n",
|
|
" long_content = \"Please analyze this text. \" + \"This is sample text. \" * 150000\n",
|
|
" \n",
|
|
" response = client.messages.create(\n",
|
|
" model=\"claude-3-7-sonnet-20250219\",\n",
|
|
" max_tokens=20000, # This plus the long prompt will exceed context window\n",
|
|
" thinking={\n",
|
|
" \"type\": \"enabled\",\n",
|
|
" \"budget_tokens\": 10000\n",
|
|
" },\n",
|
|
" messages=[{\n",
|
|
" \"role\": \"user\",\n",
|
|
" \"content\": long_content\n",
|
|
" }]\n",
|
|
" )\n",
|
|
" except Exception as e:\n",
|
|
" print(f\"\\nError from exceeding context window: {e}\")\n",
|
|
"\n",
|
|
"# Run the common error examples\n",
|
|
"demonstrate_common_errors()"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "Coconut",
|
|
"language": "coconut",
|
|
"name": "coconut"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "python",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".coco",
|
|
"mimetype": "text/x-python3",
|
|
"name": "coconut",
|
|
"pygments_lexer": "coconut",
|
|
"version": "3.0.2"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 4
|
|
}
|