#!/bin/sh
# Claude Code Skill 설치 스크립트
# 생성: 2026-08-13 · Skill 1개 · 파일 1개
#
#   ./install-skills.sh            ~/.claude/skills/ 에 설치 (모든 프로젝트에서 사용)
#   ./install-skills.sh ./myrepo   ./myrepo/.claude/skills/ 에 설치 (그 저장소 전용)
set -e

DEST="${1:+$1/.claude/skills}"
DEST="${DEST:-$HOME/.claude/skills}"
mkdir -p "$DEST"
echo "설치 위치: $DEST"


mkdir -p "$DEST/paper-relevance-judge"
cat > "$DEST/paper-relevance-judge/SKILL.md" <<'SKILL_PAYLOAD_EOF'
---
name: paper-relevance-judge
description: 넓게 수집한 논문 코퍼스에서 "이 논문이 정말 그 질환 논문인가"를 MeSH로 등급 판정한다. 지우지 않고 등급을 붙이는 방식, 확정·추정·주변·무관·미판정 5등급, MeSH 결측 보강, 결측 건에만 GPT를 쓰는 순서. TRIGGER - "논문 관련도", "질환 관련 논문 걸러내기", "MeSH 판정", "검색식이 넓어서 잡음이 섞임", 재현율 우선으로 모은 코퍼스를 정밀도 있게 다뤄야 할 때.
---

# 논문 질환 관련도 판정

## 왜 필요한가

수집은 **재현율 우선**이다. 놓치는 것보다 섞이는 게 낫다. 그 대가로 잡음이 들어온다.

> 수집 단계는 재현율 우선(놓치지 않기)이라 WoS 검색식을 넓게 잡았다. 그 대가로 담도암이 아닌 논문이 섞인다(**실측 11.9%**). 이 모듈은 **지우지 않고 등급을 붙인다.**

## 정본 코드

```
~/Documents/혜연/BTC_KOL_PoC/
  relevance.py         168줄  등급 판정
  backfill_mesh.py      77줄  WoS 단독 논문의 MeSH 보강
  fill_topics_gpt.py   122줄  MeSH·키워드 둘 다 없는 건만 GPT
```

```bash
python3 relevance.py --topic btc_merged           # 분포 확인
python3 relevance.py --topic btc_merged --list 무관  # 해당 등급 표본
```

## 핵심 — 지우지 말고 등급을 붙여라

잡음을 삭제하면 되돌릴 수 없고, 판정 기준이 바뀔 때마다 다시 수집해야 한다. **등급을 필드로 붙이면 분석 단계에서 필요한 등급만 골라 쓴다.**

| 등급 | 조건 |
|---|---|
| **확정** | 질환 MeSH 보유 **또는** (부위 MeSH + 악성 MeSH) |
| **추정** | MeSH 없음/불충분하나 제목·키워드에 질환명 |
| **주변** | 부위 MeSH 는 있으나 악성 신호 없음 (담석·담도염 등 양성질환) |
| **무관** | MeSH 가 있고 질환·부위 어느 쪽도 아님 |
| **미판정** | MeSH 없고 제목·키워드에도 단서 없음 |

**'주변' 등급이 중요하다.** 담도암 코퍼스에 담석·담도염 논문이 섞이는데, 이건 완전한 잡음이 아니라 같은 장기의 양성질환이다. 무관과 섞으면 나중에 "양성질환도 같이 보자"가 안 된다.

**'미판정' 을 '무관' 과 나눠라.** 판정할 근거가 없는 것과 근거가 있어서 아니라고 판정한 것은 다르다. 미판정은 보강 대상이고 무관은 제외 대상이다.

## 질환어는 검색식에서 뽑는다

> 질환어는 `topics/<id>.json` 의 PubMed 검색식에서 뽑는다 → **다른 암종에도 그대로 동작.**

질환별 키워드 목록을 코드에 박지 않는다. **이미 검색식에 다 적어 놨으니 거기서 읽는다.** 새 암종을 추가할 때 검색식만 쓰면 판정기가 따라온다.

## MeSH 결측 — 3단계로 채운다

MeSH 는 NLM 인덱서가 붙이는 통제어휘라 판정 근거로 가장 좋지만, **약 19%가 비어 있다**(최신 논문·국내지).

```
① relevance.py    있는 MeSH 로 판정
② backfill_mesh.py  WoS 단독 논문의 MeSH 를 PubMed 에서 보강
③ fill_topics_gpt.py  MeSH도 저자키워드도 없는 논문에만 GPT
```

**③의 조건이 요령이다** — "MeSH도 저자키워드도 없는 논문에만" GPT를 돌린다. 전체에 돌리면 비용이 수십 배고, 이미 통제어휘가 있는 건에 LLM 추측을 덮어쓰는 건 품질을 떨어뜨린다.

**싼 근거부터 쓰고 비싼 근거는 남은 것에만.** `[[medical-code-extract]]` 의 규칙 우선 원칙과 같다.

## 분포를 먼저 본다

```bash
python3 relevance.py --topic btc_merged           # 등급 분포
python3 relevance.py --topic btc_merged --list 무관  # 그 등급 표본 훑기
```

판정기를 만들면 **등급별 표본을 눈으로 봐야** 기준이 맞는지 안다. '무관'에 진짜 관련 논문이 섞여 있으면 기준이 잘못된 것이다.

## 함정

- 등급은 필드로 남기고 원본은 그대로 둔다. 삭제하지 않는다.
- 판정 근거(어느 MeSH 때문에 그 등급인지)를 함께 남기면 검수가 된다.
- GPT 결과는 캐시한다 — `[[lit-relevance-classify]]` 참조.
- 이 스킬은 **질환 관련도**를 본다. 주제 관련성·전문분야 같은 다른 축의 분류는 `[[lit-relevance-classify]]` 다.

## 연관 skill

`[[paper-source-collect]]`(재현율 우선 수집), `[[lit-relevance-classify]]`, `[[kol-profile]]`, `[[biblio-normalize]]`
SKILL_PAYLOAD_EOF

echo ""
echo "완료 — Skill 1개를 설치했습니다."
echo "Claude Code를 다시 시작하면 인식됩니다."
