본문으로 바로가기
Spring AI를 배우기 전에 정리할 것
LinkedInGitHub
WORKSPACE

EXPLORER

157 POSTS
BLOG
면접질문
해야하는 거
AI 시대, 개발자는 사라지는가?
Python Counter, 빈도수를 쉽게 세는 방법
정렬
1. 투 포인터
DFS와 BFS
알고리즘 논리
코딩 테스트 핵심 알고리즘 정리파이썬 딕셔너리와 코딩 테스트 활용
예시로 살펴보는 AXAX 프로젝트, 문제 정의부터 확산까지AX 시대의 가치 정의와 현장 리딩
MSA
1. Singleton PatternSOLID
Kafka의 핵심 설계 원리Kafka 메시징 시스템의 구성과 동작 방식Kafka 기본 개념과 EC2 Docker 구성
쿠버네티스 입문
Modular Monolith1. MonolithMSA, 서비스 분리와 운영의 원리
Socket이란 무엇인가
네크워크 참조 모델
전체 데이터 구조REST API의 개념과 설계 원칙2. Field/ Parameter / Argument/ this
Actuator 란?EntityManagerJPA 연관관계 매핑JPA 트랜잭션(Transaction)입력값 검증Java의 AOP(Aspect Oriented Programming)Async : AsynchronousBeanJPA(Java Persistence API)Proxy 패턴Spring MVCdocker container1. Spirng 필요컴포넌트 스캔
Spring 컨테이너
application.yamlLombok
이번 강의는 무엇을 노리고 있을까?Spring AI를 배우기 전에 정리할 것23
1. 기술 스택
개발 문서를 읽기 위한 핵심 기술 용어
Docker를 이해하기 위한 운영체제 기초
sigterm
6. 설정과 저장소, 앱을 운영할 수 있는 상태로 만들기5. Service와 Ingress, 요청은 어디로 흐를까4. 직접 실험하는 Kubernetes, Pod 복구부터 롤백까지3. kubectl과 Pod, 상태에서 원인을 찾는 법2. 클러스터는 명령을 어떻게 Pod로 바꿀까1. 쿠버네티스, 원하는 상태와 컨테이너 이미지Calico쿠버네티스 입문, 원하는 상태를 유지하는 시스템
Psql JSONB, 행 잠금, 멱등성Psql 함수,프로시져,트리거
머신러닝 입문딥러닝 학습 기본 개념데이터 시각화기초 통계와 ML 파이프라인 연결분석 자동화와 파이프라인 설계
CNN 아키텍처 발전 과정이미지 세그멘테이션 모델과 핵심 개념객체 탐지 모델과 핵심 개념
딥러닝 데이터셋 엔지니어링
딥러닝 학습 문제 진단과 디버깅
도메인 적응 방법현대 LLM 워크플로의 패턴
Transformer에서 LoRA 적용 대상 정하기LoRA (Low-Rank Adaptation)
LLM 양자화와 QLoRA
분산 학습과 MLOps딥러닝 모델 경량화와 추론 최적화딥러닝 기본 학습 테크닉딥러닝 중급 학습 테크닉
Mixture of Experts(MoE) 핵심 개념멀티모달 파운데이션 모델 핵심 개념State Space Model과 MambaTransformer와 Vision Transformer
Latent Space
1Chunking?
DevOps 기초 1편
실습에서는?Agile 개요, 왜 필요한가?
CI/CD 기초 4편: 배포 전략과 운영CI/CD 기초 3편: Jenkins와 Argo CD를 이용한 GitOps 배포CI/CD 기초 2편: Docker 이미지와 배포 파이프라인CI/CD 기초 1편: 개념과 GitHub Actions
OCI: 컨테이너 이미지와 런타임의 공통 표준Docker 기초 13편: Compose Healthcheck와 실전 구성Docker 기초 12편: Compose 네트워크와 VolumeDocker 기초 11편: Compose 명령어와 환경 변수Docker 기초 10편: Compose 기본 구조와 이미지 빌드Docker 기초 9편: Docker 및 Kubernetes 네트워크Docker 기초 8편: 컨테이너 런타임과 격리Docker 기초 7편: 이미지 Layer와 tar 내부 구조Docker 기초 6편: 이미지 Layer와 빌드 최적화Docker 기초 5편: 컨테이너 기본 명령어와 VolumeDocker 기초 4편: 가상화와 컨테이너 이미지 생명주기Docker 기초 3편: CI/CD 연결과 배포 원칙Docker 기초 2편: Layer, Registry, Volume과 NetworkDocker 기초 1편: Dockerfile, Image와 Container
NginxNginx 로드 밸런싱과 HTTPSNginx 리버스 프록시와 Spring Boot 연결Nginx 기초와 동작 구조
05. Pinia 상태 관리: store 설계와 사용법04. Vue 컴포넌트 설계: props, emit, slot과 생명주기03. Vue Composition API 정리02. Vue 기초 문법 점검: JavaScript, 템플릿01. Vue.js 입문: 핵심 구조와 렌더링
Java 심화 Part 3: 함수형 프로그래밍과 LambdaJava 심화 Part 2: AnnotationJava 심화 Part 1: Reflection
Java 기초 Part 5: Stream APIJava 기초 Part 4: 제네릭Java 기초 Part 3: 제어문Java 기초 Part 2: 주석과 JavadocJava 기초 Part 1: 백엔드 배경과 Java 실행 구조
Java 디버깅 Part 1: 자주 헷갈리는 핵심 개념Java 디버깅 Part 2: VS Code 자동 컴파일과 프로젝트 구조
Java 실행과 JVM Part 3: ClassLoader와 JVM 메모리Java 실행과 JVM Part 2: 메모리와 데이터 흐름Java 실행과 JVM Part 1: Java와 Python 컴파일 비교
Java 객체지향 Part 5: static 메서드와 중첩 클래스Java 객체지향 Part 4: 상속과 인터페이스Java 객체지향 Part 3: 좋은 설계와 OOP 4대 특성Java 객체지향 Part 2: OOP 핵심 문법Java 객체지향 Part 1: 클래스, 객체, 필드와 생성자
Spring 기초 Part 11: Actuator와 애플리케이션 모니터링Spring 기초 Part 10: 비동기 처리와 @AsyncSpring 기초 Part 9: JPA 트랜잭션과 동시성 제어Spring 기초 Part 8: AOP와 공통 관심사 분리Spring 기초 Part 7: Proxy 패턴과 Spring ProxySpring 기초 Part 6: JPA 연관관계 매핑Spring 기초 Part 5: EntityManager와 영속성 컨텍스트Spring 기초 Part 4: JPA, Entity와 RepositorySpring 기초 Part 3: REST API 요청값과 입력값 검증Spring 기초 Part 2: Spring MVC 요청 처리 흐름Spring 기초 Part 1: IoC, Bean, DI와 주요 Annotation
DNS = Domain Name System
Spring Boot, WebSocket, Vue, Docker 로 Raspberry Pi 실시간 모니터링 프로젝트 만들기 - 1편1. Spring Boot 구현
1. GitHub Project 만들기
Python 코드 품질: 디버깅부터 테스트와 자동화까지Python 01. 실행 구조와 실무 기초
sLLM 핵심 기술과 전체 구조제한된 자원에서 sLLM 구축하기
시대 단상에 대한 주저리주저리
WORKSPACE

SEARCH

제목, 카테고리와 태그로 검색하세요.

VERSION CONTROL

SOURCE CONTROL

masterGitHub Pages
저장소 열기
BUILD STATUS

RUN AND DEBUG

게시물은 GitHub Actions에서 검증하고 정적 페이지로 빌드합니다.

Actions 열기
WORKSPACE

MANAGE

홈 열기전체 게시물태그 보기블로그 소개
Spring AI를 배우기 전에 정리할 것●
workspace>posts>backend>spring ai>1.md
Backend / SPRING AI2026.08.181 min read0 tags

Spring AI를 배우기 전에 정리할 것

프론트엔드도 알아야 하지만, 백엔드는 조금 더 깊게 파고들고 싶다. 기술을 한 가지만 고르기보다 여러 기술을 경험하되, 결국에는 내가 잘 아는 도메인 하나를 만들어야 한다.

Spring AI를 배우기 전에 정리할 것

프론트엔드도 알아야 하지만, 백엔드는 조금 더 깊게 파고들고 싶다. 기술을 한 가지만 고르기보다 여러 기술을 경험하되, 결국에는 내가 잘 아는 도메인 하나를 만들어야 한다.

그 전에 객체 지향, Spring Boot의 계층 구조, 그리고 AI 기능이 어디에 들어가는지를 한 흐름으로 정리해 본다.


