AiTechWorlds
AiTechWorlds
The Anthropic Claude API is Claude's equivalent of the OpenAI API a messages.create HTTP call instead of chat.completions.create but it structures conversations differently: the system prompt is a top level parameter, not a message, and every response comes back as a list of typed content blocks. Think of the difference as two courier services that both deliver the same package: the address format on the label is different, but the box still arrives.
This lesson covers Claude's unique capabilities long context, vision, and its own tool use syntax and when to reach for it over GPT-4.
# pip install anthropic python-dotenv
import anthropic
from dotenv import load_dotenv
import os
load_dotenv()
client = anthropic.Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY"))# Claude's API uses messages.create, not chat.completions
response = client.messages.create(
model="claude-opus-4-7", # Most capable
# model="claude-sonnet-4-6", # Fast and capable — great default
# model="claude-haiku-4-5-20251001", # Fastest and cheapest
max_tokens=1024,
system="You are a Python expert who gives concise, practical answers.",
messages=[
{"role": "user", "content": "What are Python generators and when should I use them?"}
]
)
print(response.content[0].text)
print(f"\nModel: {response.model}")
print(f"Input tokens: {response.usage.input_tokens}")
print(f"Output tokens: {response.usage.output_tokens}")# System prompt is a top-level parameter, not a message role
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=500,
system="You are a helpful assistant.", # System is here, not in messages
messages=[
{"role": "user", "content": "Hello!"},
{"role": "assistant", "content": "Hi! How can I help you today?"},
{"role": "user", "content": "What's the capital of France?"}
]
)
# Response content is a list of content blocks
for block in response.content:
if block.type == "text":
print(block.text)Claude's tool use syntax is slightly different but follows the same concept:
import json
tools = [
{
"name": "search_database",
"description": "Search a product database for items matching a query",
"input_schema": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Search terms"
},
"max_results": {
"type": "integer",
"description": "Maximum number of results to return",
"default": 5
}
},
"required": ["query"]
}
}
]
def search_database(query: str, max_results: int = 5) -> list:
"""Mock database search."""
mock_products = [
{"id": 1, "name": "Python Programming Book", "price": 39.99},
{"id": 2, "name": "Python for Data Science", "price": 44.99},
{"id": 3, "name": "Learn Python Fast", "price": 29.99}
]
return [p for p in mock_products if query.lower() in p['name'].lower()][:max_results]
def run_claude_agent(user_message: str) -> str:
messages = [{"role": "user", "content": user_message}]
while True:
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
tools=tools,
messages=messages
)
messages.append({"role": "assistant", "content": response.content})
if response.stop_reason == "end_turn":
for block in response.content:
if hasattr(block, 'text'):
return block.text
# Process tool use blocks
tool_results = []
for block in response.content:
if block.type == "tool_use":
if block.name == "search_database":
result = search_database(**block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": json.dumps(result)
})
if tool_results:
messages.append({"role": "user", "content": tool_results})
answer = run_claude_agent("Find me some Python books under $40")
print(answer)Claude models support up to 200K tokens (about 150K words) larger than most books. This enables unique use cases:
def analyze_long_document(document_text: str, question: str) -> str:
"""Analyze a very long document — contracts, codebases, research papers."""
response = client.messages.create(
model="claude-opus-4-7", # Use Opus for best long-context performance
max_tokens=2048,
system="""You are an expert analyst. Read the entire document carefully
and answer questions with specific citations from the text.""",
messages=[
{
"role": "user",
"content": f"Document:\n\n{document_text}\n\n---\n\nQuestion: {question}"
}
]
)
return response.content[0].text
# Examples of long-context tasks:
# - Analyze an entire codebase
# - Review a legal contract for specific clauses
# - Summarize a 400-page research report
# - Extract all data from a large CSV pasted as textdef stream_claude(prompt: str, system: str = ""):
"""Stream Claude's response token by token."""
kwargs = {
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"messages": [{"role": "user", "content": prompt}]
}
if system:
kwargs["system"] = system
with client.messages.stream(**kwargs) as stream:
full_text = ""
for text in stream.text_stream:
print(text, end='', flush=True)
full_text += text
print()
return full_text
stream_claude("Explain recursion with a simple Python example",
system="Be brief and practical.")import base64
from pathlib import Path
def analyze_image(image_path: str, question: str) -> str:
"""Ask Claude to analyze an image."""
image_data = base64.standard_b64encode(
Path(image_path).read_bytes()
).decode("utf-8")
suffix = Path(image_path).suffix.lower()
media_types = {'.jpg': 'image/jpeg', '.jpeg': 'image/jpeg',
'.png': 'image/png', '.gif': 'image/gif', '.webp': 'image/webp'}
media_type = media_types.get(suffix, 'image/jpeg')
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[
{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "base64",
"media_type": media_type,
"data": image_data
}
},
{
"type": "text",
"text": question
}
]
}
]
)
return response.content[0].text
# Usage
description = analyze_image("chart.png", "What trend does this chart show?")
code_review = analyze_image("screenshot.png", "What's wrong with this code?")| Task | Recommendation |
|---|---|
| Long document analysis (50K+ words) | Claude 200K context |
| Code generation and debugging | Both are excellent |
| Complex reasoning, nuanced analysis | Claude consistently thoughtful |
| Vision and image understanding | Both are excellent |
| Function calling / tool use | Both support it |
| Fastest/cheapest option | Claude Haiku vs GPT-4o mini |
| Existing OpenAI integration | Stick with GPT |
Next lesson: Build an AI Chatbot in Python combining everything into a real application.
Get this course's notes on Telegram!
Free cheat sheets, summaries & practice exercises