Skip to main content

Claude Sonnet 4: A Hands-On Guide for Developers

Explore Claude Sonnet 4’s developer features—code execution, files API, and tool use—by building a Python-based math-solving agent.
May 25, 2025  · 11 min read

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.

Sample plots generated by Claude 4 Sonnet's native code execution tool

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:

An image that shows Claude 4 models leading on SWE-bench Verified, a benchmark for performance on real software engineering tasks.

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:

  1. Long runtimes: Both models support several hours of continuous task execution to solve problems with thousands of steps.
  2. Extended thinking with tool use: Both models can now use tools like web search during extended thinking, allowing Claude to alternate between reasoning and tool use to improve responses.
  3. Parallel tool execution: The models can now use multiple tools simultaneously rather than sequentially.
  4. More precise instruction following: Enhanced steerability gives users greater control over implementations and how Claude responds to instructions.
  5. Improved memory capabilities: When given access to local files, the models can extract and save key facts to maintain continuity and build tacit knowledge over time.
  6. Reduced shortcut behavior: Compared to previous versions, both models are 65% less likely to use shortcuts or loopholes to complete tasks (see the full announcement post for more details).

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 tools array and include the required beta header:

from anthropic import Anthropic

# Initialize client with the code execution beta header
client = Anthropic(
   default_headers={
       "anthropic-beta": "code-execution-2025-05-22"
   }
)

# Send a request that triggers code execution
response = client.messages.create(
   model="claude-sonnet-4-20250514",
   max_tokens=4096,
   messages=[{
       "role": "user",
       "content": "Solve the quadratic equation 2x² + 5x - 3 = 0 and plot the parabola"
   }],
   tools=[{
       "type": "code_execution_20250522",
       "name": "code_execution"
   }]
)

When Claude executes code, the response contains both the generated code and its execution results. Here’s how to parse the different components:

# Parse the response to extract code and results
for item in response.content:
   if item.type == "server_tool_use":
       # This contains the actual Python code Claude wrote
       print(f"Code executed:\n{item.input['code']}")
   elif item.type == "code_execution_tool_result":
       # This contains the output from running the code
       print(f"Output:\n{item.content['stdout']}")
       if item.content.get('stderr'):
           print(f"Errors:\n{item.content['stderr']}")

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, and scipy, 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:

# Upload a file once - this stores it on Anthropic's servers
uploaded_file = client.beta.files.upload(
   file=open("sales_data.csv", "rb"),
   purpose="user_upload"
)
# The uploaded_file.id can now be referenced in multiple conversations

Once uploaded, reference the file in your API calls using the container_upload content type:

# Reference the uploaded file in a conversation
response = client.messages.create(
   model="claude-sonnet-4-20250514",
   max_tokens=4096,
   messages=[{
       "role": "user",
       "content": [
           {"type": "text", "text": "Create a quarterly sales report from this data"},
           {"type": "container_upload", "file_id": uploaded_file.id}
       ]
   }],
   tools=[{
       "type": "code_execution_20250522",
       "name": "code_execution"
   }]
)

When Claude creates files during code execution (like plots or processed data), you can extract and download them:

# Extract file IDs of any files Claude created during execution
def extract_created_files(response):
   file_ids = []
   for item in response.content:
       if item.type == 'code_execution_tool_result':
           content = item.content
           if content.get('type') == 'code_execution_result':
               # Look for file objects in the execution results
               for file_obj in content.get('content', []):
                   if 'file_id' in file_obj:
                       file_ids.append(file_obj['file_id'])
   return file_ids

# Download any files Claude created
created_files = extract_created_files(response)
for file_id in created_files:
   file_content = client.beta.files.download(file_id)
   file_content.write_to_file(f"output_{file_id}.png")

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:

mkdir math-solver
cd math-solver
touch math_solver.py demo_problems.py requirements.txt README.md

Create a requirements.txt file with the necessary dependencies:

anthropic>=0.42.0

Install the dependencies:

pip install -r requirements.txt

Set your Anthropic API key as an environment variable:

export ANTHROPIC_API_KEY="your-api-key-here"

Step 1: Design the application structure

Let’s start by creating the basic structure of our MathSolver class. 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:

#!/usr/bin/env python3
"""
Interactive Math Problem Solver using Claude 4 Code Execution Tool

This application allows users to ask math questions in natural language,
gets solutions using Claude's code execution capabilities, and saves
both visualizations and detailed markdown reports.
"""

import os
import json
import datetime
from pathlib import Path
from typing import List, Dict, Any
from anthropic import Anthropic

Now let’s define our main class structure:

class MathSolver:
   def __init__(self, api_key: str = None):
       """Initialize the Math Solver with Anthropic client."""
       # API setup and directory creation will go here
       pass

   def solve_problem(self, question: str) -> Dict[str, Any]:
       """Send a math question to Claude and get solution with code execution."""
       pass