객체 지향: 캡, 추, 다, 상

객체 지향의 핵심은 클래스로 만든 객체가 자기 역할을 가지고 협력하게 하는 것이다. 외우기 쉽게 캡, 추, 다, 상이라고 정리할 수 있다.

개념뜻쉽게 말하면
캡슐화데이터와 접근 방법을 객체 안에 묶고 통제한다중요한 값은 아무나 바꾸지 못하게 숨긴다
추상화복잡한 구현을 감추고 필요한 기능만 보여 준다자동차를 운전할 때 엔진 구조까지 알 필요는 없다
다형성같은 호출이라도 객체에 따라 다르게 동작한다pay()를 호출해도 카드, 계좌이체가 각자 다르게 결제한다
상속기존 클래스의 특징을 물려받아 확장한다공통 기능을 부모 클래스에 두고 필요한 부분만 늘린다
interface Payment {
    void pay(int amount);
}

class CardPayment implements Payment {
    @Override
    public void pay(int amount) {
        System.out.println("카드로 " + amount + "원 결제");
    }
}

class TransferPayment implements Payment {
    @Override
    public void pay(int amount) {
        System.out.println("계좌이체로 " + amount + "원 결제");
    }
}

Payment payment = new CardPayment();
payment.pay(10_000); // 같은 pay(), 다른 동작

LLM 기본 용어

AI를 붙이기 전에 모델이 무엇을 기준으로 동작하는지 알아야 한다.

용어한 줄 정의알아 둘 점
토큰, token모델이 텍스트를 나누어 처리하는 단위비용, 입력 길이, 출력 길이의 기준이다. 한글 토큰 수는 문장과 모델마다 달라진다.
컨텍스트 윈도우요청 한 번에 모델이 읽을 수 있는 총 토큰 범위한도를 넘으면 입력을 줄이거나 요약해야 한다.
프롬프트모델에 보내는 전체 입력지시, 맥락, 예시, 원하는 출력 형식을 함께 넣는다.
시스템 메시지모델의 역할과 규칙을 정하는 상위 지시사용자 질문과 분리해서 관리한다.
temperature답변의 무작위성분류, 추출은 낮게, 아이디어 생성은 조금 높게 둔다.
top-p다음 토큰 후보를 확률 범위로 제한하는 값temperature와 함께 무작정 조절하지 않는다.
할루시네이션모델이 모르는 내용을 그럴듯하게 만드는 현상근거를 제공하고, 모르면 모른다고 답하게 해야 줄어든다.
파인튜닝모델 가중치를 추가 학습하는 일최신 지식 주입보다 말투, 형식, 반복 패턴을 맞출 때 더 잘 맞는다.
멀티모달텍스트 외 이미지, 음성 등을 함께 다루는 기능모델이 해당 입력과 출력을 지원해야 한다.

임베딩, 벡터 검색, RAG

임베딩이란?

임베딩은 문장을 의미를 담은 숫자 배열, 즉 벡터로 바꾸는 것이다. 뜻이 비슷한 문장은 벡터 공간에서도 가까워진다.

예를 들어 사용자가 휴가 내는 법이라고 물어도, 문서에 연차 신청 규정이라고 적혀 있으면 의미가 가까워서 찾을 수 있다. 단어가 정확히 같지 않아도 검색할 수 있다는 점이 핵심이다.

