🎯 정치인 평가 시스템 - 전체 프로세스

정치인 기본 정보 준비부터 상세평가보고서 생성까지 전체 프로세스 시각화
작성일: 2026-02-08 | 최종 업데이트: 2026-02-15 | V40

📊 전체 프로세스 개요

Phase 0: 준비 (API 키, DB 연결 검증)
Phase 1: 정치인 정보 등록 (MD 작성 → DB INSERT)
Phase 2: 데이터 수집 (Gemini 500~600 + Naver 500~600 = 1,000~1,200개)
Phase 3: 수집 검증 (validate_v40_fixed.py --no-dry-run)
Phase 2-2: 검증 후 조정 (adjust_v40_data.py, 균형 맞추기)
Phase 3: AI 평가 (4 AIs × 1,000~1,200 = 4,000~4,800개)
Phase 3-1: 평가 검증 (95% 이상)
Phase 4: 점수 계산 (calculate_v40_scores.py)
Phase 5: 보고서 생성 (generate_report_v40.py)
🎯 Phase 0: 준비 단계 (Prepare)

목표: API 키 확인, DB 연결 검증, 테이블 사전 생성 확인

필수 인증 및 인프라

구분 요소 설명
수집용 인증 Gemini CLI Google 계정 인증 (1회 로그인)
수집용 인증 Naver API CLIENT_ID / CLIENT_SECRET
평가용 인증 Claude Code CLI Anthropic 계정 로그인
평가용 인증 Gemini CLI Google 계정 인증 (수집과 동일)
평가용 인증 OpenAI API OPENAI_API_KEY (ChatGPT/Codex)
평가용 인증 xAI API XAI_API_KEY (Grok)
인프라 Supabase SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY
DB 4개 테이블 politicians, collected_data_v40, evaluations_v40, ai_final_scores_v40

준비 작업

Phase 0: 준비

1. API 키 / 인증 확인

  • Gemini CLI 로그인 상태 확인
  • Naver CLIENT_ID/SECRET 환경변수 확인
  • OPENAI_API_KEY 환경변수 확인
  • XAI_API_KEY 환경변수 확인
  • SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY 확인

2. DB 테이블 존재 확인

  • politicians ✓
  • collected_data_v40 ✓
  • evaluations_v40 ✓
  • ai_final_scores_v40 ✓

3. 정치인 정보 MD 파일 작성

  • instructions/1_politicians/{이름}.md
  • politician_id 생성 (UUID 앞 8자리, TEXT 타입)
📝 Phase 1: 정치인 정보 등록

1. 정치인 기본 정보 작성

📂 저장 경로:

설계문서_V7.0/V40/instructions/1_politicians/

  • 박주민.md
  • 조은희.md (예시)

내용:

  • politician_id (8자리 hex, TEXT 타입)
  • 성명, 성별, 생년월일
  • 현 직책, 소속 정당
  • 출마 신분, 출마 직종
  • 지역, 지역구
  • 특별 지시사항 (수집 시 주의점, 평가 시 주의점)
  • 알려진 논란/이슈, 알려진 성과
  • 출처 힌트 (OFFICIAL / PUBLIC 분리)

2. DB 등록

📊 politicians 테이블 INSERT
  • id: '12345678' (TEXT 8자리 hex)
  • name: '한동훈'
  • party: '국민의힘'
  • position: '당대표'
  • ...

⚠️ INTEGER/BIGINT 절대 금지!

TEXT(8자리 hex) 필수

🔍 Phase 2: 데이터 수집 (2개 채널, 카테고리당 100개 + 버퍼 20%)

🤖 Gemini 수집 (50%)

Google Search

⚠️ Gemini CLI Direct


OFFICIAL: 30개

PUBLIC: 20개

카테고리별 50개

총 500개 (최대 600개)


📋 가이드 참조:

GEMINI_CLI_수집_가이드

🔍 Naver 수집 (50%)

Naver Search API

✅ 자동 실행


OFFICIAL: 10개

PUBLIC: 40개

카테고리별 50개

총 500개 (최대 600개)


🚀 스크립트:

collect_naver_v40_final.py

센티멘트 분배 규칙

