Spring AI RAG 워크플로우 분석: 사용자 질문부터 AI 답변까지의 여정 (6편)

[Dev-Fortune] 시리즈 다시보기 1편: 기획부터 스택 선정까지 2편: 로컬 LLM Ollama 연동 3편: RAG와 Vector Store 구축 4편: 프롬프트 엔지니어링 실전 5편: 스트리밍 API 구현 1. 서론: 조각난 퍼즐을 하나로 합치기 데이터의 이동이 일어나는 찰나의 순간, 서버 내부에서 일어나는 유기적인 상호작용을 파헤쳐 보겠습니다. 2. 전체 워크플로우 시퀀스 (Deep-Dive) 사용자의 엔터 키 한 번이 답변으로 돌아오기까지의 7단계 여정입니다. sequenceDiagram autonumber User->>Controller: 고민 입력 (JSON) Controller->>Service: 사주 분석 요청 Service->>VectorStore: 고민 기반 유사도 검색 VectorStore-->>Service: 관련 사주 데이터 반환 Service->>AI: 프롬프트 조합 후 전달 (System+User) AI-->>Controller: 스트리밍 답변 생성 (Flux) Controller-->>User: SSE 응답 (실시간 텍스트) 3. 데이터 흐름의 5단계 요청 수신: JSON 고민 데이터 접수. 의미 검색: 사주 데이터 조각 탐색. 프롬프트 조합: 페르소나 + 지식 + 질문 결합. 추론 및 생성: AI의 인격이 투영된 답변 생성. 스트리밍 응답: 차가운 조언의 실시간 전달. 결국 데이터가 지능을 만들고, 프롬프트가 성격을 만듭니다. ...

March 22, 2026 · 1 min · 146 words · Chanyeol

Spring WebFlux와 SSE로 구현하는 AI 스트리밍 API: 실시간 대화 경험 (5편)

[Dev-Fortune] 시리즈 다시보기 1편: 기획부터 스택 선정까지 2편: 로컬 LLM Ollama 연동 3편: RAG와 Vector Store 구축 4편: 프롬프트 엔지니어링 실전 1. 서론: AI 답변, 왜 기다리게 하나요? 사용자 경험(UX)을 위해 한 글자씩 타이핑하듯 보여주는 스트리밍 방식은 필수적입니다. 우리 프로젝트는 WebFlux와 **SSE(Server-Sent Events)**를 활용했습니다. 2. 스트리밍 시퀀스 다이어그램 서버와 클라이언트 간의 끊임없는 데이터 흐름을 살펴보세요. sequenceDiagram participant U as User participant S as Spring Server (Flux) participant A as AI Model (Ollama) U->>S: POST /chat (Request) Note over S,A: Connection Stay Open A-->>S: "오늘의" (Token 1) S-->>U: data: "오늘의" A-->>S: " 사주는" (Token 2) S-->>U: data: " 사주는" Note right of U: 사용자는 실시간으로 글자가 보임 3. Flux와 SSE MediaType.TEXT_EVENT_STREAM_VALUE를 사용하여 AI가 단어(Token)를 생성할 때마다 즉시 클라이언트로 전송합니다. 비차단(Non-blocking) 방식인 WebFlux는 답변을 기다리는 동안 쓰레드를 점유하지 않아 성능적으로도 우수합니다. ...

March 21, 2026 · 1 min · 154 words · Chanyeol

프롬프트 엔지니어링 실전: AI에게 시니컬한 개발자 페르소나 주입하기 (4편)

[Dev-Fortune] 시리즈 다시보기 1편: 기획부터 스택 선정까지 2편: 로컬 LLM Ollama 연동 3편: RAG와 Vector Store 구축 1. 서론: AI의 ‘인격’은 어디서 오는가? 지식만 있는 AI는 백과사전일 뿐입니다. 우리가 원하는 “시니컬한 시니어 개발자” 인격을 형성하고 답변 형식을 강제하는 프롬프트 엔지니어링을 살펴보겠습니다. 2. 프롬프트 조합 구조 시스템 지침(Persona)과 검색된 데이터, 사용자의 질문이 하나로 섞이는 과정입니다. graph TD A[Persona: 실리콘밸리 개발자] + B[Rules: 반말/두문장] --> E[System Message] C[Retrieved Saju Data] + D[User Message] --> F[User Message with Context] E & F --> G((AI Model)) G --> H[Final Response] 3. 시스템 프롬프트(System Prompt) 설계 apiContext를 통해 페르소나를 정의하고, 건조하고 시니컬한 반말 말투를 강제합니다. 특히 출력 형식을 엄격하게 통제하여 UI 일관성을 유지합니다. ...

March 20, 2026 · 1 min · 171 words · Chanyeol