용어한 줄 정의알아 둘 점
임베딩, embedding텍스트를 의미 벡터로 바꾸는 것의미가 가까울수록 벡터도 가까워진다.
차원, dimension벡터를 이루는 숫자의 개수모델을 바꾸면 차원이 달라질 수 있어 재색인이 필요하다.
코사인 유사도두 벡터가 향하는 방향의 유사도보통 1에 가까울수록 의미가 비슷하다.
벡터 DB벡터, 원문, 메타데이터를 저장하고 검색하는 저장소pgvector, Chroma, Qdrant 등이 있다.
청킹, chunking문서를 검색 가능한 작은 조각으로 나누는 일너무 크면 잡음이 많고, 너무 작으면 문맥이 끊긴다.
overlap이웃 청크끼리 일부 문장을 겹치게 하는 것문장이 중간에서 잘려 근거가 사라지는 일을 줄인다.
top-k검색 결과로 가져올 청크 개수크게 하면 근거는 늘지만 비용과 잡음도 늘어난다.
MMR유사도와 결과의 다양성을 같이 보는 방식비슷한 문서만 여러 개 나오는 것을 줄인다.
인덱스벡터를 빠르게 찾기 위한 자료구조데이터가 커지면 HNSW, IVF 같은 인덱스를 고려한다.

RAG란?

RAG, Retrieval-Augmented Generation는 질문과 관련된 문서를 먼저 찾고, 그 근거를 모델에게 함께 주어 답하게 하는 방식이다. 모델을 다시 학습하지 않아도 문서를 교체하거나 추가해서 지식을 갱신할 수 있다.

문서 파일
  → 읽기
  → 청킹
  → 임베딩
  → VectorStore에 저장

사용자 질문
  → 질문 임베딩
  → 유사한 문서 검색
  → 검색 결과를 프롬프트에 추가
  → 모델 답변 + 출처 반환
용어한 줄 정의알아 둘 점
ingest문서를 읽고, 자르고, 임베딩해 저장하는 과정보통 문서가 바뀔 때 배치 작업으로 실행한다.
retriever질문에 맞는 청크를 찾아 주는 부분Spring AI에서는 VectorStore, Advisor 등을 이용해 구성한다.
근거, 출처답변의 바탕이 된 문서 조각과 위치출처를 같이 보여 줘야 답변을 확인할 수 있다.
rerank검색 후보를 다시 점수 매겨 상위 결과를 고르는 것검색 품질을 올릴 때 효과가 큰 단계다.
하이브리드 검색키워드 검색과 의미 검색을 결합하는 방식제품 코드, 고유명사처럼 정확한 단어가 중요한 경우 좋다.
metadata filter메타데이터 조건으로 검색 범위를 제한하는 것권한은 프롬프트가 아니라 필터와 DB 쿼리에서 막아야 한다.

도구와 에이전트

모델은 직접 DB를 수정하거나 이메일을 보내지 않는다. 모델은 어떤 도구를 호출할지 판단하고, 실제 실행은 우리 코드가 담당한다.

개념뜻주의할 점
Tool calling모델이 정해진 함수 호출을 요청하는 기능함수 이름, 설명, 파라미터 설명이 모델에게는 API 명세다.
Agent생각하고 도구를 호출한 뒤 결과를 보고 다시 판단하는 흐름호출 횟수와 시간 제한을 두지 않으면 비용이 커질 수 있다.
Human approval되돌리기 어려운 행동 전에 사람의 확인을 받는 것환불, 발송, 삭제 같은 작업에 필요하다.
Guardrail입력과 출력에 적용하는 안전 규칙차단은 메모리 저장이나 외부 호출보다 먼저 해야 한다.
Prompt injection모델 지시를 무시하게 만들려는 공격검색 문서 안에 숨어 들어오는 간접 공격도 확인해야 한다.

Spring Boot 기초: 계층 구조와 어노테이션

왜 계층을 나눌까?

계층을 나누는 이유는 문제가 생겼을 때 바꿔야 할 부분만 고치기 위해서다. 화면 요구가 바뀌면 Controller, 업무 규칙이 바뀌면 Service, 저장 방식이 바뀌면 Repository나 Mapper를 중심으로 수정한다.

HTTP 요청
  → Controller: 받고, 검증하고, DTO로 응답한다
  → Service: 업무 흐름과 트랜잭션을 결정한다
  → Repository 또는 Mapper: DB와 외부 시스템에 접근한다
  → DB / 외부 API
계층역할여기 두지 않는 것
ControllerHTTP 요청, 검증, 응답 DTO 변환복잡한 업무 규칙, SQL
Service업무 흐름, 트랜잭션, 여러 저장소 조합HTTP 세부 처리, 화면 응답 형식
RepositoryJPA로 엔티티를 저장하고 조회업무 정책
MapperMyBatis SQL을 직접 실행Controller 역할
DTOAPI에서 주고받는 데이터 모양DB 구조 그 자체

