DOCS/journey/research/260315_companyx_rag_답변합성_시나리오동시종결_리서치.md
2026-03-15 08:59:38 +09:00

13 KiB

tags
tags
research
companyx
rag
answer-composition
scenario
troubleshooting

Company X RAG 답변합성 시나리오·트러블 동시종결 리서치

상위 원칙

목적

  • Company X 근거응답 이슈를 트러블슈팅 + 시나리오 한 문제로 보고, 둘을 함께 닫기 위한 원인 기준을 고정합니다.
  • 현재 실패가 검색 인프라 문제인지, 답변 합성 문제인지, 질문별 하드코딩 구조 문제인지 단일 경로로 좁힙니다.
  • 이 문서는 해결안 확장보다 다음 plan 1건을 만들 수 있을 정도로 직접 원인을 확정하는 데만 집중합니다.

조사 질문

  1. 현재 실패의 직접 레이어는 검색인가, 답변 합성인가
  2. 컴퍼니엑스의 투자사는 몇개야?, 내부 규정 상 휴가는 얼마나 쓸 수 있어?가 왜 깨지는가
  3. 현재 Company X 경로는 일반 규칙 기반인가, 질문별 하드코딩 기반인가
  4. 트러블 문서와 시나리오 문서를 함께 닫으려면 무엇을 plan에서 고정해야 하는가

범위 / 비범위

  • 범위:
    • rb8001의 Company X grounding 진입/검색/응답 합성 경로
    • 재오픈 기준 질문 3개에 대한 처리 구조
    • 프롬프트/if 분기/질문 적합도 선별 구조
  • 비범위:
    • Company X 전체 문서셋 확대 작업
    • skill-rag-file 인덱싱 성능 일반론
    • 다른 프로젝트나 다른 RAG 경로 전면 리팩토링
    • 최종 수정안 구현 자체

사실(Facts)

1. Company X 질문은 의도 분류 전에 전용 grounding 경로로 우선 진입한다

  • route_message()는 사용자 컨텍스트 생성 직후 try_companyx_grounding()을 먼저 호출합니다.
  • 위치:
    • rb8001/app/services/message_service.py:81-93
  • 의미:
    • Company X 질문은 일반 intent/skill 경로 전에 별도 처리됩니다.
    • 따라서 이번 실패는 일반 의도 분류가 Company X 질문을 놓쳤다만으로 설명되지 않습니다.

2. Company X 경로 진입 조건은 팀 ID + 문자열 marker 기반 휴리스틱이다

  • should_handle_companyx_grounding()team_id == COMPANYX_TEAM_ID_looks_like_companyx_grounding_question(message)로만 판단합니다.
  • _looks_like_companyx_grounding_question()근거, 내부 문서, 공동 운영, 컴퍼니엑스, companyx 같은 marker 포함 여부를 봅니다.
  • 위치:
    • rb8001/app/services/companyx_grounding_service.py:28-60
  • 의미:
    • 질문 유형이나 필요한 답변 방식보다 문자열 포함 여부가 우선입니다.
    • 컴퍼니엑스만 들어가도 grounding 경로로 진입할 수 있습니다.

3. 검색 질의 확장은 사실상 질문 2종만 별도 하드코딩돼 있다

  • _build_query_candidates()는 기본적으로 원문 질문 1개를 그대로 사용합니다.
  • 추가 질의 확장은 아래 경우에만 있습니다.
    • 오늘전통 + 옐로펀치
    • X-COURSE
  • 위치:
    • rb8001/app/services/companyx_grounding_service.py:63-91
  • 의미:
    • 투자사 몇 개, 휴가 규정 같은 재오픈 질문은 전용 query expansion이 없습니다.
    • 대표 질문만 상대적으로 유리한 구조입니다.

4. 검색 결과는 질문 적합도 재평가 없이 relevance score 순으로만 합쳐진다

  • _search_companyx_documents()는 후보 질의별 검색 결과를 병합한 뒤 relevance_score 내림차순으로만 정렬합니다.
  • 질문 유형, 문서 종류, 문서-질문 정합성 재평가 단계는 없습니다.
  • 위치:
    • rb8001/app/services/companyx_grounding_service.py:113-127
  • 의미:
    • 검색 hit가 있어도 그 hit가 질문에 맞는 근거인지 다시 검증하지 않습니다.

