LLM 소셜 정보 수치화 — 방법론 draft

데이터 target-social.jsonl (157토큰, fetched 2026-06-17) · 1차 목표 loss 음성 스크린 · 방법론 합의용 draft · 2026-06-18

0. 30초 요약 — 우리가 내리는 결정

질문: 토큰에 붙은 소셜 정보(트윗·프로필·웹사이트)를 LLM으로 "수치화"해서 나쁜 토큰을 거르는 데 쓰고 싶다. 어떻게 하면 논리적·검증가능·근거기반인가?

답 (3문장):

LLM은 점수를 만들지 않는다. 자유텍스트에서 "이 트윗은 dev 자기홍보다 / 이 컨텐츠는 토큰과 무관하다" 같은 범주·참거짓 사실만 뽑는다.
수치는 코드가 만든다. 그 범주별로 과거 win/loss를 세어 승률 인덱스를 붙인다. "dev_self_promo 범주 = 과거 승률 28%" 처럼.
이 파일로는 신호 확정 불가. 진입 시점이 아니라 2026-06-17에 긁은 사후 스냅샷이라, 방법·골든셋 검증용일 뿐. 신호는 라이브 스냅샷을 쌓은 뒤 확정한다.

흔히 하는 방식왜 안 되나이 문서의 방식
LLM에 트윗 주고 "밈 강도 0~100점 매겨줘"주관 연속점수 → 검증 불가·다중비교 함정·LLM이 임계를 발명(§2)LLM은 범주만, 점수는 base-rate로 코드가(§6)
모든 소셜 필드를 LLM에 통째로 투입팔로워·계정나이는 이미 숫자 — LLM 거칠 이유 0, 비용·노이즈만3층 분해, LLM은 자유텍스트 1층만(§3)

1. 토큰 1개를 끝까지 따라가기 (가장 중요한 그림)

추상 설명 대신 실제 데이터 한 줄이 파이프라인을 통과하는 모습. 토큰 2SoWK7… (실제 jsonl 첫 행):

routedSources: website=cbherald.com (뉴스), twitter=status/2066978138…
website ogTitle: "BREAKING: Viral TikTok & Instagram Squirrel Ambassador 'Pip the Baby Squirrel' Seized by Authorities…" · isNews=true · domainAge=1543일
원천 데이터
website 뉴스기사 + 삭제된 트윗(not_found)
L1 코드 (스칼라)
domainAgeDays 1543 isNews true xAccountAge null
L2 코드 (분류)
website host = 일반 뉴스 도메인 (본인 소유 아님)
L3 LLM
contentType=news_capture · relevance: 토큰명과 대조 필요
수치 (코드)
news_capture 범주의 과거 승률을 신호값으로
읽는 법: 왼쪽 3칸(L1·L2)은 LLM이 1도 안 건드린다 — 전부 결정적 코드. LLM은 4번째 칸, "이 컨텐츠가 무슨 종류인가"라는 자연어 판단 하나만. 마지막 칸의 숫자도 LLM이 아니라 코드가 과거 데이터로 만든다.

2. 왜 "LLM 점수" 금지, "범주" 허용인가

방식구체적 문제판정
LLM 연속점수
(밈강도·품질 0~100)
천장 증거: winner 고르기는 우리가 가진 더 좋은 행동데이터로도 최강 feature AUC가 0.59에 막혔다(§10). 텍스트 주관점수가 그걸 넘을 근거 없음.
다중비교 함정: 연속점수는 임계(70점? 80점?)를 사후에 고르게 됨 → 우연히 맞는 컷이 늘 존재.
비결정: 같은 트윗에 매번 다른 점수 → OOS 재현·sweep 불가.
기각
LLM 범주/참거짓
(유형·관련성)
검증가능: 사람이 50개 손라벨 → LLM과 일치율로 신뢰도 측정 가능.
DOF 봉쇄: enum을 win/loss 보기 전에 동결 → LLM이 임계를 발명할 여지 0.
분산 있음: §9·§10이 확인 — "컨텐츠가 무엇이냐"엔 win/loss 분산이 있다(KOL "누가 샀나"는 분산 0이라 죽음).
채택

원칙 출처: time-series-llm-textualization.md §1 — "분석 레이어는 새 임계를 발명하지 않는다. LLM은 잘 명명된 범주만, 수치/임계는 결정적 코드가." 그걸 소셜에 그대로 적용한 것.

3. 3층 분해 — 필드별로 누가 처리하나

target-social.jsonl의 실제 필드를 "LLM이 필요한가"로 가른다. 대부분은 LLM이 아니라 코드의 일.