Here are the methods for file and report handling:
def extract_files_from_response(self, response) -> List[str]:
       """Extract file IDs from Claude's response."""
       pass

   def download_files(self, file_ids: List[str]) -> List[str]:
       """Download files created by code execution to local storage."""
       pass

   def extract_code_blocks(self, response) -> List[str]:
       """Extract all code blocks from the response."""
       Pass

Finally, we add the session management and entry point:

def generate_markdown_report(self, result: Dict[str, Any], downloaded_files: List[str]) -> str:
       """Generate a comprehensive markdown report of the solution."""
       pass

   def run_interactive_session(self):
       """Run the main interactive session loop."""
       pass


def main():
   """Main entry point for the application."""
   pass

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:

def __init__(self, api_key: str = None):
   """Initialize the Math Solver with Anthropic client."""
   if not api_key:
       api_key = os.getenv("ANTHROPIC_API_KEY")
       if not api_key:
           raise ValueError(
               "Please set ANTHROPIC_API_KEY environment variable or provide api_key"
           )

Next, we set up the Anthropic client with the required beta headers:

# Initialize client with both code execution and files API headers
   self.client = Anthropic(
       api_key=api_key,
       default_headers={
           "anthropic-beta": "code-execution-2025-05-22,files-api-2025-04-14"
       },
   )

Finally, we create the output directory structure:

# Create organized output directories
   self.output_dir = Path("math_solver_output")
   self.images_dir = self.output_dir / "images"
   self.reports_dir = self.output_dir / "reports"

   self.output_dir.mkdir(exist_ok=True)
   self.images_dir.mkdir(exist_ok=True)
   self.reports_dir.mkdir(exist_ok=True)

   print(f"📁 Output directories created:")
   print(f"   • Images: {self.images_dir}")
   print(f"   • Reports: {self.reports_dir}")

This initialization does three important things:

  1. API key management: Checks for the key in environment variables first, then falls back to a parameter.
  2. Client setup: Creates an Anthropic client with both beta headers for code execution and files API.
  3. Directory structure: Creates organized folders for storing images and reports.

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:

def solve_problem(self, question: str) -> Dict[str, Any]:
   """
   Send a math question to Claude and get solution with code execution.
   """
   print(f"\n🤔 Thinking about: {question}")

   try:
       # Use streaming to show real-time progress
       with self.client.messages.stream(
           model="claude-sonnet-4-20250514",
           max_tokens=4096,
Now we configure the message and tool specification:
messages=[
               {
                   "role": "user",
                   "content": f"""Solve this math problem using code execution:

Problem: {question}

Please:
1. Solve the problem with actual Python code
2. Create visualizations using matplotlib if helpful
3. Save any plots as PNG files using plt.savefig()
4. Show your calculations step by step
5. Use descriptive filenames for saved plots

Execute Python code to solve this problem.""",
               }
           ],
           tools=[{"type": "code_execution_20250522", "name": "code_execution"}],
       ) as stream:
The streaming event processing handles real-time updates:
print("\n💭 Claude is working...")

           # Process streaming events and show progress
           for event in stream:
               if event.type == "content_block_start":
                   if hasattr(event.content_block, "type"):
                       if event.content_block.type == "text":
                           print("\n📝 Response:", end=" ", flush=True)
                       elif event.content_block.type == "server_tool_use":
                           print(f"\n🔧 Using tool: {event.content_block.name}")

We handle different types of streaming events:

	elif event.type == "content_block_delta":
                   if hasattr(event.delta, "text"):
                       print(event.delta.text, end="", flush=True)

               elif event.type == "content_block_stop":
                   print("", flush=True)  # New line

               elif event.type == "message_delta":
                   if hasattr(event.delta, "stop_reason"):
                       print(f"\n✅ Completed: {event.delta.stop_reason}")

Finally, we return the result or handle errors:

	# Get the final message
           final_message = stream.get_final_message()

           return {
               "response": final_message,
               "question": question,
               "timestamp": datetime.datetime.now().isoformat(),
           }

   except Exception as e:
       print(f"❌ Error solving problem: {e}")
       return None

This function demonstrates several important concepts:

  • Streaming support: We use client.messages.stream() instead of client.messages.create() to get real-time feedback as Claude works through the problem.
  • Event handling: The streaming API sends different event types:
    • content_block_start: When Claude begins writing text or using a tool
    • content_block_delta: As content is being generated
    • content_block_stop: When a content block is finished
    • message_delta: When the entire message is complete
  • Tool specification: We include the code execution tool in the tools array with the exact type "code_execution_20250522".
  • Structured prompting: Our prompt clearly instructs Claude to use code execution and save any visualizations.

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:

def extract_files_from_response(self, response) -> List[str]:
   """Extract file IDs from Claude's response."""
   file_ids = []

   for item in response.content:
       if item.type == "code_execution_tool_result":
           content_item = item.content
          
           if isinstance(content_item, dict):
               if content_item.get("type") == "code_execution_result":
                   content_list = content_item.get("content", [])

Then we search for file IDs in the content:

  for file_item in content_list:
                       if isinstance(file_item, dict) and "file_id" in file_item:
                           file_ids.append(file_item["file_id"])

   return file_ids

The download process retrieves files and saves them locally:

def download_files(self, file_ids: List[str]) -> List[str]:
   """Download files created by code execution to local storage."""
   downloaded_files = []

   for file_id in file_ids:
       try:
           # Get file metadata and download content
           file_metadata = self.client.beta.files.retrieve_metadata(file_id)
           filename = file_metadata.filename
          
           file_content = self.client.beta.files.download(file_id)
           local_path = self.images_dir / filename
           file_content.write_to_file(str(local_path))

We track downloaded files and handle errors:

downloaded_files.append(str(local_path))
           print(f"✅ Downloaded: {filename}")

       except Exception as e:
           print(f"❌ Error downloading file {file_id}: {e}")

   return downloaded_files
  • File extraction logic: The 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 the content array.
  • File download process: The download_files() method:
    • Gets metadata for each file (including the original filename)
    • Downloads the file content using the Files API
    • Saves files to our organized directory structure
    • Returns a list of local file paths for later use

Develop AI Applications

Learn to build AI applications using the OpenAI API.
Start Upskilling For Free

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_blocks

This 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 / filename

We 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"![{filename}]({relative_path})\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 = 0

The 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 += 1

For 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:

  1. User interaction: Prompt for questions and handle exit commands
  2. Problem solving: Call our solve_problem() method
  3. File processing: Extract and download any generated files
  4. Report generation: Create a comprehensive markdown report
  5. 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:

python math_solver.py

Try some example questions:

  1. Basic calculation: “What is 15% of 240?”
  2. Algebra: “Solve for x: 3x + 7 = 22”
  3. Visualization: “Graph y = x² — 4x + 3 and find its vertex”
  4. 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:

python demo_problems.py

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.

Develop AI Applications

Learn to build AI applications using the OpenAI API.

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's photo
Author
Bex Tuychiev
LinkedIn

I am a data science content creator with over 2 years of experience and one of the largest followings on Medium. I like to write detailed articles on AI and ML with a bit of a sarcastıc style because you've got to do something to make them a bit less dull. I have produced over 130 articles and a DataCamp course to boot, with another one in the makıng. My content has been seen by over 5 million pairs of eyes, 20k of whom became followers on both Medium and LinkedIn. 

Topics

Learn more about AI with these courses!

Track

Developing AI Applications

0 min
Learn to create AI-powered applications with the latest AI developer tools, including the OpenAI API, Hugging Face, and LangChain.
See DetailsRight Arrow
Start Course
See MoreRight Arrow
Related
claude 4

blog

Claude 4: Tests, Features, Access, Benchmarks, and More

Learn about Claude Sonnet 4 and Claude Opus 4, their features, use cases, benchmarks, and testing results.
Alex Olteanu's photo

Alex Olteanu

8 min

Image representing claude 3.7 sonnet

blog

Claude 3.7 Sonnet: Features, Access, Benchmarks & More

Learn about Claude 3.7 Sonnet's hybrid approach of combining reasoning mode and generalist mode, key benchmarks, and how to access it via web or API.
Alex Olteanu's photo

Alex Olteanu

8 min

Tutorial

Claude 3.7 Sonnet API: A Guide With Demo Project

Learn how to use Claude 3.7 Sonnet's API by building a Gradio-based Research Paper Analyzer to extract insights from uploaded PDFs.
Aashi Dutt's photo

Aashi Dutt

12 min

Tutorial

Claude Sonnet 3.5 API Tutorial: Getting Started With Anthropic's API

To connect through the Claude 3.5 Sonnet API, obtain your API key from Anthropic, install the anthropic Python library, and use it to send requests and receive responses from Claude 3.5 Sonnet.
Ryan Ong's photo

Ryan Ong

8 min

Tutorial

Claude Code: A Guide With Practical Examples

Learn how to use Anthropic's Claude Code to improve software development workflows through a practical example using the Supabase Python library.
Aashi Dutt's photo

Aashi Dutt

12 min

code-along

Introduction to Claude

Aimée, a Learning Solutions Architect at DataCamp, takes you through how to use Claude. You'll get prompt engineering tips, see a data analysis workflow, and learn how to generate Python and SQL code with Claude.
Aimée Gott's photo

Aimée Gott

See MoreSee More