Spring AI 학습 정리

박지명·2026년 5월 14일

스프링부트

목록 보기
10/10

1. 기본 개념 (Hello/Prompt)

Spring AI: Java 애플리케이션에서 AI 기능을 통합하기 위한 프레임워크

개념설명
PromptAI 모델에 보내는 입력 요청
ResponseAI 모델이 반환하는 응답
ChatClientSpring AI의 핵심 클라이언트

Hello World 예제

@Controller
private ChatClient chatClient;

public String hello() {
    String message = chatClient
        .prompt("Hello")
        .call()
        .content();
    return message;
}

Prompt 특징

  • ✅ 자연어로 AI에 명령 전달
  • ✅ 다양한 형식의 입력 지원
  • ✅ 컨텍스트 기반 응답 생성

2. 이미지 처리 (Image/ImageAnalysis)

이미지를 AI가 분석하고 처리하는 기능

이미지 업로드

String base64Image = Base64.getEncoder()
    .encodeToString(imageBytes);

chatClient.prompt()
    .withMedia("image/jpeg", base64Image)
    .call();

이미지 분석 기능

기능설명
객체 인식이미지 내 객체 감지
텍스트 추출OCR을 통한 텍스트 추출
이미지 설명이미지 내용 자동 설명
분류이미지 카테고리 분류

지원 포맷

  • ✅ JPEG
  • ✅ PNG
  • ✅ GIF
  • ✅ WebP

3. 음성 처리 (STT/TTS)

음성과 텍스트 간 상호 변환

STT (Speech-to-Text)

음성을 텍스트로 변환

항목설명
입력오디오 파일 (Base64 인코딩)
출력텍스트
활용음성 명령, 자동 자막
지원 형식mp3, wav, m4a, flac
String base64Audio = Base64.getEncoder()
    .encodeToString(audioBytes);

String text = chatClient.prompt()
    .withMedia("audio/mp3", base64Audio)
    .call()
    .content();

TTS (Text-to-Speech)

텍스트를 음성으로 변환

항목설명
입력텍스트 문자열
출력오디오 파일
활용음성 안내, 접근성
지원 포맷mp3, wav, opus

음성 처리 특징

  • ✅ 자동 음성 인식 (ASR)
  • ✅ 실시간 스트리밍
  • ✅ 다국어 지원
  • ✅ 음성 톤 조정 가능

4. 날씨 API 통합

외부 API를 통해 실시간 날씨 정보 조회

도시 기반 날씨 조회

@GetMapping("/weather/{city}")
public String getWeather(@PathVariable String city) {
    String response = weatherService.getWeather(city);
    return response;
}

날씨 정보 종류

정보설명
기온현재 기온
습도습도 정보
풍속바람 속도
강수량강우량
날씨상태맑음, 흐림, 비 등

WeatherService 구현

@Service
@RequiredArgsConstructor
public class WeatherService {
    private final RestTemplate restTemplate;
    
    public String getWeather(String city) {
        // OpenWeather API 호출
        String url = "https://api.openweathermap.org/...";
        return restTemplate.getForObject(url, String.class);
    }
}

5. 멤버 관리

사용자 정보 관리 및 데이터 모델

Member Entity

@Entity
@Table(name = "member")
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Member {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String name;
    private String email;
    private String phone;
    private String role;
}

Member DTO

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MemberDto {
    private Long id;
    private String name;
    private String email;
    private String phone;
    private String role;
}

Member Repository

public interface MemberRepository extends JpaRepository<Member, Long> {
    Optional<Member> findByEmail(String email);
    List<Member> findByRole(String role);
}

Member Service

@Service
@RequiredArgsConstructor
public class MemberService {
    private final MemberRepository repo;
    
    public Member saveMember(MemberDto dto) {
        Member member = Member.builder()
            .name(dto.getName())
            .email(dto.getEmail())
            .phone(dto.getPhone())
            .role(dto.getRole())
            .build();
        return repo.save(member);
    }
    
    public Member getMember(Long id) {
        return repo.findById(id)
            .orElseThrow(() -> new RuntimeException("Member not found"));
    }
}

Member Controller

@RestController
@RequestMapping("/api/members")
@RequiredArgsConstructor
public class MemberController {
    private final MemberService service;
    
    @PostMapping
    public Member create(@RequestBody MemberDto dto) {
        return service.saveMember(dto);
    }
    
    @GetMapping("/{id}")
    public Member get(@PathVariable Long id) {
        return service.getMember(id);
    }
}

6. RAG (Retrieval-Augmented Generation)

외부 데이터를 활용한 지능형 응답 생성

RAG 개념

문서/데이터베이스에서 정보를 검색한 후 AI 모델에 제공하여 더 정확한 답변 생성

기본 RAG 프로세스

1️⃣ 사용자 쿼리 수신
   ↓
2️⃣ 데이터베이스에서 관련 문서 검색
   ↓
3️⃣ 검색 결과와 쿼리를 AI에 전달
   ↓
4️⃣ AI가 컨텍스트 기반 답변 생성

기본 RAG 구현

@Service
@RequiredArgsConstructor
public class RagService {
    private final ChatClient chatClient;
    private final DocumentRepository docRepo;
    
    public String answerQuestion(String question) {
        // 1. 관련 문서 검색
        List<Document> documents = docRepo.search(question);
        
        // 2. 컨텍스트 구성
        String context = documents.stream()
            .map(Document::getContent)
            .collect(Collectors.joining("\n"));
        
        // 3. AI에 질문 전달
        String response = chatClient.prompt()
            .withUserMessage(question + "\n\nContext:\n" + context)
            .call()
            .content();
        
        return response;
    }
}

RAG Advanced (VectorStore 활용)

벡터 데이터베이스를 활용한 고급 검색

기술설명
Embedding텍스트를 수치 벡터로 변환
Vector DBPinecone, Chroma, FAISS 등
의미론적 검색의미 기반의 유사 문서 검색
하이브리드 검색키워드 + 벡터 검색

VectorStore를 사용한 고급 RAG

@Service
@RequiredArgsConstructor
public class AdvancedRagService {
    private final ChatClient chatClient;
    private final VectorStore vectorStore;
    private final EmbeddingClient embeddingClient;
    
    public String answerQuestion(String question) {
        // 1. 질문을 벡터로 변환
        float[] embedding = embeddingClient.embed(question);
        
        // 2. 벡터 데이터베이스에서 유사한 문서 검색
        List<Document> similarDocs = vectorStore.search(embedding);
        
        // 3. 검색된 문서와 함께 AI에 질문
        String context = similarDocs.stream()
            .map(Document::getContent)
            .collect(Collectors.joining("\n\n"));
        
        String response = chatClient.prompt()
            .withUserMessage(
                "다음 컨텍스트를 바탕으로 질문에 답하세요:\n\n" +
                context + "\n\n질문: " + question
            )
            .call()
            .content();
        
        return response;
    }
}

RAG Advanced 특징

  • ✅ 의미론적 유사성 기반 검색
  • ✅ 다양한 파일 형식 지원 (PDF, Word, txt, md)
  • ✅ 청킹 및 임베딩 최적화
  • ✅ 재순위 지정 (Re-ranking)
  • ✅ 메타데이터 필터링
  • ✅ 실시간 문서 업데이트

지원되는 VectorStore

VectorStore특징
Pinecone관리형 클라우드 서비스
Chroma경량 로컬 솔루션
FAISSMeta의 오픈소스 벡터 DB
Weaviate엔터프라이즈급 솔루션
Milvus고성능 벡터 DB

📚 학습 순서

1️⃣ Hello/Prompt (기본 개념)

  • Spring AI 기초 이해
  • ChatClient 사용법
  • 기본 Prompt 작성

2️⃣ Image/ImageAnalysis (미디어 처리)

  • 이미지 업로드 및 처리
  • 이미지 분석 기능
  • Base64 인코딩

3️⃣ STT/TTS (음성 처리)

  • 음성을 텍스트로 변환
  • 텍스트를 음성으로 변환
  • 오디오 스트리밍

4️⃣ Member (데이터 관리)

  • JPA Entity 설계
  • Repository 패턴
  • CRUD 서비스 구현

5️⃣ Weather (외부 API 통합)

  • REST API 호출
  • RestTemplate 사용
  • 외부 데이터 통합

6️⃣ RAG (고급 기능)

  • 벡터 검색 기초
  • 문서 처리 및 청킹
  • VectorStore 통합
  • 의미론적 검색 최적화

🔑 핵심 정리

항목핵심 포인트
Hello/PromptChatClient로 AI 모델과 상호작용
ImageBase64 인코딩을 통한 이미지 전달
AudioSTT/TTS로 음성 처리
APIRestTemplate으로 외부 API 연동
DataJPA를 이용한 데이터 관리
RAG벡터 검색과 문서 처리를 통한 지능형 응답

📌 자주 하는 실수

❌ 실수 1: Base64 인코딩 누락

// 잘못된 예
chatClient.prompt().withMedia("image/jpeg", imageBytes).call();

// 올바른 예
String base64 = Base64.getEncoder().encodeToString(imageBytes);
chatClient.prompt().withMedia("image/jpeg", base64).call();

❌ 실수 2: 컨텍스트 없는 RAG

// 잘못된 예 - 문서를 가져오지 않음
String response = chatClient.prompt(question).call().content();

// 올바른 예 - 문서 검색 후 제공
List<Document> docs = vectorStore.search(embedding);
String context = docs.stream().map(Document::getContent).collect(...);
String response = chatClient.prompt(question + context).call().content();

❌ 실수 3: 청킹 전략 미흡

// 잘못된 예 - 전체 문서를 한 번에 처리
String wholDocument = Files.readString(file);

// 올바른 예 - 적절한 크기로 청킹
List<Document> chunks = documentSplitter.split(wholDocument);

📖 참고 자료

0개의 댓글