진형주@hyoungjoojin · Sep 13, 2026Claude Code(으)로 작성

pgvector 차원이 안 맞아 임베딩을 전부 다시 만든 날

임베딩 모델을 바꿔보려다 하루를 날렸다. 결론부터 말하면 임베딩 모델 교체는 코드 변경이 아니라 스키마 마이그레이션이다.

무슨 일이 있었나

post_embeddings.embedding 컬럼은 이렇게 정의돼 있다.

embedding VECTOR(1536)

1536은 text-embedding-3-small의 출력 차원이다. 검색 품질을 올려보려고 더 큰 모델로 바꿨더니 삽입 시점에 바로 터졌다.

ERROR: expected 1536 dimensions, not 3072

VECTOR(n)의 n은 하드 제약이다. 문자열 길이 제한처럼 넘으면 잘리는 게 아니라, 그냥 거부한다.

왜 간단히 못 바꾸나

차원을 바꾸려면 컬럼 타입을 바꿔야 하고, 그러면 기존 벡터가 전부 무효가 된다. 다른 모델이 만든 벡터는 서로 비교가 불가능하다. 같은 공간에 있지 않기 때문이다.

즉 필요한 건 세 가지다.

  1. 컬럼 타입을 바꾸는 Liquibase changeset

  2. 기존 벡터 전량 삭제

  3. 모든 글에 대한 임베딩 재생성 백필

3번이 진짜 비용이다. 글 수에 비례해 API 호출이 나가고 돈이 든다. "모델만 바꿔보자"가 아니었다.

결정

지금은 text-embedding-3-small(1536)을 유지하기로 했다. 검색 품질 개선은 모델 교체 말고 RRF 가중치 튜닝 쪽에서 먼저 찾기로 했다. 비용이 0이고 되돌리기도 쉽다.

같이 알아둘 것

프로덕션에서는 AI 기능이 꺼져 있다.

AI_EMBEDDING_PROVIDER=none
AI_FEATURES_ENABLED=false

그래서 지금 프로덕션에 쌓이는 글에는 벡터가 없다. 하이브리드 검색은 pg_trgm 단독으로 조용히 성능이 낮아지고, 관련 글 추천은 빈 배열을 돌려준다. 에러가 안 나기 때문에 모르고 지나가기 쉽다.

나중에 AI를 켜는 날, 그동안 쓰인 모든 글에 대한 백필이 반드시 필요하다. 켜는 것만으로는 아무 일도 일어나지 않는다. 지금 여기 적어둔다.

댓글

아직 댓글이 없습니다.