Claude API로 이메일 자동화하기: 개인화된 이메일 대량 생성
Claude API로 이메일을 자동 생성하려면 anthropic 패키지를 설치하고, 수신자 데이터를 변수로 주입한 프롬프트를 구성한 뒤 messages.create()를 호출하면 됩니다. 콜드 이메일의 경우 회사명·직함·관심사를 프롬프트에 삽입해 개인화하고, Batch API를 사용하면 수천 건을 50% 할인 가격에 병렬 생성할 수 있습니다. 반복 발송이 많다면 시스템 프롬프트 캐싱으로 비용을 추가 절감할 수 있습니다. 이 가이드에서는 콜드·웜 이메일 프롬프트 패턴, 개인화 변수 설계, A/B 테스트, Batch API 활용, 발송 가능성(deliverability) 체크리스트, 템플릿 관리까지 단계별로 설명합니다.
콜드/웜 이메일 프롬프트 패턴
이메일 유형에 따라 프롬프트 전략이 다릅니다.
콜드 이메일 프롬프트
처음 연락하는 수신자에게는 짧고 가치 중심적인 이메일이 효과적입니다:
COLD_EMAIL_SYSTEM = """당신은 B2B 세일즈 이메일 전문 카피라이터입니다.
다음 원칙을 반드시 따르세요:
- 제목 포함 총 150단어 이내
- 첫 문장은 수신자의 구체적인 상황 언급
- 가치 제안 1개만 명확하게
- CTA는 단 하나(미팅 요청 또는 자료 링크)
- 스팸 필터 트리거 단어 금지: 무료, 보장, 긴급
- JSON 형식으로 출력: {"subject": "...", "body": "..."}"""
def generate_cold_email(recipient: dict) -> dict:
prompt = f"""수신자 정보:
- 이름: {recipient['name']}
- 직함: {recipient['title']}
- 회사: {recipient['company']}
- 업종: {recipient['industry']}
- 최근 관심사: {recipient.get('trigger', '없음')}
위 정보를 바탕으로 개인화된 콜드 이메일을 작성하세요."""
return prompt
웜 이메일 프롬프트
기존 관계가 있는 수신자(구독자, 과거 고객)에게는 친근하고 맥락 있는 톤을 사용합니다:
WARM_EMAIL_SYSTEM = """당신은 고객 성공 팀의 이메일 전문가입니다.
- 이전 구매·상호작용 내역을 자연스럽게 언급
- 2인칭 존댓말 유지
- 재구매·업셀 유도는 본문 중반 이후에 배치
- JSON 형식: {"subject": "...", "body": "..."}"""
개인화 변수 설계
효과적인 개인화를 위해 수신자 데이터를 계층적으로 설계합니다:
| 변수 수준 | 필드 예시 | 효과 |
|---|---|---|
| 기본 (Tier 1) | 이름, 회사, 직함 | 일반 개인화 |
| 행동 기반 (Tier 2) | 최근 방문 페이지, 다운로드 자료 | 높은 관련성 |
| 의도 기반 (Tier 3) | 직원 채용 공고, 펀딩 뉴스, 경쟁사 변동 | 최고 전환율 |
# 개인화 변수 스키마
recipient_schema = {
"name": str, # 필수
"company": str, # 필수
"title": str, # 필수
"industry": str, # Tier 1
"trigger": str, # Tier 2/3 — 최근 행동 또는 뉴스
"pain_point": str, # Tier 3 — 파악된 고충
"mutual_connection": str, # 있을 경우 언급
}
Tier 3 변수가 있으면 Haiku보다 Sonnet을 사용해 섬세한 맥락 파악을 활용하는 것이 좋습니다. 모델 선택 기준은 Claude 모델 선택 가이드를 참고하세요.
Python 콜드 이메일 생성기
아래는 CSV 파일에서 수신자 목록을 읽어 이메일을 생성하는 완전한 예제입니다:
import anthropic
import csv
import json
from pathlib import Path
client = anthropic.Anthropic()
SYSTEM_PROMPT = """당신은 B2B 세일즈 이메일 전문 카피라이터입니다.
- 제목 포함 총 150단어 이내로 작성
- 첫 문장은 수신자의 구체적인 상황 언급
- 가치 제안 1개만 명확하게
- CTA는 단 하나
- 반드시 JSON 형식으로만 출력: {"subject": "제목", "body": "본문"}"""
def generate_email(recipient: dict) -> dict:
"""단건 이메일 생성"""
user_prompt = f"""다음 수신자를 위한 콜드 이메일을 작성하세요:
이름: {recipient['name']}
직함: {recipient['title']}
회사: {recipient['company']}
업종: {recipient.get('industry', '미상')}
트리거: {recipient.get('trigger', '없음')}"""
response = client.messages.create(
model="claude-haiku-4-5",
max_tokens=512,
system=[
{
"type": "text",
"text": SYSTEM_PROMPT,
"cache_control": {"type": "ephemeral"}, # 시스템 프롬프트 캐싱
}
],
messages=[{"role": "user", "content": user_prompt}],
)
raw = response.content[0].text.strip()
# JSON 파싱 (마크다운 코드 블록 제거)
if raw.startswith("```"):
raw = raw.split("```")[1]
if raw.startswith("json"):
raw = raw[4:]
return json.loads(raw.strip())
def process_csv(input_path: str, output_path: str):
"""CSV 파일 처리 — 소량(100건 이하)에 적합"""
results = []
with open(input_path, newline="", encoding="utf-8") as f:
reader = csv.DictReader(f)
for row in reader:
email = generate_email(row)
results.append({**row, **email})
print(f"생성 완료: {row['name']} — {email['subject']}")
with open(output_path, "w", newline="", encoding="utf-8") as f:
fieldnames = list(results[0].keys())
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(results)
print(f"\n총 {len(results)}건 저장 완료: {output_path}")
if __name__ == "__main__":
process_csv("recipients.csv", "emails_output.csv")
A/B 테스트
이메일 A/B 테스트는 두 가지 방식으로 설계합니다:
방법 1: 프롬프트 변형 테스트
VARIANTS = {
"A": "첫 문장은 수신자의 최근 성과를 칭찬하며 시작하세요.",
"B": "첫 문장은 수신자의 업계 공통 고충으로 시작하세요.",
"C": "첫 문장은 구체적인 숫자(통계, 비율)로 시작하세요.",
}
def generate_ab_variants(recipient: dict) -> dict:
"""동일 수신자에 대해 3가지 변형 생성"""
variants = {}
for variant_id, instruction in VARIANTS.items():
system = SYSTEM_PROMPT + f"\n추가 지시: {instruction}"
response = client.messages.create(
model="claude-haiku-4-5",
max_tokens=512,
system=system,
messages=[{"role": "user", "content": build_prompt(recipient)}],
)
variants[variant_id] = json.loads(response.content[0].text)
return variants
방법 2: 온도(Temperature) 다양성 활용
Claude API의 기본 temperature는 1.0입니다. A/B 테스트 목적으로는 동일 프롬프트를 여러 번 호출해 다양한 표현을 얻을 수 있습니다. 단, Claude는 temperature 파라미터를 0~1 범위에서 조정할 수 있으며, 낮을수록 일관성이 높아집니다.
Batch API 대량 생성
1,000건 이상의 이메일을 생성할 때는 Batch API를 사용합니다. 표준 API 대비 50% 비용 절감, 24시간 내 처리 완료를 보장합니다.
import anthropic
import json
client = anthropic.Anthropic()
def build_batch_requests(recipients: list[dict]) -> list[dict]:
"""수신자 목록을 Batch API 요청 형식으로 변환"""
requests = []
for i, recipient in enumerate(recipients):
requests.append({
"custom_id": f"email_{i}_{recipient['name'].replace(' ', '_')}",
"params": {
"model": "claude-haiku-4-5",
"max_tokens": 512,
"system": [
{
"type": "text",
"text": SYSTEM_PROMPT,
"cache_control": {"type": "ephemeral"},
}
],
"messages": [
{"role": "user", "content": build_prompt(recipient)}
],
},
})
return requests
def submit_batch(recipients: list[dict]) -> str:
"""Batch 작업 제출 후 batch_id 반환"""
requests = build_batch_requests(recipients)
batch = client.messages.batches.create(requests=requests)
print(f"Batch 제출 완료: {batch.id}")
print(f"총 요청 수: {batch.request_counts.processing}")
return batch.id
def poll_and_collect(batch_id: str) -> list[dict]:
"""Batch 완료 대기 후 결과 수집"""
import time
while True:
batch = client.messages.batches.retrieve(batch_id)
print(f"상태: {batch.processing_status} | "
f"성공: {batch.request_counts.succeeded} | "
f"실패: {batch.request_counts.errored}")
if batch.processing_status == "ended":
break
time.sleep(30) # 30초마다 폴링
results = []
for result in client.messages.batches.results(batch_id):
if result.result.type == "succeeded":
text = result.result.message.content[0].text
try:
email_data = json.loads(text)
results.append({
"custom_id": result.custom_id,
**email_data,
})
except json.JSONDecodeError:
print(f"JSON 파싱 실패: {result.custom_id}")
return results
# 사용 예시
if __name__ == "__main__":
# CSV에서 수신자 로드
import csv
with open("recipients.csv", newline="", encoding="utf-8") as f:
recipients = list(csv.DictReader(f))
batch_id = submit_batch(recipients)
emails = poll_and_collect(batch_id)
print(f"최종 수집 이메일: {len(emails)}건")
이메일 자동화 완성본 + Claude API 30개 실전 레시피
Agent SDK Cookbook (₩64,000)은 이메일 생성기 전체 소스, Batch API 파이프라인, 발송률 최적화 패턴, 멀티에이전트 워크플로우를 포함합니다.
비용 분석: Haiku vs Sonnet 이메일당
이메일 1건당 평균 입력 300토큰, 출력 200토큰 기준:
| 모델 | 입력 단가 | 출력 단가 | 이메일 1건 | 1,000건 | Batch API (50% 할인) |
|---|---|---|---|---|---|
| Haiku 3.5 | $0.80/MTok | $4.00/MTok | $0.0011 | $1.10 | $0.55 |
| Sonnet 4.5 | $3.00/MTok | $15.00/MTok | $0.0039 | $3.90 | $1.95 |
| Haiku + 캐싱 | $0.08/MTok(캐시) | $4.00/MTok | $0.00085 | $0.85 | $0.43 |
결론: 대량 발송(1,000건+)에는 Haiku + Batch API + 캐싱 조합이 최적입니다. 이메일 1,000건에 약 ₩600 수준입니다. 비용 모니터링 방법은 Claude API 비용 모니터링 가이드를 참고하세요.
프롬프트 캐싱 적용 시 조건
시스템 프롬프트가 1,024 토큰 이상이어야 캐싱이 활성화됩니다. 짧은 시스템 프롬프트는 캐싱 효과가 없으므로, 브랜드 가이드·업종별 규칙·사례 예시를 시스템 프롬프트에 포함시켜 1,024토큰 임계값을 넘기는 것이 좋습니다.
발송 가능성 (Deliverability) 체크리스트
AI가 생성한 이메일은 스팸 필터에 걸릴 위험이 있습니다. 프롬프트 단계에서 아래 항목을 시스템 프롬프트에 명시하세요:
금지 단어 목록 (시스템 프롬프트에 포함):
스팸 필터 트리거 단어를 절대 사용하지 마세요:
- 무료, 공짜, 0원, 선물, 혜택
- 보장, 확실, 100%, 절대
- 긴급, 즉시, 마지막 기회, 한정
- 클릭, 여기를 클릭, 지금 바로
- RE:, FWD: (제목에서)
발송 전 기술 체크리스트:
- SPF, DKIM, DMARC 레코드 설정 확인
- 발신 도메인과 링크 도메인 일치
- 텍스트:이미지 비율 80:20 이상 유지
- 수신 거부(unsubscribe) 링크 포함
템플릿 관리
여러 캠페인을 운영하면 템플릿을 버전 관리하는 것이 중요합니다:
# templates/email_templates.py
from dataclasses import dataclass
from typing import Optional
@dataclass
class EmailTemplate:
name: str
system_prompt: str
user_prompt_template: str
model: str = "claude-haiku-4-5"
max_tokens: int = 512
version: str = "1.0"
# 템플릿 레지스트리
TEMPLATES = {
"cold_saas": EmailTemplate(
name="SaaS 콜드 아웃리치",
system_prompt=COLD_EMAIL_SYSTEM,
user_prompt_template="이름: {name}\n직함: {title}\n회사: {company}\n...",
version="2.1",
),
"warm_reengagement": EmailTemplate(
name="기존 고객 재활성화",
system_prompt=WARM_EMAIL_SYSTEM,
user_prompt_template="이름: {name}\n마지막 구매: {last_purchase}\n...",
model="claude-sonnet-4-5", # 웜 이메일은 Sonnet으로 품질 향상
version="1.3",
),
}
def get_template(template_id: str) -> EmailTemplate:
if template_id not in TEMPLATES:
raise ValueError(f"알 수 없는 템플릿: {template_id}")
return TEMPLATES[template_id]
템플릿을 Git으로 버전 관리하면 성과가 좋은 버전으로 롤백하기 쉽습니다. 각 템플릿에 version 필드를 두고 결과 CSV에 함께 저장하면 어떤 버전이 높은 전환율을 냈는지 추적할 수 있습니다.
이메일 자동화 전체 파이프라인 + 30개 실전 Claude API 레시피
Agent SDK Cookbook (₩64,000)은 발송 파이프라인 완성본, A/B 테스트 프레임워크, Batch API 재시도 로직, 오류 처리 전략을 포함합니다.
Frequently Asked Questions
Claude API로 이메일을 어떻게 자동 생성하나요?
anthropic 패키지를 설치한 뒤 client.messages.create()에 시스템 프롬프트(이메일 작성 지침)와 사용자 프롬프트(수신자 정보)를 전달하면 됩니다. 출력 형식을 JSON으로 강제하면 subject와 body를 구조적으로 파싱할 수 있습니다. 대량 생성은 Batch API를 사용해 비용을 50% 절감하세요.
콜드 이메일에 Haiku와 Sonnet 중 어느 모델을 써야 하나요?
기본 개인화(이름, 직함, 회사)만 사용하는 경우 Haiku로 충분합니다. 이메일 1건당 약 ₩1.5 수준입니다. 수신자의 최근 뉴스·공고를 분석해 심층 맥락을 파악해야 하는 고가치 타깃(Enterprise AE 등)에는 Sonnet을 사용하세요. 모델 선택 기준은 Claude 모델 선택 가이드에서 자세히 확인할 수 있습니다.
Batch API는 일반 API와 어떻게 다른가요?
Batch API는 최대 10,000건의 요청을 한 번에 제출하고 24시간 내 처리 완료를 보장하며 가격이 50% 저렴합니다. 실시간 응답이 필요 없는 대량 이메일 생성에 적합합니다. 반면 표준 API는 즉시 응답하므로 단건·소량(100건 이하) 생성이나 대화형 UI에 적합합니다.
AI 생성 이메일이 스팸으로 분류되는 것을 어떻게 방지하나요?
프롬프트 단계에서 스팸 트리거 단어 금지 목록을 시스템 프롬프트에 명시하세요. 기술적으로는 SPF·DKIM·DMARC 설정, 발신 도메인 워밍업, 텍스트 비율 80% 이상 유지가 필요합니다. AI 생성 이메일은 문장 구조가 유사해질 수 있으므로 A/B 변형을 3개 이상 만들어 발송 비율을 분산하는 것도 효과적입니다.
이메일 생성 비용을 더 절감하려면 어떻게 하면 되나요?
세 가지 방법을 조합하세요: (1) Batch API — 50% 할인, (2) 프롬프트 캐싱 — 반복되는 시스템 프롬프트를 캐싱해 추가 90% 절감, (3) Haiku 모델 선택 — Sonnet 대비 약 1/4 비용. 세 가지를 모두 적용하면 Sonnet 표준 API 대비 최대 95% 비용 절감이 가능합니다. 비용 추적 방법은 Claude API 비용 모니터링 가이드를 참고하세요.