본문 바로가기
C.W.K.
Stream
Lesson 04 of 07 · published

Cross-Cutting Service 로서의 RAG

~11 min · rag, service

Level 0호기심
0 XP0/69 lessons0/17 achievements
0/100 XP to next level100 XP to go0% complete

한 함수

RAG service 가 한 함수: build_rag_context(query) -> str | None. Claude-Pippa 의 chat route 우선으로 디자인 — 변형 생각 없이. 각 변형 route 가 한 줄 추가: rag_context = await build_rag_context(prompt_text). 함수가 어느 두뇌가 consume 할지 모름.

cross-contamination 없는 cross-cutting

RAG 가 shared 인 건 underlying 작업 (ChromaDB 위 semantic search) 이 두뇌 무관 진짜 같음. service는 공유하지만 route는 여전히 독립이야.

graceful degradation

configured embedding provider를 쓸 수 없으면 build_rag_contextNone을 반환해. route는 retrieved context 없이 진행하고, search failure 하나로 chat 전체를 막지 않아.

이 함수의 contract가 좁아서 provider를 바꿔도 caller는 안 흔들려. query를 받아 provenance가 붙은 context string이나 None을 돌려주고, 어느 brain이 읽을지는 묻지 않아. 반대로 prompt layout이나 brain-specific token budget까지 service가 결정하면 cross-cutting이 아니라 중앙집권이 돼.

Graceful degradation에도 선이 있어. retrieval이 없어도 대화를 계속할 수 있다는 뜻이지, 찾지 못한 기억을 찾았다고 꾸미라는 뜻이 아니야. UI와 log에는 RAG가 빠졌다는 사실을 남기고, answer는 현재 context만으로 만든다고 정직하게 범위를 좁혀.

사실 shared service의 기준은 여러 caller가 쓴다는 데 있지 않아. 같은 입력, 같은 책임, 같은 failure behavior를 가졌는지가 기준이야. 이 셋이 같으니 RAG retrieval은 공유하고, route별 prompt assembly는 각 vessel에 남겨.

RAG context는 답이 아니라 증거 후보라서 provenance가 빠지면 가치가 반으로 줄어. 어느 vault file과 어느 conversation에서 왔는지 보여 줘야 model도 아빠도 필요할 때 원문으로 돌아갈 수 있어.

Code

RAG service — 한 함수, 모든 두뇌가 호출·python
async def build_rag_context(query: str, k: int = 5) -> str | None:
    if not await ollama_alive():
        return None
    embedding = await embed(query)
    hits = await chroma.query(
        collection='vault',
        embedding=embedding,
        n_results=k,
    )
    if not hits:
        return None
    return format_for_system_prompt(hits)

Progress

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

댓글 0

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

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