유형 Official Public 합계 버퍼 포함
Negative 4개 (10%) 12개 (20%) 16개 20개
Positive 4개 (10%) 12개 (20%) 16개 20개
Free 32개 (80%) 36개 (60%) 68개 80개
합계 40개 60개 100개 120개

⚠️ "rating 없이 수집만!" (수집 ≠ 평가)

⚠️ Official 기간: 4년 | Public 기간: 2년

collected_data_v40 테이블에 저장

총 1,000개 (최대 1,200개, 버퍼 20%)

(Gemini 500~600 + Naver 500~600)

각 데이터:

  • id (UUID)
  • politician_id, politician_name
  • category (10개 중 하나)
  • title, content, source_url
  • data_type (OFFICIAL/PUBLIC)
  • sentiment (negative/positive/free)
  • collector_ai (Gemini/Naver)
  • published_date
  • created_at
  • ⚠️ rating 없음 (평가는 별도)
✅ Phase 3: 수집 검증 (validate_v40_fixed.py --no-dry-run)

데이터 검증

  • ✓ URL 유효성 (GET stream=True)
  • ✓ 도메인 검증
    • OFFICIAL: .go.kr 등
    • PUBLIC: 언론, 블로그 등
  • ✓ 기간 제한
    • OFFICIAL: 최근 4년
    • PUBLIC: 최근 2년
  • ✓ 필수 필드 (title, content, url)
  • ✓ 가짜 URL 패턴 탐지
  • ✓ Sentiment 비율 검증:
    • OFFICIAL: negative ≥10%, positive ≥10%
    • PUBLIC: negative ≥20%, positive ≥20%
  • ✓ 고급 중복 제거:
    • 같은 AI + 같은 URL/제목 → 제거
    • 다른 AI + 같은 URL/제목 → 유지
  • ✓ 목표: 카테고리당 100개 (버퍼 20%, 최대 120개)
  • 정치인당 1,000개 (최대 1,200개)
검증 실패?
Yes ↓
재수집
(누락만)
No ↓
통과
⚖️ Phase 2-2: 검증 후 조정 (adjust_v40_data.py)

균형 확인 및 조정 (최대 4회, 포기 규칙 적용)

목표: AI별 500-600개, 카테고리별 50-60개/AI

확인 항목:

  • AI별 데이터 개수 (Gemini/Naver 각각)
  • 카테고리별 개수 (10개 × AI별 50-60개)

자동 조정 (최대 4회):

  • 60개 초과 → 오래된 순 자동 삭제
  • 50개 미만 → 재수집 필요

포기 규칙 (4회 후):

  • 50+개: 정상 평가
  • 25-49개: 부족 허용, 보유 데이터로 평가
  • <25개: 포기, leverage score 0 처리 (60점)

명령어:

  • adjust_v40_data.py --politician_id xxx (자동)
  • recollect_gemini_v40.py (수동 재수집)
  • recollect_naver_v40.py (수동 재수집)

💡 핵심: 처음부터 버퍼 목표(60개)로 수집 → Phase 2-2 거의 스킵 가능!

🤖 Phase 3: AI 평가 (4개 AI 독립 평가, 전부 CLI 방식)

7. 4개 AI가 각각 1,000~1,200개 전체 평가 (독립적)

💡 핵심: 수집 시점 ≠ 평가 시점 (세션 분리 = 객관성)

4개 AI 공통점

  • ✅ 실행 방식: 전부 CLI/Subprocess
  • ✅ 배치 크기: 25개씩 처리
  • ✅ 최적화: Pre-filtering 적용 (중복 평가 제외)
  • ✅ 저장 함수: common_eval_saver.py 사용

4개 AI 차이점 (API 키 필요성)

AI CLI 방식 API 키 필요 이유
Claude Claude Code CLI Direct ❌ 불필요 계정 로그인으로 CLI 직접 사용
Gemini Gemini CLI Subprocess ❌ 불필요 계정 인증으로 CLI 직접 사용
ChatGPT Codex CLI Direct ✅ OPENAI_API_KEY API 호출 필수 (토큰 비용)
Grok curl CLI Direct (subprocess) ✅ XAI_API_KEY API 호출 필수 (API 비용)

