In this article

The essential idea

Spring AI lets a Java application connect a model to tools and retrieved context. The application should keep ownership of authentication, business rules and execution. Start with a narrow read-only task before introducing actions.

01

Keep the agent close to the business services

Consider a Java application that already manages support tickets. A useful first agent could read an authorised ticket, consult a procedure and draft a suggested response. Spring AI provides tool calling through Java methods, including the @Tool annotation. The model requests an operation; application code executes it. This distinction is central to keeping the business service in control.

Our recommended design reuses the existing service layer instead of exposing unrestricted database queries or an administrative shell. Define the task, available tools and stopping conditions before selecting a model. The examples below are illustrative Java fragments based on the Spring AI 2.0 documentation consulted for this article; they are not a complete runnable application or a tested customer implementation.

ReferencesSpring AI — Tool calling ↗
Visual guide / 01

The application keeps control

The support-agent example, organised by responsibility.

  1. ChatClient

    Send the question and the tools available for this request.

  2. @Tool

    Expose a bounded operation such as reading a ticket.

  3. TicketService

    Resolve the authenticated user and enforce record access.

  4. Business data

    Return the minimal authorised view to the application.

02

Expose a narrow, authorised tool

The example deliberately accepts a ticket identifier, not a user or tenant identity chosen by the model. TicketService is an application-specific service. Its readForCurrentUser method must obtain the caller identity from trusted server-side authentication, enforce record access and return a minimal public view. Validate the identifier and bound response size before returning tool data.

Keep this operation read-only. A write operation needs a separate contract, business validation, duplicate-request handling and an approval mechanism where the workflow requires it. A human approval message in a prompt does not replace enforcement in the application. Never let a model-supplied customer identifier decide which organisation’s records it may read.

Java — Illustrative tool; TicketService and TicketView are application-owned types.
import org.springframework.ai.tool.annotation.Tool;

final class TicketTools {
    private final TicketService tickets;

    TicketTools(TicketService tickets) {
        this.tickets = tickets;
    }

    @Tool(description = "Read a support ticket visible to the current user")
    TicketView readTicket(String ticketId) {
        return tickets.readForCurrentUser(ticketId);
    }
}
03

Connect the client, then add evidence

With a configured ChatClient and an instance of TicketTools, a prompt can register that tool for the request. Start by checking valid, missing and forbidden ticket identifiers. Restrict the number of tool iterations and total execution time in the surrounding application configuration. Also plan cancellation and explicit behaviour when a downstream service is unavailable.

For document questions, Spring AI provides QuestionAnswerAdvisor and the modular RetrievalAugmentationAdvisor. Keep retrieval access constraints tied to authenticated application context. In our support scenario, the ticket supplies the product context, retrieval finds the relevant procedure and the model drafts an answer with source references. If no applicable procedure is found, return a review request rather than inventing a policy.

Java — Request fragment; the client, tool instance and authenticated execution context must already be configured.
String draft = chatClient.prompt()
    .user("Read ticket INC-1042 and summarise the confirmed facts.")
    .tools(ticketTools)
    .call()
    .content();
ReferencesSpring AI — Tool calling ↗Spring AI — Retrieval Augmented Generation ↗
04

Observe decisions without collecting everything

Spring AI documents observability for model and tool interactions. Our proposed instrumentation would connect a user request to tool outcomes, elapsed time and token usage, while avoiding unnecessary ticket contents or secrets in logs. Make the distinction between model failure, permission denial and downstream API failure visible to the operations team.

Before release, evaluate wrong identifiers, conflicting procedures, repeated calls and malicious text inside a ticket. The acceptance test is a useful draft built from authorised evidence, with no unintended change to business state. MASLOV Solutions can scope Java integration, RAG and evaluation around existing services. Start with this bounded workflow, then add actions only when their control and recovery paths are designed.

ReferencesSpring AI — Observability ↗
05

The next step: proposing a write without executing it

The read-only ticket example is a useful starting point. To add a status change, create a proposal containing the ticket identifier, requested transition, reason and expected record version. Validate the transition in the existing business service. If approval is required, store the proposal and return its review identifier rather than changing the ticket immediately.

At execution time, re-check the current user, permissions and ticket version. A ticket closed by another person should not be reopened because an old proposal finally received approval. Use a stable operation identifier for duplicate submissions. This proposed control flow keeps business invariants in ordinary application code; tool descriptions help the model request an action but do not enforce those invariants.

Process / decision path

From tool request to business command

Proposed extension of the read-only example. The service controls authorisation, version checks and duplicate prevention.

Tool request → validate transition → store proposal

Approval valid and ticket version unchanged?

  • Yes

    1. Re-check permissions → execute with operation ID
    2. Return business result to the conversation
  • No

    1. Do not modify the ticket
    2. Explain denial or ask for a revised proposal
06

Test the agent boundary without making every test a model call

Test authorisation, validation and state changes as ordinary service tests with deterministic inputs. Simulate tool requests for unknown tickets, cross-organisation access, invalid transitions and repeated operation identifiers. Keep a smaller integration suite for model behaviour: does it select the right tool, ask for missing information and explain a denied action correctly?

Observe tool duration and error categories separately from model latency. Mask sensitive arguments in traces and retain correlation identifiers so an incident can be followed across the conversation and business service. Pin compatible dependency versions and verify the complete example in your application; the snippets above illustrate the boundary, not a deployable service with authentication, storage and all error handling included.

Sources & further reading

Documentation consulted on .

FAQ / DECISIONS

Frequently asked questions

Does the model execute Java code directly?+

No. It requests a tool call. Spring AI and your application execute the registered operation, whose implementation must enforce permissions and business rules.

Do business agents always need multiple agents?+

No. Begin with one bounded workflow and a small tool set. Add coordination only when separate responsibilities produce a measurable benefit.

Explore our AI, agent and RAG services ↗