Spring AI RAG 구현하기: SimpleVectorStore로 전문 지식 데이터 주입 (3편)

[Dev-Fortune] 시리즈 다시보기 1편: 기획부터 스택 선정까지 2편: 로컬 LLM Ollama 연동 1. 서론: AI는 어떻게 사주를 ‘공부’하는가? AI에게 새로운 지식을 가르치는 방법 중 가장 경제적이고 정확한 RAG(Retrieval-Augmented Generation) 방식을 살펴봅니다. 질문이 들어올 때마다 관련 내용을 찾아서 읽어주며 답변하게 하는 원리입니다. 2. 데이터 주입 프로세스 (Data Ingestion) JSON 파일이 어떻게 벡터화되어 메모리에 저장되는지 그 흐름을 도식화했습니다. flowchart LR A[(sajuAPI.json)] --> B[DataLoader] B --> C[Text 정제: Key-Value형식] C --> D[Embedding Model] D --> E{SimpleVectorStore} E --> F[RAM Memory] style F fill:#f96,stroke:#333,stroke-width:2px 3. SimpleVectorStore와 DataLoader 우리 프로젝트는 별도의 DB 없이 메모리 기반의 SimpleVectorStore를 사용합니다. UnidocuDataLoader는 서버 기동 시점에 JSON 데이터를 읽어 벡터로 변환하여 주입합니다. ...

March 19, 2026 · 1 min · 149 words · Chanyeol

로컬 LLM Ollama와 Spring Boot 연동하기: 서버 설정과 성능 최적화 (2편)

[Dev-Fortune] 시리즈 다시보기 1편: 기획부터 스택 선정까지 1. 서론: 왜 유료 API 대신 로컬 LLM인가? 이번 2편에서는 본격적인 구현의 첫 단추인 AI 모델 환경 구축을 다룹니다. 우리는 비용 제로, 데이터 보안, 완전한 통제를 위해 Ollama를 활용한 로컬 LLM 방식을 선택했습니다. 2. 로컬 AI 서버 연동 구조 Spring Boot가 로컬에서 실행 중인 Ollama와 통신하는 물리적 구조입니다. graph LR subgraph "Local PC" A[Spring Boot App] -- "HTTP Post (11434)" --> B[Ollama Server] B -- "Model Load" --> C[qwen2.5:3b] subgraph "Application.properties" D[Base-URL] E[Temperature: 0.4] F[Model Name] end D -.-> A E -.-> A end 3. Spring Boot 프로젝트 설정: application.properties application.properties 파일에 담긴 설정값들을 하나씩 뜯어보며 그 의미를 파헤쳐 보겠습니다. ...

March 18, 2026 · 1 min · 167 words · Chanyeol

Spring Boot 예외 처리 통일하기 — @ControllerAdvice와 @ExceptionHandler

1. 서론: 왜 예외 처리를 통일해야 하는가? API를 개발하다 보면 다양한 예외 상황이 발생합니다. 데이터가 없는 경우, 입력값이 잘못된 경우, 서버 내부 로직 오류 등이 대표적입니다. 이때 각 컨트롤러에서 try-catch로 예외를 개별 처리하면 다음과 같은 문제가 발생합니다. 코드 중복: 비슷한 예외 처리 로직이 여러 컨트롤러에 반복됩니다. 응답 일관성 부족: 어떤 API는 JSON으로 에러를 주는데, 어떤 API는 HTML 에러 페이지를 주는 등 응답 형식이 제각각이 됩니다. 비즈니스 로직 집중도 저하: 예외 처리 코드가 섞여 있어 핵심 로직을 파악하기 힘듭니다. Spring은 이를 우아하게 해결할 수 있도록 @ControllerAdvice와 @ExceptionHandler를 제공합니다. ...

March 17, 2026 · 2 min · 401 words · Chanyeol

Spring AI와 Ollama로 만드는 AI 개발자 사주 챗봇: 기획부터 스택 선정까지 (1편)

1. 프롤로그: 왜 ‘AI 개발자’ 사주인가? 전통적인 사주 풀이는 어렵고 따분합니다. “올해는 물의 기운이 강하니…” 같은 말은 현대의 개발자들에게는 다소 와닿지 않죠. 하지만 만약 **“실리콘밸리 출신의 천재 개발자”**가 당신의 인생을 코드로 보고 ‘디버깅’해준다면 어떨까요? 이 프로젝트는 바로 그 엉뚱한 상상에서 시작되었습니다. 감정 섞인 위로 대신, 건조하고 시니컬한 말투로 당신의 사주를 “안티 패턴"과 “배드 해빗(Bad Habit)“으로 분석해 주는 챗봇, **‘Dev-Fortune’**입니다. 2. 프로젝트 시스템 구조도 전체적인 데이터 흐름과 기술 스택을 한눈에 살펴보겠습니다. ...

