26 KiB
26 KiB
tags
| tags | ||||||
|---|---|---|---|---|---|---|
|
Company X RAG 답변합성 시나리오·트러블 동시종결 리서치
상위 원칙
목적
Company X근거응답 이슈를트러블슈팅 + 시나리오한 문제로 보고, 둘을 함께 닫기 위한 원인 기준을 고정합니다.- 현재 실패가
검색 인프라 문제인지,답변 합성 문제인지,질문별 하드코딩 구조 문제인지 단일 경로로 좁힙니다. - 이 문서는 해결안 확장보다
다음 plan 1건을 만들 수 있을 정도로 직접 원인을 확정하는 데만 집중합니다.
연결 구조
- 같은 레벨 입력:
ideas/260312_companyx_내부문서_rag_응답_아이디어.md,scenarios/260312_companyx_내부문서_근거응답_사용자시나리오.md - 단일 리서치: 본 문서 1개
- 단일 플랜:
plans/260315_companyx_rag_답변합성_시나리오동시종결_계획.md1개 - 닫힘 흐름: 플랜 완료 기준 충족 시 시나리오/트러블과 함께 닫힘 선언 (아이디어 문서는 종결 상태 유지)
조사 질문
- 현재 실패의 직접 레이어는 검색인가, 답변 합성인가
컴퍼니엑스의 투자사는 몇개야?,내부 규정 상 휴가는 얼마나 쓸 수 있어?가 왜 깨지는가- 현재 Company X 경로는 일반 규칙 기반인가, 질문별 하드코딩 기반인가
- 트러블 문서와 시나리오 문서를 함께 닫으려면 무엇을 plan에서 고정해야 하는가
범위 / 비범위
- 범위:
rb8001의 Company X grounding 진입/검색/응답 합성 경로- 재오픈 기준 질문 20개에 대한 처리 구조
- 프롬프트/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
- 의미:
- 이것은 RAG가 아닙니다. RAG의 정의는 검색된 청크를 컨텍스트로 LLM에 전달해 답변을 생성하는 구조입니다.
- 현재 구조는 검색(Retrieval)만 있고 LLM 기반 생성(Generation)이 없습니다.
- 따라서 현재 구현 형태는 질문별 문장/분기 하드코딩에 의존하고 있어 유지보수성이 낮고, 질문 유형을 감당하지 못합니다.
- 진짜 RAG로 전환: 검색된 청크를 컨텍스트로 LLM(현재 gpt-4o-mini)에 전달해 답변을 생성하는 구조로 바꿔야 합니다.
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에 남아 있습니다.
- 관련 문서:
- 반면 재오픈 질문 다수는
- 전용 query expansion이 없고
- 질문 유형 분기 규칙도 없고
- generic fallback 문장으로 마감됩니다.
- 의미:
- 현재 성공은 일반화된 성공이 아니라
대표 질문 최적화 성공에 가깝습니다.
- 현재 성공은 일반화된 성공이 아니라
10. 따라서 지금 실패는 검색 부재보다 답변 합성 + 실패 판정 부재 + 질문별 하드코딩 편향의 결합이다
- 앞선 사실을 합치면 현재 경로는 아래 구조입니다.
- marker 기반으로 Company X 경로 진입
- 일부 질문만 유리한 query expansion
- relevance score만으로 검색 결과 채택
- 일부 질문만 direct answer 하드코딩
- 결과가 하나라도 있으면 성공처럼 문서 목록 노출
- 의미:
- 이번 이슈의 직접 레이어는
answer composition입니다. - 그러나 더 깊게 보면
질문 유형 계약이 없는 규칙 하드코딩 구조가 상위 원인입니다.
- 이번 이슈의 직접 레이어는
11. 현재 Company X RAG는 NAS 대량 문서셋 + 임베딩 전환 이슈 위에 놓여 있다
51123기준 점검에서/mnt/nas/workspace/6.Company X아래 실파일은53,249개였고, fullscan 최신 summary는2026-03-17 01:23:10+09:00, hierarchical 최신 summary는2026-03-17 11:00:06+09:00까지 누적돼 있습니다.- 의미:
- 지금 Company X RAG는 적은 대표 문서 몇 개만의 문제가 아니라, NAS에서 계속 동기화되는 대량 문서셋 위에서 동작해야 합니다.
- 따라서 대표 질문 일부만 통과하는 특례 구조로는 운영 상태를 닫을 수 없습니다.
12. Company X RAG의 임베딩 전제가 문서끼리 일치하지 않는다
DOCS/skills/companyx-rag/SKILL.md는Default embedding path: local 384d로 적고 있습니다.- 반면
260316_임베딩_전체프로젝트_현황_및_SSOT_리서치.md와260316_임베딩_Gemini_Embedding_2_전환_문제오픈.md는 로빙 전체 기준을Gemini Embedding 2,768d, 전수 교체 대상으로 둡니다. - 의미:
- 지금 Company X 답변합성 문제는 순수한 응답 문구 문제만이 아닙니다.
- 어떤 임베딩 모델/차원/컬렉션 상태를 SSOT로 볼지부터 다시 닫아야 합니다.
13. 그래서 2026-03-15 기준 리서치만으로 바로 구현에 들어가면 전제 충돌을 안고 시작한다
- 2026-03-15 리서치는 답변합성 구조 문제를 정확히 짚었지만, 그 이후 열린
Gemini Embedding 2전환 문제와 NAS 대량 문서 운영 상태까지는 반영하지 못했습니다. - 의미:
- 지금 필요한 다음 단계는
새 리서치 전체 재작성이 아니라,
- 지금 필요한 다음 단계는
현재 NAS 문서량,현재 컬렉션 차원,현재 재임베딩 여부,현재 재오픈 질문셋(20개) 재현 상태를 다시 확인하는 짧은 갱신 리서치입니다.
14. 현재 런타임 저장 구조는 PostgreSQL 중심으로 전환돼 있다
330_백엔드_PostgreSQL_ChromaDB_Vector_Memory.md상단 주석은 2026-03-17 기준 운영 런타임이skill-rag-file,rb8001의 핵심 벡터/검색/그래프 경로를 PostgreSQL 중심으로 전환했다고 명시합니다.rb8001기억 회상 핵심 경로는 이미 PostgreSQLmemory_vectors,memory_graph_nodes,memory_graph_edges기준으로 전환됐습니다.skill-rag-file의 문서 청크 벡터는 코드(upload.py,reindex.py,search.py) 기준으로PostgresDocumentVectorStore를 사용하며team_document_chunk테이블에 저장됩니다. ChromaDB는rebuild_chroma_collection.py스크립트에서만 사용되며 운영 API 경로와 분리돼 있습니다.- 확인된 파일별 저장소:
| 파일 | 사용 저장소 |
|---|---|
upload.py |
PostgresDocumentVectorStore (team_document_chunk) |
reindex.py |
PostgresDocumentVectorStore (team_document_chunk) |
search.py |
PostgresDocumentVectorStore (team_document_chunk) |
rebuild_chroma_collection.py |
ChromaDB (레거시 스크립트, 운영 API 비사용) |
- 의미:
skill-rag-file운영 API 경로는 이미 PostgreSQL 중심입니다. "ChromaDB에 저장 중" 표현은 부정확합니다.- Company X 문서 임베딩 저장 경로는
team_document_chunk(pgvector)가 SSOT입니다. - 레거시
rebuild_chroma_collection.py는 운영과 무관하며 정리 대상입니다.
15. NAS 전체 PDF 기준 임베딩 시간은 약 5.2시간(추정)이다
/mnt/nas/workspace전체 PDF 파일 수는27,849개, 200개 샘플 평균 페이지는8.05로 측정됐습니다.- 100페이지 임베딩 벤치마크(768d, Gemini 2)에서 총 요청 시간은
8.2768s였고, 이를 페이지 단위로 환산하면0.0828s/페이지입니다. - 위 수치를 곱산하면 전체 PDF 예상 페이지는 약
224,184페이지, 임베딩 요청 시간은 약5.15시간입니다. - 의미:
- 이 값은 PDF 기준 단순 추정치이며, 비PDF 파일/추가 전처리/네트워크 부하/실패 재시도는 포함하지 않습니다.
16. Go 전환이 “시간 단축”을 보장하지는 않으며, 확인된 이점은 제한적이다
- 내부 NAS Go 동기화 리서치의 1분 벤치마크(23 서버, DSM 목록 조회 루프)에서 Go는 Python 대비 총 사이클 +5~6%, 목록 조회는 더 빠르지만 로그인은 차이가 작았습니다.
- 해석:
- Go 전환의 효과는 작업 유형에 따라 제한적이며, “무조건 큰 폭의 시간 단축”이라고 단정할 수 없습니다.
- 따라서 임베딩/인덱싱 파이프라인에도 A/B 실측 없이 Go 전환 효과를 가정하지 않습니다.
- 근거 문서:
17. 현재 텍스트 변환 기반 청킹은 Gemini Embedding 2의 멀티모달 능력을 전혀 활용하지 못하고 있다
skill-rag-file은 모든 파일(PDF, 이미지, docx 등)을 텍스트로 변환한 뒤 문자 단위로 청킹합니다.- Gemini Embedding 2는 텍스트뿐 아니라 이미지, PDF, 오디오, 비디오를 직접 임베딩할 수 있는 멀티모달 모델입니다. 텍스트 변환 없이 원본 파일을 그대로 넣을 수 있습니다.
- 현재 방식의 문제:
- PDF: pdftotext/PyPDF2로 텍스트 추출 시 레이아웃, 표, 이미지 정보 손실
- 이미지 문서: 텍스트 변환 불가하거나 OCR로 품질 저하
char_per_token = 4한국어 과소 청킹으로 정보 단절
- 의미:
- 임베딩 모델을 Gemini Embedding 2로 바꿨으면, 인덱싱 파이프라인도 원본 파일 직접 임베딩 방식으로 전환해야 일관성이 있습니다.
- 텍스트 변환 파이프라인을 유지하는 것은 Gemini Embedding 2로 전환한 의미를 절반 이상 버리는 것입니다.
해석(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. 다만 지금은 응답 계약 구현 전에 운영 전제를 다시 닫아야 한다
- Company X RAG는 이미 NAS 실문서 대량 적재 상태 위에서 동작하고 있습니다.
- 동시에 임베딩 SSOT는
384d local과Gemini 2 / 768d문서가 공존합니다. - 따라서 다음 plan의 첫 단계는
답변합성 코드 수정이 아니라운영 전제 재검증이어야 합니다.
6. 하드코딩 프롬프트/문장 증식은 이 문제의 해법이 아니다
- 현재도 대표 질문 성공은 이미 하드코딩 특례에 기대고 있습니다.
- 이 상태에서
투자사,휴가,투자 건수,규정,복지식으로 질문별 문장을 더 추가하면,- 시나리오는 겉보기로만 닫히고
- 트러블은 다른 질문에서 다시 열리며
- 프롬프트와 if 분기 중복만 쌓이게 됩니다.
미확정 항목(Unresolved)
확정된 항목 (2026-03-17)
5. 컬렉션 차원:384d폐기,Gemini Embedding 2 / 768d전량 교체 확정 (0_VALUE 정책). SKILL.md 반영 완료.1. 질문 적합도 판정:_score_result_relevance()+_select_relevant_results()로 구현됨. rerank는 현재 불필요로 판단 (코드 검토 기준).2. 수치형 질문 판정:_can_answer_quantitative()+_COUNT_MARKER_PATTERN으로 구현됨. 정밀도 미검증이나 구조는 확정.
여전히 미확정
재정리형 질문은 이전 응답 재사용 없이 재검색함 (세션 연결 없음). 현재 스코프에서는 재검색 허용으로 운영.- Company X 전용 규칙은 현재 독립 모듈(
companyx_grounding_service.py)로 유지. 범용화는 이 문제 세트 밖.6. NAS 최신 문서 동기화본이 Company X RAG 검색 컬렉션에 언제, 어떤 방식으로 반영되는지는 아직 미확정.→ 확인 완료 (2026-03-17): NAS 마운트/mnt/nas(CIFS). Company X 원본:/mnt/nas/workspace/6.Company X/(53,249개). 외부→내부 NAS는 cron(30분 계층형 + 하루 1회 전수조사)으로 동기화. 단, NAS → skill-rag-file 인덱싱은 자동화 없음 — 수동 upload API 호출만 가능. 현재 114개만 인덱싱. 대량 투입 배치 스크립트 필요.7. 한국어 과소 청킹 리스크 및→ 확정 (2026-03-17): 계획 Phase 5A에서 문자 단위 청킹 제거 + PDF 직접 임베딩 전환으로 결정됨. 이 계획에서 닫음.Gemini 2 PDF 직접 임베딩미구현은 본 문제 세트에서 즉시 전환 대상으로 결정할지 미확정.
결론
- 이 이슈의 직접 원인은
Company X 검색 실패가 아니라질문 적합 근거 선별 없는 답변 합성입니다. - 더 근본 원인은
질문 유형 계약 없이 일부 질문만 하드코딩 특례 처리하는 구조입니다. - 가장 근본 원인: 현재 구조는 RAG가 아닙니다. 검색된 청크를 LLM 컨텍스트로 전달해 답변을 생성하는 구조가 없고, 규칙 기반 문자열 조합으로 대체하고 있습니다. 이를 진짜 RAG 구조로 전환해야 합니다.
- 다만 현재는
NAS 대량 문서 운영 상태와Gemini Embedding 2 전환 상태가 겹쳐 있으므로, 다음 plan은 구현 전에 운영 전제 재검증부터 고정해야 합니다. - PostgreSQL 저장 경로 전제는 확정됐으므로, plan에서는 이를 기준으로 재검증/테스트 항목을 정렬해야 합니다.
- 그 전제가 닫힌 뒤 구현 단계에서 아래 4가지를 고정해야 합니다.
- 검색된 청크를 컨텍스트로 LLM에 전달해 답변을 생성하는 구조 도입
- 질문 유형별 판정 계약
- 검색 결과의 질문 적합도 판정 계약
- 근거 부족 시 명시적 실패 계약
다음 plan이 반드시 고정해야 할 항목
- 현재 Company X RAG의 실제 임베딩 경로와 컬렉션 차원(
384d/768d)을 먼저 재검증할 것 - NAS 최신 문서 동기화본이 현재 검색 컬렉션에 언제 반영되는지 확인할 것
- 재오픈 기준 질문 20개를 현재 운영 상태에서 다시 재현해
검색 실패 / 무관한 hit / 답변 합성 실패를 분리할 것 success의 정의를검색 hit 존재가 아니라직접 답 + 질문 적합 근거 또는 명시적 부족 안내로 바꿀 것- 질문별 direct answer 하드코딩 추가를 금지하고, 질문 유형별 공통 계약으로 대체할 것
무관한 청크 반환을실패로 판정하는 경계를 추가할 것- 스킬 문서 계약과 코드 계약을 1:1로 맞출 것
- PostgreSQL 저장 경로 전제를 plan과 테스트 기준에 반영할 것
관련 문서
- Company X RAG 답변 합성 회귀
- Company X 내부 문서 RAG 응답 아이디어
- Company X 내부 문서 근거응답 사용자 시나리오
- Company X 내부문서 RAG 근거응답 현황 리서치
- Company X RAG 답변합성 시나리오·트러블 동시종결 계획
- Company X 내부문서 RAG 근거응답 1차 구현 및 부분 검증
- Company X RAG 스킬 문서
2026-03-17 코드 검토: 사실 섹션 현행화
이 리서치는 2026-03-15 코드 기준으로 작성됐습니다. 2026-03-17 실제 코드(
rb8001/app/services/companyx_grounding_service.py)를 직접 검토한 결과, 아래 사실들이 이미 코드에서 변경되거나 구현된 것으로 확인됐습니다.
이미 구현되어 outdated된 사실
| 리서치 사실 | 현재 코드 상태 |
|---|---|
| Fact 3: query expansion이 2종 하드코딩 | _build_query_candidates()가 _extract_keywords() + _DOCUMENT_HINTS_BY_TYPE 기반 동적 확장으로 변경됨 |
| Fact 4: relevance score만으로 결과 채택 | _score_result_relevance(), _select_relevant_results()로 질문 적합도 재평가 구현됨 |
| Fact 5: 직접 답이 2종 하드코딩 + generic 기본값 | _classify_question_type() + type-based _build_direct_answer()로 4개 유형 처리 구현됨 |
| Fact 6: 실패 처리가 results=0일 때만 작동 | _select_relevant_results() 필터링 후 relevant=0이면 _build_failure_answer() 호출됨. QUESTION_QUANTITATIVE는 _can_answer_quantitative()로 수치 존재 여부도 판정함 |
| Fact 9: 대표 질문만 특례 처리 | 이제 _classify_question_type() → _build_query_candidates() → _score_result_relevance() 공통 경로. 하드코딩 특례 제거됨 |
여전히 사실인 항목
- Fact 1: Company X 경로는 의도 분류 전에 우선 진입 (
message_service.py:81) - Fact 2: 진입 조건은 여전히 marker 기반 (
_looks_like_companyx_grounding_question) - Fact 7: 응답 합성은 여전히 규칙 기반 문자열 조합 (LLM 합성 아님)
현재 미해결 항목 (2026-03-17 갱신)
relevance score만으로 질문 적합도 판정 가능한지:_score_result_relevance()구현됨. 현재 구조로 운영.- 수치형 질문의
단정 가능/불가를_COUNT_MARKER_PATTERN패턴만으로 충분한지 미검증 (정밀도 테스트 필요) - 재정리형 질문은 이전 응답 재사용 없이 재검색함 (세션 연결 없음). 현재 스코프에서는 재검색 허용으로 운영.
- 임베딩 전제:
384d→Gemini Embedding 2 / 768d전환 확정 (SKILL.md 반영 완료)
현재 코드에서 추가 확인된 구조
_DOCUMENT_HINTS_BY_TYPE: 유형별 문서 힌트 (quantitative는 투자/포트폴리오/실적 계열)_supports_quantitative_focus(): 수치형 질문에서 count marker 패턴(\d+개사,총\d+등) 존재 여부 판정_select_evidence_results(): 관련 결과 중 상위 2개만 근거로 선별 (중복 문서 제거)_build_failure_answer(): 유형별 다른 실패 메시지 반환
미완료 항목 (코드 기준)
- Phase 5 테스트 고정 미완료: 재오픈 기준 질문 20개에 대한 자동화 테스트 없음
- Slack 실응답 검증 미완료: 코드는 구현됐으나 실제 Slack에서 재오픈 질문 20개 통과 여부 미확인
- 종결 worklog 미존재: 트러블슈팅 문서가 참조하는
260315_companyx_정확표기_slack_근거응답_경로종결.md파일 없음 청킹-임베딩 전제 불일치 미해결→ 해소 (2026-03-17):IndexingPipelineService도입. PDF는 6페이지 단위 바이너리 Base64 →embed_items(task_type="RETRIEVAL_DOCUMENT")직접 임베딩. 비PDF는 텍스트 추출 → 청킹 fallback 유지.chunk_text는 검색 호환용 미리보기 텍스트로만 사용.Phase 4 LLM 전환 미구현→ 구현 완료 (2026-03-17):_call_llm_companyx_grounding()+CompanyXRAGOutputPydantic 검증 도입.settings.DEFAULT_LLM_MODEL(gpt-5-mini) SSOT 참조. 규칙 기반_build_direct_answer()는 LLM 실패 시 fallback으로 유지.skill-embedding 배포 이미지와 레포 코드 일치 여부 미확인→ 확인 완료 (2026-03-17): 활성 서비스는skill-embedding-repo/(GeminiEmbedder, Gemini Embedding 2 기반). 레거시skill-embedding/(ONNX)와는 별도 레포. 해소.Phase 5A 파이프라인 전환 + 인터페이스 계약→ 코드 구현 완료 (2026-03-17):task_type(RETRIEVAL_DOCUMENT/QUERY) 전달 +metadatapass-through 양쪽(skill-embedding, skill-rag-file) 구현. 배포/재기동은 미완료.