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"
분기 함수에서 점수 계산까지 하면 복잡해집니다.
판단 재료는 노드가 미리 만들어둡니다.