유사 사례 검색 수정 플로우 설계 플랜

JERRY·2025년 12월 15일

Project

목록 보기
10/14

수정 설계 플랜

1. 핵심 설계 원칙: “질문을 먼저 분해하고, 그에 맞는 검색 플랜을 선택”

입력을 3가지로 분해한 뒤 이를 기반으로 검색 플랜을 동적으로 고름
1. 목적(goal): 보고서 작성 / 유사사례 찾기 / 처분 기준 찾기 / 통계(몇 건) / 규정 근거 확인
2. 제약(constraints): 기관, 기간/연도, 건수, 대상, 금액, 키워드 등
3. 핵심 유사축(similarity axes): 문제점(행위) / 처분(조치) / 절차(규정위반 유형) / 결과(환수 등)

2. “플랜 선택형” 구조

공통 0단계: Slot/Intent 추출(항상 수행) → 이후 파이프라인 선택 유리

  • LLM + 규칙(날짜)로 아래를 JSON으로 추출:
    • goal
    • constraints (org, date_range, count, amount…)
    • axes (issue/action/procedure/result 중 어떤 축이 중요한지)
    • missing_slots (추가로 물어봐야 할 정보)

3. 대표 검색 플랜 4종

Plan A) 제약이 강한 케이스: “필터 먼저, 유사도는 나중”

  • 기관/기간/연도/대상 등 조건이 명확하거나, 결과를 특정 범위로 한정해야 할 때
    예: “작년 A기관 복무 관련 경고 처분 사례 5건”
  • 메타데이터 필터(기관/기간/연도/유형)로 후보군 축소
    → 이 후보군 내부에서 issue/action 유사도 + rerank
  • 조건 준수(기관/기간)가 매우 강함
    오탐이 줄어듦

Plan B) 정보가 부족한 케이스: “유사도 먼저, 필터는 보조”

  • 질문이 짧고 모호하거나 제약이 거의 없을 때
    예: “병가 중 해외여행 처분 사례 찾아줘”
  • issue 중심 dense/hybrid 검색으로 넓게 후보 확보(리콜 우선)
    → 후보에서 action/procedure 메타를 추출해 클러스터링/그룹핑
    → 사용자에게 “주요 처분 패턴 3가지”로 요약 + 추가 질문 유도
  • 질문이 불완전해도 시작 가능
    추가 질문으로 자연스럽게 정밀화 가능

Plan C) “처분/수위”가 핵심인 케이스: “처분 축을 우선”

  • 사용자가 “적정 처분/수위/징계 기준”을 묻는 경우
    예: “병가 기간 해외여행한 직원, 적정 감사처분은?”
  • action(처분/징계수위) 중심 후보군 확보(메타 + 키워드)
    → 그 안에서 issue 유사도 + rerank
    → 출력은 “처분 기준으로 유사사례 묶음 + 각 묶음의 대표 근거”
  • 멘토가 말한 “처분 기준으로 고르고” 요구에 정확히 부합
    실무에서 납득하기 쉬움(처분 중심으로 제시)

Plan D) “몇 건/추세”가 핵심인 케이스: “집계 우선, 사례는 샘플링”

  • “올해/작년 몇 건”, “기관별 몇 건”, “최근 증가 추세” 등 통계형 질문
    예: “작년 개인정보 오남용 지적 몇 건이야? 기관별로”
  • 제약(기간/기관/주제)으로 집계 쿼리
    → 결과 테이블/그래프 + 대표 사례 3~5건 샘플로 첨부
  • “건수” 요구를 제대로 만족
    단순 TopK 나열보다 훨씬 설득력 있음

4. 플랜을 고르는 기준(룰)

Slot/Intent 추출 결과를 보고 아래처럼 결정

  • constraints가 2개 이상(기관+기간 등)이고 명확하면 → Plan A
  • goal이 처분 추천/수위면 → Plan C
  • goal이 건수/추세면 → Plan D
  • 그 외(모호/정보 부족) → Plan B

5. Langflow에서 구조를 어떻게 잡나(구현 관점)

공통 모듈

  • Slot/Intent Extractor (+ DateNormalizer)
  • Evidence Pack Builder
  • Report Draft / Search Answer Generator

플랜별 서브플로우(브랜치)

  • Branch A: Filter-first retrieval
  • Branch B: Similarity-first retrieval
  • Branch C: Action-first retrieval
  • Branch D: Aggregation-first retrieval

