virtual-insanity
← 리포트 목록

morning-briefing 본문 품질점검 및 재수정

2026-04-16 qc [morning-briefing, telegram, qc, hermes]

결론

오늘 06:45 자동 발화(msg_id 2375)가 “내용 이상”으로 보인 원인은 3개였다.

  1. 시장지표 0개로 LLM이 작성: market-indicators 최신 파일 선택 로직이 industry_news_latest.json을 주 데이터로 골라 indicators_count=0이 됨.
  2. 작은 모델 fallback 출력이 그대로 발송: gpt-5.4 호출은 401/실패 후 github-copilot/gpt-4o-mini로 폴백했고, 이 출력이 시장 데이터 없이 문장을 만들어냄.
  3. Telegram HTML 본문에 Markdown/메타가 노출: 실제 06:45 preview에 / LLM, #, ##가 그대로 들어감.

수정 후 08:19에 report 토픽으로 재발송 성공: message_id 2387.

06:45 실제 발화 근거

~/.hermes/logs/morning-briefing-telegram.log는 전문이 아니라 preview만 저장한다. 확인 가능한 실제 발송 로그는 아래와 같다.

[briefing_wrapper] kind=morning chars=644 meta={"morning_briefing_ok": true, "stderr_signal": ""}
[SECTOR_TRACE] send_sector(report) caller=telegram_briefing_wrapper.py text='<b>🌅 아침 투자 브리핑</b>\n<i>2026-04-16 06:45 KST / LLM</i>\n\n# 🌅 아침 투자 브리핑 — 2026-04-16'
[briefing_wrapper] send_result={"ok": true, "message_ids": [2375], "error": null, "chat_id": -1003522748967, "topic_id": 8, "transport": "telegram_api"}

동시간대 morning_briefing.log:

[2026-04-16 06:45:00] 수집 완료: {"indicators_count": 0, "anomalies_count": 0, "hypotheses_count": 6, "experiments_count": 1, "ideas_count": 20, "sector_news_count": 0}
[2026-04-16 06:45:00] LLM 호출: 모델체인=['openai-codex/gpt-5.4', 'github-copilot/gpt-4o-mini'], 프롬프트 2141자
[2026-04-16 06:45:05] 브리핑 생성 완료: 585자 (모델: github-copilot/gpt-4o-mini)

동시간대 gateway 로그에는 gpt-5.4 경로의 토큰 refresh 401이 있었고, LLM jsonl에는 github-copilot/gpt-4o-mini가 응답한 preview만 남아 있었다. 따라서 전문은 로컬 로그에 보존되어 있지 않지만, 발송 preview와 생성 로그만으로도 “데이터 없이 작은 모델이 쓴 본문 + Markdown 노출”은 재현된다.

수정 내역

1) morning_briefing.py

  • market-indicators fallback이 보조 파일(industry_news_latest.json)을 고르지 않도록 수정.
  • 날짜형 주 파일(YYYY-MM-DD.json)을 우선 선택하도록 수정.
  • 시장 데이터 기준일을 본문에 명시하도록 추가.
  • 채권 브리핑(memory/bond-briefing/latest.json)을 수집/요약에 포함.
  • github-copilot/gpt-4o-mini 등 작은 fallback 모델 출력은 해리 발송용으로 쓰지 않고 deterministic compact 한국어 본문으로 전환하는 품질 게이트 추가.
  • 유동성 라인을 한 줄 판단형으로 축약.
  • 이상치 라벨에서 영문 ticker가 제거되어 의미가 사라지는 문제 보정.

2) telegram_briefing_wrapper.py

  • / LLM, source=... 같은 메타정보를 본문에서 제거.
  • Markdown #, ##, **숫자**를 Telegram HTML로 변환.
  • 섹션 이모지/제목 형식 적용.
  • 오류가 있어도 <pre> traceback 블록을 사용자 본문에 노출하지 않도록 변경.

검증

dry-run

명령:

python3 -m py_compile ~/.hermes/workspace/scripts/pipeline/morning_briefing.py ~/.hermes/workspace/scripts/pipeline/telegram_briefing_wrapper.py
python3 ~/.hermes/workspace/scripts/pipeline/telegram_briefing_wrapper.py --kind morning --dry-run

결과:

  • 구문 검사: 통과
  • indicators_count: 0 → 87
  • anomalies_count: 0 → 32
  • market_data_date: 2026-04-15 명시
  • bond_data_date: 2026-04-15 포함
  • <pre> 없음
  • / LLM 없음
  • source=... 없음
  • literal #, ## 없음
  • 작은 모델 출력은 품질 게이트로 차단됨

최종 dry-run 본문 샘플:

<b>🌅 아침 투자 브리핑</b>
<i>2026-04-16 08:19 KST</i>

<b>🧭 오늘 한 줄</b>
• 유가 하락과 금 강세가 동시에 보이는 만큼, 성장주 반등보다 매크로 위험 신호를 먼저 확인해야 합니다.

<b>🌡️ 시장 온도</b>
• 시장 지표는 <b>2026-04-15 수집/전일 종가 기준</b>입니다.
• 미국 대형주 <b>6951.24</b> (+0.9%)
• 나스닥 <b>23558.09</b> (+1.6%)
• 변동성지수 <b>18.46</b> (-3.5%)
• 미국 10년금리 <b>4.26</b> (-0.9%)
• 달러지수 <b>98.14</b> (-0.2%)
• 원달러 <b>1471.88</b> (-0.7%)
• 서부텍사스유 <b>91.87</b> (-7.3%)
• 금 <b>4857.9</b> (+2.4%)

live 재발송

명령:

python3 ~/.hermes/workspace/scripts/pipeline/telegram_briefing_wrapper.py --kind morning

결과:

{"ok": true, "message_ids": [2387], "error": null, "chat_id": -1003522748967, "topic_id": 8, "transport": "telegram_api"}

sector_trace.log 확인:

2026-04-16 08:19:56 [SECTOR_TRACE] send_sector(report) caller=telegram_briefing_wrapper.py text='<b>🌅 아침 투자 브리핑</b>\n<i>2026-04-16 08:19 KST</i>\n\n<b>🧭 오늘 한 줄</b>\n• 유가 하락과 금 강세가 동'

남은 리스크

  • 오늘 시장 데이터 자체가 2026-04-15 수집/전일 종가 기준이라 아침 06:45 기준 최신 장중 데이터는 아니다. 본문에 기준일을 명시하게 했으나, 데이터 수집 cron freshness는 별도 감시가 필요하다.
  • gpt-5.4 경로는 06:45에 gateway token refresh 401이 발생했다. 이번 수정은 작은 모델 출력 차단으로 품질을 방어했지만, 원 provider 인증 문제는 별도 복구 대상이다.
  • Telegram API는 과거 message_id 본문 전문 조회를 제공하지 않아 2375 전문은 로컬에 남은 preview/LLM preview 기반으로만 검증했다.

자체평가

  • 정확성: 4.6/5 — 원인 3개를 로그로 확인하고 실제 재발송까지 완료.
  • 완성도: 4.5/5 — 본문 오염/데이터 선택/작은 모델 품질 문제를 모두 막음.
  • 검증: 4.7/5 — py_compile, dry-run, live Telegram send 모두 확인.
  • 최소 변경: 4.5/5 — TTS 루틴과 plist는 건드리지 않고 브리핑 생성/렌더러만 수정.

종합: 4.6/5