요청 하나가 지나가는 흐름

GET /ch02/orders/12345?userId=user1 요청을 예로 들면 다음과 같다.

  1. OrderController가 @PathVariable, @RequestParam, @Valid로 값을 받는다.
  2. OrderService에 주문 번호와 사용자 ID처럼 필요한 값만 전달한다.
  3. OrderRepository 또는 OrderMapper가 권한 조건을 포함해 데이터를 조회한다.
  4. 엔티티나 조회 결과를 응답 DTO로 변환한다. 원가나 소유자 ID처럼 외부에 보이면 안 되는 값은 제외한다.
  5. Controller가 DTO를 JSON으로 반환한다.

400은 주로 입력 검증, 404는 업무상 대상 없음, 500은 DB 연결이나 예상하지 못한 오류에서 많이 발생한다. 하지만 실제 상태 코드는 서비스의 정책과 예외 처리 방식에 따라 정해야 한다.

자주 쓰는 어노테이션

분류대표 어노테이션, 방식역할
빈 등록@Component, @Service, @Repository, @Controller클래스를 Spring이 관리하는 Bean으로 등록한다.
요청 매핑@RestController, @GetMapping, @PostMappingHTTP 요청을 메서드에 연결한다.
의존성 주입생성자 주입, @Autowired, @Qualifier필요한 Bean을 찾아 넣는다.
설정@Configuration, @Bean, @ConfigurationProperties직접 만든 Bean과 외부 설정을 등록한다.
검증, 예외@Valid, @ExceptionHandler, @RestControllerAdvice입력을 검증하고 예외를 API 응답으로 바꾼다.
부가 기능@Transactional, @Async, @Retryable, @Aspect원래 업무 코드에 공통 기능을 덧붙인다.

@SpringBootApplication은 설정 클래스, 컴포넌트 스캔, 자동 구성을 묶어 둔 시작점이다. Spring AI 스타터를 추가했을 때 관련 Bean이 자동으로 준비되는 것도 이 자동 구성 흐름에 올라탄다.

@Service, @Repository, @Controller는 모두 @Component의 구체적인 표현이다. 이름만 봐도 역할을 알 수 있게 해 주며, @Repository는 DB 접근 예외를 Spring의 예외 체계로 변환하는 의미도 가진다.

Bean과 의존성 주입

Bean은 Spring이 만들어 관리하는 객체다. 기본 스코프는 singleton이라서 애플리케이션 전체에서 보통 하나만 만든다. 그래서 Service의 필드에 사용자별 값이나 요청별 상태를 저장하면 안 된다.

@Service
public class OrderService {

    private final OrderRepository repository;

    public OrderService(OrderRepository repository) {
        this.repository = repository;
    }

    public OrderResponse findOrder(String orderId, String userId) {
        return repository.findByIdAndOwnerId(orderId, userId)
                .map(OrderResponse::from)
                .orElseThrow(() -> new OrderNotFoundException(orderId));
    }
}

필드에는 Repository처럼 바뀌지 않는 협력 객체를 두고, 주문 번호나 사용자 ID 같은 요청별 값은 메서드 파라미터로 받는다.

스코프생성 시점
singleton애플리케이션당 보통 하나, 기본값
prototype주입 또는 요청할 때마다 새 객체
requestHTTP 요청마다 하나, 웹 환경에서 사용

DTO와 엔티티는 분리한다

엔티티는 DB 구조와 연결된 내부 모델이고, DTO는 API에서 주고받는 데이터 모양이다. 엔티티를 그대로 반환하면 DB 구조가 API 규격이 되고, 원가나 소유자 ID 같은 내부 정보가 실수로 노출될 수 있다.

public record CreateOrderRequest(
        @NotBlank String productId,
        @Min(1) @Max(99) int quantity,
        @Size(max = 200) String memo
) {
}

public record OrderResponse(
        String orderId,
        String item,
        String status,
        LocalDate eta
) {
    public static OrderResponse from(Order order) {
        return new OrderResponse(
                order.getId(),
                order.getItem().getName(),
                order.getStatus().name(),
                order.getEta()
        );
    }
}