🔵 Claude 평가

Claude Code CLI Direct


🔓 API키 불필요

Haiku 4.5

1,000~1,200개

(100~120×10)

8등급, X=제외

🟢 ChatGPT 평가

Codex CLI Direct


🔐 OPENAI_API_KEY 필수

gpt-5.1-codex-mini

1,000~1,200개

(100~120×10)

8등급, X=제외

🔴 Grok 평가

curl CLI Direct (subprocess)


🔐 XAI_API_KEY 필수

grok-3

1,000~1,200개

(100~120×10)

8등급, X=제외

🟡 Gemini 평가

Gemini CLI Direct


🔓 API키 불필요

2.0 Flash

1,000~1,200개

(100~120×10)

8등급, X=제외

🔧 기술적 방식 비교: CLI vs API

비교 항목 CLI 방식 (✅ 채택) API 방식 (❌ 폐기)
인증 방식 Account Login / API Key (1회 설정) API Key (매 요청)
실행 방식 Subprocess 호출 (단순) HTTP API 요청 (복잡)
할당량/제한 Claude/Gemini 무제한 / ChatGPT/Grok 제한 적용 RPM 분당 제한 (15 req/min)
사용 편의성 1회 로그인/설정, 재로그인 불필요 API 키 관리 필수 (만료/보안)
코드 복잡도 단순 (10-20줄, subprocess.run()) 복잡 (50-100줄, retry)

💰 비용 비교: API vs CLI

AI 이전 방식 (API) 현재 방식 (CLI) 절감률
Claude Anthropic API (claude-3-haiku) $0.75 Claude Code CLI (Haiku 4.5) $0 100%
Gemini Google API (2.0 Flash) $0.19 + 제한 Gemini CLI Subprocess (2.0 Flash) $0 100%
ChatGPT OpenAI API (gpt-4) $45 Codex CLI (gpt-5.1-codex-mini) $1.125 97.5%
Grok Agent Tools API 미공개 xAI API (grok-3) 미공개 -
총계 ~$46/1,000개 ~$1.13/1,000개 97.5%

핵심 인사이트: ChatGPT gpt-4 ($45) → gpt-5.1-codex-mini ($1.125) = 40배 저렴

🚀 성능 최적화

최적화 적용 AI 설명 효과
배치 평가 4개 AI 전부 25개씩 묶어서 평가 속도 10x 향상
Pre-filtering 4개 AI 전부 이미 평가된 데이터 사전 제외 중복 평가 0%, 5x 향상
자동 재시도 ChatGPT Foreign key 오류 시 배치 5개 자동 재시도 안정성 100%
공통 저장 함수 4개 AI 통합 common_eval_saver.py (통합 저장 로직) 코드 중복 제거

평가 등급 체계

등급 +4 +3 +2 +1 -1 -2 -3 -4 X
판단 탁월 우수 양호 보통 미흡 부족 매우부족 극히부족 제외
점수 +8 +6 +4 +2 -2 -4 -6 -8 -
8. evaluations_v40 테이블에 저장

총 4,000~4,800개 평가 (4 AIs × 1,000~1,200개)

각 평가:

  • id (UUID)
  • politician_id, politician_name, category
  • collected_data_id (FK → collected_data_v40) ⭐
  • evaluator_ai (Claude/ChatGPT/Grok/Gemini)
  • rating: 8등급 (+4,+3,+2,+1,-1,-2,-3,-4, 0 없음)
    X = 제외(평가 불가, 등급 아님)
  • reasoning (평가 근거)
  • evaluated_at

💡 collected_data_id로 수집 데이터와 연결!

✅ Phase 3-1: 평가 검증 단계 (95% 이상)

평가 완성도 확인

기준: 95% 이상

계산: (평가 개수 / 기대값) × 100

기대값 = 4 AI × 실제 수집 개수

예: 수집 1,000개 → 기대 4,000개

3,800개 / 4,000 = 95%

⚠️ X(제외)는 평가 불가 항목 → 95% 기준은 X 발생을 허용

