Content QA · Before / After Comparison

타로 리딩 캐논 적용 전/후 비교
무료 6종 + 유료 샘플 4종 실제 리딩 결과

2026-07-18 · 덕사주타로(ducksajutarot) · 앱 코드를 그대로 실행해 뽑은 결정론적 샘플(가상 인물: 서연·민준)
Executive Summary

1. 배경

덕사주타로의 타로 리딩은 LLM 실시간 호출이 아니라 룰베이스 슬롯 조합형 텍스트다 — 카테고리별 포지션마다 미리 써둔 문장 변형 배열에서 카드 번호 기준 결정론적으로 하나를 골라 조립한다(public/index.html). 문제는 무료 카테고리 상당수가 포지션당 문장 변형이 3~4개뿐이라 반복 노출 시 뻔해지기 쉬웠다는 점이다.

이를 개선하기 위해 실제 인기 타로 유튜버(jinjin10960, 채널 영상 930개 전체)의 whisper 음성 전사본을 서브에이전트 15개로 병렬 분석해, 원문 문장은 인용하지 않고 몰입도를 만드는 구조·수사 기법만 증류했다. 이 패턴을 캐릭터 '꽉이'(반말·1:1·자존감 가드레일 준수)에 맞게 재해석해 무료 6개 카테고리(WEEKLY_TEXT·CAREER_TEXT·LOVETODAY_TEXT·STUDY_TEXT·SCHOOL_TEXT·WORK_TEXT)에 먼저 반영했다.

이어서 "샘플로 미리보기" 기능이 있는 유료 스프레드 4종(REUNION_TEXT 재회 리딩, BREAKUP_TEXT 이별의 진짜 이유, LOVE_TEXT 앞으로의 연애 운, CRUSH_TEXT 새 썸남과의 궁합)도 동일한 캐논을 반영했다. 이 4종은 이미 hot/mild(또는 medium/hot/mild) 스파이스 티어와 자존감 가드레일을 갖춘 고품질 콘텐츠였기 때문에, 전면 재작성 대신 기존 문장은 그대로 두고 포지션 × 스파이스 × 방향 배열마다 새 변형을 1개씩만 추가하는 보수적인 방식을 택했다.

2. 방법론 — 왜 "같은 카드"로 비교해야 하는가

1차 시도의 결함(수정됨). 처음에는 앱의 "예시 리딩 참고하기" 미리보기 로직(sampleTarotPayload()) — 같은 시드로 40개 카드 조합 후보를 만들고 그중 리딩 텍스트 총 길이가 가장 긴 조합을 고르는 방식 — 을 전/후 각각 재실행해서 비교했다. 그런데 이 방식은 문제가 있었다: LOVETODAY_TEXT의 문장 변형 개수가 3개→6개로 늘면서 각 후보의 텍스트 길이 자체가 달라지고, 그 결과 "가장 긴 조합"으로 뽑히는 카드 자체가 전/후로 달라져 버렸다. 카드가 다르면 어떤 차이가 문장 개선 때문인지, 어떤 차이가 그냥 다른 카드를 뽑아서인지 구분이 안 된다 — 비교로서 성립하지 않는다는 지적을 받고 방법을 바꿨다.
  1. 같은 카드 고정. 카드 셔플/후보 탐색 로직은 쓰지 않는다. 대신 MAJOR_ARCANA 22장 중 특정 카드 하나(카드 번호·정역방향 고정)를 직접 지정하고, 리딩 함수(loveTodayReading(), crushReading())를 전/후 두 버전의 LOVETODAY_TEXT/CRUSH_TEXT 배열에 대해 정확히 같은 카드로 호출했다. 카드는 절대 안 바뀌고, 텍스트만 바뀐다 — 이게 진짜 "같은 카드가 나왔다면"의 전/후 비교다.
  2. 어떤 카드를 골랐나. 22장 전체(카드 번호 0~21, 정방향부터 역방향까지)를 하나씩 대입해서 실제로 전/후 텍스트가 달라지는 카드를 코드로 찾아 그중 하나를 썼다(운 좋게 같은 인덱스로 매핑돼 우연히 텍스트가 같아 보이는 카드는 제외). Exhibit 1은 여황제(카드 3, 정방향), Exhibit 2는 여사제(카드 2)·여황제(카드 3)(둘 다 정방향)로 뽑았다는 사실도 코드 출력 그대로다 — 카드를 사람이 임의로 고르지 않았다.
  3. 전/후 소스. LOVETODAY_TEXT는 "전"=git show eb95883^:public/index.html(캐논 적용 직전 커밋), "후"=현재 작업 트리. CRUSH_TEXT는 "전"=git show HEAD:public/index.html(이번 세션에서 유료 4종을 고치기 직전 상태), "후"=현재 작업 트리.
