DOCS/journey/troubleshooting/251023_codex_pronoun_search_fix.md

7.3 KiB

251023_codex_웹검색_대명사_의도_수정

날짜: 2025-10-23
작성자: codex
수정일: 2025-11-18 (대명사 해소 플로우 개선 필요 사항 추가)
관련 파일: rb8001/app/brain/decision_engine.py, rb8001/app/services/workflows/web_search_workflow.py, rb8001/app/router/message_router.py


요약 (3줄)

  • 의도 매칭 누락: "대표이사 누구야?" 유형이 UNKNOWN으로 빠짐 → WEB_SEARCH 정규식 보강.
  • LangGraph 예외: 체크포인터 비동기 컨텍스트 미사용으로 get_next_version 오류 → 컨텍스트 매니저 적용.
  • 대명사 해소 오판: 휴리스틱이 최근 무관 엔티티로 치환 → LLM 우선 + 직전 명시 엔티티 우선 규칙으로 전환.

문제 상황

  • 로그: [DecisionEngine] 의도 매칭 실패 - UNKNOWN …
  • 로그: WebSearch workflow failed… '_AsyncGeneratorContextManager' object has no attribute 'get_next_version'
  • 로그: [WebSearch] Pronoun resolved … -> '지에프솔루션 …', Thompson gate가 heur로 선택해 오답.
  • 추가 문제 (2025-11-18): "엠에스 바이오 인터케어 관련 검" → "이 기업 검색해줘" 시 "오토테크"로 잘못 해소되어 검색 실행.

원인 분석

  • 규칙 공백: 대표이사 키워드가 기업/회사 동시 출현을 전제로 되어 있어 단독 질의 누락.
  • LangGraph 체크포인터 초기화 방식 변경(0.6.x/0.1.x 조합): from_conn_string가 async 컨텍스트 매니저를 반환.
  • 대명사 해소 정책: 휴리스틱 스캐닝 가중치로 최근 대화의 무관 토큰(HE/CO 등) 영향, 게이트가 heur을 과도 선호.
  • 추가 원인 (2025-11-18):
    • web_search_workflow.py:60-104: LangGraph 경로에서 _extract_entity_candidates_with_scores가 스코어만으로 정렬, 시간 순서 무시
    • web_search_workflow.py:63-65: 엔티티 추출 패턴이 "테크/솔루션" 접미사만 인식, "엠에스 바이오 인터케어" 같은 기업명 추출 실패
    • router.py:216: 의도 분류(FastPath) 이후에 대명사 해소 실행, 잘못된 엔티티로 검색 진행
    • message_router.py:27-142: LLM 우선 규칙이 LangGraph 경로에서 미적용