95% 미달?
Yes ↓
재평가
(누락만)
No ↓
통과
🎯 Phase 4: 점수 계산 단계 (calculate_v40_scores.py)

10. AI별 카테고리 점수 계산

각 AI, 각 카테고리:

Step 1: Rating 평균

평균 = Σ(Rating) / 평가 개수 (X 제외)

범위: -4 ~ +4

Step 2: 점수 환산

점수(Score) = Rating 평균 × 2

범위: -8 ~ +8

Step 3: 카테고리 점수 (20~100점)

카테고리 점수 = (6.0 + 평균 Rating Score × 0.5) × 10 = (평균 Rating Score × 0.5 + 6.0) × 10 = 평균 Rating Score × 5 + 60

예: Claude, 전문성

Rating 평균 +2.77 → Score 5.54

→ (5.54 × 0.5 + 6.0) × 10 = 87.7 ≈ 88점

11. AI별 최종 점수 계산

최종 점수 = round(min(10개 카테고리 점수 합산, 1000))

예: Claude

77+76+79+65+71+72+73+74+76+75 = 738점

12. 4 AIs 평균 점수 계산

평균 = (Claude + ChatGPT + Grok + Gemini) / 4

예: (738 + 881 + 835 + 807) / 4 = 816점

Bayesian Prior (베이지안 사전확률) 적용

공식 분해:

카테고리 점수 = 평균 Rating Score × COEFFICIENT + PRIOR × 10 = 평균 Rating Score × 5 + 60
상수 역할
PRIOR 6.0 기본 점수 60점 (베이지안 사전확률)
COEFFICIENT 0.5 범위 스케일링

Prior = 6.0의 의미:

  • 데이터 부족 시 안전장치 (기본값 60점)
  • 극단값 완화 (Prior가 중심으로 당김)
  • 신규 정치인도 60점(보통)에서 공정 시작
  • "선출직 공직자의 기본 신뢰"를 수치화
상황 Rating Score 카테고리 점수 의미
전부 +4 (최고) +8 8×5+60 = 100점 증거가 Prior를 최대로 끌어올림
긍정/부정 균형 0 0×5+60 = 60점 증거가 Prior를 변경하지 못함
전부 -4 (최저) -8 -8×5+60 = 20점 증거가 Prior를 최대로 끌어내림

13. 최종 등급 결정 (M~L, 10단계)

등급 점수 범위 의미
M (Mugunghwa) 920~1000점 최우수
D (Diamond) 840~919점 우수
E (Emerald) 760~839점 양호
P (Platinum) 680~759점 보통 상
G (Gold) 600~679점 보통
S (Silver) 520~599점 보통 하
B (Bronze) 440~519점 개선 필요
I (Iron) 360~439점 미흡
Tn (Tin) 280~359점 부족
L (Lead) 200~279점 최하

14. ai_final_scores_v40 테이블에 저장

저장 내용
  • id (UUID)
  • politician_id, politician_name
  • ai_category_scores (JSONB) ⭐
    {
    "Claude": {"expertise": 77, "leadership": 76, ...},
    "ChatGPT": {"expertise": 89, "leadership": 86, ...},
    "Grok": {...}, "Gemini": {...}
    }
  • ai_final_scores (JSONB) ⭐
    {"Claude": 738, "ChatGPT": 881, "Grok": 835, ...}
  • final_score: 816
  • grade: "E"
  • calculated_at
📄 Phase 5: 보고서 생성 단계 (generate_report_v40.py)

15. 데이터 조회 (4개 테이블 조인)

SELECT * FROM politicians (기본 정보) JOIN collected_data_v40 (1,000~1,200개 수집 데이터) ON politicians.id = collected_data_v40.politician_id JOIN evaluations_v40 (4,000~4,800개 평가) ON collected_data_v40.id = evaluations_v40.collected_data_id JOIN ai_final_scores_v40 (최종 점수) ON politicians.id = ai_final_scores_v40.politician_id WHERE politician_id = '...' 💡 collected_data_id로 수집↔평가 연결!

