BLUEPRINT_SYSTEM_PROMPT Rule 19는 "schedule a demo"를 avoidMention dead phrase로 지정하고, step goal arc에 "meeting"이 아예 없다.STEP_TEMPLATES_KO(Step 3·5·6 하드코딩). 유혜림이 본 미팅 문구는 AI가 "제안"한 게 아니라, 본문 템플릿이 blueprint 설계를 무시하고 주입한 것.goal·avoidMention을 전달하지 않는다. blueprint가 "demo 금지"로 설계해도 본문은 stepOrder만 보고 고정 미팅 템플릿을 재현한다.avoidMention 파이프라인의 미연결(누락)을 잇는 일에 가깝다. PR #8885로 발송·제안이 단일 SSOT가 되어 수정 지점도 1곳으로 좁혀졌다.바이어(유혜림 대표, 디자인플레이하우스)가 "영어 미팅 진행이 어려워, 발송 메일에서 미팅 제안 문구를 제외하고 싶다"고 요청. 우선 이메일로 소개서·도매조건을 전달하고 관심 바이어와 메일로만 소통하려는 의도.
| # | 질문 | 결론 (v2) |
|---|---|---|
| Q1 | 미팅 제안에 강제 코드가 있는가? | 있음 — 단, AI 제안이 아니라 본문 템플릿 |
| Q2 | 미팅 제거 발송이 가능한가? | avoidMention 연결로 가능 · 소규모 |
"AI 시퀀스 제안" 기능은 두 개의 독립된 LLM 호출로 구성된다.
stepOrder로 STEP_TEMPLATES_KO 고정 템플릿을 선택해 본문 작성. 실제 발송(personalized-email-streaming)과 동일한 단일 SSOT (PR #8885).sequenceEmailAgent(자체 "MISSION: lead to MEETINGS" 하드코딩)가 3,499줄과 함께 삭제됐다. 이제 ②는 발송과 동일한 step-strategies SSOT를 쓴다 → 프리뷰와 발송이 1:1 일치, drift 경로 1개 제거.
BLUEPRINT_SYSTEM_PROMPT(blueprint.prompt.ts) 전문 검토 결과, 미팅/demo/call 관련 지시는 단 1곳이며 회피 지시다.
blueprint이 생성하는 필드: recommended(language·tonePersona·sendHour) · schedule[](goal·delayDays·angle·mustMention·avoidMention·reasoningNote) · rationale · riskFlags · usedAssets. 어디에도 미팅 CTA 지시가 없다.
본문은 getStepRecipe(stepOrder)가 STEP_TEMPLATES_KO[stepOrder] 고정 템플릿을 주입하고, OUTPUT RULES가 "문장 구조/순서/톤을 최대한 보존"하라 강제한다 → 템플릿의 미팅 문장이 결과에 그대로 재현.
워커(sequence-proposal-preview-email.worker.ts:269-281)는 본문 생성 ctx에 blueprint의 goal·avoidMention을 전달하지 않는다. 오직 stepOrder(고정 템플릿 선택)와 angle(customPrompt로 격하)만 넘긴다.
| Step | blueprint 설계 (Rule 8) | 실제 본문 (STEP_TEMPLATES_KO) |
|---|---|---|
| Step 3 | social_proof | 긴급성 트리거 + "미팅 제안" CTA |
| Step 5 | objection_handling | "10분 정도만 시간 내 주시면" |
| Step 6 | social_proof | "10분만 시간 내주시면" |
| Step 7 | urgency | 거절 가능성 염두 |
avoidMention: ["schedule a demo"]로 설계해도, 본문은 stepOrder=3이면 무조건 STEP_TEMPLATES_KO[3]의 "미팅 제안을 드리고 싶었습니다"를 재현한다. AI 제안의 의도(미팅 회피)와 실제 발송 본문(미팅 강제)이 정면으로 어긋난다. 유혜림이 본 미팅 문구는 AI가 제안한 전략이 아니라, 본문 템플릿이 blueprint를 무시하고 끼워 넣은 것이다.
| 파일:라인 | 내용 | 상태 |
|---|---|---|
step-templates-ko.ts:64-65,105,122,185 | Step 3·5·6 "미팅/10분" + mission | 잔존 |
prompt-builder.ts:413,439 | CTA 옵션 "10-min ask" | 잔존 |
static-quality-guide.ts:22,48 | "30-min demo / 20-min call" | 잔존 |
email-reply-agent/prompts.ts:21,28,31 | 답장 "즉시 미팅 제안" + Calendly | 잔존 (답장 경로) |
sequence-email-agent/prompts.ts:42,112 | "MISSION: lead to MEETINGS / 10-min call" | 삭제됨 |
PR #8885로 Mastra 시퀀스 제안 경로가 사라져, 본문 미팅 출처는 사실상 STEP_TEMPLATES_KO 단일 SSOT로 수렴했다(+ 답장은 별도 경로).
근본 원인은 "영어 미팅 불가" → 진짜 제약은 미팅이 아니라 언어다. 미팅을 삭제하는 대신, 이미 설계된 avoidMention 파이프라인을 본문까지 연결해 drift를 없애는 것이 제1원리 해법이다.
| 우선순위 | 방안 | 성격 |
|---|---|---|
| 최적 | 워커가 blueprint의 avoidMention(이미 "schedule a demo" 포함)을 본문 생성 ctx로 전달 → prompt-builder가 avoidMention을 강한 가드로 주입 + Step 3·5·6 미팅 CTA를 avoidMention 매칭 시 대체 CTA로 치환 | 기존 메커니즘 연결 · drift 해소 |
| 보강 | blueprint이 email_first 의도(영어 미팅 불가 등)를 감지하면 avoidMention에 "미팅 제안 / 10분 통화"를 자동 추가 | 유혜림 케이스 직접 충족 |
| 비권장 | 전역 상수 STEP_TEMPLATES_KO에서 미팅 문구 일괄 삭제 | 전 워크스페이스 영향 · 금지 |
① 워커: ctx.step에 goal·avoidMention 포함해 전달
② prompt-builder: avoidMention을 LOCK급 가드로 주입
③ step-strategies: avoidMention에 미팅류 포함 시 Step 3·5·6 CTA 치환
④ static-quality-guide: demo/call 예시 중립화 (1024 토큰 가드 유지)
⑤ email-reply-agent: Calendly 블록 조건부
발송·제안 프리뷰가 단일 SSOT라 ②③ 한 번 고치면 양쪽 동시 적용
고관심 단계(Step 7~8)는 "한국어로 응대 가능한 담당자가 메일로 안내"로 전환력 보존.
다음 단계: 최적안의 코드 diff(워커 ctx 전달 + prompt-builder avoidMention 가드)를 구체화할 수 있습니다.