-
[SpringAI] Tool Calling (1)AI 2025. 5. 24. 16:31
Tool이란?
LLM은 학습 후 동결되어 오래된 정보를 가지고 있으며, 데이터베이스, 파일 시스템 등 외부 데이터에 접근하거나 수정할 수가 없습니다. Tool calling 메커니즘은 그런 문제점을 해결하도록 도와줍니다. 자체 서비스를 Tool로 등록하여 LLM을 외부 시스템(API, 표준 기능 등)에 연결할 수 있습니다.
메서드 Tool
메서드에 어노테이션을 달아서 Tool로 바꿀 수 있습니다.
class MyTools { @Tool(description = "") void test(@ToolParam(description = "") String ) { } }
@Tool
- name: Tool 이름. 지정하지 않으면 메서드 이름이 사용됨. AI 모델은 Tool을 호출할 때 name 값을 사용하기 때문에 고유한 값이어야 한다.
- description: 모델이 Tool을 호출하는 시점과 방법을 이해하는 데 사용할 수 있는 Tool에 대한 설명. 생략시 메서드 이름으로 유추하지만 모델이 Tool의 목적과 사용 밥법을 판단하는데 굉장히 중요한 역할을 하기 때문에 자세하게 명시하는 것이 좋다.
- returnDirect: Tool 실행 결과를 클라이언트로 바로 반환할지 모델로 반환할지 여부. 한 번에 여러 Tool을 요청하는 경우, returnDirect 어트리뷰트는 true로 설정되어야 한다. 그러지 않으면 결과가 모델로 전송됨.
- resultConverter: AI 모델에게 보내기 위해서 Tool 실행 결과를 String 객체로 바꿔주는 ToolCallResultConverter 인터페이스의 구현체.
returnDirect와 resultConverter는 이후 게시할 데이터베이스 연결에서 다루겠습니다.
@ToolParam
- description: 파라미터 설명. 생략시 파라미터 이름으로 유추
- required: 파라미터 required 여부. 기본값은 true
Tool 없이 실시간 정보를 질문한다면?
User: 오늘 날짜는? Assistant: our today's date is not fixed as I do not have real-time access to the current date.
이런 식으로 알 수 없다고 하거나, 추가 정보를 요구하거나, 심지어는 잘못된 정보를 알려줍니다. 이제 Tool을 생성하고, 등록해서 제대로 동작하도록 해보겠습니다.
DateTimeTools.java
@Component public class DateTimeTools { @Tool(description = "Returns the current time in ISO-8601 format") public String getTime() { ZonedDateTime now = ZonedDateTime.now(); System.out.println(now); System.out.println(now.format(DateTimeFormatter.ISO_DATE_TIME)); return now.format(DateTimeFormatter.ISO_DATE_TIME); } }
현재 시간을 지정된 포맷으로 반환하는 Tool 클래스를 만들었습니다. Bean으로 지정해줘야 tools() 메서드로 등록할 수 있습니다.
AiChatApplication.java
@Bean public CommandLineRunner run(OllamaChatModel ollamaChatModel, DateTimeTools dateTimeTools) { return args -> { System.out.println("------------------------------------"); ChatClient chatClient = ChatClient.builder(ollamaChatModel) .defaultSystem("You are useful assistant") .build(); try (Scanner scanner = new Scanner(System.in)) { while (true) { System.out.print("\nUser: "); System.out.println("\nAssistant: " + chatClient .prompt(scanner.nextLine()) .tools(dateTimeTools) .call() .content()); } } }; }
Tool을 등록하고 실행했지만,
다음과 같은 오류가 발생했습니다.
org.springframework.ai.retry.NonTransientAiException: 400 - {"error":"registry.ollama.ai/library/gemma3:12B does not support tools"}
gemma3:12B 모델이 Tool을 지원하지 않는다고 하네요.
그래서 다른 모델을 사용하도록 수정했습니다.
application.properties
spring.ai.ollama.chat.model=llama3.2
실행결과
User: 현재 날짜 및 시간은? 2025-05-23T15:15:12.848967+09:00[Asia/Seoul] 2025-05-23T15:15:12.848967+09:00[Asia/Seoul] // 잘못된 응답 Assistant: current date and time is 2025-05-23 15:15. User: 오늘 날짜는? 2025-05-23T15:16:26.073753+09:00[Asia/Seoul] 2025-05-23T15:16:26.073753+09:00[Asia/Seoul] // 잘못된 응답 Assistant: 오늘의日期는 2025년 5월 23일입니다. User: 오늘 날짜는? 2025-05-23T15:18:12.554478+09:00[Asia/Seoul] 2025-05-23T15:18:12.554478+09:00[Asia/Seoul] Assistant: 오늘 날짜는 2025년 5월 23일입니다.
하지만, 여러 번 물어보면 제대로 답하지 못하는 경우가 많았습니다. 단순히 '지능 수준의 문제인가?' 하고 알아보니, 여러 원인(언어 혼합 출력 문제는 LLM이 다국어 학습을 했기 때문에 나타나는 부작용이라고 합니다)이 있었고, 그에 따른 개선 방법이 있었습니다.
Tool 실행 결과를 LLM이 해석하기 쉬운 자연어로 가공하고, 한국어로 명확하게 응답하도록 descprition을 수정했습니다.
@Tool(description = "Return current date and time in Korean") public String getDateTime() { ZonedDateTime now = ZonedDateTime.now(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy년 M월 d일 HH시 mm분"); System.out.println(now); System.out.println(now.format(formatter)); return now.format(formatter); } ------------------------------------ User: 현재 날짜 및 시간은? 2025-05-23T15:09:15.021286+09:00[Asia/Seoul] 2025년 5월 23일 15시 09분 Assistant: 현재 날짜와 시간은 2025년 5월 23일 15시 09 분입니다. User: 오늘 날짜는? 2025-05-23T15:20:53.756915+09:00[Asia/Seoul] 2025년 5월 23일 15시 20분 Assistant: 오늘日期는 2025년 5월 23일입니다.
그래도 한자와 영어를 섞어서 응답하네요.
Github
https://github.com/ehddnr3473/Spring-AI-Chat-Client
참고
Spring doc
(https://docs.spring.io/spring-ai/reference/api/tools.html)
'AI' 카테고리의 다른 글
[SpringAI] Tool Calling (2) - DB 접근 (0) 2025.06.20 [SpringAI] 간단한 Ollama 채팅 클라이언트 만들기 (0) 2025.05.22 Ollama 설치 및 실행 (0) 2025.05.16