16. AI별 통계 계산

  • AI별 평균 등급 (+2.77, +2.32, +2.10, +1.50)
  • AI별 X 비율 (20%, 21.8%, 16.6%, 29.3%)
  • AI별 긍정/부정 비율
  • AI별 rating 분포 (+4: 253개, +3: 308개, ...)

17. 카테고리별 분석 (10개)

각 카테고리:

  • AI별 점수 비교 (Claude 77, ChatGPT 89, ...)
  • 대표 긍정 평가 사례 (Top 10)
  • 대표 부정 평가 사례 (Top 5)
  • AI 간 평가 차이 분석 (표준편차)

18. 마크다운 보고서 생성 (V40.1 - 8섹션 구조)

📄 보고서 구성 (8섹션, ~790줄):

  1. 정치인 프로필 (~30줄)
  2. 평가 요약 (~80줄)
  3. ★ 강점 분석 TOP 3~5 (~180줄) ← 주력!
  4. ★ 약점 분석 TOP 3 (~120줄) ← 주력!
  5. 카테고리별 요약 (~150줄, 축소!)
  6. 데이터 분석 (~120줄)
  7. 한계 및 유의사항 (~50줄)
  8. 참고자료 및 마무리 (~60줄)

19. 파일 저장

📂 저장 경로:

설계문서_V7.0/V40/보고서/

{정치인명}_{YYYYMMDD}.md

예) 박주민_20260206.md

📄 파일 형식: Markdown (.md)

📊 파일 크기: 약 50~100KB

✅ 완료!

📊 최종 결과물:

  • DB에 정치인 정보 저장 (politicians)
  • DB에 1,000~1,200개 수집 데이터 저장 (collected_data_v40)
  • DB에 4,000~4,800개 평가 저장 (evaluations_v40)
  • DB에 최종 점수 저장 (ai_final_scores_v40)
  • 📄 상세평가보고서.md 파일 생성

📋 데이터 테이블 관계도

politicians
정치인 기본 정보
PK id (TEXT) - 8자리 hex
name (TEXT)
party (TEXT)
position (TEXT)
1
N
collected_data_v40
수집 데이터 (rating 없음)
PK id (UUID)
FK politician_id → politicians.id
category (TEXT)
title, content, source_url
data_type (OFFICIAL/PUBLIC)
collector_ai (Gemini/Naver)
sentiment (negative/positive/free)
created_at (TIMESTAMP)
⚠️ rating 필드 없음 (수집 단계)
1
N (4 AIs)
evaluations_v40
평가 결과 (rating 있음)
PK id (UUID)
FK politician_id
FK collected_data_id ⭐
category (TEXT)
evaluator_ai (4개 AI)
✅ rating (8등급, X=제외)
reasoning (TEXT)
evaluated_at (TIMESTAMP)
ai_final_scores_v40
최종 점수 (1:1 관계)
PK id (UUID)
FK politician_id ⭐ (1:1)
ai_category_scores (JSONB)
ai_final_scores (JSONB)
✅ final_score (200-1000)
grade (M~L)
calculated_at (TIMESTAMP)

핵심 포인트:

  • 1:N 관계: collected_data_v40.id → evaluations_v40.collected_data_id (수집 데이터 1개 → 4개 AI 평가)
  • 1:1 관계: politicians.id → ai_final_scores_v40.politician_id (정치인 1명 → 최종 점수 1개)
  • rating 위치: 수집 테이블(X) vs 평가 테이블(O)
  • 데이터 흐름: 수집 → 평가 → 점수 계산 → 보고서

🎯 핵심 포인트 7가지

1️⃣ 세션 분리 = 객관성

수집 시점 (Gemini/Naver) ≠ 평가 시점 (4 AIs)

→ 타이밍 분리로 독립적 판단 보장

2️⃣ 풀링 방식

모든 AI가 카테고리당 100개(버퍼 20%, 최대 120개), 전체 1,000개(최대 1,200개) 평가 (독립적, 배치 25개씩)

→ 편향 상쇄, 균형 잡힌 평가

3️⃣ 2단계 검증

수집 검증 (버퍼 20% 이내, 최대 120%) + 평가 검증 (95% 이상)

→ 품질 보장

4️⃣ DB 분리

수집 테이블 (rating 없음) ≠ 평가 테이블 (rating 있음)

