Claude is surprisingly similar to OpenAI’s models at the API level, but the devil is in the details, and a few key differences can trip you up.
Let’s see Claude in action. Imagine you’re making a simple completion request. With OpenAI, it might look like this:
import openai
openai.api_key = "YOUR_OPENAI_KEY"
response = openai.ChatCompletion.create(
model="gpt-4",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "What is the capital of France?"}
]
)
print(response.choices[0].message.content)
Now, let’s switch that to Claude. The core idea of sending a message and getting a text response remains. Anthropic’s SDK simplifies this:
import anthropic
client = anthropic.Anthropic(api_key="YOUR_ANTHROPIC_KEY")
response = client.messages.create(
model="claude-3-opus-20240229",
max_tokens=1000,
temperature=0.7,
system="You are a helpful assistant.",
messages=[
{"role": "user", "content": "What is the capital of France?"}
]
)
print(response.content[0].text)
The fundamental workflow—sending a prompt, getting a text completion—is preserved. You still define a "system" message for persona and provide "user" messages for the conversation. The model parameter specifies which version of Claude you want, and max_tokens caps the output length. temperature controls randomness, just like with OpenAI.
However, the structure of the request and response objects are different. OpenAI uses a nested structure with choices[0].message.content. Claude, in the newer messages API, returns a list of content blocks, where the first block is typically text (response.content[0].text). This is a minor but important structural change to accommodate richer output types in the future, like tool use results or images.
The biggest conceptual shift is how you think about "prompts." While both systems use a chat-like format with roles, Claude’s models are often fine-tuned to respond more directly to the last message in the sequence, especially in the messages API. This means the explicit system role is crucial for setting context that should persist across turns, while the user’s instruction should be the final message.
Here’s a breakdown of what changes and what doesn’t:
What Doesn’t Change (Much):
- Core Task: Both provide text generation capabilities through APIs.
- Prompting Basics: The idea of providing context, instructions, and user queries remains.
- Model Families: Both have families of models with varying capabilities (e.g., speed vs. power).
- Parameters:
temperature,max_tokens(or equivalent),top_p(though less common in Claude’smessagesAPI by default) function similarly. - API Key Authentication: Standard API key mechanisms apply.
What Changes:
- API Endpoint & SDK: You’ll need to use Anthropic’s SDK (
anthropic) and their API endpoints. - Request/Response Structure: As seen, the
messagesAPI in Claude returnsresponse.contentas a list, notresponse.choices[0].message.content. - Model Naming: OpenAI uses
gpt-3.5-turbo,gpt-4, etc. Anthropic usesclaude-2.1,claude-3-opus-20240229,claude-3-sonnet-20240229, etc. - System Prompting: While both use a system prompt, Claude’s
messagesAPI treats it as a distinct, persistent instruction, separate from the conversational turns. You must include it if you want persona. - Token Limits: While both have token limits, the exact context window sizes for comparable models differ. Claude 3 models, for example, offer a 200K token context window by default, expandable up to 1 million tokens.
- Tool Use/Function Calling: OpenAI has a well-defined "function calling" feature. Anthropic has "Tool Use," which is conceptually similar but has a different API signature and JSON schema definition. The way you define tools and parse their outputs will be different.
- Streaming: Both support streaming responses, but the event formats differ. OpenAI uses
data: {...}chunks, while Anthropic’s streaming events are structured differently, often usingevent: message_deltaanddata: {...}. - Pricing: Costs per token are different and can vary significantly between models and providers.
The most surprising thing is how easily you can swap out the models and get functionally identical results for many basic tasks, even with slightly different response structures. It feels like a drop-in replacement until you hit more complex scenarios like tool use or need to precisely replicate output formatting.
When you’re migrating, pay close attention to how you handle the system prompt. For Claude’s messages API, it’s a first-class citizen that defines the model’s core behavior. If you omit it or place it incorrectly, you might find Claude’s persona or adherence to instructions is not what you expect, even if the rest of your prompt structure is identical to your OpenAI implementation.
The next hurdle will likely be understanding and implementing Claude’s Tool Use, which is Anthropic’s equivalent to OpenAI’s Function Calling.