아웃리치 시퀀스 빌더
구매 신호를 받아 개인화된 다채널 아웃리치 시퀀스를 생성합니다. 이메일, LinkedIn, 전화를 통해 바로 보낼 수 있는 메시지를 출력합니다.
핵심 규칙: 모든 메시지는 로드한 컨텍스트에서 완전히 채워져야 합니다. 변수로는 {{first_name}}만 허용됩니다. [회사 이름] 대괄호, [통증 포인트 삽입] 플레이스홀더는 사용할 수 없습니다. 정보가 없어 채울 수 없는 경우 작성하기 전에 질문하세요. 채워지지 않은 플레이스홀더가 있는 메시지를 절대 보내지 마세요.
1단계: 설정 확인
필요한 환경 변수 확인:
echo "GEMINI_API_KEY: ${GEMINI_API_KEY:+set}"
echo "COMPOSIO_API_KEY: ${COMPOSIO_API_KEY:-not set, Gmail 드래프트 작성이 건너뜁니다}"
GEMINI_API_KEY가 없는 경우: 중단합니다. 사용자에게 말합니다: "GEMINI_API_KEY가 필요합니다. aistudio.google.com에서 받아 .env 파일에 추가하세요."
COMPOSIO_API_KEY가 없는 경우: 계속 진행합니다. 시퀀스는 복사-붙여넣기용 형식화된 텍스트로 출력됩니다. Gmail 초안 작성은 건너뜁니다.
2단계: 컨텍스트 로드
기존 ICP 파일 및 계정 파일 확인:
ls docs/icp.md 2>/dev/null && echo "icp found" || echo "icp missing"
ls docs/accounts/ 2>/dev/null && echo "accounts found" || echo "accounts missing"
docs/icp.md가 존재하는 경우: 읽습니다. 다음을 추출합니다:
- 대상 페르소나 (직무, 직급, 부서)
- 회사 프로필 (규모, 산업, 자금 조달 단계)
- 핵심 통증 포인트 (구매자의 정확한 언어 사용)
- 주요 차별화 요소 (경쟁 제품 대비 당신의 제품의 장점)
docs/accounts/{회사}.md가 존재하는 경우: 관련 파일을 읽습니다. 다음을 추출합니다:
- 회사 이름, 규모, 최근 컨텍스트
- 알려진 기술 스택 또는 통증 포인트
- 기존 관계 또는 이전 연락
둘 다 존재하지 않는 경우: 사용자에게 다음 4가지 질문을 합니다. 4가지 모두 답변될 때까지 진행하지 마세요:
- 당신의 제품은 무엇을 하나요? (한두 문장)
- 누구를 타겟으로 하나요? (직무, 회사 규모, 산업)
- 당신이 해결하는 주요 문제는 무엇인가요? (구매자의 관점에서, 당신의 관점이 아닌)
- 당신의 주요 차별화 요소는 무엇인가요? (그들이 현재 사용하는 대안보다 당신을 선택해야 하는 이유)
3단계: 신호 식별
7가지 신호 유형 중 어떤 것이 해당하는지 결정합니다. 각 신호 유형에 대한 전체 인사이트, 브리지, 오프너, 액션 요청을 보려면 references/signal-playbook.md를 읽으세요.
7가지 신호 유형:
| 신호 | 정의 |
|---|---|
| 자금 조달 후 | 회사가 최근 30일 이내에 자금 조달 라운드를 진행함 |
| 채용 신호 | 회사가 당신이 서비스하는 기능에 5개 이상의 직무를 게시함 |
| 경쟁사 대체 | 연락 대상이 경쟁사를 사용하고 있으며 불만을 표시함 |
| 제품 출시 | 회사가 새로운 제품이나 주요 기능을 출시함 |
| 콘텐츠 참여 | 연락 대상이 당신의 콘텐츠에 좋아요, 댓글 또는 공유를 함 |
| 이벤트 후속 | 컨퍼런스나 웨비나에서 만나거나 같은 세션에 있었음 |
| 이직 | 연락 대상이 최근 60일 이내에 새 회사로 이직함 |
사용자가 프롬프트에서 신호를 제공한 경우: 유형을 확인하고 구체적인 세부 정보(라운드 규모, 직무 제목, 제품명, 이벤트명 등)를 추출합니다.
명확한 신호가 없는 경우: 질문합니다: "이 아웃리치의 트리거는 무엇인가요? (예: 자금 조달, 엔지니어 채용, 이벤트에서 만남)"
진행하기 전에 감지된 신호 유형과 구체적인 세부 정보를 명시합니다.
4단계: 각도 개발
2-3단계에서 로드한 신호 유형과 컨텍스트를 사용하여 4가지 각도 요소를 정의합니다. 이 신호 유형에 대한 공식을 보려면 references/signal-playbook.md를 읽으세요.
메시지를 생성하기 전에 명시적으로 작성합니다:
신호: [구체적인 신호 + 구체적인 세부 정보]
인사이트: [이 신호가 그들의 상황에 대해 보여주는 것]
브리지: [당신의 제품이 신호가 보여주는 것과 어떻게 연결되는지]
오프너: [구체적인 신호 세부 정보를 언급하는 한 문장]
액션 요청: [최소 실행 가능 CTA, 10단어 미만]
오프너는 특정 트리거를 명명해야 합니다. 모호한 오프너는 거부됩니다.
좋은 예: "1800만 달러 시리즈 B 축하합니다 — 영업팀을 빠르게 확장하면 일반적으로 온보딩 격차가 발생합니다." 나쁜 예: "귀사가 최근에 자금을 조달한 것을 보았습니다."
5단계: 채널 시퀀스 계획
이메일, LinkedIn, 전화를 통해 4-6개의 터치포인트를 설계합니다. 규칙:
- 총 기간: 10-14일
- 최소 간격: 두 터치 사이 2일
- 동일한 채널을 연속으로 두 번 사용하지 않음
- 각 후속 터치는 새로운 가치를 추가해야 함 (새 리소스, 새 각도, 새 증명 포인트). 절대 "그냥 후속"이 아님
- 마지막 터치포인트는 짧은 이별 메시지
대부분의 신호에 대한 기본 케이던스:
1일차: 이메일 (첫 터치, 신호 주도 오프너)
3일차: LinkedIn (연결 요청 또는 짧은 DM)
7일차: 이메일 (새 각도 또는 사례 연구)
9일차: 전화 (토크 트랙 + 음성 메일 스크립트)
12일차: 이메일 (다른 프레이밍 또는 반론 처리)
14일차: 이메일 (짧은 이별 메시지)
신호 유형에 따라 조정:
- 자금 조달 후: 더 빠르게 진행 (1, 2, 4, 7, 10일차). 발표 후 48시간 이내에 행동
- 이벤트 후속: 이메일 대신 LinkedIn으로 시작 (더 따뜻한 채널 우선)
- 콘텐츠 참여: 이메일 전에 LinkedIn 답글 또는 댓글로 시작
메시지를 작성하기 전에 각 터치포인트의 계획된 날짜와 채널을 명시합니다.
6단계: 시퀀스 생성
references/sequence-format.md를 전체 읽습니다. references/output-template.md를 읽고 이 신호 유형에 대한 템플릿을 선택합니다.
임시 파일에 Gemini 요청 작성:
cat > /tmp/outreach-sequence-request.json << 'ENDJSON'
{
"system_instruction": {
"parts": [{
"text": "당신은 답장을 받는 콜드 아웃리치를 작성하는 B2B 영업 카피라이터입니다. 규칙: 모든 메시지의 첫 문장은 당신 회사가 아닌 그들에 관한 것입니다. 오프닝 메시지에서 구체적인 구매 신호를 이름과 세부 정보로 언급하세요. 축약형을 자연스럽게 사용하세요. 짧은 문장. 기업 전문 용어 금지. 금지된 단어: 시너지, 레버리지, 접촉, 회신, 핑, 포함, 정렬, 혁신적인, 최첨단, 최고급, 세계적 수준, 판도를 바꾸는, 파괴적인, 대역폭, 딥 다이브, 쉬운 성과, 지표를 움직이다. 인사말 금지: '이 이메일이 잘 받아졌으면 좋겠네요', '즐거운 월요일', '그냥 확인하려고' 안 됩니다. 각 후속 터치는 새로운 가치를 추가합니다 — 절대 '그냥 후속'이 아닙니다. 하드 제한: 이메일 본문 100단어 미만, LinkedIn 메모 300자 미만, 전화 오프너 20단어 미만. 변수로는 {{first_name}}만 허용됩니다 — 제공된 컨텍스트에서 다른 모든 세부 정보를 채우세요. 이별 메시지는 짧고(3-4문장), 친근하며, 문을 열어둡니다."
}]
},
"contents": [{
"parts": [{
"text": "CONTEXT_AND_INSTRUCTIONS_HERE"
}]
}],
"generationConfig": {
"temperature": 0.7,
"maxOutputTokens": 4096
}
}
ENDJSON
curl -s -X POST \
"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-d @/tmp/outreach-sequence-request.json \
| python3 -c "import sys,json; d=json.load(sys.stdin); print(d['candidates'][0]['content']['parts'][0]['text'])"
CONTEXT_AND_INSTRUCTIONS_HERE를 다음으로 대체:
- 2단계의 제품 설명, 타겟 페르소나, 통증 포인트 및 차별화 요소
- 4단계의 신호 유형, 구체적인 세부 정보 및 4가지 각도 요소
- 5단계의 채널 계획
- 각 터치포인트에 대한 제목(이메일), 문자 수(LinkedIn) 및 토크 트랙(전화)을 작성하는 지침
각 이메일 터치포인트에 대해 두 가지 제목 변형(A/B 테스트)을 요구합니다.
7단계: 반론 매핑
시퀀스를 생성한 후, 이 신호 유형에 대해 가장 가능성 있는 2-4개의 반론을 식별합니다. 각 반론을 기존 터치포인트 내에서 자연스럽게 선제적으로 대응합니다. 별도의 반론 처리 메시지를 추가하지 마세요. 선제적 대응을 시퀀스에 녹여내세요.
references/sequence-format.md에서 반론 플레이북을 읽습니다. 각 반론을 처리하는 터치포인트를 매핑합니다.
선제적으로 대응해야 하는 4가지 표준 반론:
| 반론 | 선제적 대응 접근법 |
|---|---|
| "이미 솔루션이 있습니다" | 현재 도구를 인정하고, 당신의 것을 보완재 또는 다음 단계로 포지셔닝 |
| "지금은 적절한 시기가 아닙니다" | 신호를 지금이 적절한 시기인 이유와 직접 연결 |
| "너무 비쌉니다" | ROI를 프레임화하고, 그들이 중요하게 생각하는 숫자에 고정 |
| "더 많은 사람들을 참여시켜야 합니다" | 공유 가능한 리소스(원페이지, 녹화된 워크스루) 제공 |
최종 시퀀스를 제시하기 전에 각 반론을 처리하는 터치포인트를 명시합니다.
8단계: 자체 QA
제시하기 전에 모든 검사를 실행하고 위반 사항을 수정합니다:
- 모든 메시지가 그들에 관한 문장으로 시작함
- 구체적인 신호 세부 정보가 최소 첫 번째 터치포인트에 명시됨
-
{{first_name}}을 제외한 채워지지 않은 플레이스홀더 없음 - 이메일 본문이 100단어 미만 (각각 단어 수를 세고 명시)
- LinkedIn 메모가 300자 미만 (각각 문자 수를 세고 명시)
- 전화 오프너가 20단어 미만
- 모든 메시지에 금지된 단어 없음
- 후속 터치에 "그냥 후속" 없음
- 각 후속 터치가 새로운 각도 또는 가치를 추가함
- 동일한 채널이 연속으로 두 번 사용되지 않음
- 시퀀스 전체에 걸쳐 최소 2개의 반론이 선제적으로 대응됨
- 이별 메시지가 3-4문장, 친근하며, 죄책감 유발하지 않음
제시하기 전에 위반 사항을 수정합니다.
9단계: 출력 및 저장
전체 시퀀스를 코드 블록으로 제시합니다.
파일로 저장:
mkdir -p docs/sequences
cat > docs/sequences/신호-유형.md << 'EOF'
시퀀스_내용_여기
EOF
echo "시퀀스가 docs/sequences/신호-유형.md에 저장되었습니다"
COMPOSIO_API_KEY가 설정된 경우: 질문합니다: "Composio를 통해 Gmail에 이메일 터치포인트 초안을 작성할까요?"
확인 시, 각 이메일 터치포인트에 대해:
# 에이전트가 GMAIL_CREATE_EMAIL_DRAFT Composio 액션을 호출
# 제목 = [제목], 본문 = [이메일 본문], 수신자 = [알려진 경우 연락처 이메일]
초안 작성 후: "Gmail에 이메일 초안이 생성되었습니다. 임시보관함 폴더를 확인하세요."
LinkedIn 메모: 터치포인트별로 명확한 라벨과 함께 별도의 복사-붙여넣기 블록으로 제시합니다. LinkedIn은 프로그래매틱 메시징을 지원하지 않습니다.
전화 스크립트: 엄격한 스크립트가 아닌, 요점이 있는 형식화된 토크 트랙으로 제시합니다.