This is the most involved of the common migrations: both sides use a non-OpenAI shape. You move from Anthropic’s Messages API to Gemini’s google-genai SDK, remapping roles, the system prompt, generation config, and the response path.
API concept mapping
| Concept | Anthropic | Gemini (native) |
|---|---|---|
| SDK | anthropic | google-genai |
| Auth | x-api-key + anthropic-version | GEMINI_API_KEY |
| Call | messages.create | models.generate_content |
| Turns | messages[] (user/assistant) | contents[] (user/model) |
| System prompt | top-level system param | config.system_instruction |
| Max output | max_tokens (required) | config.max_output_tokens |
| Assistant text | content[0].text | response.text |
| Tools | tools + tool_use blocks | config.tools (function declarations) |
Before / after
import anthropic
client = anthropic.Anthropic()
resp = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
system="You are concise.",
messages=[{"role": "user", "content": "Explain rate limits in one line."}],
)
print(resp.content[0].text) from google import genai
from google.genai import types
client = genai.Client() # GEMINI_API_KEY
resp = client.models.generate_content(
model="gemini-2.5-flash",
contents="Explain rate limits in one line.",
config=types.GenerateContentConfig(
system_instruction="You are concise.", # was top-level system
max_output_tokens=1024,
),
)
print(resp.text) Watch for these
- Assistant role is
modelin Gemini’scontents, notassistant— remap any conversation history. - System prompt →
config.system_instruction; max output →config.max_output_tokens. - Response is
response.text, notcontent[0].text. - Tool calling moves to Gemini function declarations; port
input_schemaand the result round-trip. - Long-context pricing tier on Gemini Pro for big prompts — re-budget.
- Re-tune prompts and re-run evals.
What to do next
- Convert Claude messages → Gemini
contents(rolesuser/model) and move the system prompt tosystem_instruction. - Port tool declarations and the function-result loop.
- Update parsing to
response.textand Gemini’s finish/usage fields. - Re-price with the cost calculator. Prefer an OpenAI-shaped middle step? Go via Anthropic → OpenAI then use Gemini’s OpenAI-compatibility endpoint.
Frequently asked questions
Why is Anthropic → Gemini harder than other routes?
Neither side is OpenAI-shaped, so you can't lean on a compatibility layer for the whole thing. You remap Claude's Messages format onto Gemini's
contents/parts model with a top-level system instruction and a different response path.Is there a shortcut?
Partly: Gemini offers an OpenAI-compatibility endpoint, so you can first remap Claude → OpenAI shape and then point the OpenAI SDK at Gemini. That avoids learning the native SDK for standard chat, though native unlocks more Gemini features.
What's the #1 gotcha?
Roles: Gemini's assistant turn is
model, not assistant. Mis-mapping history is the most common cause of broken multi-turn conversations after the switch.