데모
웹훅 프롬프트에 의해 트리거되어 개인화된 메시지 예시가 포함된 약 10명의 보강된 연락처 데모 리드를 생성합니다.
실행하기 전에 ~/.claude/skills/gtm-pipeline/_shared/conventions.md를 읽으십시오.
사용 시점
- 웹훅 트리거: 사용자가 타겟 청중을 설명하는 무료 데모 양식을 제출합니다.
- 목표: AI 에이전트가 실제 리드를 사용하여 진정하고 일반적이지 않은 아웃리치를 작성한다는 것을 입증합니다.
- 범위: 약 10명의 연락처, LinkedIn + 이메일로 보강, 2~4개의 메시지 예시
데모 제한 사항
- 전화 보강 없음 — 이메일만 가능
- 약 10명의 연락처 (10~15명 요청, 보강 과정에서 손실 예상)
- 메시지 생성은 선택 사항이지만 권장됨
- 신호 검색은 옵트인 — 기본적으로 꺼져 있음.
--with-signals플래그 또는 명시적 사용자 요청 시 활성화. 5.5단계 참조. - 비용 게이트: 첫 유료 제공업체 호출 전에 예상 비용을 명시합니다 (People-Source Cadence당 파인더 검색은 대부분 무료, 약 10~15개의 이메일 보강 크레딧, 신호는 활성화 시 <$0.50). 대화형: 먼저 사용자와 확인. Headless:
run_log.md에 견적을 기록하고 진행하며, 절대 차단하지 않음.
1단계 — 프롬프트 파싱 및 ICP 설정
웹훅 프롬프트는 사용자의 타겟 청중을 설명합니다. 다음을 추출합니다:
필수 항목:
- 무엇을 판매/제공합니까?
- 이상적인 고객은 누구입니까? (산업, 직무, 회사 규모, 위치)
- 가치 제안은 무엇입니까?
- 어조는 무엇입니까? (격식 vs. 비격식, 가능하면 예시)
- 리크루팅 용인가요, 고객에게 판매하는 용인가요?
프롬프트에 없으면, 추론합니다 (지연하지 않음):
- 타겟 직함, 위치, 회사 규모/유형
청중을 해석하기 전에 요청자를 자동으로 식별합니다 (반복되는 "그들이 무엇을 팔고 있는지/왜 이 청중을 원하는지" 격차를 해결):
- 요청자 자신의 도메인을 이메일에서 확인합니다 (예:
[email protected]→acme.de), 스크랩/보강하고, 그들이 무엇을 판매하는지 파악합니다. 여러 제품을 제공하는 회사: 데모가 어떤 제품 라인을 위한 것인지 확인합니다 — 프롬프트에 명시된 제품이 실제와 다를 수 있습니다. - 타겟 청중과의 관계를 결정합니다 — 타겟 용어(예: "콜센터")는 일반적으로 그들이 판매하는 세그먼트이지, 그들 자신이 아닙니다. 분류: 판매 대상 / 구매 대상 / 인수 대상 / 파트너 / 리크루팅. 페르소나 키워드는 추측이 아닌 여기서 파생됩니다.
대화형 vs. 배포(Headless):
- 대화형: 자동 해결 후에도 필수 항목이 진정으로 모호한 경우, 간결한 명확성 질문을 하나 합니다. 그렇지 않으면 진행합니다.
- 배포/Headless (웹훅에서
claude -p를 통해 호출 — 배포 참조): 절대 질문을 위해 차단하지 않음. 프롬프트 + 요청자 도메인 조사에서 모든 필드를 추론하고, 가정을context/icp.md의 "가정" 제목 아래에 기록한 후 처음부터 끝까지 진행합니다.
의미 있는 필터를 구축할 수 있을 만큼 ICP가 명확해질 때까지 검색을 진행하지 않습니다.
ICP를 다음에 저장: {client-slug}-gtm/context/icp.md (제공 항목, 관계 분류 및 Headless 가정 포함)
2단계 — 작업 디렉토리 생성
conventions.md에 정의된 대로 {client-slug}-gtm/ 디렉토리 구조를 생성합니다. ICP 정의를 context/icp.md에 작성합니다.
3단계 — 사람 검색 (연락처 10명)
people-search 스킬을 사용하여 약 10~15명의 연락처를 찾습니다.
데모용 제공업체 선택: conventions.md → People-Source Cadence의 파인더 순서를 따릅니다 — FullEnrich Finder → BetterContact → Pipe0 → Amplemarket/Crustdata (최후 수단), 소스당 최대 2회 시도, SME/소유자 주도/비영어 세그먼트는 FE 우선. FE와 BC 모두 LinkedIn URL을 직접 반환합니다 (이메일 보강에 필요). 회사 목록이 없는 경우(페르소나 기반 프롬프트), Parallel FindAll 또는 BC Search를 사용합니다. 디렉토리/스크래핑 소스 회사 목록의 경우, 정확한 도메인이 아닌 회사 이름 + 위치로 검색합니다 (규칙 #11).
수집할 주요 필드:
full_name, first_name, last_name,
job_title, company_name, company_domain,
linkedin_profile_url, location
people-search 실행 프로토콜을 따릅니다: 샌드박스 → 테스트 → 검토 → 실행.
4단계 — 연락처 필터 (ICP 순위 지정)
발견된 10~15명의 연락처에 대해 contact-filter를 실행합니다. 소규모 배치에도 ICP 순위 지정은 유용합니다 — 보강 단계가 가장 적합한 연락처에 집중하도록 보장합니다.
- 직무 등급, 산업 등급, 위치 등급 및 회사 규모 분류 적용
- 비ICP 연락처는 하드 거부
- 통과된 연락처를 우선순위로 순위 지정
- 출력:
csv/intermediate/contacts_filtered.csv
데모의 경우: 완화된 하드 거부 임계값 사용 (등급 1~5 허용), 필터링보다 순위 지정 우선.
5단계 — 사람 보강 (이메일만)
필터링된 연락처에 대해 people-enrichment를 실행합니다. 데모 모드: 이메일만, 전화 없음.
권장 흐름:
- FullEnrich v2 (이메일) — 모든 연락처
- Pipe0 워터폴 — FE 누락에만 사용
메시지 개인화를 위한 추가 보강 (가능한 경우):
- LinkedIn 헤드라인 및 요약 (PhantomBuster를 통한 LinkedIn 스크래핑)
- 최근 LinkedIn 게시물 (연락처당 2~3개) — 메시지 품질을 크게 향상시킴
메시지 생성 최소 필드:
name, job_title, company_name, linkedin_profile_url,
headline (선택 사항), summary (선택 사항), recent_posts (선택 사항)
낮은 수확량: 필터링 + 보강 후 약 8명 미만의 연락처가 남으면, 메시지로 진행하기 전에 한 번의 추가 파인더 패스 (People-Source Cadence의 다음 소스)를 실행합니다.
5.5단계 — 신호 검색 (선택 사항)
기본값: 꺼짐. 다음 경우에 활성화:
- 사용자가 신호 기반 메시지를 명시적으로 요청하는 경우
- 웹훅 프롬프트가 구매 트리거 (자금 조달, 채용, 전환, 최근 뉴스)를 언급하는 경우
- 클라이언트의 제공 항목이 타이밍 신호에 의존하여 의미가 있는 경우 (예: "시리즈 A 이후 회사의 운영 확장을 지원합니다")
--with-signals플래그가 데모 호출에 전달된 경우
비용 참고: 고유 회사당 약 $0.010.05 추가 (웹 검색 + 점수 매기기). 10명 연락처 데모에서는 일반적으로 510개의 고유 회사이므로 <$0.50입니다.
signal-search에 필요한 입력
Signal-search는 세 가지 컨텍스트 파일이 필요합니다:
context/icp.md— 1단계에서 이미 수집context/offering.md— 1단계의 가치 제안 블록 (아직 저장되지 않은 경우 지금 작성)context/signal_criteria.md— 제공 항목과 관련된 신호 유형의 글머리 기호 목록
signal_criteria.md가 없으면 사용자에게 묻습니다: "귀사가 제공하는 것을 필요로 할 만한 회사가 지금 무엇을 하고 있을까요?" — 5~10개의 글머리 기호를 캡처하여 저장합니다.
실행
# 보강된 연락처에서 고유 회사 목록 구축
python3 -c "
import csv, sys
seen = set()
with open('csv/output/contacts_enriched.csv') as f, open('csv/input/companies_raw.csv', 'w', newline='') as out:
reader = csv.DictReader(f)
writer = csv.DictWriter(out, fieldnames=['company_name', 'company_domain', 'company_website'])
writer.writeheader()
for row in reader:
c = row.get('company_name') or row.get('company') or ''
if c and c not in seen:
seen.add(c)
writer.writerow({
'company_name': c,
'company_domain': row.get('company_domain') or '',
'company_website': row.get('company_website') or row.get('website') or '',
})
"
# 고유 회사에 대해 signal-search 실행
source \"$HOME/.claude/skills/gtm-pipeline/_shared/resolve_env.sh\" && \
export $(grep -E '^(PARALLEL_API_KEY|OPENROUTER_API_KEY|FIRECRAWL_API_KEY|GEMINI_API_KEY)=' \"$GTM_ENV_PATH\" | xargs) && \
python3 ~/.claude/skills/gtm-signal-search/signal_search.py \
--client-dir {client-slug}-gtm
resolve_env.sh 소스 라인은 새 셸에서도 $GTM_ENV_PATH가 설정되도록 보장합니다 (signal-search SKILL.md / conventions 참조). 데모의 경우 Firecrawl 및 Parallel 보강을 끄십시오 — 웹 검색 + 점수 매기기로 약 10명 연락처 리드 목록에는 충분합니다. Firecrawl은 사이트 내 콘텐츠 (채용, 블로그)가 주요 신호 소스인 경우에만 활성화하십시오. 이 시스템에서 MCP를 통해서만 Firecrawl을 사용할 수 있는 경우 (FIRECRAWL_API_KEY 없음), signal-search 스킬에 문서화된 --firecrawl-pages-dir 경로를 사용하십시오.
신호를 연락처에 다시 병합
import csv, json
signals = {}
with open('csv/intermediate/signals.csv') as f:
for row in csv.DictReader(f):
signals[row['company_name']] = {
'overall_score': row.get('overallScore', ''),
'scored_signals': row.get('scoredSignals', ''),
'overall_summary': row.get('overallSummary', ''),
}
rows_out = []
with open('csv/output/contacts_enriched.csv') as f:
for row in csv.DictReader(f):
s = signals.get(row.get('company_name') or row.get('company') or '', {})
row['company_overall_score'] = s.get('overall_score', '')
row['company_scored_signals'] = s.get('scored_signals', '')
row['company_overall_summary'] = s.get('overall_summary', '')
rows_out.append(row)
with open('csv/output/contacts_enriched.csv', 'w', newline='') as f:
w = csv.DictWriter(f, fieldnames=list(rows_out[0].keys()))
w.writeheader()
w.writerows(rows_out)
6단계의 메시지 생성 단계에서 연락처별로 company_overall_summary 및 company_scored_signals를 사용할 수 있습니다 — 가장 높은 점수의 신호를 메시지 훅으로 사용합니다.
6단계 — 메시지 예시 생성
전체 배치를 진행하기 전에 2~4개의 샘플 메시지를 생성합니다.
메시지 구조
모든 메시지는 훅 → 브릿지 → 제안 → 소프트 CTA를 따라야 합니다:
| 부분 | 목적 | 길이 |
|---|---|---|
| 훅 | 이 사람에게 특정한 것을 언급 (게시물, 경력 이동, 회사 신호) | 1문장 |
| 브릿지 | 그들의 상황을 귀사의 제안과 연결 | 1문장 |
| 제안 | 귀사가 제공하는 것을 명확히 설명 | 1문장 |
| CTA | 부드러운 요청 — "전화 일정 잡자"가 아님 | 1문장 |
총: 320~450자. 인사 후 빈 줄 없음. 단일 줄 바꿈으로 단락 구분.
품질 규칙
필수:
- 구체적인 훅 (게시물 참조 또는 경력 통찰력 또는 점수 매겨진 구매 신호 — 일반적이지 않음)
- 명확한 가치 제안
- 자연스럽고 대화체 어조
- 소프트 CTA
금지:
- 그들이 이미 알고 있는 프로필 정보 반복 ("귀하는 Y에서 X로 일하시는군요")
- 일반적인 관찰 ("인상적인 배경이네요", "귀하가 [산업]에 계신 것을 알았습니다")
- 회사 전문 용어 또는 유행어
- 강압적인 CTA ("이번 주에 전화 일정 잡읍시다")
5.5단계가 실행된 경우: 각 연락처에 대해 company_scored_signals에서 가장 높은 점수의 신호를 일반적인 LinkedIn 게시물 참조보다 훅으로 선호합니다. 점수가 70 이상인 실제 최근 뉴스에 기반한 신호는 데모가 생성할 수 있는 가장 강력한 훅입니다.
생성 프로세스
- 클라이언트별 시스템 프롬프트 작성 (
prompts/message_prompt.md에 저장) - 2~4개 샘플 생성 — LinkedIn 게시물이 있는 연락처와 없는 연락처 모두 포함
- 위 품질 체크리스트에 따라 검토
- 문제가 발견되면 시스템 프롬프트를 개선하고 다시 생성
- 품질이 승인된 후에만 배치 생성
시스템 프롬프트 템플릿 (주요 섹션)
- 클라이언트 컨텍스트: 판매하는 것, 타겟, 가치 제안, 어조
- 금지 규칙: 프로필 반복 금지, 일반적인 아첨 금지
- 메시지 구조: 훅 → 브릿지 → 제안 → CTA
- 훅 예시: 게시물 있음 / 게시물 없음
- 문자 제한: 320~450
7단계 — 정리 및 출력
7a단계 — 정리 (필수, 결정적, LLM 없음). csv/intermediate/는 모든 필드를 유지합니다. 리드 대상 항목을 구축하기 전에 공유 정리기를 실행하여 반복적인 수동 정리 (제공업체 레이블, 빈 열, 잘못된 이메일, 오래된 신호)가 자동으로 처리되도록 합니다.