미확인/한계. 같은-카드 재현은 LOVETODAY_TEXT·CRUSH_TEXT 2개만 다룬다. REUNION_TEXT/BREAKUP_TEXT/LOVE_TEXT는 포지션 4(마지막 카드)가 lastCardReading()이라는 별도 로직(LAST_CARD_FRAME)을 추가로 타서 이번 재현 범위에서는 제외하고, 대신 Exhibit 4에서 실제 코드에 반영된 신규 변형 원문을 직접 인용한다. 무료 6종(WEEKLY/CAREER/STUDY/SCHOOL/WORK)은 애초에 앱에 별도 "예시 리딩" 미리보기 기능이 없어 동일 방식의 재현 비교 대상이 아니다.

3. Exhibit 1 — 같은 카드, 리딩 원문 전/후

Exhibit 1

"오늘 연애가 잘 되려면?" — 3개 포지션 모두 👑 여황제(정방향)가 나왔다고 가정

서연(나) · 민준(그 사람) · 카드 고정(여황제/정방향) · 카드는 절대 안 바뀜, 텍스트만 비교
포지션전 — 캐논 적용 전후 — 캐논 적용 후반영된 기법
오늘의 내 연애 텐션
"오늘은 마음이 여유로운 날이야. 민준한테 평소보다 너그럽게 대할 수 있는 텐션이니까, 그 여유를 아끼지 말고 표현해줘."
"오늘 아침엔 좀 무덤덤했을 수도 있는데, 오후로 갈수록 마음이 몽글몽글해지는 흐름이야. 저녁쯤엔 민준 생각에 혼자 피식 웃고 있을걸."
시간 특정화 "오늘"이라는 뭉뚱그린 하루 대신 "아침→오후→저녁"으로 시간대를 쪼개 하루 안의 감정 곡선을 만들었다.
그 사람의 진짜 속마음: 나를 향한 시선
"민준은 지금 너한테 엄청 기대고 싶어 하는 눈치야. 겉으론 티 안 내도 네 한마디에 하루 기분이 왔다 갔다 하는 상태야."
"낮엔 민준이 좀 무심해 보일 수도 있어. 근데 저녁 되면 먼저 연락 올 가능성 있어 — 낮 동안 딴생각한 게 아니라 그냥 타이밍을 못 잡은 거야."
긴장 조성 후 반전 "무심해 보일 수도 있어"로 걱정을 먼저 던지고 "근데 저녁 되면"으로 반전시키는 구조 — 원문은 처음부터 우호적으로만 서술했다.
투데이 처방전: 싸움 방지 & 점수 따기
"오늘은 잔소리 금지 꽥! 맛있는 거 먼저 먹여라. 배부르고 기분 좋을 때 하고 싶은 말 하면 훨씬 잘 통해."
"오늘 저녁 타이밍을 노려봐 꽥. 낮엔 민준도 정신없을 수 있는데, 저녁쯤 여유 생기면 네 톡 하나에 기분 훅 좋아질 수 있어."
시간 특정화 원문의 "오늘은"이라는 막연한 하루 전체 대신 "저녁 타이밍"으로 실행 시점을 구체적으로 좁혔다.

4. Exhibit 2 — 같은 카드, "새 썸남과의 궁합" 전/후

Exhibit 2

포지션 0·2는 🌙 여사제(정방향), 포지션 1은 👑 여황제(정방향)가 나왔다고 가정

