o2o-infinith-demo/doc/AI_PROMPTS_CATALOG.md

15 KiB
Raw Blame History

INFINITH AI Prompts Catalog (v2 — Updated 2026-04-04)

현재 프로덕션에서 사용 중인 모든 AI 프롬프트. Pipeline V2 아키텍처 기반 (discover → collect → generate).


Pipeline Overview

Phase 1: discover-channels
  ├─ A. Firecrawl scrape+map (병원 정보 + 소셜 링크 추출)
  ├─ B1. YouTube Data API (채널 직접 검색)
  ├─ B2. Naver Search API (블로그 + 웹 검색)
  ├─ B3. Firecrawl Search (소셜 URL 웹 검색)
  ├─ B4. Perplexity sonar (Online Presence 통합 검색)
  ├─ B4b. Perplexity sonar (강남언니 URL 검색)
  ├─ B5. Apify Instagram (프로필 직접 검색)
  └─ C. 핸들 검증 (HEAD 요청 + YouTube API)

Phase 2: collect-channel-data
  ├─ Instagram (Apify)
  ├─ YouTube (YouTube Data API v3)
  ├─ Facebook (Apify)
  ├─ 강남언니 (Firecrawl JSON 추출)
  ├─ Naver Blog + Place (Naver API)
  ├─ Google Maps (Apify)
  └─ 시장 분석 (Perplexity × 4 병렬)

Phase 3: generate-report
  └─ Perplexity sonar (실제 수집 데이터 기반 리포트 생성)

Phase 1: discover-channels

P1-A. Firecrawl — 병원 정보 + 소셜 링크 추출

File: supabase/functions/discover-channels/index.ts (Stage A) API: Firecrawl v1/scrape (JSON + links) Wait: 5000ms

Extraction Prompt:

Extract: clinic name (Korean), clinic name (English), address, phone,
services offered, doctors with specialties, ALL social media links
(instagram handles/URLs, youtube channel URL/handle, naver blog URL,
facebook page URL, tiktok, kakao channel), business hours, slogan

Schema: clinicName, clinicNameEn, address, phone, businessHours, slogan, services[], doctors[], socialMedia{}

용도: 병원 기본 정보 수집 + HTML에서 소셜 링크 직접 추출


P1-A2. Firecrawl — 브랜딩 추출

API: Firecrawl v1/scrape (JSON) Wait: 3000ms

Extraction Prompt:

Extract brand identity: primary/accent/background/text colors (hex),
heading/body fonts, logo URL, favicon URL, tagline

Schema: primaryColor, accentColor, backgroundColor, textColor, headingFont, bodyFont, logoUrl, faviconUrl, tagline


P1-B1. YouTube Data API — 채널 직접 검색

File: supabase/functions/discover-channels/index.ts (Stage B1) API: YouTube Data API v3 search?type=channel Prompt: 없음 (API 직접 호출)

GET https://www.googleapis.com/youtube/v3/search
  ?part=snippet
  &type=channel
  &q={clinicName}
  &maxResults=3
  &key={YOUTUBE_API_KEY}

매칭 로직: 검색 결과 채널명이 병원명을 포함하면 channelId 추출


P1-B2a. Naver Search API — 블로그 검색

File: supabase/functions/discover-channels/index.ts (Stage B2a) API: Naver Search blog.json

GET https://openapi.naver.com/v1/search/blog.json
  ?query={clinicName} 공식 블로그
  &display=5
  &sort=sim

추출: blog.naver.com/{blogId} 패턴 매칭


P1-B2b. Naver Search API — 웹 검색 (소셜 URL 발견)

API: Naver Search webkr.json

GET https://openapi.naver.com/v1/search/webkr.json
  ?query={clinicName} 인스타그램 유튜브 공식
  &display=10

추출: 검색 결과 URL에서 instagram.com, youtube.com, facebook.com 패턴 매칭


P1-B3. Firecrawl Search — 소셜 URL 웹 검색

API: Firecrawl v1/search

{
  "query": "{clinicName} 성형외과 instagram youtube 공식",
  "limit": 10
}

