EP19 · April 8, 2026 · 6:49 · AI Dev Tools: The Crazyrouter Podcast

Function Calling Across Different AI Models

Every major model supports function calling, but OpenAI, Anthropic, Google and DeepSeek implement it differently, and those differences surface as bugs in production. This episode compares their request and response formats, reliability and parallel-calling behavior, explains why a normalizing gateway avoids four separate integration layers, and lists five edge cases to test before choosing a model.

Key takeaways

  • Expect different response shapes: OpenAI returns a tool_calls array, Claude returns tool_use content blocks, and Gemini returns function call parts.
  • Define tools once in OpenAI's JSON Schema format, which has become the de facto standard, and let a normalizing layer translate it for other providers.
  • For irreversible actions such as payments or database writes, use the models that produced the most consistently valid JSON in the episode's testing.
  • Send high-volume, simple lookups to fast, low-cost models and save frontier models for complex, many-tool workflows.
  • Before committing to a model, test optional parameters, enum values, nested objects, the no-tool-needed case and parallel calls against your own schemas.

Show notes

Same idea, four implementations#

Function calling is how a model reaches beyond chat and does things. The model decides when a function is needed, formats the arguments as JSON, and your code runs the operation. You return the result and the model continues reasoning. It is the foundation for agents, workflows and any tool-augmented system that goes beyond basic chat.

The concept is shared across providers, but the details are not, and those details matter once you ship. Formats differ, reliability on complex schemas differs, and so does behavior in edge cases such as parallel calls. The comparison below reflects the models discussed at the time of recording (April 2026): GPT-4o and GPT-4.1, Claude Opus 4 and Sonnet, Gemini 2.5 Pro and Flash, and DeepSeek V3 and R1.

How each provider handles tools#

  • OpenAI. You send an array of tool definitions described in JSON Schema, and the model returns a tool_calls array. Parallel function calling lets it request several tools in one response. GPT-4o was very reliable at producing valid JSON within schema constraints, and GPT-4.1 improved instruction adherence when selecting tools. This format has become the de facto standard.
  • Anthropic. Tools also go in a tools array, but Claude replies with tool_use content blocks instead of a separate tool_calls field. Claude is notably thoughtful about whether a tool call is needed at all, and Opus 4 handled complex nested schemas well. Tool call IDs use a different format from OpenAI's, which matters if you parse responses manually.
  • Google. Gemini uses its own format with function declarations in the request and function call parts in the response. Gemini 2.5 Pro was competitive on accuracy but sometimes added explanatory text alongside tool calls. Flash was very fast for simple calls. The SDK's automatic function calling is handy for prototypes but takes control away in production.
  • DeepSeek. DeepSeek V3 uses OpenAI-compatible function calling: same schemas, same response structure. It handled simple and moderate schemas well but could struggle with deeply nested ones, and its main appeal is a much lower price. The R1 reasoning model has more limited tool support.

The compatibility problem and the gateway fix#

Integrating each provider directly means four integration layers: OpenAI's tool_calls, Claude's tool_use blocks, Gemini's function call parts, and DeepSeek's OpenAI-compatible but not always identical behavior. That is a lot of glue code and a steady stream of "works with GPT-4o, breaks with Claude" bugs.

A normalizing gateway removes that layer. With Crazyrouter you define tools once in OpenAI format and send the request with any model name; the gateway translates the definitions for providers like Claude and Gemini, or passes them straight through to OpenAI-compatible models, and returns a response in the same structure regardless of which model handled it. Your code no longer needs to know whether the answer arrived as tool_use blocks or tool_calls, which makes comparing models on the same schema a configuration change rather than an integration project.

Which model for which job#

Based on the episode's real-world observations:

  • High-reliability calls (financial transactions, database mutations, anything hard to undo): GPT-4o or Claude Opus 4, which produced the most consistently valid JSON with the fewest spurious calls.
  • High-volume simple tools (data fetches, searches, lookups): Gemini Flash or DeepSeek V3, fast and inexpensive enough for the job.
  • Complex agents with many tools: Claude Opus 4 was better at choosing the right tool from ten or twenty options, whereas GPT-4o sometimes picked the first plausible one.
  • Parallel tool calling: GPT-4o and GPT-4.1 were strongest; Claude supports it but often prefers sequential calls.

Mixing models this way keeps costs down: you spend on frontier models only where correctness or tool selection is genuinely hard.

Five edge cases to test before you commit#

Before you commit to a model for tool-calling work, run these against your own tool schemas on every candidate. Running all of them through one normalized endpoint keeps the comparison fair, because only the model changes:

  1. Optional parameters. Does the model omit them correctly or fill sensible defaults?
  2. Enum values. Does it stay within the defined options or invent new ones?
  3. Nested objects. Can it handle a schema three levels deep?
  4. The don't-call case. Given a prompt that needs no tool, does it reply with text instead of forcing a call?
  5. Parallel calls. Given a request that needs two tools, does it call both or only one?

The broader lesson: do not lock your code to one provider's function-calling format. Normalize the interface, test several models on your real schemas, and route each task to the model that handles it best.

Questions from this episode

What is the difference between OpenAI tool_calls and Claude tool_use?
Both accept tool definitions in a tools array, but the responses differ. OpenAI returns a separate tool_calls array, while Claude returns tool_use content blocks inside the message content, and Claude's tool call IDs use a different format. Code that parses one format directly will not handle the other without a translation layer.
Does DeepSeek support OpenAI-style function calling?
Yes. DeepSeek V3 supports OpenAI-compatible function calling with the same schema definitions and response structure. It handles simple and moderate schemas well but can struggle with deeply nested ones, and the R1 reasoning model has more limited tool support.
Which model is best for parallel function calling?
In the episode's comparison, GPT-4o and GPT-4.1 were the strongest at making several tool calls in a single response. Claude supports parallel calls but tends to be more conservative and often calls tools one after another. Test with a prompt that clearly needs two tools to see how your chosen model behaves.

More episodes

All episodes with show notes →

Try it on your own traffic

Crazyrouter gives you one OpenAI-compatible API key for Claude, GPT, Gemini, DeepSeek and more, billed pay-as-you-go.

Get an API key →