Extracting Results from Claude Sonnet 4: Code, Visuals, and Reports
Now, let’s reuse and audit Claude’s generated code and outputs.
Step 5: Download visual outputs from Claude’s responses
For our markdown reports, we want to include the actual Python code that Claude executed:
def extract_code_blocks(self, response) -> List[str]:
"""Extract all code blocks from the response."""
code_blocks = []
for item in response.content:
if item.type == "server_tool_use" and item.name == "code_execution":
if (
hasattr(item, "input")
and isinstance(item.input, dict)
and "code" in item.input
):
code_blocks.append(item.input["code"])
return code_blocksThis method looks for server_tool_use items with the name "code_execution" and extracts the Python code from the input field. This gives us the actual code Claude wrote and executed.
Step 6: Extract Claude’s code for reuse and auditing
Our report generator creates comprehensive documentation of each solution.
First, we extract content and set up the report structure:
def generate_markdown_report(self, result: Dict[str, Any], downloaded_files: List[str]) -> str:
"""Generate a comprehensive markdown report of the solution."""
response = result["response"]
question = result["question"]
timestamp = result["timestamp"]
# Extract text content and code blocks
text_content = []
code_blocks = self.extract_code_blocks(response)
for item in response.content:
if item.type == "text":
text_content.append(item.text)Next, we generate a safe filename with a timestamp:
# Generate filename with timestamp
safe_question = "".join(
c for c in question[:50] if c.isalnum() or c in (" ", "-", "_")
).strip()
filename = f"{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}_{safe_question.replace(' ', '_')}.md"
filepath = self.reports_dir / filenameWe build the markdown content with a header and a problem statement:
# Create markdown content
markdown_content = f"""# Math Problem Solution Report
**Generated:** {timestamp}
**Question:** {question}
---
## Problem Statement
{question}
---
## Solution
"""
Add the solution explanation and code blocks:
# Add the main explanation
for text in text_content:
markdown_content += f"{text}\n\n"
# Add code sections
if code_blocks:
markdown_content += "---\n\n## Code Used\n\n"
for i, code in enumerate(code_blocks, 1):
markdown_content += f"### Code Block {i}\n\n```python\n{code}\n```\n\n"Include any generated visualizations:
# Add images section
if downloaded_files:
markdown_content += "---\n\n## Generated Visualizations\n\n"
for file_path in downloaded_files:
filename = Path(file_path).name
relative_path = f"../images/{filename}"
markdown_content += f"\n\n"
Finally, add metadata and save the report:
# Add footer
markdown_content += f"""---
## Report Details
- **Generated by:** Claude 4 Math Solver
- **Model:** claude-sonnet-4-20250514
- **Timestamp:** {timestamp}
- **Files created:** {len(downloaded_files)} visualization(s)
---
*This report was automatically generated using Claude's code execution capabilities.*
"""
# Save the report
with open(filepath, "w", encoding="utf-8") as f:
f.write(markdown_content)
return str(filepath)This report generator creates a structured markdown document containing:
- Problem statement and metadata
- Solution explanation from Claude’s text responses
- Code blocks showing the actual Python code executed
- Embedded visualizations using relative paths
- Report metadata for tracking and reference
The filename generation creates safe, timestamped filenames that won’t conflict with existing files.
Running the Math Solver Interactively
Next, let’s focus on the user interaction loop, demo tools, and testing.
Step 7: Manage the interactive session
The interactive session loop handles user input and coordinates all our components.
We start with the session setup and welcome message:
def run_interactive_session(self):
"""Run the main interactive session loop."""
print("🧮 Interactive Math Problem Solver with Claude 4")
print("=" * 60)
print("Ask me any math question and I'll solve it step by step!")
print("I can handle algebra, calculus, statistics, geometry, and more.")
print("Type 'quit', 'exit', or 'q' to end the session.")
print("=" * 60)
session_count = 0The main loop handles user input and exit conditions:
while True:
try:
# Get user input
question = input(f"\n📝 Question #{session_count + 1}: ").strip()
if question.lower() in ["quit", "exit", "q"]:
print("\n👋 Thanks for using the Math Solver! Goodbye!")
break
if not question:
print("Please enter a question.")
continue
session_count += 1For each valid question, we process the complete workflow:
# Solve the problem
result = self.solve_problem(question)
if not result:
continue
# Extract and download any files created
file_ids = self.extract_files_from_response(result["response"])
downloaded_files = []
if file_ids:
print(f"📥 Downloading {len(file_ids)} file(s)...")
downloaded_files = self.download_files(file_ids)We finish with report generation and user feedback:
# Generate markdown report
print(f"📝 Generating report...")
report_path = self.generate_markdown_report(result, downloaded_files)
print(f"\n✅ Solution complete!")
print(f"📄 Report saved: {report_path}")
if downloaded_files:
print(f"🖼️ Visualizations: {len(downloaded_files)} file(s) saved")
except KeyboardInterrupt:
print("\n\n👋 Session interrupted. Goodbye!")
break
except Exception as e:
print(f"❌ An error occurred: {e}")
print("Please try again with a different question.")This loop demonstrates a complete workflow:
- User interaction: Prompt for questions and handle exit commands
- Problem solving: Call our
solve_problem()method - File processing: Extract and download any generated files
- Report generation: Create a comprehensive markdown report
- Error handling: Gracefully handle interruptions and errors
Step 8: Write the application entry point
Finally, we need a main() function to initialize and start our application:
def main():
"""Main entry point for the application."""
try:
solver = MathSolver()
solver.run_interactive_session()
except Exception as e:
print(f"❌ Failed to initialize Math Solver: {e}")
print("Make sure you have set the ANTHROPIC_API_KEY environment variable.")
return 1
return 0
if __name__ == "__main__":
exit(main())This simple entry point handles initialization errors (like missing API keys) and provides helpful error messages.
Step 9: Add a demo problem generator
To help users get started, let’s create a separate script with example problems. Create demo_problems.py.
First, we define our problem categories:
# demo_problems.py
#!/usr/bin/env python3
"""
Demo problems for the Interactive Math Problem Solver
"""
# Sample problems organized by difficulty and topic
DEMO_PROBLEMS = {
"Beginner": [
"What is 15% of 240?",
"Solve for x: 3x + 7 = 22",
"Find the area of a circle with radius 5",
"Convert 45 degrees to radians",
"Calculate the hypotenuse of a right triangle with legs 3 and 4",
],Add intermediate and advanced problem sets:
"Intermediate": [
"Solve the quadratic equation: 2x^2 + 5x - 3 = 0",
"Graph y = x^2 - 4x + 3 and find its vertex",
"Calculate mean, median, and standard deviation of [12, 15, 18, 22, 25, 28]",
"Find where f(x) = x^3 - 3x^2 + 2 crosses the x-axis",
"Solve the system of equations: 2x + 3y = 7, x - y = 1",
],
"Advanced": [
"Find the derivative of sin(x) * e^x and plot both functions",
"Calculate the integral of x^2 from 0 to 5",
"Use Newton's method to find the root of x^3 - 2x - 5 = 0",
"Perform linear regression on data points and plot the results",
"Solve the differential equation dy/dx = x*y with initial condition y(0) = 1",
],
}Create helper functions for random selection and display:
def get_random_problem(category=None):
"""Get a random problem from a specific category or all categories."""
import random
if category and category in DEMO_PROBLEMS:
return random.choice(DEMO_PROBLEMS[category])
else:
# Pick from all problems
all_problems = []
for problems in DEMO_PROBLEMS.values():
all_problems.extend(problems)
return random.choice(all_problems)Add a function to display all available problems:
def print_demo_problems():
"""Print all demo problems organized by category."""
print("🧮 Demo Problems for Interactive Math Solver")
print("=" * 60)
print("Here are example problems you can try, organized by difficulty:\n")
for category, problems in DEMO_PROBLEMS.items():
print(f"### {category}")
print("-" * (len(category) + 4))
for i, problem in enumerate(problems, 1):
print(f"{i:2d}. {problem}")
print()
print("💡 Tips:")
print(" • Copy and paste any question into the math solver")
print(" • All visualizations and reports will be saved automatically")
print("\n🚀 Start the solver with: python math_solver.py")
if __name__ == "__main__":
print_demo_problems()
This demo script provides:
- Categorized problems from beginner to advanced levels
- Random problem selection for testing
- Usage guidance for new users
Step 10: Run and test the application
Now let’s test our complete application! Run the math solver:
Try some example questions:
- Basic calculation: “What is 15% of 240?”
- Algebra: “Solve for x: 3x + 7 = 22”
- Visualization: “Graph y = x² — 4x + 3 and find its vertex”
- Advanced math: “Find the derivative of sin(x) * e^x and plot both functions”
Each question will:
- Show real-time streaming output as Claude works
- Generate any necessary visualizations
- Save a comprehensive markdown report
- Download plot files to your images directory
You can also run the demo problems script to see all available examples:
What We’ve Built with Claude Sonnet 4
Our math problem solver demonstrates several powerful features of Claude 4 and the new API capabilities:
- Code execution: Claude can write and run Python code to solve mathematical problems, iterate on solutions, and handle complex calculations.
- File generation and management: The application automatically handles file creation, download, and organization using the Files API.
- Streaming interaction: Real-time feedback makes the experience feel responsive and engaging.
- Comprehensive documentation: Every solution is preserved in detailed markdown reports with embedded code and visualizations.
- User-friendly interface: The terminal-based interface is simple but effective for mathematical problem solving.
This project shows how Claude 4’s new capabilities can be combined to create sophisticated applications beyond simple chat interactions. The code execution tool, combined with proper file handling and streaming, creates a powerful platform for mathematical exploration and analysis.
You can also learn to build similar agents using other platforms by taking the course on Developing AI Systems with the OpenAI API.
Conclusion and Further Steps
Building this math problem solver has demonstrated how Claude 4’s new capabilities transform what’s possible with AI applications.
Our application handles everything from basic calculations to complex mathematical visualizations, showing how these API features work together to create great user experiences. The code execution tool particularly stands out as a game-changer, allowing Claude to iterate on solutions and generate visual outputs that would have required separate tools and complex integrations in the past.
From here, you can extend this math solver with web interfaces, integrate it with external data sources through MCPs, or apply similar patterns to build domain-specific assistants for other fields, such as data analysis, scientific computing, or educational tools.
- If you're a developer looking to certify your AI engineering skills, consider the Associate AI Engineer track for developers, which emphasizes production-level implementations like this.
- Data scientists interested in operationalizing LLMs can follow the Associate AI Engineer track for data scientists, which bridges analysis and AI deployment.
FAQs
What makes Claude 4 different from previous versions?
Claude 4 introduces native code execution, extended thinking with tool use, parallel tool execution, improved memory capabilities, and support for several hours of continuous task execution. These features make it particularly strong at software engineering tasks.
Can Claude 4 actually run Python code during conversations?
Yes, Claude 4 can execute Python code in a secure sandbox environment using the new code execution tool. It can run calculations, generate visualizations with matplotlib, and iterate on solutions based on execution results.
What are the limitations of Claude's code execution environment?
The sandbox has no internet access, limited computational resources, and cannot access your local file system. It comes with popular libraries like numpy, pandas, and matplotlib pre-installed, but you cannot install additional packages.
How does the new Files API work with code execution?
The Files API lets you upload documents once and reference them across conversations. When Claude creates files during code execution (like plots), you can extract their file IDs and download them locally using the API.
Do I need special API access to use Claude 4's code execution features?
You need to include the beta header "anthropic-beta": "code-execution-2025-05-22" in your API requests and use the claude-sonnet-4-20250514 model. The code execution tool is specified as "code_execution_20250522" in your tools array.