@Entity
class Order {
    @Id
    private String id;
    private String ownerId;      // 내부 전용
    private BigDecimal cost;     // 외부에 노출하면 안 되는 원가
}

DTO 변환 위치는 팀 규칙에 따라 다를 수 있지만, 중요한 것은 한 방향으로 일관되게 두는 것이다. 위 예시는 응답 DTO의 from() 메서드에 변환을 모았다.

JPA Repository와 MyBatis Mapper

둘 다 데이터를 다루지만 기준은 다르다. 객체와 엔티티의 상태 변경이 중심이면 JPA가 편하고, 복잡한 SQL을 직접 제어해야 하면 MyBatis Mapper가 편하다. 한 프로젝트에서 함께 써도 된다.

구분JPA RepositoryMyBatis Mapper
중심객체, 엔티티, ORMSQL
SQL 작성기본 CRUD는 JPA가 생성개발자가 직접 작성
잘 맞는 작업단건 CRUD, 엔티티 상태 변경동적 검색, 집계, 통계, 리포트
반환값엔티티와 영속성 컨텍스트조회 DTO나 값
성능 튜닝생성된 SQL을 확인하며 조정작성한 SQL을 직접 조정
// JPA
@Entity
public class User {
    @Id
    @GeneratedValue
    private Long id;
    private String name;
}

public interface UserRepository extends JpaRepository<User, Long> {
}

userRepository.save(user);
userRepository.findById(1L);
// MyBatis
@Mapper
public interface UserMapper {

    @Select("SELECT id, name FROM users WHERE id = #{id}")
    User findById(Long id);

    @Insert("INSERT INTO users(name) VALUES(#{name})")
    void save(User user);
}

userMapper.save(user);
userMapper.findById(1L);

Service 입장에서는 둘 다 저장소 역할을 하는 협력자다. 다만 실제 권한 조건은 조회한 뒤 자바에서 거르는 것보다, 쿼리 조건에 포함해서 처음부터 가져오지 않게 하는 편이 안전하다.


Spring AI는 어디에 둘까?

AI를 Controller에 바로 붙이면 처음에는 빨라 보이지만, 프롬프트, 도구, 보안, 메모리, 검색 정책이 섞여 나중에 관리하기 어려워진다.

Controller
  → Service
    → ChatClient
      → Advisor 체인
        → 필요하면 RAG 검색, Tool 호출
  • Controller는 질문과 세션 ID를 받고 서비스만 호출한다.
  • Service는 업무 규칙에 맞게 프롬프트와 도구 사용 여부를 결정한다.
  • Config와 Advisor는 모델 설정, 메모리, 보안, 감사처럼 공통으로 필요한 일을 맡는다.
  • RAG는 문서 인제스트, 검색, 근거 조립을 맡는다.
패키지 예시책임바뀌는 이유
configChatClient, Advisor, 기본 옵션 조립모델 또는 공급자 변경
service업무 흐름, 프롬프트 조립업무 규칙 변경
rag문서 적재, 검색, 근거 구성문서와 검색 품질 변경
tools모델이 호출할 수 있는 실제 행동연동 시스템 추가
advisor로깅, 안전, 메모리, 감사보안과 운영 정책 변경
webREST, SSE API화면 요구 변경
eval골든 세트와 품질 기준품질 목표 변경

/api/chat 요청 한 번의 흐름

POST /api/chat
  → ChatController: 인증 확인, 질문과 세션 ID 전달
  → AuditAdvisor: 감사 기록 시작
  → SafetyAdvisor: 위험 입력 차단
  → MemoryAdvisor: 같은 세션의 대화 이력 추가
  → RetrievalService: 관련 문서 검색, 근거 추가
  → HelpDeskService: 프롬프트 조립, 모델 호출
  → OrderTools: 모델이 필요할 때만 주문 정보 조회
  → TokenMeter: 토큰과 지연 시간 기록
  → AnswerDto: 답변, 출처, 도구 사용 여부를 반환