March 17, 2026 · 1 min · 192 words · Chanyeol

Java Stream API 실전 가이드 — filter, map, reduce 완벽 정리

1. 서론: 명령형에서 선언형으로의 전환 Java 8에서 도입된 Stream API는 자바 프로그래밍 패러다임을 획기적으로 바꾸어 놓았습니다. 기존의 for, while 루프를 사용한 명령형(Imperative) 방식은 “어떻게(How)” 동작하는지에 집중했다면, 스트림은 선언형(Declarative) 방식으로 “무엇을(What)” 할 것인지에 집중합니다. 스트림을 사용하면 코드의 가독성이 높아지고, 병렬 처리를 쉽게 적용할 수 있으며, 복잡한 데이터 처리를 간결한 체이닝으로 해결할 수 있습니다. 이번 가이드에서는 가장 핵심적인 연산인 filter, map, reduce를 중심으로 실무 활용법을 알아봅니다. 2. 스트림의 핵심 연산 3종 세트 2.1. filter: 조건에 맞는 데이터 선별 filter는 스트림의 요소 중 특정 조건(Predicate)을 만족하는 요소만 남기는 중간 연산입니다. ...

March 17, 2026 · 2 min · 416 words · Chanyeol

마이크로서비스 아키텍처(MSA)의 핵심 패턴과 통신 방식

서론: 왜 마이크로서비스 아키텍처(MSA)인가? 거대한 하나의 애플리케이션으로 모든 기능을 처리하던 모놀리식 구조는 서비스 규모가 커질수록 유지보수와 확장에 한계를 드러냅니다. 이러한 문제를 해결하기 위해 등장한 **마이크로서비스 아키텍처(MSA)**는 서비스를 독립적인 작은 단위로 쪼개어 개발하고 배포하는 방식입니다. 각 서비스가 독립적으로 운영되므로 특정 기능의 장애가 전체 시스템으로 확산되는 것을 방지할 수 있습니다. 오늘날 수많은 기업들이 비즈니스의 유연성을 확보하기 위해 **마이크로서비스 아키텍처(MSA)**를 도입하고 있습니다. 1. 마이크로서비스 아키텍처(MSA)의 설계 원칙 **마이크로서비스 아키텍처(MSA)**를 성공적으로 구축하기 위해서는 ‘느슨한 결합(Loose Coupling)‘과 ‘높은 응집도(High Cohesion)‘가 필수적입니다. 각 서비스는 자신만의 데이터베이스를 가지며, 다른 서비스의 데이터에 직접 접근하지 않고 API를 통해서만 소통해야 합니다. 이러한 원칙을 통해 **마이크로서비스 아키텍처(MSA)**는 각 팀이 서로 간섭받지 않고 독립적으로 기술 스택을 선택하고 배포 주기를 관리할 수 있는 환경을 제공합니다. 비즈니스 영역을 기준으로 서비스를 나누는 ‘도메인 주도 설계(DDD)‘는 마이크로서비스 아키텍처(MSA) 설계의 핵심적인 기반이 됩니다. ...

March 17, 2026 · 3 min · 588 words · Chanyeol

쿠버네티스(Kubernetes) 클러스터 구조와 핵심 개념 완벽 정리

서론: 왜 쿠버네티스(Kubernetes)인가? 현대적인 클라우드 네이티브 환경에서 컨테이너 기술은 필수적인 요소가 되었습니다. 하지만 수많은 컨테이너를 수동으로 관리하는 것은 불가능에 가깝습니다. 이때 등장한 **쿠버네티스(Kubernetes)**는 컨테이너화된 애플리케이션의 배포, 확장 및 관리를 자동화해주는 오픈소스 플랫폼입니다. 구글의 운영 노하우로 탄생한 **쿠버네티스(Kubernetes)**는 현재 전 세계 기업들의 표준 인프라로 자리 잡았으며, 효율적인 서버 관리를 위한 필수 도구입니다. 1. 쿠버네티스(Kubernetes)의 전체적인 구조 쿠버네티스(Kubernetes) 클러스터는 크게 두 부분으로 나뉩니다: 전체 클러스터를 관리하는 ‘컨트롤 플레인(Control Plane)‘과 실제 애플리케이션이 구동되는 ‘노드(Node)‘입니다. **쿠버네티스(Kubernetes)**는 이 구조를 통해 높은 가용성과 확장성을 보장하며, 복잡한 분산 시스템을 하나의 거대한 컴퓨터처럼 사용할 수 있게 해줍니다. 사용자가 원하는 상태를 선언적으로 정의하면, **쿠버네티스(Kubernetes)**는 실제 상태를 그에 맞추기 위해 지능적으로 동작합니다. ...

March 16, 2026 · 3 min · 499 words · Chanyeol
1