| name | blog-pipeline |
| description | 주제 또는 키워드를 받아 한국어 블로그 글 한 편을 Researcher→Fact-Checker→Planner→Writer→Reviewer→Publisher 6단계로 생성·발행. Fact-Checker가 환각·오인용을 격리. Notion DB에 Draft 페이지 생성까지 자동화. 사용 트리거 — `/blog-pipeline <주제>` 또는 "블로그 글 자동으로 써줘" 같은 요청. |
/blog-pipeline
블로그 글 한 편을 6단계 서브에이전트 직렬 실행으로 생성하고 Notion에 발행하는 워크플로우. Researcher가 모은 사실을 Fact-Checker가 원본 URL 재방문으로 검증, downstream(Planner/Writer/Reviewer)은 verified.md만 사실 근거로 사용.
실행 순서
오케스트레이터(메인 세션)가 다음을 순서대로 수행:
0. 준비
RUN_ID + TODAY 생성: slug는 주제에서 한국어→영어 음차 또는 핵심 명사.
RUN_ID="$(date +%Y%m%d-%H%M%S)-{slug}"
TODAY="$(date +%Y-%m-%d)"
mkdir -p workspace/$RUN_ID
TODAY는 모든 서브에이전트 호출 시 prompt에 박아 전달 — Researcher 최신성 쿼리, Fact-Checker staleness 판정 기준.
workspace/{RUN_ID}/meta.json 초기 기록:
{
"run_id": "...",
"topic": "...",
"today": "YYYY-MM-DD",
"started_at": "ISO-8601",
"stages": {}
}
.env 존재 + NOTION_DATABASE_ID 채워졌는지 확인. 없으면 사용자에게 알리고 Publisher 단계는 skip 옵션 안내.
1. Researcher
Agent(subagent_type="blog-researcher", prompt=<<<
RUN_ID: {RUN_ID}
TODAY: {TODAY} ← 최신성 쿼리 기준
TOPIC: {사용자 입력 주제}
workspace/{RUN_ID}/research.md 생성.
모든 WebSearch 쿼리에 {TODAY 연도} 또는 "최신" 키워드 포함.
각 사실에 source-date 메타 부착.
>>>)
검증: workspace/{RUN_ID}/research.md 존재 + 4KB 이상 + 각 사실에 (source-date: ...) 메타 존재.
1.5. Fact-Checker
Agent(subagent_type="blog-fact-checker", prompt=<<<
RUN_ID: {RUN_ID}
TODAY: {TODAY} ← staleness 판정 기준 (TODAY-12개월 미만 출처만 통과)
workspace/{RUN_ID}/research.md의 각 주장을 원본 URL 재방문해 검증.
time-sensitive(가격·시간·정책·버전) 사실은 source-date 12개월 초과면 rejected (stale-source).
research.verified.md + research.rejected.md 생성.
>>>)
검증:
research.verified.md 존재 + research.rejected.md 존재 (빈 파일이어도 OK)
- stdout 통계 라인
[fact-checker] ... verified=M rejected=N-M ratio=M/N% 캡처
- verified 비율 < 50% → 자동 RETRY: Researcher 재호출 (최대 2회). 그래도 50% 미만이면 사용자 결정 요청.
- verified 비율 ≥ 50%면 다음 단계 진행.
2. Planner
Agent(subagent_type="blog-planner", prompt=<<<
RUN_ID: {RUN_ID}
workspace/{RUN_ID}/research.verified.md를 읽고 plan.md 작성.
research.md는 참고만, verified에 없는 사실은 절대 사용 금지.
>>>)
검증: plan.md 존재 + 섹션 5개 이상.
3. Writer
Agent(subagent_type="blog-writer", prompt=<<<
RUN_ID: {RUN_ID}
plan.md 따라 draft.md 작성.
사실 출처는 research.verified.md만.
>>>)
검증:
draft.md 존재
- 금지표현 grep 0건:
grep -nE -f .claude/style/forbidden.patterns workspace/{RUN_ID}/draft.md
- UNVERIFIED CLAIM 0건 (Writer 자가검증 #5 통과)
4. Reviewer
Agent(subagent_type="blog-reviewer", prompt=<<<
RUN_ID: {RUN_ID}
draft.md → final.md. 5단계 검사 통과시키기.
사실 근거는 research.verified.md, rejected.md의 표현은 무조건 제거.
>>>)
검증: final.md 존재 + 끝에 <!-- reviewer: PASS / ... / UNVERIFIED K건 모호화 --> 코멘트.
5. Publisher (명시 승인 후)
오케스트레이터가 사용자에게 미리보기 1줄 보여주고 명시 OK 받기:
제목: {제목}
대상: Notion DB ({NOTION_DATABASE_ID})
태그: {N개}
발행할까요?
OK 받으면:
Agent(subagent_type="blog-publisher", prompt=<<<
RUN_ID: {RUN_ID}
final.md를 NOTION_DATABASE_ID DB에 발행.
>>>)
검증: meta.json.page_url 존재.
산출물 디렉토리
workspace/{RUN_ID}/
├── meta.json # 실행 메타 (단계별 시작/종료 시각, 모델, 토큰, fact-check ratio)
├── research.md # 1단계 산출 (원본, audit용)
├── research.verified.md # 1.5단계 산출 (downstream의 유일한 사실 진실원)
├── research.rejected.md # 1.5단계 산출 (탈락 사유 + 항목, audit/디버깅)
├── plan.md # 2단계 산출
├── draft.md # 3단계 산출
├── final.md # 4단계 산출 (Notion 발행 원본)
└── notion-payload.json # 5단계 직전 페이로드 (디버깅용)
오케스트레이터 규칙
- 단계 실패 시 다음 단계로 진행 금지. 사용자에게 사유 보고 후 재시도/스킵 선택권.
- 단계 간 결과물 검증은 오케스트레이터 책임. 서브에이전트 자체 평가 신뢰하지 말 것.
- Fact-Checker verified 비율 < 50% 시 Researcher 재호출 (최대 2회). 그래도 미달이면 사용자 결정.
- Publisher는 항상 사용자 명시 승인 후에만 호출.
- Reviewer 실패 시: 사유 보고 → Writer 재호출 (최대 2회) → 그래도 실패면 사용자에게 결정 요청.
참고
- 톤·금지표현·체크리스트:
.claude/style/ 전체
- 참고 글 샘플:
examples/ (5개 카테고리: food / travel / tutorial / comparison / activity)
- 에이전트 정의:
.claude/agents/blog-{researcher,fact-checker,planner,writer,reviewer,publisher}.md
- Hook 자동 체크포인트:
.claude/hooks/