Skip to content

[Feat] W3 Entity 추출 파이프라인 구현 #13

Description

@TaskerJang

컨텍스트

W3의 첫 번째 핵심 작업. Chunk → Entity 추출을 자동화한다.
#12 보너스에서 박제된 프롬프트를 파이프라인 코드로 정식화.

WBS 1.8 — 5/9 (토) → 5/10 시작 (Spike #8 통과 후 본격).

참고: Spike #8 (PR #29) 에서 시행착오 3건 (SSL 인증서, Kimi base_url, f-string + .format() 충돌) 박제 완료. 본 작업은 그 위에 정식 모듈로 쌓는다.

변경 사항 (2026-05-10 본문 업데이트)

  • 파일명: kg/entity_extractor.pykg/extractor.py (kg/README.md 모듈 명명 규약과 일관성 유지)
  • 라벨 4 → 5개로 확장: Recommendation 추가
  • LLM: Kimi (Moonshot K2/K2.5) 사용 — agent.llm_client.LLMClient 재활용
  • 프롬프트 분리: 회사 레포 summarizer/prompts/ 패턴 차용 (kg/prompts/*.md)

작업

1. kg/ontology.py — 도메인 스키마 (Pydantic)

  • 5개 라벨 enum: Company, Metric, Recommendation, Risk, Outlook
  • 4개 관계 enum: HAS_METRIC, RECOMMENDED_FOR, FACES_RISK, HAS_OUTLOOK
  • ExtractedEntity Pydantic — local_id, type, canonical, source_span, section
  • ExtractedRelation Pydantic — source, type, target, evidence
  • ExtractionResultentities: list, relations: list

2. kg/prompts/ — Kimi 맞춤 프롬프트 v1

회사 레포 summarizer/prompts/system_v1.md, chunk_summary_v1.md 패턴 차용 + Kimi 특성 반영 (번호 매긴 헤더, 마크다운 표, 구체 태그):

  • entity_system_v1.md — 역할 + 핵심 원칙 + 5개 라벨 정의 + 4개 관계 정의
  • entity_extract_v1.md — 작업 + 입력 ({doc_id}, {section}, {text}) + 제약 + 출력 JSON 스키마

3. kg/extractor.py — Chunk → ExtractionResult

  • 회사 레포 summarizer/llm.py 출처 주석 (Map-Reduce + Semaphore 패턴 포팅)
  • agent.llm_client.LLMClient 재활용 (Spike 에서 검증됨)
  • LLM 호출 wrap (Pydantic 응답 파싱, JSON 코드펜스 제거 방어 코드, 실패 시 retry)
  • 배치 처리 — 1문서 N chunks 를 asyncio.gather + Semaphore(MAX_CONCURRENT) 로 병렬
  • 토큰/시간/실패율 stdout 로깅 (Opik @track 은 W5 에서 추가)
  • 빈 chunk · 인식 실패 chunk graceful 처리 (KeyError 등 X)

4. tests/kg/test_extractor.py — 단위 테스트

  • mock LLM 응답 1개 (회사 두산밥캣 샘플 재사용)
  • 라벨 검증 (5개 안 들어가면 drop)
  • graceful 실패 — 빈 chunk 처리

DoD

  • 1문서 → ExtractionResult 추출 end-to-end 동작
  • 빈 chunk · 인식 실패 chunk 를 graceful 하게 처리
  • 추출 결과를 [Feat] W3 NED + Dedup (Cosine similarity 기반) #14 NED 의 입력 형태로 반환 (ExtractionResult.entities)
  • Spike 의 두산밥캣 샘플 재실행 시 5개 → 5개 (또는 그 이상, 5개 라벨 활용) 추출

참고

Kimi 특성 반영 포인트

회사 레포는 GPT-5.2 기준이라 그대로 가져가지 않음. Kimi(K2) 권장 사항 반영:

항목 회사 레포 (GPT) Kimi 조정안
헤더 스타일 # 역할, # 핵심 원칙 번호 매긴 헤더 (# 1. 역할, # 2. 핵심 원칙)
타입 정의 본문 텍스트 마크다운 표 (Kimi attention 친화적)
모호 명령 "문서에 명시된 내용만" "source_span 필드에 원문 인용 포함" (구체 태그)
JSON 출력 정규식 코드펜스 제거 response_format={"type": "json_object"} 활용 + 방어 코드 유지
Temperature 0.3 0.2 ~ 0.3 (정밀 추출이라 낮게 유지)

Spike 결과 → v0 baseline (개선 포인트 박제)

Spike (이슈 #8 코멘트 참고) 에서 v0 결과:

  • ✗ Metric "영업이익" + "35% 감소" 가 별도 Entity 로 분리 → {name, value, period} 통합 필요
  • ✗ "건설장비 수요 둔화" 가 Outlook 으로 분류 (실제는 Risk 의 원인)
  • ✗ Recommendation 라벨 자체가 부재 (4개 라벨만 검증했었음)

본 작업의 v1 프롬프트는 위 3개 개선 포인트를 직접 겨냥.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions