Migrating from Google Gemini to OpenAI: A Practical Guide

If you used Gemini’s native google-genai SDK, moving to OpenAI means converting contents/parts into OpenAI messages, the system instruction into a system message, and response.text into choices[0].message.content. If you used Gemini’s OpenAI-compatibility endpoint, it’s just a base-URL/key/model swap.

Already on the compat endpoint? Then it’s trivial

Compat endpoint → OpenAI
from openai import OpenAI
# Before: OpenAI(base_url="https://generativelanguage.googleapis.com/v1beta/openai/", api_key=GEMINI_KEY)
client = OpenAI()  # OPENAI_API_KEY, default base_url
resp = client.chat.completions.create(model="gpt-5.4",
  messages=[{"role": "user", "content": "Hello"}])
print(resp.choices[0].message.content)

Native SDK — concept mapping

Gemini native → OpenAI Chat Completions (as of June 2026).
ConceptGemini (native)OpenAI
SDK google-genaiopenai
Call models.generate_contentchat.completions.create
Turns contents[] (user/model)messages[] (user/assistant)
System prompt config.system_instructionmessages[] with role: system
Max output config.max_output_tokensmax_tokens
Assistant role modelassistant
Response text response.textchoices[0].message.content
Tools config.tools (declarations)tools + tool_calls

Before / after (native)

Before — Gemini native
from google import genai
from google.genai import types
client = genai.Client()

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.", max_output_tokens=1024),
)
print(resp.text)
After — OpenAI
from openai import OpenAI
client = OpenAI()

resp = client.chat.completions.create(
  model="gpt-5.4",
  messages=[
      {"role": "system", "content": "You are concise."},
      {"role": "user", "content": "Explain rate limits in one line."},
  ],
)
print(resp.choices[0].message.content)
Watch for these
  • Role rename: Gemini model turns become OpenAI assistant turns.
  • contents/parts → flat messages; collapse multi-part text into content.
  • system_instruction → a system message; max_output_tokensmax_tokens.
  • Tools: Gemini function declarations → OpenAI tools + tool_calls + role: tool results.
  • Re-price and re-eval — OpenAI is typically pricier than Gemini Flash.

What to do next

  1. If on the compat endpoint, just drop the Gemini base URL/key and pick a GPT model.
  2. For native, convert contentsmessages (rename modelassistant) and the system instruction → a system message.
  3. Port tool declarations to OpenAI tools.
  4. Re-price with the cost calculator; reverse route is OpenAI → Gemini.

Frequently asked questions

Is Gemini → OpenAI hard?
It's involved only if you used the native SDK — then you remap contents/parts to messages, rename the model role to assistant, and move the system instruction into a message. If you used Gemini's OpenAI-compatibility endpoint, it's a config change.
How do roles map?
Gemini uses user and model; OpenAI uses user and assistant. Rename modelassistant when porting conversation history.
What happens to my Gemini tools?
Convert Gemini function declarations into OpenAI's tools schema, read tool_calls from the response, and return results as role: tool messages.