5. 직접 답 생성은 질문별 if 분기 하드코딩이고, 기본값은 generic 문장이다

  • _build_direct_answer()는 아래 경우만 별도 문장을 가집니다.
    • 오늘전통 + 옐로펀치
    • X-COURSE
  • 그 외 모든 질문은 기본값 Company X 내부 문서에서 관련 근거를 찾았습니다.를 반환합니다.
  • 위치:
    • rb8001/app/services/companyx_grounding_service.py:136-153
  • 의미:
    • 투자사는 몇개야? 같은 수치형 질문은 답을 계산하거나 단정 불가를 판단하지 않고 generic 문장으로 끝납니다.
    • 현재 구조는 질문 유형별 답변 계약이 아니라 일부 질문별 문장 하드코딩입니다.

6. 실패 처리는 검색 결과가 0개일 때만 작동하고, 검색은 됐지만 무관한 경우를 다루지 않는다

  • _build_grounded_response()의 실패 문장은 if not results일 때만 반환됩니다.
  • 결과가 1개라도 있으면 질문 적합성 검증 없이 근거 문서: 목록을 붙입니다.
  • 위치:
    • rb8001/app/services/companyx_grounding_service.py:155-171
  • 의미:
    • 휴가 질문에 무관한 companyx_todaytradition.pdf 청크가 잡히면, 시스템은 이를 실패가 아니라 성공처럼 출력합니다.
    • 즉 현재 실패 경계는 no result만 있고 irrelevant result는 없습니다.

7. 현재 Company X 응답은 LLM 기반 합성이 아니라 규칙 기반 문자열 조합이다

  • Company X 전용 경로는 검색 결과를 가져온 뒤 _build_direct_answer()와 청크 요약 문자열을 이어붙여 응답을 만듭니다.
  • 위치:
    • rb8001/app/services/companyx_grounding_service.py:130-171
  • 의미:
    • 현재 이 문제의 본질은 프롬프트가 약해서라기보다, 규칙 설계가 질문 유형을 감당하지 못하는 상태입니다.
    • 다만 구현 형태는 질문별 문장/분기 하드코딩에 의존하고 있어 유지보수성이 낮습니다.

8. 스킬 문서가 요구하는 계약과 현재 구현 계약은 일치하지 않는다

  • SKILL.md는 답변 순서를 direct answer -> evidence documents -> short evidence summary로 고정합니다.
  • 또한 documents are missing, say the evidence is insufficient를 요구합니다.
  • 위치:
    • DOCS/skills/companyx-rag/SKILL.md
  • 현재 구현은 아래 차이가 있습니다.
    • 직접 답이 generic 문장으로 대체될 수 있음
    • 문서 부족무관한 문서 반환을 구분하지 않음
    • 증거 문서 적합성 검증 없이 score 상위 청크를 그대로 노출함
  • 의미:
    • 문제의 직접 원인은 스킬 문서 부재가 아니라, 구현이 스킬 계약을 끝까지 지키지 못하는 데 있습니다.

9. 대표 성공 질문은 구조적으로 우대돼 있고, 재오픈 질문은 일반화 경로에 놓여 있다

  • 오늘전통 + 옐로펀치 질문은
    • 별도 query expansion이 있고
    • 별도 direct answer 하드코딩이 있으며
    • 대표 근거 문서셋도 이미 worklog에 남아 있습니다.
  • 관련 문서:
  • 반면 재오픈 질문 2개는
    • 전용 query expansion이 없고
    • 질문 유형 분기 규칙도 없고
    • generic fallback 문장으로 마감됩니다.
  • 의미:
    • 현재 성공은 일반화된 성공이 아니라 대표 질문 최적화 성공에 가깝습니다.

10. 따라서 지금 실패는 검색 부재보다 답변 합성 + 실패 판정 부재 + 질문별 하드코딩 편향의 결합이다

  • 앞선 사실을 합치면 현재 경로는 아래 구조입니다.
    1. marker 기반으로 Company X 경로 진입
    2. 일부 질문만 유리한 query expansion
    3. relevance score만으로 검색 결과 채택
    4. 일부 질문만 direct answer 하드코딩
    5. 결과가 하나라도 있으면 성공처럼 문서 목록 노출
  • 의미:
    • 이번 이슈의 직접 레이어는 answer composition입니다.
    • 그러나 더 깊게 보면 질문 유형 계약이 없는 규칙 하드코딩 구조가 상위 원인입니다.

