C.W.K.
Stream
Lesson 04 of 05 · published

Update, Delete, Re-embedding

~20 min · chroma, lifecycle

Level 0Scout
0 XP0/41 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

id 로 upsert

재-ingest 할 때 collection.upsert() 사용. id 있으면 update, 없으면 insert. 이게 idempotent ingest 파이프라인과 두 번째 실행에서 폭발하는 파이프라인의 차이야.

tombstone 으로 soft-delete, id 로 hard-delete

audit-friendly 시스템은 삭제된 청크에 metadata {'deleted': True} 마크 + query 시점에 제외. 프로덕션 cleanup 에는 collection.delete(ids=[...]) 로 물리적 제거.

Re-embedding 전략

임베딩 모델 전환은 모든 벡터 재빌드 필요. 두 패턴:

  • side-by-side collection. docs-bge-m3-v1 옆에 docs-bge-m3-v2 빌드. 준비되면 read pointer 전환. 일주일 뒤 v1 삭제.
  • in-place 재빌드. id 순회, 재임베딩, upsert. 작은 collection 에서는 OK; 큰 거에서는 위험 — 재빌드 중 query consistency 잃음.

항상 side-by-side 선호. rollback path 가 그냥 "v1 가리키게 되돌려놓기".

Code

upsert 로 idempotent ingest·python
docs.upsert(
    ids       =[c['id']       for c in chunks],
    documents =[c['text']     for c in chunks],
    metadatas =[c['metadata'] for c in chunks],
    embeddings=vecs,
)
side-by-side 재임베딩 마이그레이션·python
src = client.get_collection('docs-bge-m3-v1')
dst = client.get_or_create_collection('docs-bge-m3-v2',
                                      metadata={'hnsw:space': 'cosine'})

batch = src.get(include=['documents', 'metadatas'])
new_vecs = new_model.encode(batch['documents'], normalize_embeddings=True).tolist()

dst.upsert(
    ids       =batch['ids'],
    documents =batch['documents'],
    metadatas =batch['metadatas'],
    embeddings=new_vecs,
)
# dst.count() == src.count() 되면 앱 config 의 read pointer 전환

External links

Exercise

미니 side-by-side 마이그레이션 빌드: collection v1 에 청크 200개 (모델 1개), v2 로 복사 (다른 모델), 같은 query 5개 양쪽에 돌려서 top-3 overlap 보고. 그 숫자가 본인 마이그레이션 risk budget.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.