실제 필드 (이 파일에 있는 것)처리LLM?
L1
스칼라
authorFollowers 416576 · authorCreatedAt 2018-12-08 · likeCount 606 · viewCount 72781 · domainAgeDays 1543 · isBlueVerified · 트윗ID→나이(snowflake)코드❌ 이미 숫자
L2
분류
website host→x-linkgithub뉴스배포툴 · imageUrl host 지문 · 트윗ID·imageUrl 중복(카피캣) · 작성자 핸들 재등장코드
(도메인 규칙)
❌ DOF≈0 규칙
L3
텍스트
text "Just onboarded… KIWI the Cat" · description "Forge your path through the trenches…" · ogTitleLLM✅ 자연어 의미만
왜 L1·L2를 LLM에 안 주나: 팔로워 수에 LLM을 쓰면 비결정성·비용·다중비교만 늘고 얻는 게 없다. 이들은 metric-ledger의 기존 축(afExited·mcMonotonic)과 동급으로 코드가 처리·등재한다. LLM은 코드가 원천적으로 못 하는 "자연어 의미" 한 곳에만.

4. contentType 5종 — 실제 트윗으로 (사람이 경계를 판단)

이게 LLM 출력의 핵심. 범주가 잘 나뉘는지는 실제 사례로 직접 봐야 판단 가능. 각 범주에 jsonl 실제 트윗 1개씩:

dev_self_promo — 무명 dev가 토큰 띄우려 직접 올림

@Himothy_Goggins · 팔로워 339 · 계정 2025-08 · like 5 · view 1001
"hes saying we can just run this coin without his wallet"
프로필 @Forgers_Online · 팔로워 249 · 계정 2026-01 · blue ✓
"Forge your path through the trenches in this free-to-play MMORPG! Launch coming soon"

신호: 작은 신규계정 + "coin/launch" 자가언급. L1 스칼라(팔로워·나이)가 보조하지만 "홍보 의도"의 판정은 텍스트 의미 → LLM.

external_viral — 토큰과 무관하게 원래 큰 계정의 유기적 컨텐츠

@Kalshi · 팔로워 416,576 · 계정 2018 · like 606 · view 72,781
"JUST IN: Jim Cramer says SpaceX has become a 'meme stock'"

큰 실계정의 진짜 컨텐츠 — 토큰 측이 여기 올라탄 것. L1만으론 dev_self_promo와 안 갈림(둘 다 "트윗"). 구분점 = 컨텐츠가 토큰 홍보냐 독립 화제냐 = 의미판단.

news_capture — 뉴스/언론 컨텐츠 캡처

@coinbureau · 팔로워 1,107,325 · 계정 2017
"🚨SBF SAYS HE'LL LAUNCH A NEW TOKEN AFTER PRISON … New York Magazine reports…"
website WIRED · isNews=true
ogTitle: "Leak Exposes Members of Peter Thiel's Secretive 'Dialog' Society"

L2의 isNews·뉴스도메인이 1차 신호지만, 트위터발 뉴스 캡처는 텍스트로만 잡힘.

ai_bot_reply — AI/봇이 생성한 답글·자동홍보

프로필 @LoopyAgentAi · 팔로워 104 · 계정 2026-06-16 · blue ✓
"the only meta-agent that learns how you use claude code + codex, then auto-writes the loops…"

hijacked_unrelated — 무관한 유명인 트윗을 토큰이 도용

@pmarca (Marc Andreessen) · 팔로워 3,882,118 · 계정 2007
"#FreeSidney @fxshaw"
@blknoiz06 (KOL) · 팔로워 962,765
"@toiwins mutumbo"

대형계정이지만 컨텐츠가 토큰과 전혀 무관 → 컨텐츠 하이재킹. §5.3 어휘매칭 소유권 메커니즘의 컨텐츠 일반화. 이 범주가 loss 스크린의 핵심 타깃.

사람이 판단할 것 (§10 O3)
위 5종이 ① 상호배타적인가 ② 모든 트윗을 덮나 ③ loss와 상관될 법한 경계인가. 예: external_viral과 hijacked_unrelated는 둘 다 "큰 계정"이라 유일한 차이가 '토큰과 관련 있나' → 그래서 §5 관련성 판정이 필수 짝.

5. 관련성(이진) + ⚠️ 이 파일의 ticker 결손

관련성 = "이 컨텐츠가 이 토큰의 티커/이름과 실제 관련 있나" (이진). external_viral(좋을 수도) vs hijacked(나쁨)를 가르는 결정타.

중대한 데이터 한계 (먼저 알아야 함)
target-social.jsonl의 행 키는 tokenAddress · routedSources · fetched · liveTags · errors 뿐 — 토큰의 name/ticker가 없다. 그래서 "@pmarca의 #FreeSidney가 이 토큰과 관련 있나?"를 이 파일만으로는 판정 불가. → 관련성 라벨링은 반드시 tokens 컬렉션에서 name/symbol을 조인해야 함. 구현 전 선결 과제.
관련성실제 예해석
무관 (false)@pmarca "#FreeSidney" — 토큰명과 매칭 안 됨(가정)하이재킹 → loss 후보
관련 (true)@Forgers "…MMORPG! Launch coming soon" + 토큰 심볼 FORGE최소한 본인 컨텐츠

6. 수치화 = base-rate 인덱스 (LLM 아니라 코드)

LLM이 범주를 붙이면, "수치"는 그 범주의 과거 승률이다. 단일 주관점수가 아니라 경험분포.

