Spring AI + Langfuse: ObservationFilter를 이용한 스트리밍 트레이싱 (Tracing)
요약
Spring AI에서 스트리밍 응답 시 발생하는 트레이싱 문제를 ObservationFilter를 통해 해결하는 방법을 다룹니다. 기존 Advisor 방식의 한계를 극복하고 OpenTelemetry를 활용해 Langfuse로 데이터를 효율적으로 전송하는 최적의 관측성 확보 전략을 제시합니다.
핵심 포인트
- 스트리밍 방식에서는 기존 CallAdvisor가 응답을 제대로 캡처하지 못함
- ObservationFilter를 사용하여 실행 흐름을 방해하지 않고 관측 데이터 풍부화 가능
- OpenTelemetry를 통해 Spring AI의 관측값을 Langfuse로 전송
- 도구 호출(Tool calling) 시 발생하는 다중 모델 호출 흐름을 정확히 트레이싱 가능
첫 번째 파트에서, 우리는 CallAdvisor를 통해 Langfuse에 prompt와 response를 추가했습니다.
이는 단순한 .call() 방식에서는 잘 작동합니다. 하지만 스트리밍 (streaming) 방식으로 전환하면 이 접근 방식은 적합하지 않게 됩니다.
문제점
문제는 stream()으로부터 오는 응답이 CallAdvisor를 거치지 않는다는 점입니다.
Spring AI에 StreamAdvisor가 있기는 하지만, 트레이싱 (tracing)을 위한 항상 최선의 선택은 아닙니다. 어드바이저 (Advisors)는 실행 흐름의 일부입니다. 이들은 순서에 의존할 수 있고, 도구 호출 (tool calling)과 겹칠 수 있으며, 트레이스 (traces)에 불필요한 노이즈를 추가할 수 있습니다.
관측성 (observability)을 위해서는 요청 실행을 방해하지 않고, 대신 기존의 관측값 (observations)을 풍부하게 만드는 것이 더 좋습니다.
새로운 접근 방식
Spring AI는 이미 모델 호출에 대한 관측값 (observations)을 생성하고 있습니다.
우리는 스팬 (spans)을 수동으로 생성하거나 표시할 필요가 없습니다. 오직 ObservationFilter를 통해 누락된 속성 (attributes)을 추가하기만 하면 됩니다.
아이디어는 다음과 같습니다:
- Spring AI가 관측값 (observation)을 생성합니다.
ObservationFilter가 프롬프트 (prompt)와 완료 (completion) 내용을 추가합니다.- OpenTelemetry가 트레이스 (trace)를 Langfuse로 전송합니다.
stream()을 사용하는 컨트롤러 (Controller)
엔드포인트는 내부적으로 stream()을 사용하면서도 여전히 완전한 문자열을 반환할 수 있습니다:
@GetMapping("/ai")
String ai(@RequestParam(defaultValue = "Say hello in one short sentence") String message) {
var response = this.chatClient.prompt()
...
ChatClient는 더 이상 커스텀 어드바이저 (custom advisor)가 필요하지 않습니다.
ObservationFilter
CallAdvisor 대신 ObservationFilter를 추가합니다.
이는 ChatModelObservationContext와 함께 작동하며, 기존 Spring AI 관측값 (observation)에 프롬프트 (prompt)와 완료 (completion) 내용을 추가합니다:
@Component
class LangfuseObservationFilter implements ObservationFilter {
...
이 필터는:
- 모델을 호출하지 않습니다.
- 응답을 변경하지 않습니다.
- 스트리밍 (streaming)에 영향을 주지 않습니다.
- 어드바이저 (advisor) 순서에 의존하지 않습니다.
- 오직 트레이싱 (tracing) 데이터만 풍부하게 만듭니다.
도구 호출 (Tool calling)
도구 호출 (tool calling)을 사용하면, 하나의 사용자 요청이 여러 번의 내부 모델 호출을 생성할 수 있습니다:
- 사용자 프롬프트 (User prompt).
- 모델이 도구 호출 (tool calling)을 결정함.
- 도구 실행 (Tool execution).
- 최종 모델 응답 (Final model response).
따라서 하나의 트레이스 (trace) 안에 여러 개의 모델 관찰 (observation)이 존재하는 것은 정상입니다. 이는 실제 실행 흐름을 반영합니다.
이러한 방식은 트레이싱 (tracing)을 실행 로직과 분리하여 유지하며, Spring AI 모델에 더 적합합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기