서연(나) · 민준(썸남) · mild 스파이스 · 카드 고정, 텍스트만 비교
포지션전 — 캐논 적용 전후 — 캐논 적용 후반영된 기법
썸남은 어떤 사람 (🌙 여사제)
"민준 카드는 겉보다 속이 훨씬 다정한 사람으로 나와. 표현이 조금 느려도 진심은 분명히 있는 유형이니까 너무 서운해하지 않아도 돼. 카드가 보여주는 건, 너랑 나눈 대화를 혼자 조용히 곱씹는 다정한 모습이야."
"민준은 리액션이 크지 않아도 네가 지나가듯 흘린 말을 마음속에 은근히 담아두는 타입이야. 시간이 좀 지난 뒤에 그 얘기를 먼저 꺼내준다면, 그게 이 사람 나름의 다정한 애정표현이라고 생각하면 돼."
구체적 행동 단서 "속이 다정한 사람"이라는 추상적 묘사에서 "흘린 말을 기억해뒀다가 나중에 먼저 꺼낸다"는 관찰 가능한 행동 근거로 바뀌었다.
지금 썸남의 속마음 (👑 여황제)
"소름 돋게 반가운 소식이야. 민준도 너한테 조금씩 마음이 기울고 있어. 다만 아직 확신이 없어서 조심스럽게 지켜보는 중이야. 속마음은 아마 이럴 거야. '괜히 티 냈다가 어색해지면 어쩌지.'"
"민준이 너한테 답장하는 속도가 처음보다 조금씩 빨라지고 있어. 다른 사람한테는 안 그러면서 너한테만 유독 그렇다면, 그건 이미 마음이 기울고 있다는 다정한 신호야."
구체적 행동 단서 "속마음 추측"에서 "답장 속도 변화"라는 실제 관찰 가능한 메신저 근거로 바뀌었다.
이 썸의 미래 (🌙 여사제)
"서두르지 않으면 아주 좋은 인연이 될 수 있는 카드야. 대략 한 계절 정도 지나는 사이에 관계가 자연스럽게 한 단계 깊어질 거야. 지금처럼 네 페이스대로 편안하게 가면 충분해."
"이 썸은 둘만의 시간이 자연스럽게 한 번 만들어지면 그때 관계가 부드럽게 한 걸음 더 나아가는 흐름이야. 여행이나 모임 같은 기회가 온다면 편안하게 그 시간을 즐겨봐."
구체적 행동 단서 "시간이 지나면"이라는 막연한 경과에서 "둘만의 시간(여행·모임)"이라는 구체적 계기로 바뀌었다.

5. Exhibit 3 — 카테고리 구조 변화 전체 (10종 포지션당 변형 수)

Exhibit 3

캐논을 반영한 타로 카테고리 10종, 포지션당 변형 개수

카테고리스프레드전(포지션당)후(포지션당)
WEEKLY_TEXT이번주 타로 운세 (무료)6개8개
CAREER_TEXT오늘의 취업·이직운 (무료)3개6개
LOVETODAY_TEXT오늘 연애가 잘 되려면? (유료, Exhibit 1)3개6개
STUDY_TEXT오늘의 학업운 (무료)4개6개
SCHOOL_TEXT오늘의 학교 생활은? (무료)4개6개
WORK_TEXT오늘의 직장 생활은? (무료)4개6개
REUNION_TEXT재회 리딩 (유료)2~3개3~4개
BREAKUP_TEXT이별의 진짜 이유 (유료)2~3개3~4개
LOVE_TEXT앞으로의 연애 운 (유료)2개3개
CRUSH_TEXT새 썸남과의 궁합 (유료, Exhibit 2)2~3개3~4개

무료 6종은 변형 풀을 큰 폭(대략 2배)으로 넓혔고, 유료 4종은 이미 갖춰진 hot/mild 티어 구조를 건드리지 않고 각 배열에 1개씩만 보수적으로 추가했다 — 기존 문장은 전부 그대로 남아 있다.

6. Exhibit 4 — 유료 4종 신규 변형 실제 원문 발췌

Exhibit 4

REUNION_TEXT / BREAKUP_TEXT / LOVE_TEXT에 실제로 추가된 변형 중 대표 1개씩

