audit_rag_1~5 플로우를 기준으로, 버전별(각 노드 기준) 역할/원리/변경점/설계 이유/권장 파라미터를 정리한 내용입니다.
(노드는 A/B/C 브랜치에 동일한 컴포넌트가 복제되어 있는 경우가 많아, 설명은 “노드 유형” 단위로 1회만 상세히 작성하고, “어느 브랜치에 몇 개” 형태로 병기했습니다.)

0) 공통 아키텍처 계약(Data Contract)
공통 입력/중간 산출물
-
user_question (Message): 사용자 원문 질문
-
stage1_payload (Message JSON): Stage1(LLM Router)이 만든 “의도/슬롯/키워드/플랜선택/필터” 통합 JSON
- v2~에서 안정화를 위해 “LLM 실패 시 rule fallback으로도 반드시 JSON을 내보내는” 설계로 변경
-
stage1_bundle (Message JSON): Stage1 산출물(라우터 JSON/선택 플랜/필터/키워드)을 Stage2가 쓰기 쉬운 형태로 패키징
-
stage2 payload (Message JSON): A/B/C 각각에 전달될 payload. v2~에서는 enabled가 주입되어 Gate가 downstream을 차단할 수 있습니다.
-
candidates (DataFrame): Postgres Retriever 출력
-
grouped (Message JSON): “대표 사례” 단위(case)로 묶인 결과
-
evidence_pack (Message): 프롬프트에 바로 붙일 수 있는 표준 텍스트(근거팩)
-
final_bundle (Message JSON): ABC Guard가 선택한 최종 route + evidence_pack + debug + requested_cases
-
final_prompt (Message): Prompt Template Switch가 최종 생성한 LLM 입력 프롬프트
1) audit_rag_1 (Base) — 노드별 상세 설명 (전체 구조 기준)
1.1 Stage1: 의도/슬롯/키워드/플랜 선택
(1) Stage1 LLM Router (OneOut)
- 역할: 질문을 LLM으로 파싱/분류하고, 플랜(A/B/C) 및 필터/키워드를 만들어
stage1_payload 1개로 출력.
- 원리
- OpenAI Responses API를 호출해 JSON을 받는 방식(“json_object” 포맷).
- 실패 시 rule 기반 fallback 로직이 존재(법령/조항/처분류 → C 우선 등).
- 설계 이유
- 라우팅/필터가 downstream 성능(특히 Recall)에 직접 영향을 주므로, “한 번에” 구조화.
- 다만 v1은 “LLM 응답 품질/형식 불안정”이 발생할 수 있어 이후 버전에서 Stable로 강화됨.
- 권장 파라미터(기본값)
- model:
gpt-5-mini
- temperature: 0
- max_output_tokens: 1200 (v1 기본)
- category_hint: 필요 시만(운영에서는 고정값으로 숨기는 편이 안전)
(2) Stage1 Payload Unpacker (MultiOut)
- 역할:
stage1_payload(JSON)을 router_json / selected_plan / filter_params / keywords_csv로 분리.
- 원리: 단순 JSON parse 후 키별 Message 출력.
- 설계 이유: Langflow에서 포트 연결/타입 문제를 줄이기 위해 “MultiOut로 명시 분리”.
- 권장 파라미터: 없음(구조 변환 노드)
(3) Stage1 Bundle Builder
- 역할: Stage1 산출물(라우터/선택플랜/필터/키워드)을 Stage2가 참조하기 쉬운 고정 스키마 JSON으로 재패키징.
- 원리:
selected_plan 정규화 + shortcut 필드(intent, requested_cases 등) 제공.
- 설계 이유: Stage2/Guard/Prompt 단계에서 “어느 필드를 어디서 꺼낼지” 일관성 확보.
1.2 Stage2: 플랜별 payload 생성/게이팅
(4) Stage2 Route Selector
- 역할: stage1_bundle + (키워드 override/prefilter 등)을 조합해 plan payload를 생성.
- 원리: 버전에 따라 A/B/C payload 생성 방식이 달라 이후 버전에서
Stage2RouteSelectorABCStable로 통합됩니다.
- 변경점(후속 버전): v2부터
enabled 주입 + 최종 route 확정 안정화(아래 v2에서 상세).
(5) Plan Enable Switch
- 역할: 선택된 플랜에 따라 A/B/C enable(bool)을 생성. (v2~에서는
always_run_b 같은 운영 옵션이 포함됨)
- 원리: selected_plan 판독 후 “true/false Message” 출력.
- 설계 이유: Langflow에서 브랜치 실행을 “게이트 노드”로 통제하기 위해.
- 권장 파라미터
- v1에선 단순 on/off,
- 운영 안정성 관점에서는 v2~처럼 “항상 B fallback 가능” 옵션 추가.
(6) Plan Payload Gate
- 역할: enable=false일 때 payload를 빈 Message 또는 None으로 만들어 downstream 실행/토큰 낭비를 방지.
- 원리: enable 파싱 → disabled면 return_empty/return_none 정책 적용.
- 설계 이유: “선택되지 않은 플랜의 Retriever/LLM이 실행되는 문제”를 구조적으로 차단.
1.3 Retrieval 공통: “DF 후보 → Rerank → Case 그룹핑 → Evidence Pack”
(7) Postgres Hybrid Retriever (Plan A Filtered)
- 역할: Prefilter로 좁힌 sub_code 집합 안에서 Vector + Keyword 검색. (distance 기반 + keyword bonus)
- 원리: pgvector distance + ILIKE keyword hit 조합, id 기반 dedup/merge.
- 설계 이유: Plan A는 “필터 기반 정밀 검색”이 목표라 prefilter가 핵심.
- 권장 파라미터(기본값 예시, v5 기준)
- top_k_vector=100
- top_k_keyword=80
- max_keywords=8
- Recall이 부족하면 top_k_vector부터 150~300으로 올리고, 키워드가 과도하면 max_keywords를 6~8로 제한.
(8) Prefilter Candidates (SQL)
- 역할: filter_params로 sub_code 후보를 미리 좁힘(Plan A 전용).
- 원리: category/audit_type/org 등을 약하게(where 조건 최소화) 적용해 recall 급락 방지.
- 권장 파라미터
- max_candidates=500(기본) → A에서 “너무 빈번히 0건”이면 1000~3000까지 확대.
(9) Plan A Embedding Query Builder
- 역할: user_question + filter_params를 조합해 embedding query를 구성(빈 입력 방어 포함).
- 원리: “질문 + 기관/카테고리/감사유형/키워드”를 파이프(|)로 묶어 임베딩 안정화.
- 권장 파라미터: 없음(문자열 조립)
- 역할
- Embedder: query를 OpenAI embedding으로 변환
- Extractor: downstream(Postgres)에서 파싱 가능한 JSON list 형태로 정규화
- 권장 파라미터
- model:
text-embedding-3-large
- 입력이 비면 “빈 임베딩”이 되므로 upstream에서 user_question이 빈 값으로 전달되지 않도록 Stage1/Relay 연결.
(11) Postgres Hybrid Retriever (Plan B, law boost)
- 역할: B는 “범용 사례 검색(Recall)”이 목표라 Vector+Keyword 기반으로 넓게 가져오되, 법령 관련 overlap을 약하게 부스팅.
- 원리: topK 후보를 크게 확보 후 soft_bonus/law_bonus 등으로 재정렬.
- 권장 파라미터(대표)
- top_k_vector 200~400
- top_k_keyword 150~300
- law_bonus는 너무 크면 “법령만 매칭되는 엉뚱한 사례”가 튀므로 0.05~0.10 범위에서 소폭.
(12) Postgres Hybrid Retriever (Plan C, Action-first Soft)
- 역할: C는 “법령/조항/기준” 계열 질의에 대해 action/topic 키워드 후보를 먼저 만들고, 필요 시 vector fallback + soft boost.
- 원리
- action_hints(있으면) 우선, 없으면 질문에서 topic 키워드 추출
- candidate_k(후보 풀) → top_k(최종 DF)
- 권장 파라미터
- candidate_k=400~800
- top_k=100~300
- C는 관련_laws/criteria가 비어있는 케이스가 많으면, chunk_text 검색 비중을 높이는 쪽이 안정적.
(13) Cohere ReRanker (DF→DF, MinUI)
- 역할: DF 후보를 Cohere rerank로 재정렬 후 top_n으로 절단. 에러 시 FAIL_OPEN(원본 반환).
- 원리:
chunk_text를 Cohere documents로 보내고 relevance score로 정렬.
- 설계 이유
- pgvector distance만으로는 “질문 의도와의 정합성”이 부족 → rerank로 precision을 회복.
- FAIL_OPEN은 운영 안정성(외부 API 장애 시 전체 플로우 다운 방지).
- 권장 파라미터
- top_n: A는 80~120, B는 40~80, C는 60~100 수준에서 시작
(14) DF Diversify (cap per sub_code) — v3~에서 본격화
- 역할: rerank 전에 sub_code별 과다 중복을 제한(“한 케이스에서 chunk만 수십 개” 문제 완화).
- 원리: group_key(sub_code)별 per_group_limit 만큼만 남기고 max_total까지 자름.
- 권장 파라미터
- per_group_limit=3~7
- max_total=200~500
- Cohere 비용/latency가 크면 max_total을 먼저 낮추는 게 효과가 큽니다.
(15) Case Grouper (by sub_code)
- 역할: 후보 row들을 sub_code/doc_code 단위로 묶어 “대표 사례 케이스”를 만듭니다.
- 원리: best_distance 기준 정렬 + 케이스당 최대 chunk 수 제한.
- 권장 파라미터(v5 기본)
- max_cases=20,
- max_chunks_per_case=10
(16) Case Post-Rerank + Diversity
- 역할: “case 단위” 텍스트를 구성해 Cohere로 다시 rerank하고, doc_code/audit_field 기준 diversity cap을 적용해 최종 케이스를 뽑음.
- 원리
- case_to_text: 문제/조치/기준/법령/메타+첫 chunk를 합쳐 rerank
- pass1: doc_code/audit_field cap 적용
- pass2: 부족하면 cap 완화하여 채움
- 설계 이유
- “대표 사례 최대 N건” 요구는 chunk-level이 아니라 case-level 최적화가 맞음.
- Diversity cap으로 특정 문서/분야가 상위 N을 독식하는 것을 방지.
- 권장 파라미터
- max_cases: 최종 출력 목표가 3이면, post-rerank는 5~8로 두고 마지막에 3으로 절단하는 편이 안정적(다양성 확보)
- max_per_doc_code: 1~2
- max_per_audit_field: 2~3
(17) Evidence Pack Builder (Plan A/B/C)
- 역할: grouped cases를 표준 Evidence Pack 텍스트로 렌더링(근거팩 규격). v5에서 “Standard”로 명확히 규격화.
- 원리:
[Evidence Pack] / [USER_QUESTION] / [ROUTE] / [CASE i] / [CHUNKS] / [DEBUG] 섹션으로 출력.
- 권장 파라미터
- max_cases=3~5
- preview_chars=800~1600 (LLM 입력 길이/정합성 trade-off)
(18) ABC Guard → Final Bundle (OneOut)
- 역할: A/B/C 결과를 받아 선택 플랜을 우선하되, 비어있으면 fallback을 수행해
final_bundle 하나로 통합.
- 원리: (cases_count ≥ min_cases) AND (pack이 비어있지 않음) 조건으로 ok() 판단 후 fallback 탐색.
- 권장 파라미터
- min_cases: 1
- allow_fallback: True
(19) Prompt Template Switch (Stage4)
- 역할: final_bundle을 읽고 search/report 템플릿을 선택해 최종 프롬프트를 생성.
- 원리: evidence pack이 비어있는지([EMPTY] 포함 여부) 등을 보고 모드/프롬프트를 구성.
- 권장 파라미터
- 템플릿은 운영 중 교체가 잦으면 노출, 고정이면 숨김(당신이 원한 “UI 단순화”에 해당)
2) audit_rag_2 — “라우팅 안정화 + fallback” 중심 변경점(노드별)
v2의 핵심은 “항상 Route를 확정하고(enabled 포함), 선택되지 않은 브랜치는 Gate로 확실히 차단”입니다.
2.1 Stage1 LLM Router가 Stable로 변경
- 변경점
- 이름/역할: “Stable, OneOut” (실패해도 rule fallback으로 A/B/C 확정 + debug 포함)
- max_output_tokens 기본값도 조정(예: v5에서는 900)
- 설계 이유
- “생각 중지됨/LLM JSON 파싱 실패/빈 출력”이 downstream 전파되면 전체 플로우가 무너짐 → Stage1에서 항상 스키마를 만족하는 payload를 강제.
2.2 Stage2 Route Selector가 ABCStable로 통합
- 변경점
final_route를 확정하고, A/B/C payload에 enabled를 주입
- 법령/처분 키워드 regex가 있으면 C로 override
- 설계 이유
- “Stage1이 B라고 했지만 사실 C가 맞는 질의(법령/조항/처분)”에서 품질을 안정화.
- Gate가
enabled를 읽어 확실히 downstream 실행을 차단할 수 있게 됨.
2.3 Plan Payload Gate가 표준화
- 변경점
- enable=false면 빈 Message로 차단하는 표준 Gate
- 설계 이유
- “선택되지 않은 Plan이 실행되는 현상”을 코드/엣지 레벨에서 제거.
2.4 Plan B/Plan C Retriever 목적별 강화
- Plan B: law boost
- 법령 overlap에 대한 약한 부스팅(하드필터는 피함)
- Plan C: action-first soft
- law_names(GIN) → action_type(징계/처분 등) → keyword → vector fallback
3) audit_rag_3 — “리랭커(전/후 2단) + Dedup/다양성” 추가(노드별)
3.1 DF Diversify (cap per sub_code) 추가
- 위치: Retriever → Cohere rerank 직전
- 효과: 동일 sub_code에서 chunk가 과다하게 뽑혀 Cohere에 “비슷한 문장만” 들어가는 문제를 완화.
3.2 Case Post-Rerank + Diversity 추가
- 위치: Case Grouper → Evidence Pack Builder 직전
- 효과
- “대표 사례”를 chunk가 아니라 case 레벨로 rerank → 결과 품질(precision) 상승
- doc_code/audit_field cap으로 다양성 확보
4) audit_rag_4 — MultiQuery(키워드 확장) 도입(노드별)
노드 구성은 v3과 동일하지만, Retriever 내부 로직에 “키워드 확장(MultiQuery)”이 추가됩니다.
MultiQuery(키워드-only expansion)
- 원리: 동의어 사전(_SYNONYMS) + 질문에서 추가 키워드 추출 → 키워드 세트를 여러 개 만들어 keyword 검색 recall을 늘림
- 설계 이유
- 감사 도메인은 “표현 변형(부실시공/부실 공사/부실 시공)”이 매우 흔함.
- 임베딩만으로 못 잡는 키워드를 keyword 채널에서 보완.
- 권장 파라미터
- n(세트 개수): 2~4부터 시작(너무 늘리면 SQL 부하/노이즈 증가)
- 사전은 “자주 실패하는 질의”를 기준으로 점진 확장(Plan C 힌트 튜닝과 결합)
5) audit_rag_5 — Evidence Pack 규격화 + 프롬프트 튜닝(진행중)
5.1 Evidence Pack Builder가 “Standard”로 교체
- 변경점: (Plan A/B/C) 모두 “Standard” 빌더로 교체되어 동일 규격 유지
- 설계 이유
- PromptTemplateSwitchStage4가
[EMPTY], [ROUTE], [CASE] 등을 안정적으로 판독 가능.
- 평가(groundedness/consistency)에서 입력 포맷이 흔들리면 점수 해석이 불가능해짐.
5.2 Prompt Template Switch(Stage4) 튜닝
- 변경점: Plan별 목적 템플릿(A/B/C) 강제 분리 / 라우팅 기준 규칙 수정
- A: 구체화된 사례 + 처분(주의/통보/시정/고발/과태료 등)이 결합된 질문 → 처분 중심으로 제시
- B: 유사사례/대표사례/비슷한 사례 등 유사사례 검색 → 사례 표 + 케이스 카드 중심으로 제시(법령 나열은 조연)
- C: 법령/규정/조항/근거를 묻거나, 처분의 기준/수준/추천(처분 자체)을 묻는 질문 → “법령/규정/조항/근거” 또는 “처분 수준·기준·추천(처분 자체)”을 규정 후보 중심으로 제시
5.3 History 기능 추가
- 변경점: History 기능 추가
- Current Message(for session_id)에 현재 질문을 연결하여 세션을 안정적으로 식별
- Messages(Text)를 Stage4의 {history}로 주입