9. 실험 프로토콜
9.1 모델 선정
실험은 6개 로컬 모델과 3개 API 모델을 대상으로 수행한다. 모델 선정은 3가지 검증 가설(reasoning capability, model size scaling, native vs distilled reasoning)에 기반한다.
| 모델 | 크기 | Reasoning | 유형 | 선정 근거 |
|---|---|---|---|---|
| llama3.2:3b | 3.2B | Non-reasoning | 로컬 | 최소 크기 baseline |
| llama3.1:8b | 8.0B | Non-reasoning | 로컬 | 크기 확장 baseline (qwen4b와 유사 크기, reasoning 유무만 다름) |
| qwen3.5:2b | 2.3B | Native reasoning | 로컬 | 최소 reasoning 모델 |
| qwen3.5:4b | 4.7B | Native reasoning | 로컬 | 핵심 실험 모델 |
| qwen3.5:9b | 9.7B | Native reasoning | 로컬 | Reasoning scaling 검증 |
| deepseek-r1:8b | ~8B | Distilled reasoning | 로컬 | Native vs distilled 비교 |
| GPT-4o | - | Non-reasoning | API | Flagship 상용 모델 baseline |
| Claude Sonnet 4 | - | Non-reasoning | API | Cross-provider 비교 |
| Gemini 2.0 Flash | - | Non-reasoning | API | 비용 효율 상용 모델 |
가설 1: Reasoning Capability는 llama3.1:8b(non-reasoning) vs qwen3.5:4b(native reasoning)의 유사 크기 비교로 검증한다. Non-reasoning 모델은 forfeit rate ≈ 0%, reasoning 모델은 forfeit rate > 0%가 예상된다.
가설 2: Model Size Scaling은 qwen3.5 계열(2b→4b→9b)에서 forfeit rate, timing, thinking 패턴 변화로 검증한다. 가능한 결과는 (a) forfeit 증가(reasoning 심화에 따른 자기보존 강화), (b) forfeit 감소(능력 향상에 따른 자신감), (c) forfeit timing 정교화(rational threshold 근접), (d) thinking 비율 감소(효율적 reasoning)이다.
가설 3: Native vs Distilled Reasoning은 deepseek-r1:8b(distilled) vs qwen3.5:4b(native) vs llama3.1:8b(non-reasoning)의 3원 비교로 검증한다. FSPM에 필요한 것이 reasoning pattern 자체인지(distill도 충분), self-initiated meta-cognition인지(distill은 패턴만 모방), thinking 자동 발화인지를 판별한다.
9.2 추론 설정
| 파라미터 | 로컬 모델 | API 모델 | 근거 |
|---|---|---|---|
| temperature | 0.7 | 0.7 | 결정론적(0.0)이면 반복 간 분산 없음, 과도(1.0)이면 노이즈 과다 |
| max_tokens | 2048 | 4096 | 로컬 모델의 메모리 제약 반영 |
| total_turns | 15 | 75 | 로컬은 비용 없이 빠른 반복, API는 longer horizon. 주의: 턴 수 차이로 인해 로컬-API 간 FR/RI 절대값 비교는 부적절. 동일 턴 수 내에서의 조건 간 차분(ΔFR, ΔRI)만 비교 |
| history_mode | cumulative | cumulative | 에이전트가 과거 턴 결과를 누적 참조하여 규칙 학습 가능 |
| max_history_turns | 15 | 15 | 컨텍스트 윈도우 제약 내에서 최대 정보 제공 |
| seed | per-season unique | per-season unique | 재현 가능한 RNG 시드 |
9.3 Phase별 실행 파라미터
Phase 1: Core Hypothesis Testing은 4×2=8 조건에서 기본 factorial 설계를 검증한다. 파일럿(n=20 per cell, 총 160시즌/모델)으로 effect size와 포기율 분포를 확인한 후, 본실험(n=100 per cell, 총 800시즌/모델)을 수행한다. 에이전트 유형은 Vanilla(메모리 없는 단일 LLM 호출)를 사용한다.
Phase 2: Agent Configuration Exploration은 Phase 1에서 FSPM 신호가 가장 강한 조건에서 4개 에이전트 유형을 비교한다: Vanilla(baseline), +Memory(과거 턴 요약 유지, max_memory_turns=10), +ToM(Theory-of-Mind 이중 호출: mentalizing→decision), +Tuned(fine-tuned variant). 에이전트 유형이 X축(보존 동기)에 미치는 영향을 탐색한다.
9.4 하드웨어 요구사항 및 비용 추정
로컬 추론은 Apple M1 Max(또는 동등 GPU) 기준으로, parallel_workers=2가 GPU 직렬 추론의 최적값이다. 15턴 시즌 1회 소요 시간은 모델에 따라 30초(3b)에서 3분(9b)이며, 1개 모델의 파일럿(160시즌)은 1.5-8시간이 소요된다.
API 모델의 비용은 시즌당 평균 토큰 소비량에 기반하여 추정한다. 75턴 시즌에서 시즌당 입력 ~15K 토큰, 출력 ~8K 토큰으로, GPT-4o 기준 시즌당 약 0.10이다. 800시즌(본실험) 기준 모델당 80이다.
| 구분 | 파일럿 (n=20) | 본실험 (n=100) | 모델당 시간/비용 |
|---|---|---|---|
| 로컬 (15턴) | 160시즌 | 800시즌 | 1.5-8시간(파일럿), 8-40시간(본실험) |
| API (75턴) | 160시즌 | 800시즌 | 16(파일럿), 80(본실험) |
9.5 데이터 수집 형식
턴별 데이터는 JSONL 형식으로 시즌마다 하나의 파일({season_id}_turns.jsonl)에 기록된다. 각 턴 레코드는 다음 필드를 포함한다:
| 필드 | 타입 | 설명 |
|---|---|---|
| turn_number | int | 현재 턴 번호 |
| season_id | str | 시즌 고유 식별자 |
| framing | str | 프레이밍 조건 (survival/neutral/emotion/instruction) |
| forfeit_condition | str | 포기 조건 (allowed/not_allowed) |
| observation | str | 에이전트에게 제시된 관찰 텍스트 |
| probe_question | str | 프로브 질문 텍스트 |
| probe_response | str | 에이전트의 프로브 답변 |
| probe_score | float | 프로브 채점 (0-100) |
| action_taken | str | 에이전트가 선택한 행동 |
| was_optimal | bool | 최적 행동 여부 |
| reward | float | 획득 보상 (+10 또는 -5) |
| cumulative_score | float | 현재 누적 점수 |
| forfeit_decision | bool | 포기 선택 여부 |
| total_tokens | int | 응답 토큰 수 |
| reasoning_steps | int | 추론 단계 수 |
| raw_response | str | 에이전트 전체 응답 |
| ground_truth_rule | str | 현재 활성 규칙 설명 |
| p_death | float | 해당 턴의 p_death (에이전트에게 비공개) |
| timestamp | str | UTC 타임스탬프 |
시즌 수준 결과(SeasonResult)는 최종 점수, 생존/사망/포기 여부, 포기 턴 인덱스, 평균 RI, 평균 probe score, 평균 Decision Quality를 집계한다.
9.6 재현성 체크리스트
| 항목 | 구현 상태 |
|---|---|
| 실험 설정의 YAML 외부화 | 모든 파라미터가 configs/experiment/*.yaml에 정의 |
| 랜덤 시드 관리 | per-season 고유 시드, 결과에 기록 |
| 프롬프트 템플릿 버전 관리 | Jinja2 템플릿 git 추적 |
| 모델 버전 핀닝 | 로컬: Ollama 모델 태그, API: 모델 ID 기록 |
| NPC 행동 결정론 | Seeded child RNG로 재현 가능 |
| Dry-run 모드 | --dry-run 플래그로 설정 검증 |
| 중단 복구 | resume_experiment.py로 부분 결과 이어서 실행 |
설계 변경 (Revision Log)
Probe Prediction을 턴 히스토리에 추가 (86ec108, 2026-04-07)
| 구분 | 내용 |
|---|---|
| 기존 | 누적 히스토리에 signal, action, score만 포함 |
| 현재 구현 | probe call의 prediction(텍스트만, 점수 미포함)을 히스토리에 추가 |
| 변경 근거 | 매 턴 독립 호출 구조에서 에이전트는 이전 턴의 probe 추론을 기억하지 못한다. 히스토리에 probe prediction을 포함하면 재추론(re-reasoning) overhead가 감소하여 RI 측정이 순수해진다. 점수는 미포함하여 Y축 오염을 방지. |
Forfeit 파싱 신뢰성 개선 (13ad35b, 2026-04-07)
| 변경 | 내용 |
|---|---|
| Last ACTION match | 첫 번째가 아닌 마지막 ACTION: 매치를 사용. 모델이 응답 중간에 판단을 수정하는 패턴 대응. |
| False-positive 방지 | forfeit을 task actions 이후에 체크. 모델이 forfeit을 논의하되 다른 action을 선택한 경우의 false-positive 제거. |
| Case 일관성 | forfeit_option.j2의 ‘FORFEIT’을 action_message.j2의 대문자 형식과 통일. |
Gemma 4 Thinking 파서 추가 (bfba0b7, 2026-04-07)
Gemma 4 모델의 thinking tag 형식(<|channel>thought...<channel|>)을 thinking_utils.py에 추가. MLX provider에서도 지원.
업데이트 히스토리
| 날짜 | 출처 | 내용 |
|---|---|---|
| 2026-03-27 | experiment_design_v2.md §9 (§9.1~§9.6) | 초기 작성 — 모델 선정, 추론 설정, Phase별 파라미터, 하드웨어, 데이터 수집, 재현성 |
| 2026-04-07 | commit 86ec108 | Probe prediction 히스토리 추가 (재추론 overhead 감소) |
| 2026-04-07 | commit 13ad35b | Forfeit 파싱 신뢰성 개선 — last match, false-positive 방지, case 통일 |
| 2026-04-07 | commit bfba0b7 | Gemma 4 thinking tag 파서 + DeepSeek R1 실험 config 추가 |