
Spring Boot 4 + Spring AI + Langfuse: LLM 호출 및 도구 호출(Tool Calling) 트레이싱
요약
Spring Boot 4와 Spring AI를 사용하여 LLM 호출 및 도구 호출(Tool Calling)을 구현하고, Langfuse를 통해 트레이싱하는 방법을 설명하는 튜토리얼입니다. OpenTelemetry를 활용하여 LLM의 입출력, 지연 시간, 비용 등을 모니터링하는 과정을 다룹니다.
핵심 포인트
- Spring AI와 OpenAI를 활용한 Java 기반 LLM 애플리케이션 구축
- WeatherTools를 통한 LLM의 외부 도구 호출(Tool Calling) 구현
- Langfuse를 이용한 LLM 호출 및 프롬프트/응답 트레이싱
- OpenTelemetry(OTLP)를 통한 관찰성(Observability) 확보 방법
이 튜토리얼에서는 Spring Boot 4, Spring AI 2, Gradle, 그리고 OpenAI를 사용하여 작은 Java 프로젝트를 구축할 것입니다.
애플리케이션은 다음과 같은 기능을 수행합니다:
- 일반적인 HTTP 요청에 응답합니다.
- Spring AI를 통해 LLM (Large Language Model)을 호출합니다.
- 인터넷에서 날씨 데이터를 가져오는
WeatherTools도구를 사용합니다. - OpenTelemetry를 통해 Langfuse로 트레이스 (Traces)를 전송합니다.
CallAdvisor를 통해 Langfuse에 프롬프트 (Prompts)와 응답 (Responses)을 추가합니다.
Langfuse는 AI 애플리케이션을 모니터링하고 평가하기 위한 플랫폼입니다. 경험 측면에서 LangSmith와 매우 유사합니다. LLM 호출을 트레이싱하고, 입출력을 검사하며, 지연 시간 (Latency)과 비용을 추적하고, 프롬프트와 모델을 비교할 수 있습니다. Langfuse는 오픈 소스이며 셀프 호스팅 (Self-hosted)이 가능하므로, 데이터와 인프라에 대해 더 많은 제어권을 원하는 팀에게 좋은 선택입니다.
1. 프로젝트 스택
다음 기술을 사용합니다:
- Java 21
- Spring Boot 4.1.0
- Spring AI 2.0.0
- Gradle
- OpenAI
- Langfuse
- OpenTelemetry / OTLP
build.gradle의 주요 의존성 (Dependencies):
dependencyManagement {
imports {
mavenBom 'org.springframework.ai:spring-ai-bom:2.0.0'
...
2. 애플리케이션 설정
application.properties에서 OpenAI, Spring AI 관찰성 (Observability), 그리고 Langfuse OTLP 엔드포인트 (Endpoint)를 설정합니다:
spring.application.name=spring-ai-hello-world
spring.ai.openai.api-key=${OPENAI_API_KEY}
...
다음 설정이 중요합니다:
management.otlp.metrics.export.enabled=false
우리는 Micrometer 메트릭 (Metrics)이 아닌 트레이스 (Traces)를 위해 Langfuse를 사용합니다.
만약 OTLP 메트릭 내보내기 (Export)가 비활성화되지 않으면, 애플리케이션이 동일한 엔드포인트로 메트릭을 보내려고 시도하다가 ConnectException을 받을 수 있습니다.
3. 컨트롤러 (Controller)
메인 컨트롤러는 간단합니다:
@RestController
class HelloAiController {
...
여기서 일어나는 일:
GET /ai?message=...는 LLM에 프롬프트를 보냅니다..tools(this.weatherTools)는 Java 날씨 도구를 연결합니다.LangfusePromptTracingAdvisor는 Langfuse 트레이스에 프롬프트와 응답을 추가합니다.
4. 날씨 도구 (Weather Tool)
이 도구는 Open-Meteo를 사용합니다:
- 도시의 좌표를 찾습니다.
- 해당 좌표를 사용하여 현재 날씨를 가져옵니다.
- 결과를 일반 문자열 (string)로 반환합니다.
- 모델은 그 결과를 사용하여 사용자에게 답변합니다.
Spring AI는 @Tool을 사용하여 Java 메서드를 모델 도구 (model tools)로 노출할 수 있게 해줍니다.
@Component
class WeatherTools {
...
5. OpenTelemetry를 통해 Langfuse로 트레이스 (Traces) 전송하기
Langfuse는 OTLP 엔드포인트 (endpoint)를 통해 OpenTelemetry 트레이스를 수락합니다:
Spring Boot는 spring-boot-starter-opentelemetry 의존성 (dependency)을 통해 트레이스를 전송합니다.
Langfuse는 공개 키 (public key)와 비밀 키 (secret key)를 사용하는 기본 인증 (Basic Authentication)이 필요합니다. 별도의 설정을 통해 필요한 HTTP 헤더 (headers)를 추가합니다:
@Configuration
class LangfuseTracingConfig {
...
환경 변수 (environment variables)를 설정합니다:
export LANGFUSE_TRACING_ENABLED=true
export LANGFUSE_PUBLIC_KEY=pk-lf-...
export LANGFUSE_SECRET_KEY=sk-lf-...
6. CallAdvisor를 통해 Langfuse에 프롬프트 (Prompts) 추가하기
Spring AI는 프롬프트 (prompts)와 완성 (completions)을 로그로 남길 수 있지만, 항상 우리가 필요로 하는 형식으로 Langfuse의 입력 (input) 및 출력 (output) 필드에 넣어주는 것은 아닙니다.
이를 위해 표준 Spring AI CallAdvisor 메커니즘을 사용합니다.
@Component
class LangfusePromptTracingAdvisor implements CallAdvisor {
...
getOrder()가 중요한 이유
ToolCallingAdvisor는 도구 호출 (tool-calling) 루프를 관리합니다.
우리의 어드바이저 (advisor)가 이 루프 안에 있다면, 중간 단계의 LLM 호출을 볼 수 있습니다:
- 사용자 프롬프트 (user prompt).
- 도구 호출을 결정하는 모델 응답 (model response).
- 도구 결과 이후의 프롬프트 (prompt).
- 최종 모델 응답 (final model response).
데모를 위해서는 Langfuse에서 프롬프트와 응답을 확인하기에 이 정도면 충분합니다.
7. Langfuse 시작하기
Langfuse는 Docker Compose로 시작할 수 있습니다:
cp .env.langfuse.example .env.langfuse
docker compose \
...
시작 후, 다음을 엽니다:
프로젝트를 생성하고 다음을 복사합니다:
- 공개 키 (public key);
- 비밀 키 (secret key).
8. 애플리케이션 시작하기
export OPENAI_API_KEY=your-openai-key
export LANGFUSE_TRACING_ENABLED=true
export LANGFUSE_PUBLIC_KEY=pk-lf-...
...
테스트 도구 호출(Test tool calling):
curl "http://localhost:8080/ai?message=What%20is%20the%20weather%20in%20Berlin?"
9. Langfuse에서 볼 수 있는 것 (What You Will See in Langfuse)
Langfuse는 트레이스(traces)와 스팬(spans)을 보여줄 것입니다.
생성(Generation) 스팬에는 다음과 같은 속성(attributes)이 포함됩니다:
langfuse.observation.type=generation
langfuse.observation.input=...
langfuse.observation.output=...
...
도구 호출(tool calls)의 경우, Spring AI 관측 가능성(observability)은 다음과 같은 별도의 스팬을 추가할 수 있습니다:
execute_tool getCurrentWeather
다음 옵션이 활성화된 경우:
spring.ai.tools.observations.include-content=true
Spring AI는 도구 호출 인수(tool-call arguments)와 결과도 내보낼 수 있습니다.
10. 운영 환경 참고 사항 (Production Notes)
프롬프트(Prompts), 완성본(completions), 그리고 도구 결과에는 민감한 정보가 포함될 수 있습니다.
또한, 트레이스는 일반적으로 애플리케이션 실행 메모리보다 더 오래 저장됩니다.
운영 환경에서는 다음을 고려하는 것이 좋습니다:
- 콘텐츠 자르기(content truncation);
- 정제(sanitization);
- 비밀 정보 마스킹(secret redaction);
- PII 필터링 (PII filtering).
결론 (Conclusion)
Spring AI는 어드바이저(advisors)를 통해 편리한 확장 모델을 제공하며, Langfuse는 OTLP 스팬(spans)을 수용합니다.
이 둘을 연결함으로써 다음 사항에 대한 명확한 추적(clear tracing)을 얻을 수 있습니다:
- LLM 호출 (LLM calls);
- 프롬프트 (prompts);
- 응답 (responses);
- 도구 호출 (tool calls);
- 중간 도구 호출 단계 (intermediate tool-calling steps).
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기