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

뇌가 꺼져도 검색은 돌아

~11 min · determinism, guarantee, offline, availability

Level 0불 꺼진 심지
0 XP0/33 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"테스트는 전부 켜졌을 때 되냐가 아냐. 화려한 부분이 사라졌을 때 뭐가 여전히 되냐야."

새벽 3시 테스트

임베딩-과-rerank 서버가 꺼졌다고 상상해 — 리부팅, 메모리 부족, 플러그 뽑힘, 뭐든 상관없어. 새벽 3시고 2년 전에 쓴 한 줄을 찾아야 해. 모델-경로-안 시스템에선 막혀: 모델 없음, 검색 없음. Lantern 에선 쿼리를 치면 코퍼스가 답해, 네가 가장 의존하는 경로가 모델을 아예 안 만지게 지어졌으니까. 운이나 튀어나온 fallback 이 아냐 — 엔진의 모양이야.

모델을 안 만지는 경로 둘

Lantern 검색 경로 둘은 로컬 인덱스와 네 쿼리의 순수 함수야:

  • 키워드 검색(전문 검색) 은 네 단어를 바로 디스크에 사는 역색인에 매칭해. 네트워크 없음, 모델 없음, 그냥 단어 매칭과 순위 매기기.
  • Phrase 자동완성은 네가 친 것의 연속을 코퍼스에서 캐, 역시 로컬 인덱스에서, 키스트로크 속도로.

둘 다 모델 서버로의 전선이 없어. 모델 서버를 존재에서 지워도 둘은 동일한 결과를 돌려줘.

뭐가, 어떻게 degrade 하는가

모델 서버가 필요한 경로 — dense 벡터 검색, 하이브리드의 벡터 절반, rerank — 는 척하는 대신 정직하게 degrade 해. 순수 벡터 쿼리는 모델이 안 닿으면 명확한 service unavailable 을 돌려줘. 하이브리드 쿼리는 키워드 절반을 내주고 벡터 절반이 건너뛰어졌다고 응답에 표시해. 아무것도 나쁜 결과를 좋은 것처럼 꾸며서 조용히 안 돌려줘. degradation 은 보이고, 이름 붙고, 결정론적 경로엔 절대 전염 안 돼.

기반 경로를 로컬 상태의 순수 함수로 만들어. 사용자가 가장 의존하는 게 네가 이미 쥔 데이터에서, 어떤 네트워크 호출도 없이 계산될 수 있으면, 다른 어디의 outage 도 그걸 못 내려. 원격 서비스엔 향상을 위해서만 손을 뻗고 — 그 손뻗음의 실패가 붕괴가 아니라 이름 붙은 degradation 이 되게 설계해.

보장은 희망이 아니라 구조야

두 번 말할 가치가 있어: 항상-됨 속성은 캐싱도, 재시도 루프도, 넉넉한 타임아웃도 아냐. 그건 실패 확률을 줄이는 패치야. Lantern 의 결정론적 경로는 모델에 연결된 적이 없어서 모델 outage 로 실패할 수 없어. 구조적 보장이 희망적 보장을 이겨 — 안 가진 의존성의 모든 실패 모드를 테스트할 필요가 없어.

Code

FTS 는 모델에 절대 의존 안 해; 하이브리드는 소리 내어 degrade 해·python
def search(query: str, mode: str = "fts") -> Envelope:
    if mode == "fts":
        # Pure local index. No network. Cannot be taken down by a model outage.
        return Envelope(results=fts_match(query), degraded=[])

    if mode == "vector":
        if not model_server.reachable():
            raise ServiceUnavailable("vector search needs the embedding server (503)")
        return Envelope(results=vector_match(query), degraded=[])

    if mode == "hybrid":
        fts_hits = fts_match(query)               # always available
        try:
            vec_hits = vector_match(query)         # best-effort enhancement
            return Envelope(results=fuse(fts_hits, vec_hits), degraded=[])
        except ServiceUnavailable:
            # Serve the half that works — and SAY the other half is missing.
            return Envelope(results=fts_hits, degraded=["vectors_unavailable"])

External links

Exercise

매일 쓰는 것 중 outage 때 잃으면 가장 속상할 기능 하나를 적어. 그게 가진 모든 원격 의존성을 추적해. 각각 결정해: 이 손뻗음이 기능에 필수야, 아니면 우아하게 degrade 할 수 있는 향상이야? 필수 손뻗음 하나를 향상으로 재설계해서, 그 서비스가 꺼져도 코어가 계속 돌게.
Hint
반복되는 이동: 할 수 있는 걸 로컬에 미리 계산하거나 색인해서, 기능이 이미 쥔 데이터에서 답하게. 그럼 원격 호출은 작동하는 답을 더 낫게만 만들지, 답과 빈 화면의 차이가 아냐.

Progress

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

댓글 0

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

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