그리고 상위 라우터가 (1), (2)를 결정

  • (1) search vs report
  • (2) search라면 Plan A/B/C/D

6. 출력도 플랜별 포맷을 다르게 지정

  • Plan B는 “추가 질문 유도”가 있어야 좋고
  • Plan D는 “집계 결과 + 대표 사례”가 있어야 좋습니다.

필수 전제 사항

1. 데이터/메타데이터가 “필터 가능한 형태”로 정규화되어 있어야 함

  • 기관 표준값 org_norm: 표기 흔들림(약칭/오타) 없이 필터 가능해야 함
  • 기간/연도 필드 audit_start_date, audit_end_date, audit_year: “올해/작년/최근 3년”을 범위로 걸 수 있어야 함
  • 처분/조치 분류 action_type(또는 action_level): “경고/주의/징계/시정/환수…”를 코드화
  • 문제점 분류 issue_type(또는 problem_category): “복무/개인정보/계약/회계…” 같은 축이 있어야 함
  • 문서/사례 단위의 고유키: doc_code/sub_code 같은 “케이스를 묶는 키”

2. “질문 슬롯 추출”의 스키마가 고정돼야 함

플랜 선택형 구조의 출발점은 항상 “질문을 구조화(JSON)”하는 단계
따라서 라우터/슬롯 추출기의 출력 스키마를 고정

  • goal: 유사사례/처분추천/통계/보고서수정 등
  • constraints: org, date_range, count, amount…
  • axes: issue/action/procedure 중 무엇이 중요?
  • missing: 추가 질문할 항목 리스트

3. “시간 표현(올해/작년…) 정규화”는 규칙 기반 보정이 필요

LLM만으로 “올해/작년/최근”을 처리하면 케이스마다 엇나갈 수 있음. 따라서 다음은 룰 기반으로 한 번 더 보정 필요

  • 올해 = 현재연도
  • 작년 = 현재연도-1
  • 최근 N년 = [현재-N+1, 현재]
  • “상반기/하반기/분기” 같은 표현 처리

4. 검색 단위를 확정해야 함 (Case vs Chunk)

유사사례를 “문서/사례(case) 단위”로 찾는 건지, “청크(chunk) 단위”로 찾는 건지 전제가 필요

  • Case 단위 추천(실무형): “이 사건과 비슷한 감사사례”는 보통 케이스 단위가 맞음
  • Chunk 단위는 근거 발췌에는 좋지만, 유사사례 “선정”의 단위로 쓰면 산만해짐
    → 1차 후보 = case_id 수준 / 근거팩 = 그 case의 상위 chunk들

플랜 적용 가능성

Plan A) 제약이 강한 케이스: “필터 먼저, 유사도는 나중”

  • 선택 기준: 기관/기간/연도/대상 등 조건이 명확하거나, 결과를 특정 범위로 한정해야 할 때
    • constraints ≥ 2 (예: 기관+기간, 기관+분야 등)이고 값이 명확
    • 예: “환경부 + 2023~2024 + 통보 사례”
  • 적용 가능성: 높음
    • 하드 필터 축인 audit_field/category/기간 커버리지가 높습니다(결측 0~5.8% 수준)
    • Plan A는 데이터 품질 측면에서 가장 안정적으로 결과를 낼 수 있을 것으로 예상
  • 위험 구간
    • 기관(category) 매칭 실패: 표기 변형(“환경부/환경부(본부)/환경부 산하기관”)
    • 기간이 너무 좁아 0건: 특히 “올해/작년”을 잘못 해석하거나 범위를 너무 타이트하게 잡을 때
    • 필터를 AND로 과도하게 걸어 0건: 기관+기간+처분까지 모두 강제하면 급격히 비어짐
  • 필수 가드레일
    • 필터 결과가 0~소수면 자동 완화:
      기간(올해→최근2년→최근5년) → 기관(정확→부분/동의어) → 처분은 하드 필터가 아니라 “가점”으로