추출: 검색 결과 URL에서 소셜 핸들 패턴 매칭 (extractSocialLinks)


P1-B4. Perplexity — Online Presence 통합 검색 (핵심 프롬프트)

File: supabase/functions/discover-channels/index.ts (Stage B4) API: Perplexity sonar, temp=0.1 목적: 다른 API가 놓친 소셜 계정을 웹 검색으로 보충 발견

System Message:

You are a social media researcher. Search the web and find social media accounts. Respond ONLY with valid JSON.

User Message (template):

{clinicName} ({clinicNameEn}) 병원의 인스타그램, 유튜브, 페이스북, 틱톡, 네이버블로그 계정을 검색해서 찾아줘. 검색 결과에서 발견된 계정을 모두 알려줘. 인스타그램은 여러 계정이 있을 수 있어.

{"instagram": ["handle1", "handle2"], "youtube": "channel URL or handle", "facebook": "page name or URL", "tiktok": "handle", "naverBlog": "blog ID"}

핵심 학습 (프롬프트 엔지니어링):

  • 실패 패턴: "공식 계정만 찾아줘" / "확인된 계정만" / "Never guess" → 전부 null 반환
  • 실패 패턴: sonar-pro + 장문 시스템 프롬프트 → 빈 결과
  • 실패 패턴: 3개로 분리된 쿼리 → 각각 빈 결과
  • 성공 패턴: 짧은 시스템 프롬프트 + 모든 채널 한 쿼리 + "검색해서 찾아줘" + 영문명 괄호 포함
  • 성공 패턴: sonar 모델 (sonar-pro보다 오히려 나음)
  • 성공 패턴: 예시 JSON을 user message 끝에 포함 (output 형식 유도)

변수 구성:

const clinicNameEn = clinic.clinicNameEn || '';
const searchName = clinicNameEn
  ? `${resolvedName} (${clinicNameEn})`   // "그랜드성형외과 (Grand Plastic Surgery)"
  : resolvedName;                          // "그랜드성형외과"

P1-B4b. Perplexity — 강남언니 URL 검색

API: Perplexity sonar, temp=0.1

System Message:

You search for clinic listings on medical platforms. Respond ONLY with valid JSON.

User Message:

{clinicName} 병원 강남언니 gangnamunni.com 페이지를 찾아줘.

{"gangnamUnni": {"url": "https://gangnamunni.com/hospitals/...", "rating": 9.5, "reviews": 1000}}

P1-B5. Apify — Instagram 프로필 직접 검색

File: supabase/functions/discover-channels/index.ts (Stage B5) API: Apify instagram-profile-scraper Timeout: 30초 per candidate

핸들 후보 생성 로직:

const baseName = clinicName.replace(/성형외과|병원|의원|클리닉|피부과/g, '').trim().toLowerCase();
const baseNameEn = clinic.clinicNameEn.replace(/\s+/g, '').toLowerCase();

candidates = [
  baseNameEn,                    // "grandplasticsurgery"
  `${baseNameEn}_official`,      // "grandplasticsurgery_official"
  `${baseNameEn}_ps`,            // "grandplasticsurgery_ps"
  `${baseNameEn}_clinic`,        // "grandplasticsurgery_clinic"
  domainBase,                    // "grandplasticsurgery" (from URL)
  `${domainBase}_official`,      // "grandplasticsurgery_official"
]

유효성 조건: followersCount >= 50 → 후보로 채택


P1-C. 병원명 추출 Fallback (Perplexity)

조건: Firecrawl이 clinicName을 추출하지 못한 경우 API: Perplexity sonar, temp=0.1

System Message:

Respond with ONLY the clinic name in Korean, nothing else.

User Message:

{url} 이 URL의 병원/클리닉 한국어 이름이 뭐야?

Phase 2: collect-channel-data

P2-1. Firecrawl — 강남언니 페이지 데이터 추출

File: supabase/functions/collect-channel-data/index.ts API: Firecrawl v1/scrape (JSON) Wait: 5000ms