해결 방안

  1. WEB_SEARCH 정규식 보강 (대표이사/CEO 직접 매칭)

    • decision_engine.py:188: .*대표이사.*(누구|알려|검색|찾|이름), (ceo|CEO).*누구 추가
  2. LangGraph 체크포인터 안전화

    • web_search_workflow.py:25: async with AsyncSqliteSaver.from_conn_string(uri) as checkpointer: 내부에서 컴파일·실행
  3. 대명사 해소 정책 수정 (LLM 우선, 직전 명시 엔티티 우선 규칙)

    • message_router.py:27-142: 직전 사용자 발화에서 X (검색/알려줘…) 패턴이면 heur-direct 우선, 그 외에는 LLM 우선
    • 환경변수: PRONOUN_THOMPSON_GATE=false (기본 비활성)
    • 로깅: Selected pronoun resolution source: ... 추가
  4. 대명사 해소 플로우 개선 (2025-11-18 구현 완료)

    • router.py:179-195: 대명사 포함 시 의도 분류 전에 대명사 해소 먼저 수행, 해소된 메시지로 의도 분류
    • web_search_workflow.py:60-149: 최신 대화(인덱스 0)의 엔티티를 최우선 선택, 시간 우선순위를 스코어보다 우선시
    • web_search_workflow.py:69-70: 엔티티 추출 패턴 확장 (접미사 없이도 기업명 인식, 한글 3글자 이상 또는 영문 대문자 시작)
    • message_router.py:118-126: 최신 대화 우선 정렬 로직 적용
    • 커밋: cc7a162 (2025-11-18)
    • 배포: Gitea Actions 자동 배포 완료, rb8001 컨테이너 정상 동작 확인
  5. 모든 의도에 슬롯 추출 및 재질문 로직 추가 (2025-11-18 구현 완료)

    • router.py:261-329: 모든 의도에 슬롯 추출 로직 추가
      • web_search: 검색어/엔티티 슬롯 추출 (정규식 기반)
      • email_send: 받는 사람, 제목, 내용 슬롯 추출 (정규식 기반)
      • calendar_event: 날짜, 시간, 장소 슬롯 추출 (기존 로직 유지)
    • router.py:331-372: 필수 슬롯 확인 및 재질문 로직 추가
      • web_search: 검색어/엔티티 슬롯 없으면 "무엇을 검색할까요?" 또는 "어떤 기업을 말씀하시나요?" 재질문
      • email_send: 받는 사람 슬롯 없으면 "누구에게 이메일을 보낼까요?" 재질문
      • calendar_event: 날짜 슬롯 없으면 "언제 일정을 등록할까요?" 재질문
    • router.py:387-399: web_search 실행 시 슬롯의 검색어 우선 사용
    • 커밋: 8dbfe59 (2025-11-18)
    • 배포: Gitea Actions 자동 배포 완료, rb8001 컨테이너 재시작 확인
  6. 재질문 후 검색 시 원래 질문의 키워드 보존 (2025-11-18 구현 완료)

    • 문제: "이 기업 대표이사가 누구야?" → 재질문 → "엠에스 바이오" → "엠에스 바이오"만 검색되어 대표이사 정보 누락
    • 해결:
      • router.py:275-289: 원래 질문의 키워드(대표이사, CEO 등) 추출 및 슬롯 저장
      • router.py:300-310: 재질문 응답에서 엔티티 추출 로직 추가 (메시지 전체를 엔티티로 간주)
      • router.py:408-416: 재질문 응답 후 검색 시 엔티티 + 원래 질문의 키워드 조합하여 검색
      • 예: "이 기업 대표이사가 누구야?" → 재질문 → "엠에스 바이오" → "엠에스 바이오 대표이사" 검색
    • 커밋: bc953b5, 47e88bb (2025-11-18)
    • 배포: Gitea Actions 자동 배포 완료, rb8001 컨테이너 재시작 확인
  7. 한글 접미사 하드코딩 제거 (2025-11-18 구현 완료)

    • web_search_workflow.py:64-65, 94-95, 38, 48: "솔루션|테크|컴퍼니|주식회사" 하드코딩 제거, 접미사 없이도 기업명 인식
    • message_router.py:51-54, 99-100, 436, 451: 동일하게 한글 접미사 하드코딩 제거
    • 영문 접미사(Company, Inc, Corp 등)는 유지
    • 커밋: 032bd0d (2025-11-18)
    • 배포: Gitea Actions 자동 배포 완료, rb8001 컨테이너 정상 동작 확인
  8. 부수 수정

    • pipelines/langgraph_document.py: import os 누락 보완
    • 환경: WEB_SEARCH_USE_GRAPH=true, PRONOUN_RESOLVE_LLM=true, PRONOUN_THOMPSON_GATE=false, RECENT_WINDOW_HOURS=24

검증

  • 배포 후 docker logs rb8001 --tail 100 | grep -E 'UNKNOWN|Thompson|Pronoun|workflow failed'
  • 실제 시나리오:
    1. "솔트룩스 검색해줘."
    2. "이 기업 대표이사 검색해줘." → Selected pronoun resolution source: llm 또는 heur-direct(솔트룩스) 로 안정 치환
    3. 검증 완료 (2025-11-18): "엠에스 바이오 인터케어 관련 검" → "이 기업 검색해줘" → 최신 대화 우선 로직으로 "엠에스 바이오 인터케어" 정확히 해소 (확장 패턴 적용)

교훈

  • 의도 패턴은 "핵심 키워드 단독" 케이스를 반드시 포함할 것(대표/대표이사/CEO 등).
  • 외부 라이브러리 초기화는 버전별 컨텍스트/팩토리 시그니처 확인(특히 LangGraph/체크포인터).
  • 대명사 해소는 "직전 명시 엔티티 > LLM > 휴리스틱 스캔"의 우선순위를 기본으로 하고, 베이지안/밴딧은 옵트인으로 적용.
  • 추가 교훈 (2025-11-18): 대명사 해소는 시간 순서(최신 대화 우선)를 스코어보다 우선시하고, 의도 분류 전에 수행하여 정확한 엔티티로 검색을 진행해야 함.