Tool Calling

You will understand what tool calling is, why it exists, and how to wire it into a Spring Boot service so an LLM can fetch real data from your system on demand.

The Tutor That Didn't Know the Answer

Picture this: a student opens EngineerPrep at 11 PM, nervous about a mock interview in the morning. They type into the AI tutor: "Do I still have questions left to practice tonight?" The tutor pauses. Then confidently replies: "Yes, you have plenty of practice questions available!" The student clicks through. Zero questions. The weekly limit was hit two days ago. The LLM didn't lie on purpose. It simply had no way to check. It was trained on text; it has no connection to your database. So it guessed — and guessed wrong. Stuffing the count into every prompt feels like the fix. But that means your backend has to pre-fetch data for every possible question the student might ask, before they even ask it. That's slow, wasteful, and increasingly hard to get right as the number of possible questions grows.…

The Simple Idea

Think about a new employee on their first day. They're smart, well-read, and great at conversation. But they don't know your company's internal systems. So you give them a list of phone extensions: "If a customer asks about their order status, call extension 204. If they ask about billing, call extension 301." The employee doesn't handle those things themselves. They just know who to call and what to say when they pick up the phone. Tool calling works exactly like that. You give the LLM a list of tools — think of a tool as a named action with a description and a set of inputs. For example: get remaining questions(userId: string) . The LLM reads the description and learns what the tool does. When the LLM decides it needs real data to answer a question, it doesn't guess. Instead it says: "I want to call the get remaining questions tool with userId = 'abc123' " .…

See It in Action

Imagine a simple back-and-forth between the student, the LLM, and your Spring Boot backend. Step 1 — Student sends a message. The student types: "How many questions do I have left this week?" Your backend receives this and forwards it to Claude on Amazon Bedrock, along with the tool list you've registered. At this point, the LLM sees the message AND a description of the get remaining questions tool. What changed: the LLM now knows a tool exists and what it does. Step 2 — LLM decides it needs the tool. Claude reads the student's question and determines it needs real data to answer accurately. It does NOT write a final answer yet. Instead it returns a structured response indicating: "Call get remaining questions with userId = 'student-42' " . What changed: the LLM has paused and handed control back to your code. Step 3 — Your backend executes the tool.…

A Quick Example

We'll build the simplest possible version: a Spring AI-backed service that registers one tool and lets Claude call it. Spring AI has first-class support for tool calling. You annotate a plain Java method with @Tool , and Spring AI takes care of describing it to the LLM and routing the call back to your method. The tool method lives in a plain @Service . It's just a regular Java method that queries the database. java // Step 1 — the tool itself The @Tool annotation tells Spring AI: "This method is available for the LLM to call." The description is what the LLM reads to decide when to use it — write it like you're explaining it to a smart colleague, not a computer. The chat service wires the tool into the LLM call using Spring AI's ChatClient . You pass the tool as an option on the request, and Spring AI handles the back-and-forth loop automatically. java // Step 2…