Bex Tuychiev builds voice agents and LLM systems, and most of his work goes into making them reliable enough to run in production, preferably in healthcare.





Anthropic recently launched the updated Claude Sonnet 4.5, Claude Agents SDK, and Imagine with Claude.
With the release of Claude Sonnet 4, developers now have access to powerful new capabilities—including native code execution, a flexible Files API, and dynamic tool use. These features open up exciting possibilities for building AI-powered applications that go beyond simple text interactions.
In this tutorial, I’ll walk you through these new features by building a Python-based agent that can solve advanced math problems right from your terminal. You’ll learn to use the newly introduced native code execution tool and the files API.
By the end, you’ll have a working agent powered by Claude Sonnet 4 to analyze problems, write and run Python code, and render visuals like the ones below.
Check out the GitHub repository for this project to see all the code for building the application.
If you're just beginning your journey into building with LLMs like Claude, this AI developer roadmap outlines essential tools, skills, and learning paths to get started.
What’s New in the Anthropic API
Before we go into the tutorial, let’s look at all the recently released new features available through the Anthropic API. Feel free to skip ahead if you’re already aware of them.
I think the entire Claude 4 announcement can be summarized in this one image:
Claude 4 models (Opus and Sonnet 4) beat the competition in verified software engineering tasks by a significant margin. Anthropic achieved this feat by introducing a few important changes to how the models behave:
Additionally, as part of the Claude 4 model family announcement, Anthropic has added four new features for building AI agents: the code execution tool, Files API, MCP connector, and extended prompt caching. These tools change how developers can build AI applications.
Code execution tool: Run Python code securely
The code execution tool allows Claude to run Python code in a secure sandbox environment. Instead of just writing code suggestions, Claude can now execute code, analyze results, and iterate on solutions.
To use the code execution tool, add it to your
toolsarray and include the required beta header:When Claude executes code, the response contains both the generated code and its execution results. Here’s how to parse the different components:
Sandbox limitations: The code execution environment has several built-in security restrictions. Claude runs in an isolated container with no internet access, limited computational resources (1 GB RAM, 5 GB disk space, and 1 CPU), and cannot access your local file system. The environment comes pre-installed with popular libraries like
numpy,pandas,matplotlib, andscipy, but you cannot install additional packages during execution.Files API: Persistent file context for complex tasks
The Files API allows you to upload documents once and reference them across multiple conversations. This removes the need to include large documents in every API request.
First, upload your file to Anthropic’s servers:
Once uploaded, reference the file in your API calls using the
container_uploadcontent type:When Claude creates files during code execution (like plots or processed data), you can extract and download them:
MCP connector: Plug Claude into any workflow
The MCP connector brings Model Context Protocol support directly to the API. MCPs allow Claude to connect to external services like databases, APIs, and productivity tools without custom integration code.
Previously, connecting to MCP servers required building client infrastructure. Now, you can simply provide a remote MCP server URL in your API request, and Claude automatically discovers available tools, manages connections, and handles authentication.
This opens up access to a growing ecosystem of MCP servers from companies like Zapier and Asana, allowing you to build agents that can read your calendar, update project management tools, or integrate with hundreds of other services.
Getting Started with Claude Sonnet 4: Project Overview and Setup
Now that we understand the new API features, let’s build our interactive math problem solver. It will combine Claude’s code execution capabilities with file handling to create a complete mathematical assistant.
Our application will accept natural language math questions, execute Python code to solve them, generate visualizations, and save comprehensive reports.
For a structured approach to building projects like this, check out the Developing AI Applications track.
> Note: Since we will be breaking up long code blocks with explanations, the code indentation may not be entirely accurate in snippets. For this reason, we recommend opening the GitHub repo for this project in a separate tab while following along.
Step 0: Set up your Claude Sonnet 4 project environment
Before writing any code, let’s set up our development environment and dependencies.
Create a new directory for your project and set up the required files:
Create a
requirements.txtfile with the necessary dependencies:Install the dependencies:
Set your Anthropic API key as an environment variable:
Step 1: Design the application structure
Let’s start by creating the basic structure of our
MathSolverclass. This class will handle all the main functionality: API communication, file management, and user interaction.First, let’s set up the imports and basic structure:
Now let’s define our main class structure:
Finally, we add the session management and entry point:
This structure gives us a clear roadmap: initialization, problem solving, file handling, report generation, and user interaction. Each method has a specific responsibility in our math-solving pipeline.
Building a Math Solver with Claude Sonnet 4 Code Execution
Now, let’s implement core functionality using Claude's code execution tool and streaming responses.
Step 2: Initialize Claude with secure API headers
Let’s implement the
__init__()method to handle API client setup and directory creation.First, we handle API key management:
Next, we set up the Anthropic client with the required beta headers:
Finally, we create the output directory structure:
This initialization does three important things:
Step 3: Write the core solver function
The
solve_problem()method is the heart of our application. It sends requests to Claude with streaming support.Let’s start with the function signature and initial setup:
We handle different types of streaming events:
Finally, we return the result or handle errors:
This function demonstrates several important concepts:
client.messages.stream()instead ofclient.messages.create()to get real-time feedback as Claude works through the problem.content_block_start: When Claude begins writing text or using a toolcontent_block_delta: As content is being generatedcontent_block_stop: When a content block is finishedmessage_delta: When the entire message is completetoolsarray with the exact type"code_execution_20250522".Step 4: Solve math problems with streaming code execution
When Claude creates files during code execution (like matplotlib plots), we need to extract their file IDs and download them locally.
The file extraction method navigates through the response structure:
Then we search for file IDs in the content:
The download process retrieves files and saves them locally:
We track downloaded files and handle errors:
extract_files_from_response()method navigates through the response structure to find file IDs. Code execution results are nested in a specific format where files appear in thecontentarray.download_files()method: