The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Use ChatModel when you need Spring AI’s direct, provider-neutral model contract; use ChatClient for application code that assembles prompts, applies advisors or tools, and converts responses fluently. ChatClient is built on a ChatModel, not a competing model implementation. The choice is usually about the layer of your application: infrastructure and provider integration belong on ChatModel, while controllers, services, RAG flows, memory, and tool-enabled conversations usually belong on ChatClient.
The core difference in one view
Spring AI separates the portable model contract from the application-facing conversation API. A ChatModel represents a model implementation and accepts a Prompt, returning a ChatResponse. A ChatClient is a fluent facade constructed around that model; it builds the request, applies defaults and advisors, invokes the model, and exposes convenient response conversions.
As an Amazon Associate I earn from qualifying purchases.
| Question | ChatModel |
ChatClient |
|---|---|---|
| Primary role | Direct, portable model abstraction | Application-facing fluent API |
| Input style | Explicit Prompt or String |
Fluent system, user, template, option, advisor, and tool configuration |
| Typical output | ChatResponse or reactive response stream |
String, ChatResponse, ChatClientResponse, typed entity, or reactive equivalents |
| Best fit | Provider adapters, shared infrastructure, explicit model control | Controllers and services implementing conversations, RAG, memory, tools, and structured responses |
| Construction | Provider-specific Spring bean | Built from ChatClient.Builder or a selected ChatModel |
Spring AI’s model abstraction is intended to let an application switch providers with minimal code changes. The current model reference lists implementations including OpenAI, Ollama, Amazon Bedrock, Mistral, and Anthropic, among others. ChatClient preserves that portability because it delegates execution to whichever ChatModel you provide.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →What ChatModel exposes
The direct contract
ChatModel extends Model<Prompt, ChatResponse> and StreamingChatModel. Its central operations are:
#1 Best Overall
- Read Before You Buy — No Video Output: These adapters support charging and USB 2.0 data transfer, but cannot transmit video signals. Except for standard USB webcams (which use USB data only), they are not compatible with HDMI/DisplayPort cables, video-capable USB-C hubs, or docking stations with video output.
- Convert USB-A Ports to USB-C: Designed to connect USB-C earphones, cables, flash drives, card readers, and other USB-C accessories to standard USB-A ports. Plug-and-play with no drivers or software required.
- Aluminum Alloy Housing: Built with a sturdy aluminum alloy shell that aids in heat dissipation and protects against daily wear and scratches. Designed to maintain a stable and secure connection.
- Compact & Travel-Friendly: The ultra-compact design allows the adapter to stay plugged into your device without blocking adjacent ports or adding bulk, reducing wear and tear on your original USB ports.
- 12-Month Warranty: Backed by a 12-month manufacturer warranty for peace of mind. Designed to meet strict quality control standards for reliable everyday performance.
call(String)for a simple text request.call(Prompt)when you need explicit messages and options.stream(Prompt)for a reactive stream of model output.
A Prompt contains the messages sent to the model and optional ChatOptions. The resulting ChatResponse contains one or more generations plus response metadata. That metadata and the complete generation structure are available without going through a convenience conversion to plain text.
When the direct API is the right boundary
- Provider adapters: code that implements or wraps a provider should depend on the model contract rather than on application-level prompt orchestration.
- Shared infrastructure: gateways, fallback services, retry layers, and policy components often need to construct a complete
Promptand inspect the full response. - Explicit options: code that chooses the model, temperature, token limit, penalties, stop sequences, top-k, or top-p per request can express those choices directly.
- Raw response handling: moderation, usage accounting, finish reasons, multiple generations, and provider metadata are easier to handle from
ChatResponse.
Direct call example
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.ChatOptions;
import org.springframework.ai.chat.model.ChatResponse;
public final class ModelGateway {
private final ChatModel chatModel;
public ModelGateway(ChatModel chatModel) {
this.chatModel = chatModel;
}
public ChatResponse answer(String question) {
ChatOptions options = ChatOptions.builder()
.temperature(0.2)
.maxTokens(500)
.build();
Prompt prompt = new Prompt(question, options);
return chatModel.call(prompt);
}
}
This style keeps request construction visible. It is useful when the caller must inspect the response object, but it also means the caller is responsible for assembling messages, applying conversation context, and handling any orchestration.
What ChatClient adds
A fluent request pipeline
ChatClient is created from a ChatClient.Builder. In a Spring Boot application, Boot can auto-configure a prototype-scoped builder when a ChatModel is available. A basic request looks like this:
Free tools Windows power users keep installed
One-click scans. No signup required.
@Service
class AnswerService {
private final ChatClient chatClient;
AnswerService(ChatClient.Builder builder) {
this.chatClient = builder.build();
}
String answer(String userInput) {
return chatClient.prompt()
.user(userInput)
.call()
.content();
}
}
The fluent chain can set system and user content, expand prompt templates, provide per-request model options, add advisors, register tools, and choose the desired response representation. It is deliberately similar in style to Spring’s WebClient and RestClient APIs.
Terminal methods and lazy execution
call() selects synchronous execution, but the model is not necessarily contacted at that point. Actual execution occurs when a terminal result is requested, such as content(), chatResponse(), or responseEntity(). This allows the chain to finish specifying how the response should be converted before the request is sent.
For synchronous results, ChatClient can return:
- A plain
Stringthroughcontent(). - A full
ChatResponsethroughchatResponse(). - A
ChatClientResponsewhen application-level context and response details are needed. - A typed Java object through
responseEntity(YourType.class)or the corresponding conversion API.
For streaming, stream() can expose a reactive Flux<String>, Flux<ChatResponse>, or Flux<ChatClientResponse>.
Choosing the abstraction by task
| Your requirement | Preferred API | Why |
|---|---|---|
| Implement a provider adapter or model gateway | ChatModel |
The direct Prompt/ChatResponse contract keeps provider concerns explicit. |
| Answer one user prompt in a controller or service | ChatClient |
Fluent construction and direct content extraction reduce plumbing. |
| Apply one system prompt to most requests | ChatClient |
Builder defaults centralize shared instructions. |
| Use conversation memory, RAG, or advisors | ChatClient |
Advisors can add history, retrieved documents, and other context before execution. |
| Use tools or function calling | ChatClient |
Tool orchestration is integrated into the client pipeline. |
| Inspect generations and provider metadata | ChatModel, or ChatClient.chatResponse() |
Both expose ChatResponse; ChatModel is the lower-level contract. |
| Stream tokens reactively | ChatClient.stream() or ChatModel.stream() |
Both expose reactive streams; your application stack still determines whether streaming is practical. |
Many applications use both: a ChatClient at the feature boundary and a ChatModel behind it for infrastructure, tests, or a second workflow that needs unprocessed responses.
Rank #2
- 5-in-1 USB-C Hub: Experience comprehensive connectivity featuring a Power Delivery input, two USB-A 2.0 ports, a USB-A 3.0 port, and an HDMI port. (Note: The USB-C power delivery input port is only for connecting an external wall charger to power your laptop and cannot power peripheral devices.)
- 90W Pass-Through Charging: Achieve optimal charging with 90W pass-through power to your laptop, supported by a total input of 100W, with the hub reserving 10W for operational efficiency. (Note: Wall charger not included.)
- Quick Data Transfers: Accelerate your productivity with rapid data transfers using a high-speed 5Gbps USB 3.0 port and two 480Mbps USB 2.0 ports.
- 4K HDMI Display: Enhance your visual experience with a hub capable of delivering 4K resolution at 30Hz in both mirror and extend modes. Please note that this hub is compatible with MacBook (macOS 12 and newer), Windows 10 and 11, ChromeOS, and laptops equipped with DP Alt Mode and Power Delivery. Note: This device is not compatible with Linux.
- What You Get: Anker USB-C Hub (5-in-1, 4K HDMI), welcome guide, 18-month warranty, and our friendly customer service.
Prompt construction, defaults, and option precedence
ChatModel startup options versus request options
Model configuration supplied when a ChatModel is initialized establishes its startup options. Portable ChatOptions fields include model, temperature, maximum tokens, frequency and presence penalties, stop sequences, top-k, and top-p. Provider implementations can add provider-specific options.
Options placed in a Prompt fully override the startup options for that request. Therefore, a request-level value is not merely merged with an identical startup value; it wins for the fields it supplies. Keep this precedence in mind when a model appears to ignore a setting configured at startup.
ChatClient defaults and incremental customizers
ChatClient is useful when most calls share a system instruction, user prefix, model option, advisor, or tool configuration. Builder defaults establish that common baseline. Request customizers then act as deltas over those defaults, so a single call can adjust one setting without rebuilding the complete prompt configuration.
A practical pattern is to put stable behavior in builder defaults and keep user-specific data in the request:
Recommended Free Tools
ChatClient client = builder
.defaultSystem("Answer with concise, verifiable guidance.")
.build();
String result = client.prompt()
.user(u -> u.text("Explain {topic}").param("topic", topic))
.call()
.content();
Use direct Prompt construction instead when a reusable infrastructure component must control every message and option explicitly.
Advisors, memory, RAG, and tools
Advisors are the orchestration hook
ChatClient advisors can modify the prompt and its context before the model runs. Common uses include adding conversation history, retrieving documents for retrieval-augmented generation, enforcing a policy, or attaching application context.
Advisor order matters. Each advisor receives the changes made by earlier advisors, so ordering can change the final prompt. For example, an advisor that retrieves documents may need to run before one that formats the final context, while a policy advisor may need to run after user and retrieval content have been assembled.
Rank #3
- Sleek 7-in-1 USB-C Hub: Features an HDMI port, two USB-A 3.0 ports, and a USB-C data port, each providing 5Gbps transfer speeds. It also includes a USB-C PD input port for charging up to 100W and dual SD and TF card slots, all in a compact design.
- Flawless 4K@60Hz Video with HDMI: Delivers exceptional clarity and smoothness with its 4K@60Hz HDMI port, making it ideal for high-definition presentations and entertainment. (Note: Only the HDMI port supports video projection; the USB-C port is for data transfer only.)
- Double Up on Efficiency: The two USB-A 3.0 ports and a USB-C port support a fast 5Gbps data rate, significantly boosting your transfer speeds and improving productivity.
- Fast and Reliable 85W Charging: Offers high-capacity, speedy charging for laptops up to 85W, so you spend less time tethered to an outlet and more time being productive.
- What You Get: Anker USB-C Hub (7-in-1), welcome guide, 18-month warranty, and our friendly customer service.
Conversation memory requires an identifier
Memory advisors need ChatMemory.CONVERSATION_ID on every call. Omitting that identifier raises IllegalArgumentException; it is not treated as an anonymous new conversation. Pass a stable conversation key from your application, while keeping tenant and authorization boundaries in mind.
The default MessageWindowChatMemory window is 20 messages. That is an implementation default, not a guarantee that every provider or application should retain exactly 20 messages. Increase, reduce, or replace the memory strategy when your context budget, privacy policy, or conversation design requires a different window.
Tool calling has operational consequences
ChatClient supports tool calling, including automatic ToolCallingAdvisor registration. Automatic registration can be disabled globally with:
spring.ai.chat.client.tool-calling.enabled=false
It can also be disabled for an individual call. Tool calling is imperative and can block while the application executes a tool. Do not assume that a reactive-looking client chain makes tool execution non-blocking; isolate blocking tools or adapt them deliberately to your runtime.
Streaming, blocking calls, and the Spring stack
Reactive streaming
Both APIs support streaming through reactive methods. With ChatModel, call stream(Prompt). With ChatClient, use stream() and select a reactive result such as Flux<String> or Flux<ChatResponse>. This is the appropriate path for incremental token delivery to a reactive endpoint or UI.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteNon-streaming execution
Implementation details matter when choosing an application stack. Streaming is supported through the reactive stack, while non-streaming support is tied to the servlet stack and can block in a reactive application. A reactive controller that calls a blocking path directly can consume event-loop capacity and degrade unrelated requests. Use an appropriate bounded scheduler or a genuinely reactive integration rather than assuming that the return type alone makes the operation non-blocking.
HTTP client customization
When customizing HTTP clients, configure both RestClient and WebClient when the selected model implementation uses them. Configuring only one client can leave synchronous or streaming requests using an unintended default, producing inconsistent timeouts, proxies, interceptors, or observability behavior.
Rank #4
- Dual Converters, Infinite Potential:Includes 2× USB C male to USB A female adapters and 2× USB A male to USB C female adapters. Perfect for a wide range of uses—tablets with Bluetooth keyboards, expand USB ports on macbook, and more. Two different converters for all your daily needs
- Next-Level 10Gbps & 3A Charging: No more slow 480Mbps, this usb to usb c adapter has a transfer speed of up to 10Gbps, allowing you to do more transferring in less time. This usb adapter fits both USB A and USB C charger, supporting up to 3A fast charging
- Upgraded Exquisite Craftsmanship: With an aluminum alloy housing and metal connector, the usbc to usb adapter is extremely durable and sturdy. Rigorously tested to withstand more than 10,000 times of plugging and unplugging, ensuring long-lasting performance
- Broad Compatible: The usb c to usb adapter widely supports all USB C/ USB A devices like laptops, tablets, cellphones, car chargers, and phone chargers. Such as compatible with MacBook Pro/Air 2023/2022, Thunderbolt 4/3 Devices,Apple MagSafe Watch 9/8/7/SE/Ultra, iPad Pro 2022/2021, Samsung Galaxy S23/S20/S10, and iPhone 17/16/15 Pro. Plug and play
- Please Note: To reach 10Gbps speed, keep the cable under 3.3 ft. For USB A Male to USB C adapters, try flipping the USB C connector. USB C Male to USB A adapters support bidirectional 10Gbps transfer within 3.3 ft
Structured output and response handling
Choose the response terminal method based on what the feature needs. Use content() when the output is intentionally plain text. Use chatResponse() when you need generations or model metadata. Use typed response conversion when the model is expected to produce a schema represented by a Java class.
Typed conversion belongs naturally at the ChatClient boundary because the fluent request can combine the system instruction, user data, options, advisors, and the final target type in one chain. Infrastructure code that must preserve provider-specific fields should retain the ChatResponse instead of immediately reducing it to a domain object.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsDependency injection and multiple models
One model, many clients
Spring Boot’s auto-configured ChatClient builder is prototype-scoped. You can build multiple ChatClient instances over the same ChatModel, each with different defaults, such as a concise support client and a verbose analysis client.
@Configuration
class AiClients {
@Bean
ChatClient supportClient(ChatClient.Builder builder) {
return builder
.defaultSystem("Answer support questions in short steps.")
.build();
}
@Bean
ChatClient analysisClient(ChatClient.Builder builder) {
return builder
.defaultSystem("Explain assumptions and alternatives in detail.")
.build();
}
}
Different model types
For a client backed by a different model type, you can call ChatClient.create(chatModel) or ChatClient.builder(chatModel). Those direct factory calls bypass auto-configured observability and builder customizers. If those integrations matter, use ChatClientBuilderConfigurer so the custom client retains the application-wide configuration.
Several ChatModel beans
When multiple ChatModel beans are present, injection can become ambiguous. Mark one bean @Primary when there is a clear default, or define an explicitly qualified builder/client for each model. Qualifiers make the provider choice visible at the injection point and prevent an accidental switch when another starter is added.
Portability and provider-specific behavior
ChatModel is the portability seam: application code can target the common interface while configuration selects OpenAI, Ollama, Amazon Bedrock, Mistral, Anthropic, or another supported implementation. ChatClient does not remove provider differences. Model names, option ranges, tool behavior, token accounting, structured-output support, and streaming characteristics can still vary by provider.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Keep portable options in shared code and isolate provider-specific options behind a provider-aware configuration or adapter. If a feature depends on a provider extension, document that dependency rather than presenting it as a guarantee of the ChatModel interface.
Best Value
- 5-in-1 Connectivity: Equipped with a 4K HDMI port, a 5 Gbps USB-C data port, two 5 Gbps USB-A ports, and a USB C 100W PD-IN port. Note: The USB C 100W PD-IN port supports only charging and does not support data transfer devices such as headphones or speakers.
- Powerful Pass-Through Charging: Supports up to 85W pass-through charging so you can power up your laptop while you use the hub. Note: Pass-through charging requires a charger (not included). Note: To achieve full power for iPad, we recommend using a 45W wall charger.
- Transfer Files in Seconds: Move files to and from your laptop at speeds of up to 5 Gbps via the USB-C and USB-A data ports. Note: The USB C 5Gbps Data port does not support video output.
- HD Display: Connect to the HDMI port to stream or mirror content to an external monitor in resolutions of up to 4K@30Hz. Note: The USB-C ports do not support video output.
- What You Get: Anker 332 USB-C Hub (5-in-1), welcome guide, our worry-free 18-month warranty, and friendly customer service.
Common mistakes and how to correct them
Injecting ChatClient into infrastructure code by default
If a gateway needs exact prompts, model options, response metadata, or provider fallback logic, ChatModel is usually the cleaner dependency. ChatClient can do the job, but its orchestration layer may hide decisions that the infrastructure component must own.
Using ChatModel for every controller prompt
Direct calls force each endpoint to repeat message assembly, defaults, conversion, and advisor wiring. Build a ChatClient for application-facing flows and reserve ChatModel for components that truly need the lower-level contract.
Calling call() and expecting execution immediately
With ChatClient, execution occurs when a terminal result such as content(), chatResponse(), or responseEntity() is requested. Ensure your chain reaches the intended terminal operation before measuring latency or troubleshooting a missing request.
Forgetting the conversation ID
A memory advisor without ChatMemory.CONVERSATION_ID fails with IllegalArgumentException. Add the identifier to every memory-enabled request, including follow-up turns.
Assuming reactive means non-blocking
Streaming uses the reactive stack, but non-streaming model calls and tool execution can block. Inspect the selected implementation and move blocking work off event-loop threads.
Overriding the wrong option layer
A value in a request Prompt overrides the ChatModel’s startup option. In ChatClient, request customizers modify builder defaults. Check both layers when a temperature, model name, or token limit appears incorrect.
Losing observability on a second model
Directly creating a ChatClient around another ChatModel can bypass auto-configured observability and builder customizers. Use the builder configurer when those features are required across all clients.
A practical selection procedure
- Identify the boundary. If the class integrates a provider, fallback policy, or shared model infrastructure, start with
ChatModel. If it implements a user-facing conversation, start withChatClient. - List response requirements. Choose direct
ChatResponsehandling for generations and metadata; choose ChatClient conversion for text or typed domain output. - Decide whether context is assembled dynamically. Advisors, RAG retrieval, memory, and tools favor ChatClient.
- Choose the execution model. Use the streaming method for incremental output, and verify that your servlet or reactive stack can handle the selected path without blocking the wrong threads.
- Define configuration ownership. Put stable defaults in the builder or model startup configuration; put request-specific overrides at the request layer.
- Resolve model multiplicity explicitly. Add
@Primary, qualifiers, or named ChatClient beans before multiple providers enter the application. - Pin documentation to your Spring AI line. The project currently lists Spring AI 2.0.1 as stable, with 1.1.8 and 1.0.9 also stable; 2.1.0-M1 is preview. API signatures and implementation details can change between lines, so use the reference documentation matching the version in your build.
Bottom line
ChatModel is the portable, explicit engine contract: construct a Prompt, call or stream it, and inspect the resulting ChatResponse. ChatClient is the fluent application layer on top: define defaults, assemble prompts, apply advisors, invoke tools, and convert the result to text or a typed object. Inject ChatClient for most feature-level conversation code; inject ChatModel when the component’s job is model infrastructure or when complete control over requests and responses is the requirement.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