해석(Interpretation)

1. 이 문제는 검색 인프라 장애가 아니라 응답 정책 부재 문제다

  • Company X 전용 경로는 실제로 존재하고, 검색 호출도 수행합니다.
  • 실패가 나는 지점은 질문에 대한 직접 답을 어떻게 만들고, 어떤 검색 결과를 근거로 채택하며, 언제 모른다고 말할지가 비어 있다는 점입니다.

2. 지금 구조는 시나리오를 닫기 어려운 형태다

  • 시나리오는 설명형, 사실 확인형, 수치 확인형, 재정리형을 모두 요구합니다.
  • 하지만 현재 구현은 실질적으로 대표 사실 확인형 2종만 특례 처리합니다.
  • 따라서 새 질문이 들어올수록 if와 문장 하드코딩이 늘어날 가능성이 높고, 시나리오를 일반 규칙으로 닫을 수 없습니다.

3. 트러블 문서가 지적한 회귀의 직접 원인은 질문 적합도 검증 부재다

  • 재오픈 질문들은 검색 결과가 0개라서 실패한 것이 아닙니다.
  • 결과가 있어도 질문과 무관한 청크를 success처럼 출력했습니다.
  • 즉 이번 회귀를 닫는 핵심은 retrieval result exists가 아니라 retrieval result is fit for this question를 판정하는 단계입니다.

4. 스킬 문서는 방향이 맞지만, 구현 계약으로 내려오지 않았다

  • SKILL.md는 이미 직접 답, 근거 문서, 부족 시 명시를 요구합니다.
  • 문제는 그 계약이 코드에서 재현 가능한 판정 규칙으로 변환되지 않은 것입니다.
  • 따라서 다음 plan은 새 문구를 더 쓰는 게 아니라, 스킬 계약을 코드가 판정 가능한 구조로 바꾸는 데 집중해야 합니다.

5. 하드코딩 프롬프트/문장 증식은 이 문제의 해법이 아니다

  • 현재도 대표 질문 성공은 이미 하드코딩 특례에 기대고 있습니다.
  • 이 상태에서 투자사, 휴가, 투자 건수, 규정, 복지 식으로 질문별 문장을 더 추가하면,
    • 시나리오는 겉보기로만 닫히고
    • 트러블은 다른 질문에서 다시 열리며
    • 프롬프트와 if 분기 중복만 쌓이게 됩니다.

미확정 항목(Unresolved)

  1. skill-rag-file의 반환 score만으로 질문 적합도를 판정할 수 있는지, 별도 rerank가 필요한지는 아직 미확정입니다.
  2. 수치형 질문의 단정 가능 / 단정 불가를 문서 메타데이터만으로 먼저 판정할지, 후속 요약 계층을 둘지는 아직 미확정입니다.
  3. 재정리형 질문을 이전 응답 재사용으로 처리할지, 다시 검색해도 되는지는 아직 미확정입니다.
  4. Company X 전용 규칙을 독립 계약 모듈로 둘지, 범용 grounding 정책으로 올릴지는 아직 미확정입니다.

결론

  • 이 이슈의 직접 원인은 Company X 검색 실패가 아니라 질문 적합 근거 선별 없는 답변 합성입니다.
  • 더 근본 원인은 질문 유형 계약 없이 일부 질문만 하드코딩 특례 처리하는 구조입니다.
  • 따라서 다음 plan은 프롬프트 문장 추가가 아니라 아래 3가지를 고정해야 합니다.
    1. 질문 유형별 판정 계약
    2. 검색 결과의 질문 적합도 판정 계약
    3. 근거 부족 시 명시적 실패 계약

다음 plan이 반드시 고정해야 할 항목

  1. 재오픈 기준 질문 3개를 공통 검증셋으로 고정할 것
  2. success의 정의를 검색 hit 존재가 아니라 직접 답 + 질문 적합 근거 또는 명시적 부족 안내로 바꿀 것
  3. 질문별 direct answer 하드코딩 추가를 금지하고, 질문 유형별 공통 계약으로 대체할 것
  4. 무관한 청크 반환실패로 판정하는 경계를 추가할 것
  5. 스킬 문서 계약과 코드 계약을 1:1로 맞출 것

관련 문서