RAG2026-5일19차시 · Node 이해8 / 19← 이전목차다음 →MetaContents

19차시. Node 이해

5. 실습 ① — Retrieve 노드 만들기

출처: 원본 PDF 19차시_Node이해.pdf 11~12쪽 · 쪽 그림 11쪽 12쪽

📝 src/nodes/retrieve.py

출력
import config
from indexer import get_store
_store = get_store()
def retrieve_node(state: dict) -> dict:
    # 검색만 담당한다. 판단은 하지 않는다.
    query = state.get("query") or state["question"]
    k     = state.get("top_k", config.TOP_K)
    pairs = _store.similarity_search_with_relevance_scores(
        query, k=k)
    # 기준(MIN_SCORE)을 넘는 것만 골라 담기
    docs = []
    for d, s in pairs:
        if s >= config.MIN_SCORE:
            docs.append(d)
    scores = [round(s, 3) for _, s in pairs]
    return {
        "documents":    docs,
        "scores":       scores,
        "retrieval_ok": len(docs) > 0,
        "log":          [f"[retrieve] '{query}' → "
                         f"{len(docs)}/{len(pairs)}건 통과"],
    }
# ── 단독 테스트 ──
if __name__ == "__main__":
    r = retrieve_node({"question": "환불은 며칠 이내인가요?"})
    print("통과 문서:", len(r["documents"]))
    print("점수      :", r["scores"])
    print("검색 성공 :", r["retrieval_ok"])
    print("로그      :", r["log"][0])

실행 결과
──────────────────────────────────────
$ python nodes/retrieve.py

통과 문서: 3
점수      : [0.73, 0.639, 0.489, 0.402, 0.351]
검색 성공 : True
로그      : [retrieve] '환불은 며칠 이내인가요?' → 3/5건 통과

💡 retrieval_ok를 노드가 계산해두는 이유
20차시에서 조건부 Edge를 만들 때
분기 함수가 이렇게 단순해집니다.
def route(state):
return "ok" if state["retrieval_ok"] else "empty"
분기 함수에서 점수 계산까지 하면 복잡해집니다.
판단 재료는 노드가 미리 만들어둡니다.

← 이전 절19차시 · 4. RAG를 어떻게 나눌까?다음 절 →19차시 · 6. 실습 ② — Generate 노드 만들기