bond_daily 실제 본문 품질점검 및 즉시 개선
결론
해리 피드백이 맞았다. PDF 폰트 문제와 별개로 본문 품질 문제가 있었다.
가장 큰 원인은 3개였다.
1. LLM이 N/A를 시장 해석으로 과잉 번역했다.
2. 파서가 한 줄로 뭉친 Gmail 노트에서 낙찰/스프레드 일부를 놓쳤다.
3. 새벽 이후 도착한 아침 입찰 메일이 일일 마감 리포트보다 최신으로 잡힐 위험이 있었다.
즉시 수정했다.
- LLM 본문 생성 기본값을 끄고, 검증 가능한 숫자 기반 deterministic renderer로 바꿨다.
- 낙찰 파서를 보강해 1건 → 12건으로 복구했다.
- 크레딧 스프레드 음수 파싱을 복구했다.
- bond_daily_report가 아침 금일 입찰 안내보다 일일/마감 노트를 우선 고르도록 바꿨다.
- 재실행 후 새 PDF를 실제 발송했다: 그룹 message_id=51890, DM message_id=11648.
확보한 최신 본문
점검 대상 이전 PDF:
- /Users/ron/.hermes/workspace/memory/bond-briefing/briefing_2026-04-15.pdf
- 2026-04-16 02:33 cron 산출물
- 그룹 발송: message_id=51871
- pdftotext로 /tmp/bond_latest_20260416.txt 추출
개선 후 PDF:
- /Users/ron/.hermes/workspace/memory/bond-briefing/briefing_2026-04-15.pdf
- 2026-04-16 08:21 재실행 산출물
- 그룹 발송: message_id=51890
- pdftotext로 /tmp/bond_qc_after_notify_pdf.txt 추출
이전 본문 샘플
채권 트레이더 브리핑 | 2026-04-15
안녕, 후배야. 오늘 시장 데이터를 쏙쏙 뽑아 봤어. 숫자만 외우는 게 아니라, 그 숫자 뒤에 숨겨진 시장의 숨을 따라
가자. 15 년 차 트레이더가 보는 눈으로, 오늘 하루를 정리해 볼게.
**[PART 1 — 시장 온도 읽기]**
**[헤드라인]** 글로벌 침묵 속 국내 금리, 3-10 스프레드가 숨 쉬는 순간
**[1A. 글로벌 금리판]**
미국채 2Y: N/A (N/A) 10Y: N/A (N/A)
2-10 스프레드: N/A
달러/원: N/A WTI: $N/A
▶ 커브 해설:
오늘은 글로벌 데이터가 아예 들어오지 않아. 미국과 유가가 보이지 않는 상태라, 우리는 '글로벌 커브'를 직접 보지
못해. 대신 국내 커브가 어떻게 움직였는지가 더 중요해.
개선 후 본문 샘플
채권 트레이더 브리핑 | 2026-04-15
요약부터 말할게. 오늘 본문은 확인된 숫자만 사용했다. 글로벌 데이터가 비어 있는 부분은 해석하지 않았다.
**PART 1 — 어제 낙찰/수요예측 한눈에 보기**
- 낙찰 구조화 건수: 12건
- 구조화 낙찰금액 합산: 13,800억
- 최고 응찰배율: 한국가스공사 7D 4.17x
- 최저 응찰배율: 한전 5Y 1.0x
| 발행사(등급) | 만기 | 금리/스프레드 | 금액 | 응찰 | 구분 |
| :--- | :--- | :--- | ---: | ---: | :--- |
| 한국가스공사(A1) | 7D | 2.51% | 1,200억 | 4.17x | CP/전단채 |
| 통안채(국고) | 3Y | 3.38% | 1,000억 | 1.44x | 국고/통안 |
| 재정증권(국고) | 63D | 2.64% | 2,500억 | 1.82x | 국고/통안 |
| 한국가스공사(AAA) | 2Y | 민평-2.0bp | 1,200억 | 2.75x | 공사채 |
| 한국가스공사(AAA) | 3Y | 민평-1.0bp | 900억 | 2.89x | 공사채 |
이상 포인트 8개
| # | 이상 포인트 | 이전 본문 증거 | 원인 | 조치 |
|---|---|---|---|---|
| 1 | N/A를 시장 상황처럼 해석 | 글로벌 침묵 속 |
글로벌 데이터가 {}인데 LLM이 의미를 부여 |
deterministic 본문에서 수집 안 됨으로만 표기 |
| 2 | N/A 수치가 본문 중심을 차지 | 미국채 2Y: N/A |
LLM 프롬프트가 글로벌 섹션을 강제 | 글로벌 섹션을 짧은 경고 문장으로 축소 |
| 3 | RP 해석 과장 | 금리 인하 사이클 |
RP -2bp를 정책금리 신호로 과잉 해석 | 단기자금 수급 신호로만 제한 |
| 4 | 용어 오류 | RP(리피드) |
LLM 환각 | LLM 본문 생성 제거 |
| 5 | 낙찰 누락 | 로그 낙찰: 1건 |
Gmail 노트가 한 줄로 뭉쳐 기존 섹션 파서 실패 | loose auction parser 추가, 12건 파싱 |
| 6 | 크레딧 스프레드 누락 | 스프레드 데이터는 |
스프레드 정규식이 음수 값을 못 읽음 | -0.2 같은 부호 있는 숫자 허용 |
| 7 | 커브 수치 혼선 | 2-10 스프레드 |
프롬프트는 3-10, 내부 계산은 2-10 성격 혼재 | deterministic에서 3Y-10Y로 28.5bp 계산 |
| 8 | 섹션 구조 불일치 | 오늘 4개 이상 |
퀴즈/강의 중심이라 해리가 보는 시장 요약과 다름 | 낙찰/발행/금리/신용/뉴스/판단 6파트로 재구성 |
수정 파일과 핵심 변경
/Users/ron/.hermes/workspace/scripts/pipeline/bond_report_parser.py
164-180: 크레딧 스프레드 정규식이 음수 전일비를 읽도록 수정.328-344: 기존 섹션 파서가 놓친 낙찰을 loose parser로 보강하고 중복 제거.347-470: 한 줄 Gmail 노트용 낙찰 보강 파서 추가.- 통안채/재정증권 조 단위 낙찰
- 개별 언더/오버 공사채
- 일물 전단채
- MBS 스프레드 낙찰
결과:
수정 전: 낙찰 1건, spreads {}
수정 후: 낙찰 12건, spreads {'bank_aaa_2y_chg_bp': -0.2, ...}
/Users/ron/.hermes/workspace/scripts/pipeline/bond_daily_report.py
75-95:_find_latest_hwang_note()가일일/마감노트를 우선 선택하도록 수정.420-579:_build_factual_report()추가.- 낙찰/발행/금리/신용/뉴스/판단 구조
- 확인된 숫자만 사용
- N/A 해석 금지
- RP 과잉해석 방지
1196-1201: 메인 본문 생성 경로를 LLM → deterministic factual renderer로 전환.1203-1208: 리포트 중점 포인트도 LLM 없이 제목/URL만 직접 렌더링.
핵심 diff 요약:
- insight, used_model, err = llm_chat_with_fallback(...)
- log(f"LLM 완료 (모델: {used_model}, {len(insight)}자)")
+ insight = _build_factual_report(data, prev)
+ used_model = "deterministic-factual-renderer"
+ log(f"본문 생성 완료 (모델: {used_model}, {len(insight)}자)")
- candidates.sort(key=lambda p: p.name, reverse=True)
- return candidates[0]
+ daily = [p for p in candidates if ("일일" in p.name or "마감" in p.name)]
+ target = daily or candidates
+ target.sort(key=lambda p: p.name, reverse=True)
+ return target[0]
재실행 결과
실행 명령:
cd /Users/ron/.hermes/workspace
PYTHONPATH=/Users/ron/.hermes/workspace/scripts/shared:/Users/ron/.hermes/workspace/scripts/pipeline \
/usr/bin/python3 /Users/ron/.hermes/workspace/scripts/pipeline/bond_daily_report.py --notify
로그:
[2026-04-16 08:21:31] bond_daily_report 시작
[2026-04-16 08:21:31] 노트: 260415_황대진_전달-일일-415-수-채권시장-마감정리-DS증권-황대진.md
[2026-04-16 08:21:31] 파싱 완료 — 타입: 입찰안내, 날짜: 2026-04-15, 낙찰: 12건
[2026-04-16 08:21:31] 본문 생성 완료 (모델: deterministic-factual-renderer, 2422자)
[2026-04-16 08:21:31] PDF 생성: /Users/ron/.hermes/workspace/memory/bond-briefing/briefing_2026-04-15.pdf (93KB) [ReportLab AppleGothic]
[2026-04-16 08:21:34] 텔레그램 그룹 PDF: 성공 message_id=51890 error=None
[2026-04-16 08:21:37] PDF DM 전송: briefing_2026-04-15.pdf message_id=11648 error=None
PDF 검증:
path=/Users/ron/.hermes/workspace/memory/bond-briefing/briefing_2026-04-15.pdf
size=95749
Pages=3
AppleGothic embedded=yes
품질 grep:
글로벌 침묵: 0
리피드: 0
Reference Price: 0
강력한 신호: 0
작성 원칙: 0
고정 포맷: 0
현재 남은 한계
- 수요예측 결과와 익일 입찰 안내는 원문에 있으나 아직 구조화 파서가 충분히 읽지 못한다. 그래서 개선본은 “원문 확인 필요”라고 보수적으로 처리한다.
- 리포트 URL 중
koscom계열은 원문 내 공백 때문에 일부가 짧게 잘리는 경우가 남아 있다. - 본문은 정확성 우선으로 바꿔 교육적 해설의 깊이는 줄었다. 깊이 해설은 다음 단계에서 deterministic 숫자 요약 위에 별도 LLM 해설을 붙이는 방식이 안전하다.
자체평가
- 정확성: 4.6/5 — 낙찰 12건, 금리, 스프레드, RP, 발행 물량을 확인된 데이터로 재생성.
- 완성도: 4.4/5 — 핵심 품질 문제는 해결. 수요예측/익일입찰 세부 파서는 후속 필요.
- 검증: 4.8/5 — py_compile, parser 직접 실행, dry-run, notify 재실행, PDF 텍스트 추출, Telegram message_id 확인.
- 최소 변경: 4.1/5 — LLM 본문을 우회하는 변경은 작지 않지만, 품질 사고를 즉시 막기 위한 범위 내 조치.
종합: 4.5/5