Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01JXVi2GMQ7bR5EmbUFdDj7N
2.8 KiB
providers
Companion code for Anthropic Claude vs OpenAI vs Gemini in Spring AI 2.0: Switching Providers and Comparing Cost, part of the Spring AI series on ankurm.com.
One small application (TicketService, which summarises a support ticket) runs on the real OpenAiChatModel, AnthropicChatModel and GoogleGenAiChatModel, and the tests look at what each one does differently.
No vendor API was called, and no claim is made about any vendor's behaviour. FakeProviderServer is a local HTTP server that answers in the three wire formats. It records every request the real Spring AI classes send, which is the evidence for the "what is different on the wire" results. Three things in it are simulation: token counts are characters / 4, the answer is a fixed JSON string, and cache hits follow the rules the vendors document (thresholds and prefix matching, read on 2026-10-09) applied to the request that really arrived. So the cost table is a worked example of the price sheets, not a bill, and latency is not measured at all.
Versions
| Component | Version |
|---|---|
| Spring Boot | 4.1.1 (parent) |
| Spring AI | 2.0.1 (spring-ai-openai, spring-ai-anthropic, spring-ai-google-genai) |
| Models named in the examples | gpt-6.1-sol, claude-sonnet-5-5, gemini-3.8-flash |
| Java | 25 (LTS) |
Quickstart
scripts/run-all.sh # runs the suite, regenerates output/01 .. 05
Two consecutive runs produce byte-identical files.
What's here
| File | What it is |
|---|---|
ProviderModels.java |
The one class that knows which vendor is behind a ChatModel |
TicketService.java |
The application; sees only ChatModel |
FallbackChatModel.java |
Tries providers in order on transient failures |
Failures.java |
Reads an HTTP status out of three unrelated exception families |
Cost.java |
Usage to dollars, with the per-provider meaning of "prompt tokens" |
Output files
| File | Written by |
|---|---|
01-wire.txt |
WireTest: the same call as each provider's HTTP request |
02-options.txt |
OptionsTest: portable and provider-specific options, and the per-call trap |
03-caching.txt |
CachingTest: breakpoints sent, cache tokens reported, text order |
04-cost.txt |
CostTest: 100 requests priced on three price sheets |
05-fallback.txt |
FallbackTest: which failures fail over, and requests per plan |