텔레그램 메시지 한 줄을 받아 다중 LLM 분석을 거친 뒤 자유 형식 mono 보고서를 생성하는 시스템. 보고서 형태는 사건마다 LLM 편집장이 자유 결정함.
입력: 텔레그램에 사건 한 줄 (예: "미국-이란 호르무즈 봉쇄 분석"). 심층/짧게/요약 같은 키워드로 분석 강도 모드 자동 결정.
처리: 1) 상황 분석관 이 웹 검색으로 사실·타임라인·출처 수집 → 2) 전략 기획자 가 핵심 질문/의도/렌즈 결정 → 3) 모드별로 페르소나·렌즈 1~4종이 다각도 분석 → 4) 종합 판단관 이 모순/판단 정리 → 5) 편집장 (Opus 4.7) 이 보고서 본문을 자유 형식으로 작성 → 6) HTML 렌더 후 Cloudflare Pages 배포.
출력: mono 톤 HTML 보고서 URL. 사건마다 섹션 수/제목/순서/톤이 다름 (정형 슬롯 부어넣기 폐기).
핵심 변화 v3.4.7 → v3.5.0: 편집장 이 모든 모드에서 호출됨. 차트는 편집장이 본문에서 명시 reference 한 것만 박힘 (이전엔 데이터만 있으면 9종 차트가 무차별 발화). 테마는 mono 2종 (burgundy_mono · light_mono) 만 사용.
token_budget.py 가 SSOT. 사용자 메시지의 키워드로 자동 매핑되며 (없으면 standard), 호출되는 에이전트 / 렌즈 수 / LLM 호출 cap 이 다름.
| 항목 | fast ⚡ | standard 🟢 | deep 🔬 |
|---|---|---|---|
| 키워드 | 짧게/간략/요약/빠르게 | (기본) | 심층/자세히/면밀 |
| LLM 호출 cap | 5 | 8 | 13 |
| 최대 lens 개수 | 1 | 2 | 4 |
| 레거시 페르소나 (Player/Dynamics/ChainReaction) | 미호출 | 미호출 | 호출 |
| Quality Gate 1 LLM | 휴리스틱만 | 휴리스틱만 | LLM |
| Quality Gate 2 (커버리지) | 스킵 | 휴리스틱 | LLM |
| Synthesis Judge LLM | 휴리스틱 | 조건부 | LLM |
| red_team / pre_mortem 메타 lens | 없음 | 조건부 | 자동 |
| NarrativeComposer (편집장 Opus 4.7) | 호출 (v3.5.0) | 호출 (v3.5.0) | 호출 |
이전 (v3.4.7) 에는 fast/standard 에서 편집장이 호출되지 않아 정형 archetype 11종 중 1개에 데이터를 슬롯-부어넣는 패턴이었음. 이제 모든 모드에서 편집장이 보고서 본문을 자유 작성하므로 보고서 형태가 사건마다 다름.
한 분석 1회당 거치는 단계. 점선 박스는 모드 또는 조건부 호출, 굵은 골드 좌측 보더는 편집장 (composer), 점선 좌측 도트는 결정적 (LLM 없음).
ContextAnalysis.sources 로 보존.lens_policy.py) 이 처리.lens_policy.py 가 결정한 1~4종 렌즈 (geopolitical / financial_transmission / tech_architecture / accident_causality / market_structure / stakeholder / structural / cascade / red_team / pre_mortem 등) 가 각자 finding 을 emit. 각 finding 은 claim + evidence_id 1+ 강제.counter_hypothesis 로 보존. 신뢰도 3축 분해 (출처 다양성·신선도·전문가 합의) 산출.cited_claim_ids 로 evidence 추적성 강제. 차트는 embedded_charts: [chart-id] 에 적은 것만 본문에 박힘. 실패 시 archetype 폴백.ComposedReport 또는 (실패 시) archetype 의 section_plan 을 받아 mono 테마 HTML 생성. freeform_essay.html 또는 report_block.html 폴백. wrangler 로 Cloudflare Pages 에 배포 후 URL 반환.watch_signals 를 SQLite 레지스트리에 INSERT. 텔레그램 /watchlist, /fire 명령으로 후속 추적.fast 5회 (context + strategy + scenarios + lens 1 + composer) · standard 8회 · deep 13회. Quick mode 진입 시 모든 에이전트가 Sonnet 4.6 으로 다운그레이드.
현재 v3.5.0 에서 살아있는 7개 에이전트. 좌측 보더 굵은 솔리드 = Opus 라인 (heavy). 점선 사선 패턴 = Sonnet 라인 (light). 골드 글로우 = 편집장 (Opus 4.7).
웹 검색으로 사건의 사실/타임라인/핵심 수치/출처 URL 수집. 1차 evidence 의 출처가 됨.
3~5개 시나리오 (기본/최선/최악/구조전환) + 감시 신호 + 무효화 조건. confidence + driver_signals 도 emit.
핵심 행위자 식별, 입장·자원·전략·취약점·관계 구도. fast/standard 에서는 stakeholder lens 가 대체.
구조적 원인, 비대칭, 피드백 루프, 전환점, 인지 편향, 반대가설. fast/standard 에서는 structural lens 가 대체.
인과 사슬 (단계별 severity / time_horizon / 가역성), 차단 지점, 와일드카드, 최악의 경우. fast/standard 에서는 cascade lens 가 대체.
모든 finding 의 모순 표면화 (봉합 금지). 신뢰도 3축 분해. core_question 미답변 자동 감지.
7명의 분석가 결과를 받아 보고서 본문을 자유 형식으로 작성. 섹션 수/제목/순서/톤/pull quote/차트 referencing 모두 결정. claim 인용 강제로 evidence 추적성 보존.
Gate 1 (계획 sanity) + Gate 2 (커버리지). deep 에서만 LLM, 그 외 휴리스틱. 실패 시 1회 재시도.
v3.0~v3.4.x 에 있던 시각화 LLM. v3.5.0 에서 모든 모드의 LLM 경로가 사실상 비활성. visual_builder.py 의 결정적 빌더가 9종 차트 데이터를 추출하지만, 자동 박힘은 차단됨. 편집장이 명시 reference 한 차트만 본문에 박힘.
사건 카테고리 × 의도 × 모드 → lens_policy.select_lenses() 가 결정. 한 사건당 1~4종 (mode 별 cap). 각 렌즈는 독립 LLM 호출로 finding 을 emit.
| lens_id | 적용 분야 | 핵심 기법 |
|---|---|---|
| geopolitical | 전쟁·외교·안보 | DIME / PMESII / Escalation Ladder / Capability-Intent |
| financial_transmission | 금융·거시 | Balance Sheet / Flow of Funds / Transmission Channel / Liquidity Stress |
| tech_architecture | 기술·AI·IT | Architecture Decomposition / Dependency Graph / Bottleneck |
| accident_causality | 사고·재난 | Fault Tree / Bow-Tie / Swiss Cheese / STAMP |
| policy_implementation | 정책·규제 | Stakeholder Incentive / Distributional Impact / Implementation Gap |
| market_structure | 시장·산업 | Network Analysis / Game Theory / Regime Shift |
| stakeholder | 행위자 분석 (페르소나 대체) | 이해관계자 식별·전략 매핑 — fast/standard 에서 PlayerAnalyst 대체 |
| structural | 구조 분석 (페르소나 대체) | 피드백 루프·전환점 — fast/standard 에서 DynamicsAnalyst 대체 |
| cascade | 인과 사슬 (페르소나 대체) | 전이 경로·차단점 — fast/standard 에서 ChainReactionAnalyst 대체 |
| red_team | 메타 (반론) | ACH / Devil's Advocate — what_to_do, where_vulnerable 의도 |
| pre_mortem | 메타 (실패 시뮬) | 실패 가정 후 역설계 — what_next, where_vulnerable 의도 |
v3.5.0 에서 멀티컬러 6테마 (burgundy/geopolitical/financial/tech/nature/liquidglass) 를 통째 폐기하고 mono 2종만 사용. 카테고리 구분은 hue 가 아니라 패턴 (45° hatch) 과 명암으로. lens_policy.select_theme() 이 사건 카테고리에서 자동 선택.
딥와인 + 앰버 골드 + 파치먼트. 정보 밀도 높은 분석에 적합. 일반·금융·기술·지정학·산업·사고 사건의 기본 테마.
크림 + 딥버건디 + 포레스트 그린. 편집·인쇄·문서 친화. 정책 사건 (policy_implementation) 의 기본 테마.
색이 한 hue 로 수렴하므로 카테고리 구분은 4종 패턴 + 액센트 솔리드로. 모든 사선은 45° 한 방향만 (Anti-pattern: cross-hatch / opposite diagonals 금지).
visual_builder.build_chart_payload() 가 분석 결과에서 9종 차트 데이터를 결정적으로 추출. 그러나 자동 박지 않음. 편집장이 본문에서 명시 reference 한 chart-id 만 freeform_essay.html 에서 렌더 (mono guide anti-pattern #6: 무지성 차트 박힘 차단).
| chart-id | 형식 | 데이터 출처 | Insight Gate |
|---|---|---|---|
| chart-scenarios | 막대 | scenarios[].probability | ≥1 |
| chart-figures | 도넛 | context.key_figures | ≥3 + non-uniform |
| chart-severity | 히트맵 | chain_reaction.chain[].severity | ≥1 |
| chart-confidence | 3축 | judgment.confidence (3축) | 판단 존재 |
| chart-stacked | 누적 막대 | scenarios[].impact_by_player | ≥4 segments + non-uniform |
| chart-bubble | 버블 | chain.wildcards (확률 × 영향) | ≥1 |
| chart-gantt | 간트 | context.timeline | ≥2 |
| chart-network | 포스 | players.players + alliances | ≥2 nodes |
| chart-timeseries | 선 | (예약 — 미사용) | — |
① 분석 끝 → ② build_chart_payload() 가 가용 차트 데이터 추출 → ③ build_chart_catalog() 가 편집장에게 "지금 가용한 차트 목록" 전달 → ④ 편집장이 본문 작성 시 embedded_charts: ["chart-id"] 로 명시 → ⑤ 그 chart-id 만 freeform_essay.html 의 차트 카드로 렌더. 편집장이 reference 안 한 차트는 박히지 않음.
v3.4.7 → v3.5.0 의 단일 PR. 보고서 자유도 확보 + mono 표준 적용 + 차트 무지성 박힘 차단.
token_budget: fast/standard 에도 use_llm_narrative_composer=True. max_llm_calls cap +1 (fast 4→5, standard 7→8).report_block.html: "DATA DASHBOARD / 한눈에 보기" 섹션 통째 삭제 (9개 차트 슬롯). 무지성 박힘 영구 차단.report.css: 6 멀티컬러 테마 정의 (burgundy/geopolitical/financial/tech/nature/liquidglass) 통째 폐기.report.css: burgundy_mono + light_mono 정의 (mono guide §3 팔레트). 컴포넌트 클래스용 legacy alias (--red→--down 등) 로 호환 보존.lens_policy.select_theme(): 매핑이 mono 2종만 emit. policy 사건은 light_mono, 그 외 burgundy_mono.data-theme = burgundy_mono.AnalysisStrategy.theme 디폴트 + _empty_strategy_fallback + orchestrator fallback 모두 burgundy_mono.다중 에이전트 + 렌즈 파이프라인을 1~2개로 압축해 분석 깊이를 trade-off 하는 변경은 v3.5.0 에서 진행하지 않음. 이해관계 분석관 / 구조 분석관 / 종합 판단관 등 7개 에이전트 모두 살아있음. v3.5.0 의 자유도 결과를 며칠 운용해본 뒤 깊이가 충분한지 확인하고 결정할 사안.
v3.5.0 의 핵심 파일. 골드 = 디렉토리, 진한 텍스트 = SSOT 위치.
python -m src.main 진입점
docs/
├── MONO_THEME_GUIDE.md ← 본 페이지의 SSOT (Tier 2)
├── ARCHITECTURE.md
├── REPO_MAP.md
├── CATALOGS.md
└── DATA_MODELS.md
samples/
├── chart_map_mono_compare.html ← mono 비교 샘플
└── v3_5_0_architecture.html ← 본 페이지코드 변경 시 VM 의 봇 프로세스 재기동 필요. orchestrator 가 프로세스 시작 시점에 BUILD_INFO (branch / commit / VERSION) 를 캡처해 텔레그램 /status 응답에 노출.
cd ~/agents_reviewer
git pull origin main
kill -9 <old_pid>
source venv/bin/activate
nohup python -m src.main > bot.log 2>&1 &
disown
확인: 텔레그램 /status → commit: 733d604 / VERSION: v3.5.0 출력. 옛 commit 이 보이면 재기동 안 된 것.