Skip to main content
JSON is the go-to format for LLM tool responses, but recent discussions around alternative formats like TOON (Token-Oriented Object Notation) claim potential benefits in token efficiency and performance. While the debate continues—with critical analyses pointing to context-dependent results—the question is: how to experiment with these formats in your own Spring AI applications? This article demonstrates how to configure Spring AI to convert tool responses between JSON, TOON, XML, CSV, and YAML, enabling you to decide what works best for your specific use case.

Spring AI Tool Calling: A Quick Overview

Let’s briefly review how Spring AI Tool Calling works:
  1. Tool definitions (name, description, parameters schema) are added to the chat request.
  2. When the model decides to call a tool, it sends the tool name and input parameters.
  3. Spring AI identifies and executes the tool with the provided parameters.
  4. Spring AI handles the tool result.
  5. Spring AI sends the tool result back to the model as part of the conversation history.
  6. The model generates the final response using the tool result as additional context.
The ToolCallback interface is at the heart of this process. Each tool is wrapped in a ToolCallback that handles the serialization and execution logic. We can intercept and convert the response format at two key points:
  • Tool Result level: After the tool executes but before JSON serialization (Approach 1)
  • Response level: After JSON serialization, transforming JSON to another format (Approach 2)
Both approaches have their merits, and the choice depends on your specific requirements. Let’s explore each in detail.

Approach 1: Custom ToolCallResultConverter Configuration

Important: Applicable only for local tool implementations such as @Tool, FunctionToolCallback and MethodToolCallback. Currently it is not supported by the MCP Tools.
The ToolCallResultConverter interface provides fine-grained control over individual tool formats. The DefaultToolCallResultConverter serializes the result to JSON, but you can customize the serialization process by providing your own ToolCallResultConverter implementation. For example, a custom ToonToolCallResultConverter can look like this:
It uses the default JSON converter, then converts to TOON using libraries such as JToon or toon4j. Register with @Tool:
Uses the resultConverter attribute to set the custom ToonToolCallResultConverter. Execution flow: Tool executes → Default converter creates JSON → TOON converter transforms JSON → LLM receives TOON response. You can also register the ToolCallResultConverter with the FunctionToolCallback and MethodToolCallback builders programmatically. Limitations:
  • MCP incompatible: Doesn’t work with @McpTool (Model Context Protocol tools)
  • Repetitive: Must implement and register for each tool needing conversion
  • Maintenance overhead: Changes require updating multiple tool definitions
The Application2.java provides an implementation example.

Approach 2: Global Tool Response Configuration

Apply format conversion globally using a custom ToolCallbackProvider that wraps existing providers with delegator pattern:

Component 1: DelegatorToolCallbackProvider

This provider wraps an existing ToolCallbackProvider and creates a DelegatorToolCallback wrapper for each tool callback. The format parameter specifies which format to convert to.

Component 2: DelegatorToolCallback

The callback wrapper intercepts the call() method, allowing the original tool to execute normally, then converts its JSON response to the desired format.

Component 3: ResponseConverter Utility

The ResponseConverter provides conversion methods for each supported format, handling the specific requirements of each (like wrapping arrays for XML or building dynamic schemas for CSV). Usage example:
Execution flow: User prompt → LLM calls tool → Wrapper intercepts → Tool executes → JSON created → Format converter transforms → LLM receives converted response. The Application example leverages the ToolCallAdvisor (e.g. moving the tool execution as part of the Advisor chain) and a custom logging advisor MyLogAdvisor that helps to see the actual tool responses in different formats. This advisor will print out the tool responses, allowing you to see the target format output.

Format Conversion Details

Let’s examine each supported format and see what the output looks like.

JSON (default)

TOON

XML

YAML

CSV

Token Usage

Here is the tokens usage estimates per each format

Best Practices and Recommendations

  • Start with JSON—it’s proven, safe, and universally understood
  • Measure performance in your specific context; don’t assume alternatives are always better
  • Avoid converting complex nested structures to CSV or TOON
  • Include error handling in all converters
  • Provide JSON fallback when conversion fails
  • Log conversion metrics for monitoring

Conclusion

Spring AI offers flexibility for experimenting with tool response formats through two distinct approaches. Use ToolCallResultConverter for selective, per-tool conversion when you need fine-grained control. Choose the global DelegatorToolCallbackProvider approach for consistent format conversion across all tools, including MCP tools. Both support multiple formats—TOON, YAML, XML, CSV, and JSON—giving you the freedom to optimize for your specific use case.

Try It Yourself

Note: The following code is for demonstration purposes only and should not be used in production without proper testing, error handling, and security considerations.
The complete demo is available on GitHub. Run it with different formats:
Experiment with the formats and measure their impact in your specific environment to determine what works best for your use case.

Resources