여기서 순서가 중요하다. 안전 검사는 메모리 저장이나 외부 도구 호출보다 먼저 실행해야 한다. 그리고 주문 정보의 권한 검증은 프롬프트가 아니라 Repository 쿼리나 Tool의 실제 코드에서 다시 확인해야 한다.


Spring AI의 세 가지 핵심 추상화

Spring AI는 특정 AI 공급자의 SDK에 바로 묶이지 않도록 공통 인터페이스를 제공한다. 중심에는 ChatModel, EmbeddingModel, VectorStore가 있다. 실무에서는 저수준 ChatModel을 직접 쓰기보다 ChatClient로 감싸 사용하는 경우가 많다.

추상화하는 일사용 예
ChatModel프롬프트를 받아 대화 응답을 생성챗봇, 요약, 분류
EmbeddingModel텍스트를 의미 벡터로 변환문서, 질문 임베딩 생성
VectorStore벡터를 저장하고 유사한 문서를 검색RAG의 근거 검색
@Service
public class EmbedService {

    private final EmbeddingModel embeddingModel;

    public EmbedService(EmbeddingModel embeddingModel) {
        this.embeddingModel = embeddingModel;
    }

    public float[] embed(String text) {
        return embeddingModel.embed(text);
    }
}

이 세 가지를 조합하면 챗봇, 문서 검색, RAG, 도구를 사용하는 에이전트까지 확장할 수 있다.

공급자 독립성과 옵션

내 코드는 ChatClient, ChatModel 같은 Spring AI 추상화에 의존하고, 실제 모델 선택은 스타터 의존성과 application.yml에서 한다. 그래서 공통 기능만 쓴다면 개발 환경은 가벼운 모델, 운영 환경은 더 성능 좋은 모델로 비교적 쉽게 바꿀 수 있다.

구분공통 옵션 예공급자 고유 옵션 예
모델 선택model공급자별 모델 식별자
창의성temperature, topPfrequencyPenalty, presencePenalty 등
길이 제한maxTokens 계열공급자별 완료 토큰 옵션
출력 형식구조화 출력 설정JSON Schema 같은 공급자별 세부 설정
추론 설정공통화되지 않을 수 있음reasoning effort, thinking 등

공급자 고유 옵션은 필요한 경우에만 쓴다. 그 옵션을 쓰는 코드만큼은 해당 공급자에 의존하게 된다는 점을 알고 경계를 나누면 된다.


핵심만 다시 정리

주제기억할 한 문장
객체 지향객체가 자기 책임을 지고 협력하게 만든다.
계층 구조Controller는 HTTP, Service는 업무, Repository와 Mapper는 데이터 접근을 맡는다.
DTOAPI에 필요한 값만 주고받고, 엔티티는 외부에 그대로 노출하지 않는다.
RAG문서를 검색해 근거와 함께 모델에게 전달하는 방식이다.
Tool판단은 모델이 하더라도 실제 실행과 권한 검증은 우리 코드가 한다.
Spring AIChatModel, EmbeddingModel, VectorStore를 중심으로 AI 기능을 Spring 방식으로 조립한다.
안전차단은 저장과 외부 호출보다 앞에 두고, 권한은 프롬프트가 아니라 코드와 쿼리로 검증한다.
PREVIOUS전체 데이터 구조NEXT현대 LLM 워크플로의 패턴
DISCUSSION

COMMENTS

GitHub 계정으로 로그인하여 댓글을 남길 수 있습니다. 댓글은 GitHub Discussions에 공개 저장되며, 작성 내용과 GitHub 프로필 정보가 다른 방문자에게 보일 수 있습니다.

GitHub 로그인 후 댓글 쓰기Discussion 열기
DOCUMENT STRUCTURE

이 문서에는 목차가 없습니다.

DOCUMENT INFO
TYPE
Markdown
DATE
2026.08.18
READ
1 min read
WORDS
0
CATEGORY
Backend / SPRING AI
RELATED DOCUMENTS
이번 강의는 무엇을 노리고 있을까?23쿠버네티스 입문Kafka의 핵심 설계 원리Kafka 메시징 시스템의 구성과 동작 방식
main Backend / SPRING AI
1 min readUTF-8Markdown
본문 글씨 크기
RECENTLY OPENED1
Spring AI를 배우기 전에 정리할 것recently opened