Sunday, April 5, 2026

Spring AI tutorial: The best way to develop AI brokers with Spring


[
    {
        "category": "Clothing",
        "description": "Lightweight mesh running sneakers",
        "id": 24,
        "name": "Running Shoes",
        "price": 109.99
    },
    {
        "category": "Clothing",
        "description": "Cross-training athletic shoes",
        "id": 83,
        "name": "Training Shoes",
        "price": 109.99
    }
]

So, the agent successfully decided what I meant by “sports activities footwear,” chosen some related key phrases to seek for, filtered the merchandise based mostly on value, and returned an inventory of two choices for me. As a result of LLMs are usually not deterministic, your outcomes could also be completely different from mine. For instance, in different runs with the identical question, the agent searched for various key phrases and returned a bigger checklist. However with the ability to translate a pure language question right into a set of database queries and discover related outcomes is spectacular!

Spring AI’s built-in assist for growing brokers

Now that you just perceive what an agent loop is, what it does, and methods to deal with instrument executions, let’s take a look at Spring AI’s built-in assist for managing its personal agent loop and power execution. Right here is our up to date ProductSearchAgent code:

package deal com.infoworld.springagentdemo.ai.agent;

import java.util.ArrayList;
import java.util.Checklist;

import com.infoworld.springagentdemo.ai.instruments.ProductSearchTools;
import com.infoworld.springagentdemo.mannequin.Product;

import org.springframework.ai.chat.shopper.ChatClient;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.immediate.Immediate;
import org.springframework.ai.instrument.technique.MethodToolCallbackProvider;
import org.springframework.stereotype.Element;

@Element
public class ProductSearchAgent {

    non-public last ChatClient chatClient;
    non-public last ProductSearchTools productSearchTools;

    public ProductSearchAgent(ChatClient.Builder chatClientBuilder, ProductSearchTools productSearchTools) {
        this.chatClient =  chatClientBuilder.construct();
        this.productSearchTools = productSearchTools;
    }

    public Checklist run(String userRequest) {

        Immediate immediate = buildPrompt(userRequest);

        AgentResponse response = chatClient
                .immediate(immediate)
                .toolCallbacks(
                        MethodToolCallbackProvider.builder().toolObjects(productSearchTools).construct()
                )
                .name()
                .entity(AgentResponse.class);

        System.out.println(response.reply());
        return response.merchandise();
    }

    non-public Immediate buildPrompt(String userRequest) {

        Checklist messages = new ArrayList<>();

        // 1. System message: defines the agent
        messages.add(new SystemMessage("""
You're a product search agent.

Your duty is to assist customers discover related merchandise utilizing the obtainable instruments.

Tips:
- Use the supplied instruments every time product knowledge is required.
- It's possible you'll name instruments a number of instances to refine or develop the search.
- If the request is imprecise, make cheap assumptions and try a search.
- Don't ask follow-up questions.
- Proceed utilizing instruments till you might be assured you might have the absolute best outcomes.

If the consumer asks about merchandise in a sure value vary, first seek for the merchandise after which filter
the outcomes based mostly on the value. Every product is outlined with a value.

When you might have accomplished the search course of, return a structured JSON response on this format:

{
  "reply": "...",
  "merchandise": [...]
}

Don't return conversational textual content.
Return solely legitimate JSON.
"""));

        // Add the consumer's request
        messages.add(new UserMessage(userRequest));

        return new Immediate(messages);
    }
}

As I discussed earlier, the ProductSearchToolssearchProducts() technique is annotated with the @Instrument annotation. This annotation has particular which means for Spring AI if we add a toolCallbacks() technique name to our LLM name. On this case, we autowire the ProductSearchTools into our constructor after which invoke the toolCallbacks() technique in our LLM name, passing it an inventory of all of the courses containing instruments we wish to give the LLM entry to in a MethodToolCallbackProvider.builder().toolObjects() name. Spring AI will see this checklist of instruments and do a number of issues:

  1. Introspect all strategies annotated with the @Instrument annotation within the supplied courses.
  2. Construct the instrument specification and move it to the LLM for us, together with the outline of the instrument and the strategy signature, which implies that we now not have to explicitly outline the instrument specification in our SystemPrompt.
  3. As a result of it has entry to name the instruments, the ChatClient’s name() technique will run in its personal agent loop and invoke the instruments it wants for us.

Due to this fact, the response we obtain would be the last response from the LLM with our checklist of merchandise, so we don’t have to construct an agent loop ourselves. We construct our immediate with a system immediate (which once more doesn’t have the instrument specification) and the consumer’s request. We then make a single name to the name() technique, which performs all of the actions it must arrive at a conclusion.

Related Articles

Latest Articles