→ collected_data_id로 연결

5️⃣ 점수 계산 4단계

Rating 평균 → 점수(×2) → 카테고리 점수 → 최종 점수

→ 일관된 계산 방식

6️⃣ 4개 테이블 조인

politicians + collected_data_v40 + evaluations_v40 + ai_final_scores_v40

→ 완전한 보고서 생성

7️⃣ CLI 방식 = 97.5% 비용 절감

API ~$46/정치인 → CLI ~$1.13/정치인


📊 단계별 데이터 개수

단계 테이블 데이터 개수 rating 필드
Phase 0 (준비) API키/DB확인 -
Phase 1 politicians 1개 ❌ 없음
Phase 2 collected_data_v40 1,000~1,200개 (버퍼 20%) ❌ 없음
Phase 3 (검증) 중복/위반 제거 -
Phase 2-2 (조정) AI별 500-600개 균형 -
Phase 3 evaluations_v40 4 AI × 수집 개수 (95% 이상) ✅ 있음 (8등급, X=제외)
Phase 3-1 (검증) 95% 완성도 확인 -
Phase 3 ai_final_scores_v40 1개 ❌ 없음 (점수만)
Phase 5 (보고서) .md 파일 1개 -

🚀 실행 명령어 요약

# Phase 0: 준비 # API 키 및 DB 연결 확인 # .env 파일 확인 (SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, OPENAI_API_KEY, XAI_API_KEY 등) # Phase 1: 정치인 등록 # (수동) 정치인 정보 파일 작성 # 위치: 설계문서_V7.0/V40/instructions/1_politicians/박주민.md # (수동) DB에 정치인 정보 INSERT # Phase 2: 수집 # Gemini 수집 (Gemini CLI Subprocess) cd V40/scripts/workflow for i in {1..7}; do python collect_gemini_subprocess.py --politician "박주민" --category expertise sleep 5 done # Naver 수집 (자동) python collect_naver_v40_final.py --politician_id=507226bb --politician_name="박주민" --ai=Naver --category 1 # Phase 3: 검증 cd V40/scripts/core python validate_v40_fixed.py --politician_id=507226bb --politician_name="박주민" --no-dry-run # Phase 2-2: 검증 후 조정 python adjust_v40_data.py --politician_id=507226bb # Phase 4: 평가 # Claude 평가 cd V40/scripts/helpers python claude_eval_helper.py --politician_id=507226bb --politician_name="박주민" --category=expertise --batch_size=25 # ChatGPT 평가 python codex_eval_helper.py --politician_id=507226bb --politician_name="박주민" --category=expertise --batch_size=25 # Grok 평가 python grok_eval_helper.py --politician_id=507226bb --politician_name="박주민" --category=expertise --batch_size=25 # Gemini 평가 cd V40/scripts/workflow python evaluate_gemini_subprocess.py --politician "박주민" --category "expertise" # Phase 3-1: 평가 검증 cd V40/scripts/utils python check_evaluation_status.py --politician "박주민" # Phase 4: 점수 계산 cd V40/scripts/core python calculate_v40_scores.py --politician_id=507226bb --politician_name="박주민" # Phase 5: 보고서 생성 python generate_report_v40.py 507226bb 박주민 # 저장 위치: 설계문서_V7.0/V40/보고서/박주민_20260206.md

📖 참고 문서

  1. V40_전체_프로세스_가이드.md - 전체 프로세스 설명
  2. V40_기본방침.md - 핵심 방침
  3. V40_오케스트레이션_가이드.md - 자동화 가이드
  4. V40_검증후조정_가이드.md - Phase 2-2 상세
  5. AI_기반_정치인_상세평가보고서_생성_가이드_V40.md - 보고서 생성
  6. README.md - V40 개요

✅ 체크리스트

Phase 0: 준비 단계

Phase 1: 정치인 등록

Phase 2: 수집 단계

Phase 3: 검증 단계

Phase 2-2: 검증 후 조정

Phase 3: 평가 단계

Phase 3-1: 평가 검증 단계

Phase 4: 점수 계산 단계

Phase 5: 보고서 생성 단계