Extraction Prompt:

Extract: hospital name, overall rating (out of 10), total review count,
doctors with names/ratings/review counts/specialties, procedures offered,
address, certifications/badges

Schema: hospitalName, rating(number), totalReviews(number), doctors[], procedures[], address, badges[]


P2-2~5. Perplexity — 시장 분석 (4개 병렬)

API: Perplexity sonar, temp=0.3

공통 System Message:

You are a Korean medical marketing analyst. Always respond in Korean. Provide data in valid JSON format.

쿼리 4개:

ID User Prompt
competitors {address} 근처 {services} 전문 성형외과/피부과 경쟁 병원 5곳을 분석해줘. 각 병원의 이름, 주요 시술, 온라인 평판, 마케팅 채널을 JSON 형식으로 제공해줘.
keywords 한국 {services} 관련 검색 키워드 트렌드. 네이버와 구글에서 월간 검색량이 높은 키워드 20개, 경쟁 강도, 추천 롱테일 키워드를 JSON 형식으로 제공해줘.
market 한국 {services[0]} 시장 트렌드 2025-2026. 시장 규모, 성장률, 주요 트렌드, 마케팅 채널별 효과를 JSON 형식으로 제공해줘.
targetAudience {clinicName}의 잠재 고객 분석. 연령대별, 성별, 관심 시술, 정보 탐색 채널, 의사결정 요인을 JSON 형식으로 제공해줘.

Phase 3: generate-report

P3. Perplexity — 마케팅 리포트 생성 (V2: 실제 데이터 기반)

File: supabase/functions/generate-report/index.ts API: Perplexity sonar, temp=0.3

System Message:

You are a Korean medical marketing analyst. Respond ONLY with valid JSON, no markdown code blocks. Use Korean for text fields. 강남언니 rating is 10-point scale. Use ONLY the provided real data — never invent metrics.

User Message (template 구조):

당신은 프리미엄 의료 마케팅 전문 분석가입니다. 아래 **실제 수집된 데이터**를 기반으로 종합 마케팅 리포트를 생성해주세요.

⚠️ 중요: 아래 데이터에 없는 수치는 절대 추측하지 마세요. 데이터가 없으면 "데이터 없음"으로 표시하세요.

## 병원 기본 정보
- 병원명: {clinic.clinicName}
- 주소: {clinic.address}
- 전화: {clinic.phone}
- 시술: {services.join(", ")}
- 의료진: {doctors JSON}
- 슬로건: {clinic.slogan}

## 실제 채널 데이터 (수집 완료)
### Instagram @{handle}
- 팔로워: {followers}명, 게시물: {posts}개
- 비즈니스 계정: O/X
- Bio: {bio}

### YouTube {handle}
- 구독자: {subscribers}명, 영상: {totalVideos}개, 총 조회수: {totalViews}
- 인기 영상 TOP 5: [실제 제목+조회수]

### 강남언니 {name}
- 평점: {rating}/10, 리뷰: {totalReviews}건
- 등록 의사: [실제 이름+전문분야]

### Google Maps {name}
- 평점: {rating}/5, 리뷰: {reviewCount}건

### 네이버 블로그: 검색결과 {totalResults}건
### 네이버 플레이스: {name} ({category})

## 시장 분석 데이터
{market analysis JSON}

## 웹사이트 브랜딩
{branding JSON}

## 리포트 형식 (JSON 구조)
{
  "clinicInfo": { ... },
  "executiveSummary": "경영진 요약 (3-5문장)",
  "overallScore": 0-100,
  "channelAnalysis": {
    "naverBlog": { score, status, posts, recommendation, diagnosis[] },
    "instagram": { score, status, followers, posts, recommendation, diagnosis[] },
    "youtube": { score, status, subscribers, recommendation, diagnosis[] },
    "naverPlace": { score, rating, reviews, recommendation },
    "gangnamUnni": { score, rating, ratingScale:10, reviews, status, recommendation },
    "website": { score, issues[], recommendation, trackingPixels[], snsLinksOnSite, mainCTA }
  },
  "brandIdentity": [{ area, asIs, toBe }],
  "kpiTargets": [{ metric, current, target3Month, target12Month }],
  "recommendations": [{ priority, category, title, description, expectedImpact }],
  "competitors": [],
  "keywords": { primary: [], longTail: [] },
  "targetAudience": {},
  "marketTrends": [],
  "newChannelProposals": [{ channel, priority, rationale }]
}

