Spring AI - Tool Calling

Tool calling (also known as function calling) is a common pattern in AI applications, allowing a model to interact with a set of APIs, or tools, augmenting its capabilities.

Tools are mainly used for:

  • Information retrieval - Tools in this category can be used to retrieve information from external sources, such as a database, a web service, a file system, or a web search engine.
  • Taking Action - Tools in this category can be used to take action in a software system, such as sending an email, creating a new record in a database, submitting a form, or triggering a workflow.

Configuration

pom.xml file add Google Gemini dependency:

1
2
3
4
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-google-genai</artifactId>
</dependency>

application.properties file add Google Gemini API key. Assuming you have the API key stored in an environment variable named GEMINI_API_KEY, you can reference it in your application.properties file like this:

1
2
spring.ai.google.genai.api-key=${GEMINI_API_KEY}
spring.ai.google.genai.chat.options.model=gemini-2.5-flash

Models are listed in the Google Gemini documentation.

Tool Calling

LLMs can’t return real-time data, but they can call tools to get real-time data.

If you ask for today’s date, the model can’t give you the answer directly. An example response would be “I do not have access to real-time information, including the current date. My knowledge cutoff is June 2024. Therefore, I cannot tell you what today’s date is.”

1
String response = chatModel.call("What date is it today?");

But if you have a tool that can return the current date, the model can call the tool to get the answer. An example response would be “Today’s date is 2026-02-15.”

1
2
3
4
String response =  ChatClient.create(chatModel)
.prompt("What date is it today?")
.tools(new DateTimeTool())
.call().content();

DateTimeTool - use @Tool annotation to mark the method as a tool that can be called by the model. The description attribute provides a brief description of what the tool does, which can help the model understand when to use it.

1
2
3
4
5
6
public class DateTimeTool {
@Tool(description = "Get the current date and time in the user's timezone")
public String getCurrentDate() {
return LocalDateTime.now().atZone(LocaleContextHolder.getTimeZone().toZoneId()).toString();
}
}

You can also ask the model to take action. For example, you can ask the model to set an alarm for you. The model can call the setAlarm tool to set the alarm for you.

1
2
3
4
String response = ChatClient.create(chatModel)
.prompt("set an alarm 1 hour from now" )
.tools(new DateTimeTool())
.call().content();

DateTimeTool with setAlarm method - use @ToolParam annotation to mark the parameter as a tool parameter that can be passed by the model. The description attribute provides a brief description of what the parameter is, which can help the model understand how to use it.

1
2
3
4
5
6
7
8
9
10
11
12
public class DateTimeTool {
@Tool(description = "Get the current date and time in the user's timezone")
public String getCurrentDate() {
return LocalDateTime.now().atZone(LocaleContextHolder.getTimeZone().toZoneId()).toString();
}

@Tool(description = "Set a user alarm for the given time")
void setAlarm(@ToolParam(description = "Time in ISO-8601 format") String time) {
LocalDateTime alarmTime = LocalDateTime.parse(time, DateTimeFormatter.ISO_DATE_TIME);
System.out.println("Alarm set for " + alarmTime);
}
}

Reference