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
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
| Concept | Gemini (native) | OpenAI |
|---|---|---|
| SDK | google-genai | openai |
| Call | models.generate_content | chat.completions.create |
| Turns | contents[] (user/model) | messages[] (user/assistant) |
| System prompt | config.system_instruction | messages[] with role: system |
| Max output | config.max_output_tokens | max_tokens |
| Assistant role | model | assistant |
| Response text | response.text | choices[0].message.content |
| Tools | config.tools (declarations) | tools + tool_calls |
Before / after (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) 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
modelturns become OpenAIassistantturns. contents/parts→ flatmessages; collapse multi-part text intocontent.system_instruction→ asystemmessage;max_output_tokens→max_tokens.- Tools: Gemini function declarations → OpenAI
tools+tool_calls+role: toolresults. - Re-price and re-eval — OpenAI is typically pricier than Gemini Flash.
What to do next
- If on the compat endpoint, just drop the Gemini base URL/key and pick a GPT model.
- For native, convert
contents→messages(renamemodel→assistant) and the system instruction → a system message. - Port tool declarations to OpenAI
tools. - 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 model → assistant 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.