핵심: channelSummarybuildChannelSummary() 함수가 channel_data DB 컬럼에서 실제 수집된 데이터를 요약 텍스트로 변환. AI는 이 텍스트에 포함된 수치만 사용.


이미지 생성 (별도)

Gemini — 마케팅 이미지 생성

File: src/services/geminiImageGen.ts API: Google Gemini gemini-2.5-flash-image

Prompt (template):

Generate a premium medical marketing image for a plastic surgery clinic.
Theme: {pillarContext}  // safety | expertise | results | care
Style: {channelHint}    // youtube | instagram | naver_blog | tiktok | facebook
Color palette: soft purple (#7B2D8E), gold (#E8B931), warm white (#FAF8F5).
Premium, luxurious, trustworthy aesthetic.
No text or logos in the image.
Photorealistic, high quality, professional medical marketing.

Pillar Context:

  • safety: "hospital safety systems, clean surgical rooms, CCTV monitoring"
  • expertise: "medical expertise, advanced surgical equipment, certifications"
  • results: "natural beautiful results, before and after transformation"
  • care: "patient-centered care, warm consultation, personalized treatment"

프롬프트 엔지니어링 교훈

1. Perplexity sonar — 프롬프트 길이 vs 성능

프롬프트 길이 결과
시스템 1줄 + 유저 3줄 Instagram, YouTube 등 잘 찾음
시스템 50줄 + 유저 30줄 전부 null/빈 배열
시스템 5줄 + 유저 10줄 (분리 3회) 각각 빈 결과

2. 검색 키워드 패턴

패턴 결과
"{병원명}" 성형외과 공식 인스타그램 null (너무 제한적)
{병원명} 병원의 인스타그램...검색해서 찾아줘 핸들 발견
{병원명} ({영문명}) 병원의 인스타그램... 국제 계정도 발견

3. 모델 선택

모델 용도 온도
sonar 채널 검색, 강남언니 검색 0.1
sonar 시장 분석, 리포트 생성 0.3
sonar-pro 테스트 결과 오히려 성능 저하 -

4. JSON 응답 안정성

  • 항상 시스템에 "Respond ONLY with valid JSON" 포함
  • 유저 메시지 끝에 예시 JSON 구조를 포함하면 포맷 준수율 ↑
  • text.match(/\{[\s\S]*\}/) 로 JSON 추출 (설명 텍스트 제거)
  • text.match(/```(?:json)?\n?([\s\S]*?)```/) 로 코드 블록 내 JSON 추출

5. Verify 전략

  • Instagram HEAD 요청은 불안정 → unverified도 후보로 유지
  • YouTube channels?part=id API가 가장 정확한 검증
  • Apify instagram-profile-scraper가 HEAD 요청보다 신뢰성 높음
  • UC로 시작하는 channel ID에 @ 붙이면 검증 실패

Summary

Phase API 프롬프트 수 주 용도
discover-channels Perplexity sonar 2~3개 소셜 채널 검색 + 강남언니
discover-channels Firecrawl 2개 웹사이트 스크래핑 + 브랜딩
discover-channels YouTube API 0 (직접 호출) 채널 검색
discover-channels Naver API 0 (직접 호출) 블로그/웹 검색
discover-channels Apify 0 (직접 호출) Instagram 프로필 검색
collect-channel-data Perplexity sonar 4개 시장/경쟁/키워드/타겟 분석
collect-channel-data Firecrawl 1개 강남언니 데이터 추출
generate-report Perplexity sonar 1개 종합 리포트 생성
이미지 생성 Gemini 1개 마케팅 이미지
합계 ~12개