Hyeok의 웹 개발 블로그

<2025.08.07> Embedding 기능 및 VectorStore 기능 본문

TIL/AI

<2025.08.07> Embedding 기능 및 VectorStore 기능

Yhyeok 2025. 8. 7. 21:49

1️⃣개요

  • 사용자의 자연어 요청을 단순 키워드가 아닌 의미 기반으로 분석하고, 이에 가장 적절한 강의를 추천하는 시스템
  • 이를 위해 OpenAi의 임베딩 모델을 사용해 강의 콘텐츠와 사용자 입력을 벡터로 변환하고, VecotorStore(PGVector)를 이용해 이 벡터 간의 유사도를 계산하여 가장 유사한 강의를 빠르게 찾는다.
  • 이 시스템은 정확한 추천뿐만 아니라, 사용자의 재질문이나 조건 변경에도 유연하게 대응할 수 있는 구조를 갖추고 있다.
  • 프로젝트 초기에는 벡터 저장 방식을 SimpleVectorStore를 사용했습니다. 하지만 프로젝트를 진행하며 PgVectorStore 로 변경하여 구현하였습니다.

2️⃣기술 도입 배경

🔹 임베딩의 필요성

  • 컴퓨터가 이해할 수 있도록 텍스트를 수치화
  • 강의 설명을 벡터로 변환해서 DB에 저장 (float[])
  • 사용자가 입력한 검색어 또는 질문도 벡터로 변환
  • 둘의 유사도를 비교해서 가까운 강의를 추천 → pgvector Store에서 유사도 검색

🔹VectorStore 사용 이유

  • 텍스트를 벡터로 변환해 의미가 비슷한 내용 검색 가능
  • 빠른 유사도 검색 가능
    • 코사인 유사도를 사용해 대규모 벡터에서 빠른 검색 가능
  • LLM과 연결성 뛰어남

🔹SimpleVectorStore 에서 PgVectorStore 변경 이유

SimpleVectorStore는 Spring AI 에서 기본으로 제공하는 인메모리 벡터 저장소로 설정이 간단하고 빠르게 기능 구현이 가능하다는 장점이 있습니다. 하지만 프로젝트가 운영환경으로 확장하고 진행됨에 따라 한계점이 발생

  • SimpleVectorStore
    • 벡터 수가 많이 질 수록 검색 기능이 낮아지고 저하되는 스케일링 한계
    • 다중 서버나 배포 환경에서 벡터 공유가 불가능하여 확장성과 안정성이 부족
    • 어플리케이션 재시작 시 저장된 벡터 데이터 모두 초기화
  • PgVectorStore
    • 어플리케이션 재시작 시 벡터가 안전하게 보존
    • 유사도 검색 최적화 : pgvector의 벡터 연산기능을 통해서 cosine기반 고속 검색 가능
    • 다중서버간 데이터 공유가 가능하고 확장성과 유지보수가 뛰어남

3️⃣ 주요 흐름 (초기 구조: 전체 응답 수신 방식)

  1. 사용자 입력 수신
    • 사용자가 자연어로 요청을 보낸다.
  2. 사용자 입력을 입베딩 변환
    • EmbeddingService를 통해 사용자 질문을 임베딩(벡터)으로 변환
    • OpenAi의 Embedding API 사용 (Model : text-embedding-3-small)
      • application.yml에 Ai Model 밑에 Embedding model을 작성
    // application.yml
      ai:
        openai:
          api-key: ${OPENAI_API_KEY}
          base-url: <https://api.openai.com>
          chat:
            options:
              model: gpt-4o-mini
          embedding:
            model: text-embedding-3-small
    
    • 변환 결과는 float[ ]형태의 벡터 데이터
  3. VectorStore에 저장된 강의 데이터와 유사도 검색
    • PGVector가 적용된 PostgreSQL 기반 VectorStore에서 미리 임베딩해둔 강의 정보와 입력 벡터를 비교
    • Cosine Similarity를 통해 유사도 계산
  4. 가장 유사한 강의 추출
    • 유사도가 높은 순으로 정렬
    • 상의 N개의 강의 정보를 추출하여 결과 구성
  5. 응답 생성 및 반환
    • 추천 결과를 사용자에게 자연스러운 문장으로 구성해 응답
    • WebSocket 또는 REST API를 통해 프론트에 전달

 

 


4️⃣ 기술 구성 요소

  SimpleVectorStore  PgvectorStore
저장 방식 메모리 기반 PostgreSQL + pgvector 확장
데이터 유지 비영속성 (서버 꺼지면 사라짐) 영속성 (DB에 저장됨)
유사도 검색 가능 (작은 규모에 적합) 가능 (대규모 최적화됨)
설치 없음 (간단하게 사용) PostgreSQL + pgvector 필요
성능 적은 벡터 수에 빠름 수천~수백만 벡터도 처리 가능
개발 용도 로컬 테스트, 데모 실제 운영 환경, 서비스 구축
     
사용하기 좋은 곳 기능 시연, 빠른 테스트 사용자 데이터 기반 추천 서비스

5️⃣ 결과

  • 사용자의 질문을 의미 단위로 분석하여 가장 유사한 강의를 빠르고 정확하게 추천합니다.
  • 임베딩 기반 유사도 검색을 통해 사용자 질문에 맞는 강의를 의미적으로 매칭한다.

6️⃣ 회고

  • 기술적 회고
    • 단순 GPT 호출하는 것이 전부인 줄 알았지만, 실제로 프롬프트 구성, 의미 파악, 후처리 등이 챗봇의 품질과 성능에 큰 영향으 미쳤다.
    • Embedding 결과는 float 배열이라 가시성이 없어서, 유사도 기준 설정에 많은 실험이 필요
    • LLM이 생성하는 답변이 항상 정답이 아니기 때문에, 추천 결과를 유연하게 해석하고 제어하는 로직 설계가 필요하다는 점을 알게됨.
  • 추후 개선 사항
    • 현재는 키워드를 수집합니다. 수집한 키워드를 기반으로 강의를 추천해주고있습니다. 추후에는 키워드 뿐만아니라, 전체적인 대화 흐름을 지금보다 더 정확하게 분석하고 판단하여 강의를 추천하도록 개선
    • 사용자의 요청이 바뀔 때, 대화 흐름과 추천 상태를 어떻게 이어갈지에 대한 고민이 많았고, 이 부분에 대해서는 아직 개선 가능성이 많다 생각해서 추후 개선하면 성능 향상에 많은 도움이 될 것이라 생각

'TIL > AI' 카테고리의 다른 글

<2025.08.01> 프롬프트 (Zero-Shot, One-Shot, Few-Shot)  (0) 2025.08.01
<2025.06.02> RAG (검색-증강 생성)  (1) 2025.06.02