Plan B) 정보가 부족한 케이스: “유사도 먼저, 필터는 보조”

  • 선택 기준
    • 모호/정보 부족(기관/기간 등이 불명확)
    • 또는 Plan A 실행이 빈약해서 fallback이 필요할 때
  • 적용 가능성: 높음
    • 메타데이터가 비어 있어도 chunk_text 임베딩 검색은 항상 가능
    • 결과 품질은 “케이스 단위 묶기”와 “중복/쏠림 제어”에 달려있음
  • 위험 구간
    • 청크 단위로만 TopK를 뽑고 케이스로 묶지 않음 → 같은 케이스만 잔뜩 나옴
    • 필터를 사후에 너무 강하게 적용 → 유사도 TopK가 전부 날아가고 빈 결과
  • 필수 가드레일
    • “유사도 TopK(청크)” → sub_code로 그룹핑해서 케이스 후보로 만든 뒤, 그 케이스 후보에만 필터를 약하게 적용(또는 점수 가산)

Plan C) “처분/수위”가 핵심인 케이스: “처분 축을 우선”

  • 선택 기준
    • goal이 처분 추천/수위(징계 수준, 통보/주의/시정/징계 등)
    • 예: “병가 중 해외여행 적정 처분/수위”
  • 적용 가능성: 중간(조건부 가능)
    • action_type이 케이스 기준 56.5% 결측이라서, “처분 축 우선”을 하드 필터로 구현하면 절반 이상이 시작부터 제외됨
      • 처분을 “필터”가 아니라 “우선순위/가점(soft)”로 사용
      • 전처리로 action_type을 채우는 backfill이 선행
  • 위험 구간
    • 처분을 하드 필터(@> 등)로 걸면 빈 결과/표본 편향
    • 처분이 비어 있는 케이스가 많아 “처분 우선”이 실제로는 “처분 있는 소수 케이스만 반복 노출”로 변질
    • “수위 추천”은 근거(기준/규정)가 필요한데 criteria가 66.9% 결측이라 근거 생성이 약해짐
  • 예상 구현 방법
    • 후보 생성은 Plan A/B 방식으로 넓게 확보
    • 그 다음 처분(action_type)이 있으면 가점 + “OR 성격 포함(&&)” 정도만 적용
    • 처분이 없으면: action 텍스트/본문에서 처분 단서 키워드로 약한 가점
    • 결과가 부족하면 자동으로 Plan B로 전환

Plan D) “몇 건/추세”가 핵심인 케이스: “집계 우선, 사례는 샘플링”

  • 선택 기준
    • goal이 건수/추세/비율/증
    • 예: “최근 3년 환경 분야 통보 건수 추이”, “기관별 징계 비중”
  • 적용 가능성: 중간(집계 축에 따라 달라짐)
    • audit_field는 100%라 집계 축으로 괜찮음
    • 기간은 결측이 약 5.8% 케이스에 존재 → 추세 집계 시 누락/왜곡 가능(보정 필요)
    • 처분(action_type) 기반 집계는 큰 편향 위험: action_type 결측이 56.5%라서 “징계 건수” 같은 집계는 ‘기록된 것만’의 추세가 됨
  • 위험 구간
    • 집계를 chunk 기준으로 하면 100% 왜곡 → 케이스 단위 집계
    • 시간축 정의가 흔들림
      • audit_end_date 기준? doc_upload_date 기준? 둘이 섞이면 추세가 왜곡
    • 처분 기준 집계 편향
      • action_type이 없는 케이스가 절반 이상 → “징계/주의 비중”을 계산하면 ‘관측된 처분만’의 비중이 됨
  • 권장 가드레일
    • 추세/건수 질의는 기본적으로:
      • 시간축을 하나로 고정(권장: audit_end_date, 없으면 doc_upload_date로 보정)
      • COUNT(DISTINCT sub_code)로 집계
    • 처분(action_type) 기준 추세는 반드시 결과에 주석/경고:
      • “action_type 기재된 케이스만 집계한 값”임을 명시하거나,
      • 전처리 backfill 이후에만 공식 지표로 사용

“플랜 선택 룰” 자체의 위험 구간

  • constraints_count 판정 오류
    • “올해/작년/최근”이 기간으로 인식되지 않으면 Plan A로 못 감
  • goal 오인식(검색 vs 보고서/추천)
    • Plan 선택이 아니라, 상위 라우팅(검색/보고서)부터 오분기되면 전체가 깨짐
  • Plan C/D로 갔는데 데이터가 못 받쳐주는 경우
    • action_type/criteria 결측 때문에 C/D는 반드시 fallback을 가져야 함

0개의 댓글