에러 로그만 보고 정확한 수정 코드를 제안하려면 LLM이 소스 파일을 알고 있어야 한다. 소스 파일 전체를 매번 프롬프트에 넣을 수는 없다. RAG(Retrieval-Augmented Generation)가 필요한 이유다. 왜 RAG를 도입했나 SEMS는 수백 개의 Java 파일로 구성되어 있다. 이걸 전부 LLM 프롬프트에 넣으면: 토큰 ...
에이전트의 뼈대가 되는 FastAPI 서버를 어떻게 설계했는지, 그리고 SEMS(Spring Boot)에서 어떻게 에러를 보내는지 정리한다. 왜 FastAPI인가 에이전트 백엔드로 Python을 선택한 이유는 LLM 생태계 때문이다. Ollama Python SDK, LangChain, ChromaDB 등 LLM 관련 라이브러리가 Python에 집...
개요 PuppyNote 프로젝트에 반려동물 음식 안전 정보를 제공하는 AI 검색 기능을 추가했다. “당근은 강아지에게 먹여도 되나요?” 같은 질문을 입력하면 AI가 안전 여부와 영양 정보를 답변해주는 기능이다. AI 호출은 비용(응답 시간)이 크기 때문에 Elasticsearch를 1차 캐시로 사용해 동일한 질문이 반복될 경우 AI를 거치지 않고...
회사 SEMS 플랫폼을 운영하면서 반복적으로 겪는 불편함이 있었다. 오류가 발생할 때마다 처리 흐름이 너무 길고 소모적이었다. 왜 만들었나 SEMS 운영 중 오류가 발생하면 흐름은 항상 같았다. 콘솔을 열고 → 서버에 접속하고 → 로그를 뒤지고 → 원인을 파악하고 → 수정 후 PR을 생성하고 → 배포 후 오류가 해결됐는지 다시 확인한다. 단순히 반...
Spring Cloud Eureka를 도입했다가 제거하고 Gateway에서 직접 VM을 관리하는 방식으로 변경했다. 이유와 설정 방법을 정리한다. Eureka를 제거한 이유 Eureka는 서비스가 많고 인스턴스가 동적으로 늘어나는 환경에서 진가를 발휘한다. 새 VM이 뜨면 Eureka에 자동 등록되고, Gateway는 그걸 감지해서 자동으로 라...
Eureka 서버에 서비스가 올라오거나 내려갈 때 알람을 보내고 싶었다. Spring Cloud Eureka Server는 서비스 등록/해제 시 ApplicationEvent를 발행하기 때문에 @EventListener로 간단하게 감지할 수 있다. 사용 이벤트 이벤트 발생 시점 ...
기존에는 각 서비스를 직접 호출하거나 Nginx로 라우팅했는데, 서비스가 늘어날수록 관리가 어려워져서 Spring Cloud Gateway를 도입했다. Eureka와 연동해서 서비스가 자동으로 라우팅되고 로드밸런싱까지 되게 구성했다. 전체 구조 클라이언트 │ ▼ [Gateway :8080] ──Eureka 조회──▶ [Eure...
마이크로서비스 구조에서 서비스 디스커버리를 위해 Spring Cloud Netflix Eureka를 도입했다. Gateway가 각 서비스의 IP를 직접 하드코딩하는 게 아니라, Eureka를 통해 동적으로 서비스를 발견하고 로드밸런싱까지 가능하게 하는 게 목표였다. 전체 구조 [platform-data-api] ──등록──▶ [Eureka Se...
3대의 Azure VM에 구축한 Kafka KRaft 클러스터를 Grafana/Prometheus로 모니터링하는 방법을 정리한다. 모니터링 대상 Kafka 클러스터에서 Lag을 모니터링 하려한다. Consumer Lag이 중요한 이유: Lag이 계속 쌓이면 컨슈머가 처리를 못 따라가고 있다는 신호다. 빠르게 감지해야 장애 전에 스케일아웃할 수...
Kafka Consumer에서 에러가 발생했을 때 그냥 로그만 남기고 넘어가면 해당 메시지는 영원히 유실된다. DLQ(Dead Letter Queue)는 처리 실패한 메시지를 별도 토픽에 보관해 나중에 재처리할 수 있게 해주는 패턴이다. 기존 코드의 문제점 @KafkaListener(topics = "${gateway.kafka.topic}")...