--- tags: [research, companyx, rag, answer-composition, scenario, troubleshooting] --- # Company X RAG 답변합성 시나리오·트러블 동시종결 리서치 ## 상위 원칙 - [Writing Principles](../../book/300_architecture/312_writing-principles.md) - [Company X RAG 답변 합성 회귀](../troubleshooting/260312_companyx_rag_answer_composition_regression.md) - [Company X 내부 문서 근거응답 사용자 시나리오](../scenarios/260312_companyx_내부문서_근거응답_사용자시나리오.md) ## 목적 - `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에 남아 있습니다. - 관련 문서: - [Company X 내부문서 RAG 근거응답 1차 구현 및 부분 검증](../worklog/260312_companyx_내부문서_rag_근거응답_구현및시나리오검증.md) - 반면 재오픈 질문 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로 맞출 것 ## 관련 문서 - [Company X RAG 답변 합성 회귀](../troubleshooting/260312_companyx_rag_answer_composition_regression.md) - [Company X 내부 문서 근거응답 사용자 시나리오](../scenarios/260312_companyx_내부문서_근거응답_사용자시나리오.md) - [Company X 내부문서 RAG 근거응답 현황 리서치](./260312_companyx_내부문서_rag_근거응답_현황_리서치.md) - [Company X RAG 답변합성 시나리오·트러블 동시종결 계획](../plans/260315_companyx_rag_답변합성_시나리오동시종결_계획.md) - [Company X 내부문서 RAG 근거응답 1차 구현 및 부분 검증](../worklog/260312_companyx_내부문서_rag_근거응답_구현및시나리오검증.md) - [Company X RAG 스킬 문서](../../skills/companyx-rag/SKILL.md)