structured-tool-use-round-trip · EN · 2026-10-19

Tool Calls Across Backends: Which Ones Round-Trip Through the Aggregator Without Losing Fields

Understand how tool (function) calls survive round-trips when using a multi-model API aggregator. Learn which backends preserve field fidelity, why some fields get dropped or transformed, and how to design resilient tool-calling workflows.

Why Tool Call Round-Tripping Matters

When your application uses tool calling (also known as function calling), the model returns structured data indicating which tool to invoke and with what arguments. That data then passes through your aggregator to the actual backend model provider, and the response travels back. If any field is lost, renamed, or coerced along the way, your tool execution logic can break.

Round-tripping refers to the complete journey: request → aggregator → model backend → response → aggregator → your app. The aggregator must faithfully translate tool definitions, tool choices, and tool call results between its own API surface and each backend's native format.

Common Fields in Tool Calls

Across providers, tool calls typically include:

  • Tool name – identifier for the function.
  • Arguments – JSON object with parameters.
  • Tool call ID – opaque identifier for correlating results.
  • Type – usually function or equivalent.
  • Index – position when multiple tool calls are returned (optional).
  • Additional metadata – provider-specific fields like function.arguments vs arguments, or nested structures.

Different backends have different native schemas. The aggregator normalizes these into a common format, but normalization is rarely lossless for every field.

How Each Backend Handles Tool Calls

OpenAI‑style Backends (GPT family)

OpenAI defined the de facto standard for tool calling. Its format includes tool_calls with id, type, function.name, and function.arguments (a JSON string). Most aggregators adopt this schema as the canonical representation. Round‑tripping through OpenAI‑compatible backends is generally the most faithful, because the aggregator’s internal model often mirrors it directly.

However, some aggregators implement a “compatibility layer” that may rename or restructure fields when forwarding to other backends. For OpenAI itself, expect high fidelity for core fields (name, arguments, id).

Anthropic Claude

Claude uses a different tool use format: tool_use blocks inside the content array, with id, name, and input (a JSON object, not a string). The aggregator must convert between the OpenAI‑style string arguments and Claude’s object input.

Round‑tripping considerations:

  • Arguments usually survive as a JSON object, but if the aggregator expects a string and Claude returns an object, you may see a type mismatch.
  • Tool call ID is preserved, but the format may differ (e.g., toolu_ prefix).
  • Multiple tool calls are returned as separate content blocks; the aggregator must merge them into the tool_calls array. Order and index may not be guaranteed.
  • Nested or non‑string values in arguments are fine with Claude (since it uses objects), but if the aggregator stringifies them for compatibility, you might need to parse them back.

DeepSeek

DeepSeek offers an OpenAI‑compatible API for many models. Its tool calling schema closely follows OpenAI’s, so round‑tripping through DeepSeek is typically straightforward. The aggregator can treat DeepSeek as an OpenAI‑compatible backend without heavy transformation.

Watch for:

  • Tool choice behavior may differ (e.g., how tool_choice is interpreted).
  • Parallel tool calls may or may not be supported; the aggregator should gracefully degrade.

Qwen (Alibaba)

Qwen models (especially those served via DashScope or OpenAI‑compatible endpoints) often support tool calling with a schema similar to OpenAI’s. However, some Qwen variants use a slightly different format for arguments, sometimes accepting/returning a JSON string or an object depending on the serving stack.

Round‑tripping risks:

  • Arguments type may be inconsistent across model versions.
  • Tool call ID may be absent or use a different pattern.
  • The aggregator must normalize these variations; if it doesn’t, your code might fail when expecting an id field.

GLM (Zhipu)

GLM models support function calling, but their native API may not be fully OpenAI‑compatible. The aggregator likely performs a translation layer. Fields like name and arguments are usually preserved, but the structure of the response (e.g., whether tool calls are embedded in choices[0].message.tool_calls or elsewhere) can vary.

Potential loss points:

  • Tool call ID might be dropped or regenerated.
  • Arguments may be returned as a stringified JSON or as an object; the aggregator should standardize.
  • Parallel calls may not be supported.

Kimi (Moonshot)

Kimi’s API is largely OpenAI‑compatible, and tool calling follows the same pattern. Round‑tripping is generally reliable for core fields. However, Kimi may not support all advanced features (e.g., tool_choice with specific functions), and the aggregator might silently ignore unsupported options.

Key checks:

  • Tool call ID is usually present.
  • Arguments are a JSON string.
  • Multiple tool calls are supported in recent versions; verify per model.

What Typically Gets Lost or Transformed

Even with careful normalization, some fields are prone to loss:

  • Provider‑specific metadata – custom fields added by a backend (e.g., internal IDs, timestamps) are rarely passed through.
  • Exact JSON string formatting – if arguments are stringified, whitespace and key order may change. This is usually harmless but can affect caching or hashing.
  • Tool call index – when multiple calls are returned, the original order may be preserved but the index field might be omitted or renumbered.
  • Tool choice nuance – options like tool_choice: {"type": "function", "function": {"name": "x"}} may be simplified to a string or ignored by some backends.
  • Error details – if a backend returns a tool call error, the aggregator may wrap or flatten it, losing structured error info.

Designing for Fidelity

To minimize round‑trip loss:

  1. Use the aggregator’s canonical schema – treat the aggregator’s documented tool call format as the source of truth, not any single backend’s native format.
  2. Validate and normalize on receipt – always parse arguments if it’s a string, and handle missing id fields gracefully.
  3. Don’t rely on provider‑specific fields – they are unlikely to survive.
  4. Test with each backend – tool calling behavior can vary even within the same provider’s model family.
  5. Log raw responses during development – compare what the backend returns vs what the aggregator delivers.
  6. Handle partial support – if a backend doesn’t support parallel tool calls, your code should still work with a single call.

When to Expect Perfect Round‑Tripping

Perfect fidelity is most likely when:

  • The backend is OpenAI‑compatible and the aggregator uses that schema internally.
  • You stick to core fields: name, arguments (as string or object, consistently), and id.
  • You avoid provider‑specific extensions.

Expect some transformation when:

  • The backend uses a fundamentally different tool calling paradigm (e.g., Claude’s content blocks).
  • The aggregator adds its own abstraction layer for normalization.
  • You use advanced features like forced tool choice or parallel calls.

Practical Checklist for Developers

  • [ ] Confirm the aggregator’s tool call schema in its documentation.
  • [ ] For each backend you plan to use, run a simple tool call and inspect the full response.
  • [ ] Check that arguments is consistently a string (or object) across backends.
  • [ ] Verify that id is present and stable for correlating results.
  • [ ] Test multi‑turn conversations where tool results are fed back; ensure the aggregator correctly passes tool call IDs back to the model.
  • [ ] If you rely on parallel tool calls, test with each backend to see if they are supported.
  • [ ] Implement fallback logic for missing fields (e.g., generate your own ID if absent).

Conclusion

Tool call round‑tripping through an aggregator is generally reliable for core fields, especially with OpenAI‑compatible backends like GPT, DeepSeek, and Kimi. Backends with different native formats (Claude, GLM, some Qwen endpoints) introduce transformation points where fields like argument type or tool call ID format can change. By understanding these differences and designing your application to handle normalized, minimal tool call objects, you can maintain robust tool execution across multiple model providers.