카테고리포지션신규 변형 원문반영된 기법
REUNION_TEXT 지금 그가 나를 보는 마음 "하나만 더 짚을게. {ex} 핸드폰 사진첩에 아직 지우지 못한 폴더가 있어. 둘이 갔던 여행 사진, 삭제 버튼 앞에서 몇 번이나 멈칫한 흔적이 보여. 지우려다 못 지운 거, 그게 지금 그 사람 마음이야." 구체적 행동 단서
BREAKUP_TEXT 앞으로 나아갈 길 "구체적으로 하나만 실천해봐. 그 사람 SNS 스토리 확인하는 습관, 알림부터 꺼. 사소해 보여도 이게 연락 끊기의 8할이야. 눈에서 멀어져야 마음도 진짜로 멀어져." 구체적 행동 단서
LOVE_TEXT 연애가 찾아올 시기 "달력에 몰래 표시해둬도 좋아. 계절이 한 번 바뀌는 그 지점, 대략 3~6개월 즈음에 마음이 술렁이는 일이 생겨. 몇 번을 다시 봐도 같은 자리에서 같은 카드가 나와 — 우연이 아니라 흐름이야, 흐름." 시간 특정화반복 강조

세 문장 모두 public/index.html에 실제로 반영된 코드에서 그대로 발췌했다(재현 스크립트가 아니라 파일 직접 확인). {ex}는 앱 실행 시 사용자가 등록한 실제 이름으로 치환된다.

7. 가드레일 검증

꽉이 캐릭터의 절대 원칙 — 사용자 본인의 외모·자존감·능력을 깎아내리지 않는다 — 이 10개 카테고리 전/후 모두에서 위반 없이 유지됐다. Exhibit 1·2의 신규 텍스트와 Exhibit 4의 신규 변형들도 대상은 항상 사용자의 특정 행동이나 상대방(ex/crush)의 상황이지, 사용자 본인의 가치나 매력이 아니다. jinjin10960 원본 채널의 "팩폭"도 상대(전남친 등)나 상황에만 향한다는 점과 원칙이 일치한다.

8. 결론 및 다음 단계

그래서 무엇을 해야 하는가.

  1. 배포. public/index.html의 10개 카테고리 변경사항 중 무료 6종은 커밋됐지만(eb95883), 유료 4종(REUNION/BREAKUP/LOVE/CRUSH)은 이 보고서 작성 시점 기준 아직 커밋 전이다. 둘 다 라이브 앱(Cloudflare Workers)에 배포됐는지 확인하고, 안 됐다면 배포한다.
  2. 다음 후보. db/tarot-patterns.html 캐논에 이미 기록된 대로, MAJOR_ARCANA 22장의 lu/lr(오늘의 한 장 리딩)이 카드당 변형 1개뿐이라 다음 확장 우선순위다.
  3. 측정. 이 비교는 정성적(텍스트 품질) 개선이라 사용자 반응(재방문율, 리딩 완독 시간 등)으로 사후 검증하는 것을 권장한다 — 현재는 A/B 데이터가 없다(미확인).

부록 — 출처

캐논 문서: db/tarot-patterns.html (jinjin10960 채널 930개 영상 whisper 전사본, 2026-07-18 15개 배치 병렬 분석)
적용 전 소스(무료 6종): git show eb95883^:public/index.html (커밋 eb95883의 부모)
적용 전 소스(유료 4종): git show HEAD:public/index.html (커밋 eb95883은 유료 4종을 건드리지 않았으므로 HEAD가 곧 적용 전)
적용 후 소스: 작업 트리 public/index.html(무료 6종은 커밋 eb95883에 반영, 유료 4종은 이 보고서 작성 시점 기준 미커밋)
재현 스크립트: Node.js로 hasBatchim/fixJosa/_jz/_rv/MAJOR_ARCANA/LOVETODAY_TEXT/CRUSH_TEXT/loveTodayReading/crushReading 로직을 원본 그대로 추출하고, 카드(카드 번호·정역방향)는 고정값으로 직접 지정해 재실행(세션 스크래치패드에 보관, 필요 시 재실행 가능). 22장 전체를 대입해 실제로 텍스트가 달라지는 카드를 코드로 찾은 뒤 그중 하나를 골랐다.