// §11 이미지호스트 운용법과 동일: 고정 리스트 X, 트레일링 승률 인덱스
signal(category) = trailing_win_rate(category)
                   + min_sample 가드(표본 부족 시 중립값)

예시 표 (숫자는 형식 설명용 가상값 — 실측 아님):

LLM 범주nwinRate→ 신호값
hijacked_unrelated1217%강한 음성 (컷 후보)
dev_self_promo6131%약한 음성
external_viral2348%중립~양성
news_capture9— (표본부족)중립 기본값

이렇게 하면 ① 단일 점수의 과적합 회피 ② OOS에서 임계 sweep 가능 ③ 표본 적은 범주는 중립 처리(§11 운용 원칙). 신호의 정당성이 LLM 주관이 아니라 base-rate 측정에 있음.

7. ⚠️ 이 파일로 할 수 있는 것 / 없는 것

한 줄
target-social.jsonl2026-06-17에 긁은 사후 스냅샷. 진입 시점 상태가 아니다. → 방법·골든셋 검증용 탐색 데이터일 뿐, 신호 확정 증거가 아니다.
사실 (실측)함의look-ahead
x: not_found 21 + null 20 = 41/157 결손스캠일수록 트윗 삭제 → "fetch 성공분만" 보면 최악 토큰이 표본에서 빠짐 = 생존편향위험
likeCount/viewCount = 현재값진입 시점 engagement ≠ 지금. §9.3대로 소급 불가Unsafe
text/description = 현재 상태수정·삭제 가능 → 이 스냅샷 LLM 라벨은 백테스트 무효Conditional
트윗나이(snowflake)·authorCreatedAt·트윗ID/이미지 중복불변 or 자체 DB 인덱스 → 소급 정당Safe

그래서: 진짜 신호화는 라이브 watching 진입 시점에 text+engagement 스냅샷 저장(social_fetcher_plan)을 먼저 깔고 2~4주 쌓은 뒤. 이 문서 산출물 = 그 라이브 라벨링이 따를 스펙·골든셋·검증틀.

8. 검증 9단계 — 기존 머신에 연결 (새 틀 안 만듦)

#단계통과 기준
1enum 사전등록 (blind)win/loss 보기 전 5종 동결 · 대칭 사전(loss 유형만 나열 금지)
2골든셋 50개 손라벨 vs LLM일치율 ≥ 합의선 → 라벨 신뢰도 확보
3범주별 base rate각 category winRate/avgPnl 산출(§6)
4day-split 재현06-01·06-02 양일 방향 유지(flip=노이즈)
5교란 체크maxAfCount·buyMC proxy? 기존 KEEP축과 중복?
6제거비 ≥ 2:1비대칭 원칙(winner 1 살해 ≈ loser 3~4 제거)
7L2 직교성website-source·created_on 축과 중첩 적은가
8OOS 다기간 재현별도 구간 방향 유지
9ledger 등재KEEP/KILL + 근거 영구 기록

9. LLM 출력 스키마 (StructuredOutput) — 점수 필드 없음

// 토큰·소스당 1행. LLM은 이 구조만 채운다
{
  "tokenAddress": string,
  "source": "x_tweet" | "x_profile" | "website_meta",
  "relevance": {
    "matchesToken": boolean,     // 티커/이름과 관련? (tokens 조인 필요 §5)
    "evidenceSpan": string       // 판단 근거 원문 조각
  },
  "contentType": "dev_self_promo" | "external_viral" | "news_capture"
                 | "ai_bot_reply" | "hijacked_unrelated",
  "confidence": "high" | "low"   // 연속점수 아님 — 2단 플래그
}

신호 수치는 이 출력에 없다. 코드가 범주별 trailing winRate를 인덱스로 산출(§6)·검증(§8)한 뒤에만 신호가 된다.

10. 미결 결정 + 다음 단계

#쟁점선택지
O1골든셋 라벨 주체수동 50개 전수 vs LLM 셀프 후 일부 수동 감사
O2LLM 모델 등급Haiku급 1콜(§10 "비용 비문제") vs 관련성만 상위모델
O3contentType enum 최종위 5종 동결 vs 추가/병합 (§4 경계 보고 판단)
O4name/ticker 조인 (선결)tokens 컬렉션 어느 필드로 조인 → relevance 가능케
O5profile description 포함?트윗 text만 vs description도 L3

다음 단계

  1. 합의: O1~O5 확정 → enum/스키마 동결
  2. 탐색(이 파일): 결손 41 제외 편향을 명시한 채 157토큰 시범 라벨 → 골든셋 + 범주별 base rate 1차 측정 (신호 확정 아님, 방법 검증)
  3. 라이브 인프라: social_fetcher_plan에 진입시점 text+engagement 저장 + LLM 라우팅 추가
  4. 검증: 2~4주 축적 후 §8 9단계 → ledger 등재

연계: docs/drafts/social-content-source-loss-filter.html(§9·§10 흡수·승격) · docs/research/time-series-llm-textualization.md(extractor 원칙) · validation-playbook · metric-ledger.