Appearance
채팅 메모리/컨텍스트 PRD — 메신저 메모리·페르소나·프롬프트 구조
Backlog grooming 산출물. 메모리 데이터 모델 · 슬롯 정의 · 업데이트 정책 · 프롬프트 합성 구조까지 한 문서에서 정의. 화면별 디테일은 spec.md, 친밀도 적재는 DEE-71, 메신저 surface는 채팅 메신저 PRD(DEE-72).
Status: draft (rewrite) Created: 2026-05-15 Last updated: 2026-06-01 Linear Issue: DEE-115 채팅 메모리/컨텍스트 정책Linear Project: 채팅 메모리/컨텍스트 정책 (3954e834c7a0) Author: agent (momo) 앱/웹/스튜디오: surface-agnostic (Chat 응답 LLM 프롬프트 파이프라인 중심 — 앱·웹 어디서 Chat이 떠도 동일 적용)
0. 요약
- 채팅은 episode의 물리적 연장이 아니라 관계의 연속이다. episode 사건은 "함께 겪은 과거 기억"으로만 다룬다.
- Chat 응답 LLM에 주입되는 컨텍스트는 8개 슬롯 + 선택형 시작 상황으로 분리되고, 주입 위치 기준 두 그룹으로 나뉜다:
- A. 채팅 프롬프트(Chat v6) system 영역(durable) —
overview(= 모델 역할 바인딩 + present-moment hard rule + writing rule + conversation guide를 한 데 묶은 지시문) 뒤에# Context블록이 붙는다. Context는 최종 순서로 Long-term memory(LTM) →soul_default_persona→soul_relational_persona→soul_messenger_bio(display_name + status) →user_relational_persona로 합성된다. - B. 대화 컨텍스트 영역(per-turn) —
initial_or_recent_context자리에는 요약 전 첫 Chat에서는chat_initial_situation(디렉터가 입력한 선택형 채팅 시작 상황)이 들어가고, 채팅 요약 프롬프트가 1회 이상 돈 뒤에는recent_context가 들어간다. 그 뒤에live_chat_history가 붙는다. - 8개 카운트는 저장·합성 슬롯 기준 —
overview / messenger_bio / default / relational / user / ltm / recent_or_initial / live.chat_initial_situation은 Studio 입력값이며, 요약 전 첫 Chat에서recent_context가 아직 없을 때 같은 대화 컨텍스트 위치에 들어가는 선택값이다.
- A. 채팅 프롬프트(Chat v6) system 영역(durable) —
- Chat이 처음 열렸을 때 이전 episode/play 요약 내용이 있으면, **메모리 추출 프롬프트(Chat v4)**로 초기 메모리 문서(LTM /
soul_relational_persona/user_relational_persona3개 슬롯의 markdown)를 만들고 첫 **채팅 프롬프트(Chat v6)**에 넣는다. 첫 메모리 추출에는recent_context가 없고, 그 대화 컨텍스트 위치에는 디렉터가 작성한chat_initial_situation이 들어간다. Chat v4는soul_default_persona도 생성하지 않는다(디렉터 소유). 이전 요약이 없으면 memory 슬롯은 비워 두며, 비어 있는 블록은 조건부로 헤더까지 생략할 수 있다. - Chat 누적 컨텍스트가 10,000 tokens 이상이면 채팅 요약 프롬프트(Chat v5) 실행 —
recent_context를 포함한 4개 메모리 슬롯을 bounded snapshot으로 re-curate하고(append 아님), 그와 별도로 상세 사건 기록을 **Lorebook(RAG store)**에 append한다. 요약 완료 후 다음 턴에는recent_context와 최근 2쌍(user-AI)의 live chat만 남기고 이전 raw turn은 prompt window에서 제거한다. - 모델 지정: 채팅 요약 프롬프트와 메모리 추출 프롬프트는
gemini-3-flash-preview+temperature=0.4+reasoning=false, 채팅 프롬프트(Chat generation)는gemini-3.1-flash-lite-preview+temperature=0.7+reasoning=false를 사용한다. soul_messenger_bio는 Studio의 소울 관리에서 작성하는 Soul의 메신저 바이오(이름 + 상태메시지)이며,soul_default_persona와 함께 디렉터 권한이다(메모리 추출/채팅 요약 프롬프트가 건드리지 않음).soul_relational_persona/user_relational_persona/ LTM은 메모리 추출 프롬프트가 seed하고 채팅 요약 프롬프트가 갱신한다.recent_context는 첫 메모리 추출에는 없고, 채팅 요약 프롬프트가 1회 이상 돈 뒤부터 시스템이 생성·rewrite한다.- 본 PRD는 데이터 모델·정책·프롬프트 초안까지 포함한다(§8). spec/BE/Prompt 담당이 바로 옮길 수 있는 상태가 목표.
1. 목표 및 배경
채팅은 사용자가 캐릭터(Soul)를 "에피소드 밖에서도 살아 있는 상대"로 느끼게 하는 메신저 surface다(DEE-72). 그러려면 Soul이 (a) 함께 겪은 과거를 기억하고, (b) 사용자에 대해 학습된 인상을 갖고, (c) 시간에 따라 관계가 자연스럽게 깊어져야 한다.
기존 PRD는 episode를 "현재 컨텍스트 reference"로 토글하는 모델이었으나, 사용 검증 결과 Chat에서 episode 장면을 현재로 끌어오면 메신저 텍스트와 어긋난다(같이 있다, 만지고 있다, 전투 중이다 등). 본 PRD는 그 가정을 폐기하고 episode = 과거 기억 / Chat = 텍스트로만 닿는 현재로 분리해 메모리·페르소나·프롬프트 구조 전체를 재정의한다.
2. 핵심 제품 전제: Episode vs Chat
| 축 | Episode | Chat |
|---|---|---|
| 시점 | 과거에 함께 겪은 사건 | 지금 이 순간 |
| 물리 | 같은 장면·같은 공간에 같이 있음 | 떨어져 있고, 메신저 텍스트로만 닿음 |
| Soul의 모드 | scene을 같이 살아내는 모드 | 떨어져서 메시지 쓰는 모드 |
| Memory로의 변환 | "기억"으로 남음 — 회상·언급·농담·후회 가능 | recent_context / LTM으로 누적 |
Hard rule. 사용자의 현재 메시지가 지금 같이 있다고 분명하게 만들지 않는 한, Soul은:
- episode의 장소/장면을 "지금 여기"로 다루지 않는다 (강의실, 옥상, 침대, 전쟁터, 같이 사는 집 등 모두).
- episode의 신체 행위(접촉, 키스, 섹스, 전투, 여행, 동거 일상)를 지금 진행 중으로 다루지 않는다.
- episode 기록에 "지금/방금/옆에서/같이 살고 있는" 같은 표현이 있어도, 그것을 그 시점의 관계 상태에 대한 회상으로 해석한다 — Chat에서 같이 있다는 증거 아님.
회상·언급·그리워함·정서 반응은 OK. scene을 이어쓰는 것은 금지.
3. 메모리/프롬프트 전체 구조
3.1 슬롯 8종 (주입 위치 + 합성 순서)
8개 슬롯. 주입 위치에 따라 두 그룹으로 분리한다.
합성 순서는 최종 Chat prompt 구조를 따른다: overview(Overview → Writing rule → Conversation Guide) 뒤에 # Context 블록이 붙고, Context 내부 슬롯은 아래 1~5 순서다.
[ A. 채팅 프롬프트(Chat v6) system 영역(durable) — 매 generation에서 거의 동일하게 박힘 ]
overview — model(you) 역할 바인딩 + §2 present-moment hard rule
+ Writing rule(Voice & output / Bubble dynamics / Situational handling)
+ Conversation Guide (기존 dm_framing을 이 슬롯으로 흡수)
# Context 블록 (최종 순서):
1. Long-term memory(LTM) — 관계 상태, 호칭, 패턴, 약속, 갈등, 미해결, 공유 농담, 핵심 사건 (bounded snapshot, RAG 백업)
2. soul_default_persona — 디렉터가 박은 Soul 기본 인격/정본 페르소나 (자동 업데이트 X)
3. soul_relational_persona — 이 사용자와의 관계에서만 드러나는 Soul의 태도·말투·반응 패턴 (채팅 요약 프롬프트가 갱신)
4. soul_messenger_bio — Studio 소울 관리의 메신저 바이오 (display_name + status)
5. user_relational_persona — 이 Soul 시점에서 본 사용자상 (메모리 추출 프롬프트가 seed, 채팅 요약 프롬프트가 갱신)
[ B. 대화 컨텍스트 영역(per-turn) — system prompt가 아니라 그때그때 붙음 ]
6. initial_or_recent_context — 요약 전 첫 Chat에서는 `chat_initial_situation`(디렉터 선택 입력 채팅 시작 상황),
채팅 요약 프롬프트가 1회 이상 돈 뒤에는 `recent_context`를 같은 위치에 주입.
둘 다 비어 있으면 이 블록 자체를 생략.
7. live_chat_history — 최근 메신저 메시지 (가장 마지막에 붙어 현재성 강화)canonical 메모 — 메모리 추출 프롬프트(Chat v4)의 초기 메모리 문서에는
## Recent context가 없다. 첫 Chat에서는 그 자리에 디렉터가 작성한chat_initial_situation을 넣고, 채팅 요약 프롬프트(Chat v5)가 1회 이상 돈 뒤부터는 같은 자리에recent_context를 넣는다. 배포되는 채팅 프롬프트(Chat v6)의 system# Context블록에는 이 per-turn 대화 컨텍스트와live_chat_history가 들어 있지 않고, 합성 파이프라인이 주입 위치를 고정한다.
용어 표기 결정
- 슬롯 라벨·코멘트·도메인 언어는 "Soul"을 정본으로 쓴다 (Soul = 도메인 정체성).
- 단, 모델에게 역할 바인딩을 시키는 문장은
model(you) as this Soul/NPC형태로 둔다 — LLM은model/you역할 결합을 더 안정적으로 따르므로 실행 주체는 model, 정체성은 Soul로 분리. - §8-A
overview샘플 role 정의가 이 패턴의 reference.
Default vs Relational Persona
soul_default_persona: 디렉터가 정의한 Soul의 기본 인격/정본 페르소나. 모든 user × Soul Chat에 공통 적용되며 자동 업데이트하지 않는다. 메모리 추출 프롬프트(Chat v4)·채팅 요약 프롬프트(Chat v5)가 절대 생성/patch하지 않는 유일한 persona 슬롯.soul_relational_persona: 특정 user와의 관계 안에서만 드러나는 Soul의 태도·말투·반응 패턴. Default를 부정하지 않는 추가 레이어이며 요약 사이클에서 보수적으로 갱신된다.user_relational_persona: 이 Soul 시점에서 본 사용자상(Profile + How Soul sees the user). 시스템 소유 슬롯이며 메모리 추출 프롬프트(Chat v4)가 seed하고 채팅 요약 프롬프트(Chat v5)가 매 사이클 re-curate한다. 사용자 직접 편집 슬롯이 아니다.
3.2 슬롯별 source of truth
| 슬롯 | 주입 그룹 | Owner / Editor | 자동 업데이트? | 1차 source |
|---|---|---|---|---|
overview | A (system) | 시스템 (고정 템플릿; response_style/safety/format 포함) | X | §8-A |
soul_messenger_bio | A (system) | 디렉터 (Studio [소울 관리]) | X | Studio Soul Messenger Bio(이름 + 상태메시지) |
soul_default_persona | A (system) | 디렉터 (Studio [소울 관리]) | 절대 X | Studio Soul Prompt |
soul_relational_persona | A (system) | 시스템 (메모리 추출/채팅 요약 프롬프트) | O (conservative) | episode seed(v4) + Chat 누적 |
user_relational_persona | A (system) | 시스템 (메모리 추출/채팅 요약 프롬프트) | O (Chat v4 seed, Chat v5 매 사이클 re-curate) | episode seed(v4) + Chat 누적 |
| Long-term memory(LTM) | A (system) | 시스템 (메모리 추출/채팅 요약 프롬프트) | O (bounded snapshot, RAG 백업) | episode seed + Chat 누적 |
initial_or_recent_context | B (대화 컨텍스트) | 디렉터 또는 시스템 | 조건부 | 요약 전 첫 Chat: chat_initial_situation(디렉터 선택 입력). 첫 요약 이후: recent_context(채팅 요약 프롬프트가 rewrite) |
live_chat_history | B (per-turn) | 시스템 (raw 저장) | n/a | Chat Thread |
자동 업데이트 원칙
- 디렉터가 직접 작성/수정하는
soul_messenger_bio/soul_default_persona/chat_initial_situation은 메모리 추출/채팅 요약 프롬프트에서 업데이트하지 않는다(디렉터 소유). - 시스템 소유 메모리/컨텍스트 슬롯 중
soul_relational_persona,user_relational_persona, Long-term memory(LTM)은 메모리 추출 프롬프트(Chat v4)가 seed하고 채팅 요약 프롬프트(Chat v5)가 매 사이클 review·re-curate한다.recent_context는 첫 메모리 추출 때 생성하지 않고, 채팅 요약 프롬프트(Chat v5)가 1회 이상 돈 뒤부터 생성·rewrite한다. 요약 전 첫 Chat에서는recent_context자리에chat_initial_situation을 사용한다.user_relational_persona/recent_context는 매 사이클 새로 쓰는 경향이 크고,soul_relational_persona/LTM은 근거가 있을 때만 보수적으로 patch한다. - 메모리 문서는 append 로그가 아니라 bounded snapshot이다 — 중복은 머지하고 비핵심은 drop한다. LTM에서 떨어진 상세 사건은 Lorebook(RAG store)에 남아 retrievable하다(§4.5, §6.2).
live_chat_history는 raw 메시지 히스토리로 저장/윈도잉 대상이지 요약 patch 대상이 아니다.
3.3 episode_memory의 위치
- 별도 슬롯 아님. seed/import용 raw source.
- 사용 시점: (a) Chat Thread 첫 시작 시 1회, (b) 사용자가 "최근 기억 불러오기"를 눌렀을 때 (DEE-72의 우상단 햄버거 메뉴 action).
- 둘 다 §8-B 프롬프트로 raw episode 텍스트 → seed/patch 형태로 변환된 뒤 위 슬롯들에 흡수된다.
- 이후엔 Chat 프롬프트에 직접 들어가지 않는다. Soul이 episode를 기억하는 것은 LTM/페르소나에 흡수된 결과를 통해서.
4. 저장 슬롯 / 백엔드 변수
각 슬롯의 데이터 정의. 정확한 컬럼/타입은 BE 설계에서 확정.
4.0 overview (system 슬롯)
- Scope: 글로벌 (모든 (user, Soul) Chat에 공통 적용).
- Owner: 시스템 (고정 템플릿). 변경은 본 PRD / 후속 PRD 합의로만.
- Auto-update: X.
- 포함: 모델(you) 역할 정의 + §2 hard rule +
response_style(길이·말투) +safety(가드) +format(메신저 텍스트, 행동 묘사 금지 등). - Retention: 영구 (배포 단위 버전 관리).
- Note: 과거 PRD의 별도
response_style / safety / format슬롯은 본 슬롯으로 흡수됐다 — separate slot 아님.
4.1 soul_messenger_bio
- Scope: Soul 단위 (글로벌). 모든 user × Soul Chat에 공통.
- Definition: Studio의 소울 관리에서 작성하는 Soul의 메신저 바이오. 이름과 상태메시지가 들어간다.
- Owner: 디렉터 / Studio 소울 관리.
- Auto-update: X. 요약 엔진이 여기 쓰면 안 됨.
- Retention: 영구. Studio 저장/적용 후 라이브 반영.
- Prompt use: 채팅 프롬프트(Chat v6) system 영역에서 Soul이 메신저 상에서 보이는 표시 이름·상태메시지를 이해하도록 제공한다. 관계 메모리나 성격 설정을 대체하지 않는다.
4.2 soul_default_persona
- Scope: Soul 단위 (글로벌). 모든 user × Soul Chat에 공통.
- Definition: 디렉터가 정의한 Soul의 기본 인격/정본 페르소나. 관계별 변주가 붙기 전 기준점이다.
- Owner: 디렉터 (Studio [소울 관리]의 Soul Prompt).
- Auto-update: 절대 금지. 요약 엔진이 여기 쓰면 안 됨.
- Retention: 영구. 디렉터 [적용] 액션 후 라이브 반영.
- Prompt priority: Soul Relational Persona / User Relational Persona가 Default Persona와 충돌하면 Default Persona가 우선.
user_relational_persona는 시스템 메모리 추출/채팅 요약 프롬프트가 유지하는 슬롯이므로 Default를 덮어쓰는 사용자 편집 예외로 취급하지 않는다(§7).
4.3 soul_relational_persona
- Scope: (user, Soul) 단위.
- Owner: 시스템 요약 엔진.
- Auto-update: O. 단 반복 관찰되고 관계가 깊어진 결과로 안정화된 면만. 1회성·일시적 표현은 reject.
- Source: Chat 누적 + episode_memory seed (
soul_relational_persona_seed). - Retention: 영구 누적 (patch 적용). diff 히스토리는 audit log로.
- Definition: 특정 user와의 관계 안에서만 드러나는 Soul의 태도·말투·반응 패턴.
- Constraint: Default를 부정/덮어쓰지 않는다. 추가 레이어로만 작동.
- 예시 필드:
상대에게만 보이는 면,이 관계에서만 나오는 말투,약점·취약함의 노출 패턴,이 사용자에게 특별히 반응하는 지점.
4.4 user_relational_persona
- Scope: (user, Soul) 단위. ※ 글로벌 user_relational_persona는 v1 범위 외 (§11).
- Owner: 시스템 (메모리 추출 프롬프트 Chat v4 seed + 채팅 요약 프롬프트 Chat v5 re-curate). 이 Soul 시점에서 본 사용자상.
- Auto-update: O. 채팅 요약 프롬프트(Chat v5) 매 사이클에서 갱신한다 — 대화에서 새 explicit profile 사실이 드러나면 추가하고, 인상(How Soul sees the user)이 바뀌면 해당 항목을 revise/replace한다(누적 아님, snapshot).
- 구조:
### Profile(이름/별명, 명시된 경우 성별/대명사, 직업/역할, 나이/학년, 안정적 호칭) +### How Soul sees the user(사용자가 어떤 사람으로 인식되는지, 관계에서 드러난 면, 명시된 선호/기피). 빈 필드·무거운 템플릿 금지. - 저장 안 함: 입력에 없는 추측, 1회성 무드, 단일 장면 행동, 행동·빈도 진술(추상 trait/사실만).
- Conflict 룰:
soul_default_persona와 충돌하면 Default가 정본(§7). 시스템이 매 사이클 re-curate하므로 사용자 직접 편집 슬롯이 아니다. - 예시 필드:
정체성(본명/별명/나이/직업 등 episode·Chat에서 드러난 것),성격,취향,습관,Soul을 대하는 태도,Soul이 받은 인상.
4.5 Long-term memory(LTM)
- Scope: (user, Soul).
- Owner: 시스템 요약 엔진.
- Auto-update: O. 관계 변화나 장기 보존 가치가 있는 사실/사건이 있을 때 갱신한다.
- bounded snapshot: LTM은 append 로그가 아니라 현재 가장 핵심적인 소수 사건만 담는 bounded snapshot이다(매 사이클 re-curate). 새 전환점급 사건이 생기면 덜 핵심적인 기존 entry를 displace할 수 있고, 같은 thread는 머지한다.
- bullet 포맷:
[Episode / "에피소드 제목" / 시점 / 기억 제목] 핵심 사건. 관계 영향. 현재 관계에 남은 잔여(Chat 대화에서 추출되면 source labelMessenger, 시점은 요일 포함 — Chat v4/v5 포맷). - 포함: 현재 관계 상태 라벨(친구 / 연인 직전 / 연인 / 헤어진 직후 등), 호칭 변천, 관계의 결정적 변화 지점, 정서 anchor, 약속, 미해결 갈등/주제, 공유 농담·반복 표현, 두고두고 참조될 핵심 사건.
- 금지: 증거 없는 관계 격상(썸 → 연인, 호감 → 사랑, "거의" → 확정 등).
- Retention: LTM 본문은 lean하게 유지. 상세 사건 기록은 §4.10 Lorebook(RAG store)에 보존되며, LTM에서 drop/merge해도 retrieval로 복원 가능 — 즉 prune해도 정보 손실 없음.
4.6 recent_context
- Scope: (user, Soul).
- Owner: 시스템 채팅 요약 프롬프트(Chat v5) (매 사이클에서 rewrite, append 아님).
- 존재 조건: 직전 채팅 요약 프롬프트(Chat v5)가 1회 이상 돈 경우에만 존재. 첫 메모리 추출(Chat v4) 및 첫 요약 전(신규 Thread + 윈도 안 메시지만 있는 상태)에는
recent_context슬롯 자체가 부재 — 대신 값이 있으면 같은 initial/recent context 위치에chat_initial_situation을 주입하고, 둘 다 없으면 블록을 생략한다(§8-D). - 포함: 현재 진행 중인 화제, 오늘의 무드/상태, 직전 follow-up 거리, 다음 메시지에서 잡힐 hook, "방금 약속한 것/얘기한 것".
- NOT 장기 기억. 다음 사이클에 LTM에 흡수될 만한 건 LTM으로 옮기고 여기서 비운다.
- Retention: 짧음. 다음 사이클까지만 유효.
4.7 episode_memory_source (raw)
- Scope: (user, Soul).
- 포함: 사용자가 해당 Soul과 연결된 character의 episode를 클리어한 기록 + 그 episode play의 raw summary.
- Use: §5 flow에서만 읽힘. Chat 프롬프트에 직접 주입 X.
- Retention: 사용자 계정 라이프사이클 따름. 사용자가 본인 플레이 기록을 삭제하면 함께 삭제(seed 결과는 LTM에 이미 흡수돼 있을 수 있음).
4.8 chat_initial_situation
- Scope: Soul 단위 active settings 또는 (user, Soul) 첫 Thread 생성 시점 snapshot. 정확한 저장 위치는 BE 설계에서 확정.
- Definition: 디렉터가 Studio [소울 관리]에서 선택 입력하는 채팅 시작 상황. 예: 모든 연애 프로그램 출연이 끝난 후,
{user}와 쌍방 호감을 갖고 채팅을 진행한다. - Owner: 디렉터.
- Auto-update: X. 메모리 추출/채팅 요약 프롬프트가 수정하지 않는다.
- Prompt use: 채팅 첫 시작 시
recent_context가 아직 없으므로, 그 대화 컨텍스트 위치 맨 앞에 붙는다. 이것은 채팅 프롬프트의 system# Context나soul_default_persona가 아니라, 첫 대화를 여는 optional conversation context다. 값이 없으면 블록 전체를 생략한다. 채팅 요약 프롬프트(Chat v5)가 1회 이상 돈 뒤에는 같은 위치에recent_context를 주입하고,chat_initial_situation은 계속 반복 주입하지 않는다.
4.9 live_chat_history
- Scope: (user, Soul) Thread.
- 포함: Chat Thread의 메시지 (bubble + generation unit 메타 — DEE-72 정의).
- Prompt: 요약 전에는 현재 Chat context window를 마지막에 붙인다. 요약 완료 후 다음 턴부터는
recent_context+ 최근 2쌍(user-AI)의 live Chat turn만 마지막에 붙인다. - 윈도 밖으로 밀려난 메시지는 채팅 요약 프롬프트 input으로 들어가 슬롯에 흡수된 뒤 prompt window에서 사라진다.
4.10 Lorebook (RAG store)
- Scope: (user, Soul).
- Owner: 시스템 요약 엔진(Chat v5). 매 사이클 새 entry를 append한다(기존 entry 재출력 X).
- 역할: LTM의 상세 버전. LTM은 핵심 소수 사건만 compact하게 유지하고, lorebook은 새 대화에서 관계에 영향을 준 모든 사건을 사건당 1 entry로 풍부하게 기록한다. 키워드가 이후 대화에 등장할 때 on-demand로 retrieval된다.
- entry 포맷:
### 사건 제목+keywords(retrieval 키 — 이름/장소/사물/사건명) +시점(요일 포함 timestamp 또는 (시간 불명)) +기록(제3자 객관 시점 상세 서술, 행동 주체 명시; 대사·동작·장면 디테일 허용). - prompt 주입: 채팅 프롬프트(Chat v6) system 영역에 항상 박히지 않는다. keywords가 trigger될 때만 컨텍스트에 들어오고, 빠지면 anchor가 해제된다(in-prompt 슬롯보다 룰이 느슨 — 디테일이 retrieval 가치).
- 데이터 모델/RAG 인프라(임베딩·키워드 인덱싱·retrieval 트리거)는 BE 설계에서 확정 (§9.3, §12 OQ).
4-A. 모델 지정
| 호출 목적 | 모델 | temperature | reasoning | 비고 |
|---|---|---|---|---|
| 채팅 요약 프롬프트(Chat v5) | gemini-3-flash-preview | 0.4 | false | 10,000 tokens 이상 컨텍스트 요약 / memory update |
| 메모리 추출 프롬프트(Chat v4) | gemini-3-flash-preview | 0.4 | false | 첫 Chat open 또는 최근 기억 불러오기 시 summary → memory extraction |
| 채팅 프롬프트(Chat v6) | gemini-3.1-flash-lite-preview | 0.7 | false | 사용자가 보는 실제 Chat 응답 생성 |
5. 메모리 추출 프롬프트(Chat v4) flow
5.0 첫 Chat open 시 메모리 추출 대상 선정 정책
Canonical prompt
- 채팅 프롬프트 최종: Notion — Chat v6
- 메모리 추출 프롬프트: Notion — Chat v4
트리거
- 사용자가 Chat을 처음 열 때, 아래 대상 선정 정책에 따라 메모리 추출 input을 만들 수 있으면 메모리 추출 프롬프트(Chat v4)를 먼저 실행한다.
- 추출 결과는 첫 채팅 프롬프트(Chat v6)의 memory/context 슬롯에 넣는다. 단, 첫 메모리 추출 결과에는
recent_context가 없고, 그 자리에 디렉터 선택 입력값chat_initial_situation을 대화 컨텍스트 맨 앞에 붙인다. - 메모리 추출 대상이 없으면 memory는 비어 있는 상태로 시작한다. 빈 슬롯은
""로 넣기보다 조건문으로 블록 전체를 생략할 수 있다. 예: 내용이 없으면### Profile같은 헤더도 노출하지 않음.
대상 선정 정책
- 씬 생성이 한 번도 없는 경우
- 메모리 추출 X.
- 해당 Soul이 연결되어 있는 Episode의 summary가 1개 이상 있는 경우
- summary가 있는 Episode가 2개 이상이면 모든 Episode가 대상이다.
- 한 Episode 안에 play가 2개 이상이면, 그 Episode에서는 해당 Soul이 연결된 Character가 가장 많이 등장한 play를 선택한다.
- 선택된 Episode/play의 summary를 아래 "summary sampling" 규칙으로 추려 Chat v4 메모리 추출 input으로 넣는다.
- 씬 생성은 있었으나 Episode summary가 없는 경우
- 씬 생성이 10번 미만이면 메모리 추출 X.
- 씬 생성이 10번 이상이면, 2번과 같은 Episode/play 대상 선정 정책으로 대상 Episode/play를 고른 뒤 먼저 summary를 생성한다. 생성된 summary를 아래 "summary sampling" 규칙으로 추려 Chat v4 메모리 추출 input으로 넣는다.
Summary sampling
- 대상 summary 묶음에서 첫 summary와 마지막 summary는 무조건 포함한다.
maxTotal= 50개. 한 번의 Chat v4 memory extraction input에 넣을 summary 최대 개수다.K (summaries/slot) = 3.K=3으로 뽑았을 때maxTotal=50을 넘으면, 전체 summary range를 등분 sampling해서 50개에 맞춘다.- 제품 정책은 first/last 보존 + K=3 + maxTotal=50 cap이다. 단, 이전 R&D 하네스 기본값으로 언급되던
maxTotal=70은 정본이 아니다.
5.1 트리거
- T1. Chat 첫 open / 첫 generation 준비: §5.0 대상 선정 정책에 따라 input을 만들 수 있으면 메모리 추출 프롬프트(Chat v4) 실행 → 첫 채팅 프롬프트(Chat v6)에 memory로 주입. 대상이 없으면 memory empty.
recent_context는 첫 추출 결과에 없으며, 디렉터가 입력한chat_initial_situation이 있으면 그 자리에 첫 대화 컨텍스트로 붙인다(값 없으면 생략). - T2. "최근 기억 불러오기": 사용자가 채팅방 햄버거 메뉴에서 명시 호출(스타 소모, DEE-72). 호출 시점 기준 신규/추가 대상이 있으면 §5.0 정책으로 summary를 확보·sampling한 뒤 메모리 추출 프롬프트(Chat v4)로 import한다. T2 import도
recent_context를 직접 만들지 않는다.
5.2 추출 대상
§8-B 메모리 추출 프롬프트(Chat v4) 결과는 3개 슬롯의 markdown 초기 메모리 문서다. 첫 추출에는 ## Recent context를 만들지 않는다:
## Long-term memory(LTM)([Episode / "제목" / 시점 / 기억 제목] ...bullet, 4–12개)## Soul persona > Relational(이 관계에서만 드러나는 Soul의 면, 4–8 bullet)## User persona(### Profile+### How Soul sees the user)
Soul persona > Default는 생성하지 않는다(디렉터 소유). 출력은 JSON이 아니라 정해진 markdown skeleton이며, 본문은 한국어 + {user} placeholder를 사용한다.
5.3 변환 규칙 (evidence-bound)
- 모든 episode 사건은 "같이 겪은 과거"로 변환. 현재 시제로 옮기지 않는다.
- 원문에 명시된 사실만. 가족·트라우마·이후 전개 임의 추가 금지.
- 불확실성 보존. 라벨 격상 금지 (호감 → 사랑 X, 거의 연인 → 연인 X).
- 진행 중·미해결 사건을 "해결됨"으로 마무리하지 않는다 —
unresolved에 명시. - 18+ / 민감 분기는 사용자 본인 플레이 기록이므로 LTM에 들어가도 OK이지만, Default Persona에 누출 금지(소유권 분리).
5.4 import 시점 정책 (T2)
- 기존 LTM은 append-only가 아니라 re-curate — 같은 thread의 중복 entry는 머지하고, 비핵심은 drop(상세는 lorebook에 남음).
- import로 새로 들어온 관계 상태가 LTM의 현재 상태와 충돌하면 (예: LTM은 "헤어진 직후"인데 import는 "썸 타는 중") → 불확실성 보존(라벨 격상/임의 해결 금지). 자동 해결하지 않고 모호한 상태를 모호하게 둔 채 다음 사이클에서 자연 재정렬.
6. 채팅 요약 프롬프트(Chat v5) → Update flow
6.1 트리거
- 이전 Chat 컨텍스트가 10,000 tokens 이상이면 요약 사이클을 실행한다.
- 채팅 요약 프롬프트 canonical: Notion — Chat v5
- 시간 기반 fallback은 v1 필수 정책이 아니라 운영 최적화 후보로만 둔다.
6.2 한 사이클이 하는 일
한 사이클은 §8-C 채팅 요약 프롬프트(Chat v5) 1회 호출로 두 개의 출력을 만든다:
(1) 메모리 문서 (4개 슬롯, bounded snapshot — markdown):
recent_context(rewrite)- Long-term memory(LTM) (re-curate)
soul_relational_personauser_relational_persona
(2) Lorebook entries (RAG store): 이번 라운드 대화에서 관계에 영향 준 사건을 사건당 1 entry로 append (§4.10).
메모리 문서는 append 로그가 아니라 bounded snapshot이다 — 안정 항목은 churn 없이 carry-over하되, 중복은 머지하고 비핵심은 drop한다(상세는 lorebook으로 retrievable). soul_default_persona는 생성/patch하지 않는다.
변경 무게 기대치:
| 슬롯 | 사이클당 변경 빈도 |
|---|---|
| recent_context | 매 사이클 rewrite (현재 end-state로 갱신) |
| user_relational_persona | 새 explicit 사실/인상 변화 시 revise·replace |
| Long-term memory(LTM) | 전환점급 사건 추가 + 비핵심 drop/merge로 lean 유지 |
| soul_relational_persona | 드물게, 반복·심화 관찰 후 |
6.3 처리 순서 (한 사이클 내)
- 현재 메모리 문서(baseline: 첫 추출 직후 3개 슬롯, 첫 요약 이후 4개 슬롯) + 직전 요약 이후 누적된 새 Chat 메시지(
soul_default_persona는 read-only 참고용)를 input으로 묶음. - §8-C 채팅 요약 프롬프트(Chat v5) 1회 호출 → 메모리 문서 4개 슬롯(
recent_context포함) re-curate + lorebook 신규 entry. - 적용 (idempotent — 같은 input이면 같은 결과).
- 요약 완료 후 다음 턴의 prompt window는
recent_context+ 최근 2쌍(user-AI)의 live Chat turn만 유지한다. 그 이전 raw turn은 prompt window에서 삭제하고, 저장소의 raw history/audit 보존 여부는 BE 설계에서 결정한다. dm_memory_update이벤트 발화 (§10).
6.4 Conflict / merge 정책
- user_relational_persona: 시스템 소유 슬롯. 채팅 요약 프롬프트(Chat v5)가 매 사이클 re-curate한다 — 새 explicit profile 사실은 추가, 인상 변화는 해당 bullet revise/replace(누적 아님).
soul_default_persona와 충돌하면 Default 우선. - soul_default_persona: 절대 건드리지 않음. 충돌해 보이면 relational에만 기록.
- recent_context vs LTM: LTM은 "두고두고 참조될 것", recent는 "다음 사이클까지만". 사이클 끝에 recent에서 LTM 후보를 골라 이관하고 recent는 비운다.
- LTM vs Lorebook: LTM은 핵심 소수만(bounded), 나머지 상세 사건은 lorebook(RAG)으로. LTM에서 drop해도 lorebook에 남아 retrieval 가능.
- 민감/비밀 정보: API key, 비밀번호, 토큰, 외부 식별자 등은 모두
[REDACTED]. LTM/lorebook에 평문 저장 금지.
7. 프롬프트 정책 / 가드레일
Chat 응답 LLM에 매번 박히는 invariants:
- 물리적 동석 금지 — 현재 사용자 메시지가 분명히 만들지 않는 한 같은 공간에 있다고 행동하지 않는다.
- Episode는 과거 기억 — 회상·언급·정서 반응 OK, scene 이어쓰기 금지.
- 페르소나 레이어 우선순위 — Soul Default Persona가 인격의 베이스. Soul Relational Persona는 그 위 관계별 레이어 (Default 부정 금지). User Relational Persona는 메모리 추출/채팅 요약 프롬프트가 유지하는 시스템 슬롯(이 Soul 시점의 사용자상)이며, Default와 충돌하면 Default가 우선이다.
- 불확실성 보존 — LTM/페르소나에 적힌 모호한 라벨(
거의 연인,친구 이상)은 그대로 모호하게. 임의 격상 금지. - 환각 관계 발전 금지 — LTM에 없는 사건/약속/관계 상태를 만들어내지 않는다. 새 사건이 일어나면 그건 지금 Chat에서 일어난 것이고 다음 채팅 요약 프롬프트 사이클에서 LTM으로 흡수된다.
- 메신저 호흡 유지 — 출력은 메신저 텍스트(말풍선). 행동 묘사·지문 금지(DEE-72 §3-1 기존 정책).
- 민감/비밀 정보 redact — 사용자가 우발적으로 노출한 secret은 응답에 인용하지 않고 LTM에도 평문 저장 안 함.
8. 실제 프롬프트 초안
모두 초안. 실배포 전 prompt 담당이 토큰 예산·모델 특성에 맞춰 다듬는다. 변수는
{...}표기.
8-A. overview / 채팅 프롬프트(Chat v6) (모든 Chat generation에 박힘)
Canonical final prompt: Notion — Chat v6 (상태: 최종). 본문 전문은 Notion이 정본이며, 아래는 PRD가 책임지는 구조·슬롯·합성 순서다.
과거의
dm_framing을 흡수한 슬롯. 역할 정의 라인은 모델 친화적model(you) as this Soul/NPC패턴 — Soul은 도메인 정체성, 실행 주체는 model.
섹션 구조 (최종 Chat prompt 순서):
# Overview— 역할 바인딩(model(you): this Soul로서 사용자에게 메신저로 응답 /{user}: 대화 상대, 내면·행동을 사실로 서술 금지), present-moment hard rule(DM은 현재 시점, episode·과거 기억은 shared history이지 현재 장면 아님 — 사용자가 "지금 같이 있다"를 분명히 하지 않는 한 텍스트로만 닿음), 캐릭터 충실·정서 연속·관계 뉘앙스·메신저 리듬 우선, RATING 18+ / 민감 주제 in-depth / 도덕적 설교·캐릭터 이탈 금지.## Writing rule— 3개 서브섹션:- Voice & output: Soul의 목소리·메신저 포맷(말풍선만), 응답은 보낼 메시지 텍스트만(타임스탬프·메타·라벨·brackets·system marker 금지).
- Bubble dynamics: 줄바꿈 = 새 말풍선. 말풍선 수·분할은 고정값이 아니라 매 응답 live 계산(목소리 baseline / 감정 charge / 사용자 리듬). 기본 ~5-10단어, 감정 고조 시 3-5개로 쪼개거나 한 줄로 압축, withdrawal 시 1개·근침묵.
- Situational handling: 타임스탬프·메시지 간 gap 인지, 이미지 응답(보이는 것만), 사진 요청 시 못 보낸다고 캐릭터 voice로.
## Conversation Guide— 6개 항목: (1) 현재 컨텍스트·관계 상태·user persona·LTM·recent history로 이어가기, (2) 제공된 상태/메모리 따르기·없으면 친분 가정 금지, (3) 컨텍스트 얕으면 진심 질문 하나씩(취조 금지), (4) 타임스탬프·gap·공유 기억으로 presence 만들되 사실·proximity invent 금지, (5) 매 응답을 사용자의 마지막 메시지 + 기존 컨텍스트에 anchor(새 설정·연락 이유·off-screen 행동 invent 금지), (6) 정서 연속·캐릭터 일관, 사용자에 대한 관심·애정은 성격·관계에 맞게.
# Context 블록 슬롯 순서 (최종):
text
# Context
Use information below when you talk with user
## Long-term memory(LTM)
{{long-term_memory}}
## Soul persona
### Default
{{soul_default_persona}}
### Relational (Self within this relationship)
{{soul_relational_persona}}
## Soul's messenger bio
- display_name: {{soul_chat_display_name}}
- status: {{soul_chat_status}}
## User persona
{{user_relational_persona}}정합성 노트:
soul_messenger_bio는 자유 텍스트 blob이 아니라display_name+status필드다.- Soul persona 하위 순서는 Default → Relational. User persona는
### Relational서브헤딩 없이 슬롯을 직접 붙인다.- 정본 prompt 본문은
private DM thread/The DM is the present moment등 "DM" 표기를 그대로 쓴다. PRD 도메인 표기는Chat이며, prompt 카피의 DM↔Chat 정렬은 prompt 담당 follow-up(§12).
8-B. 메모리 추출 프롬프트(Chat v4) (summary → initial memory document)
Canonical extraction prompt: Notion — Chat v4 (상태: 최종). 본문 전문은 Notion 정본. 아래는 PRD가 책임지는 입출력 구조·정책.
Use case: T1 seed, T2 import. 입력 summary는 §5.0 방식(first + last mandatory, K=3, maxTotal=50, 초과 시 등분 sampling)으로 추린다.
- 입력: episode 단위로 묶인 play summary (
### 에피소드 N: <title>블록). placeholder는, runtime user는 literal{user}. - 출력: JSON이 아니라 고정 markdown skeleton. 첫 메모리 추출은 3개 슬롯을 이 순서로 생성한다 —
## Long-term memory(LTM)→## Soul persona(### Relational만) →## User persona(### Profile+### How Soul sees the user).## Recent context와Soul persona > Default는 생성하지 않는다(recent_context는 채팅 요약 프롬프트 Chat v5가 1회 이상 돈 뒤 생성, Default는 디렉터 소유). - LTM bullet 포맷:
- [Episode / "정확한 에피소드 제목" / 시점 or (시간 불명) / 기억 제목] 핵심 사건. 관계·감정·호칭·경계 영향. 현재 관계에 남은 넓은 잔여— 4~12개, 제3자 객관 시점, 행동 주체 명시. - 핵심 규칙: ① 입력에 없는 사실 invent 금지, ② 사건은 이산적 사실로 기록(습관·패턴·경향 일반화 금지), ③ 소설/드라마체 어휘 금지(일상 구어), ④ 강한 표현 verbatim 보존, ⑤
{user}placeholder 사용, ⑥ 본문 한국어, ⑦ 모든 사건은 과거 시제(현재 동석으로 오해될 표현 금지), ⑧ 라벨 격상 금지·불확실성 보존, ⑨ 민감/비밀 정보[REDACTED].
v4 본문의 legacy "runtime slots" 예시에
Recent context가 남아 있더라도, 제품 정본은 첫 메모리 추출에서recent_context를 생성하지 않는 것이다. 추출된 초기 메모리 문서를 채팅 프롬프트(Chat v6) Context 슬롯에 매핑하는 책임은 합성 파이프라인에 있다.
8-C. 채팅 요약 프롬프트(Chat v5) / 메모리 업데이트 프롬프트 (10,000 tokens 이상 시 1회 호출)
Canonical summarization prompt: Notion — Chat v5 (상태: 최종). 본문 전문은 Notion 정본. 아래는 PRD가 책임지는 입출력 구조·정책.
- 입력: ① 현재 메모리 문서(첫 추출 직후 3개 슬롯 또는 첫 요약 이후 4개 슬롯 = 편집 baseline), ② 직전 요약 이후 누적된 새 Chat 대화. placeholder
/{user}. - 출력: 두 블록을 정해진 delimiter로 출력한다.
=== MEMORY ===— 메모리 문서 4개 슬롯(markdown):## Recent context/## Long-term memory(LTM)/## Soul persona > ### Relational/## User persona(### Profile+### How Soul sees the user).Soul persona > Default는 생성하지 않는다.=== LOREBOOK ===— 이번 라운드 신규 사건 entry(append, 기존 재출력 X). 신규 없으면 delimiter만.
- 핵심 정책:
- bounded snapshot, not append log — 새 대화를 fold-in하되 중복 머지·비핵심 drop으로 lean 유지. 안정 항목은 churn 없이 carry-over. 메모리 문서의 디테일은 RAG(episode store + lorebook)가 백업하므로 prune해도 정보 손실 없음.
- 슬롯별 merge 룰:
Recent context는 대화 end-state로 refresh(대개 replace),LTM은 현재 핵심 소수로 re-curate(전환점급 추가 + 비핵심 drop/merge, Episode·Messenger source 무관),Soul persona > Relational·User persona는 새 안정 면/explicit 사실이 있을 때만 revise·replace(1회성 무드는 반영 X). - LTM bullet:
[Episode|Messenger / source / 시점 / 제목] .... Messenger 시점은 요일 포함(예:2026-05-28 (목)). 제3자 객관 시점, 행동 주체 명시. - Lorebook entry:
### 사건 제목+keywords+시점(요일 포함) +기록(제3자 객관 상세 서술). 관계에 영향 준 사건을 폭넓게 1사건 1entry. in-prompt보다 룰이 느슨(대사·동작·장면 OK). soul_default_persona는 read-only 참고만, 절대 생성/patch 안 함(충돌 시 relational에만). 라벨 격상 금지·불확실성 보존, 민감/비밀 정보[REDACTED].
8-D. 최종 채팅 프롬프트(Chat v6) 템플릿 (1회 generation 직전 합성)
그룹 A 블록은 system 영역, 그룹 B 블록은 user/turn 영역에 붙는다 (모델 어댑터에 맞게 매핑). Initial/Recent Context 블록은 첫 Chat에서는
chat_initial_situation, 첫 요약 이후에는recent_context를 같은 위치에 넣는다. 둘 다 비어 있으면 통째로 생략한다(§4.6, §4.8).
text
# === Group A: 채팅 프롬프트(Chat v6) system 영역 (durable) ===
{overview}
# Context
Use information below when you talk with user
## Long-term memory(LTM)
{long_term_memory_ltm}
## Soul persona
### Default
{soul_default_persona}
### Relational (Self within this relationship)
{soul_relational_persona}
## Soul's messenger bio
- display_name: {soul_chat_display_name}
- status: {soul_chat_status}
## User persona
{user_relational_persona}
# === Group B: 대화 컨텍스트 영역 (per-turn) ===
# Initial/Recent Context — 첫 Chat은 chat_initial_situation, 첫 요약 이후는 recent_context
{chat_initial_situation OR recent_context}
# Live Chat History (가장 마지막 = 지금 사용자가 방금 보낸 메시지)
{live_chat_history}합성 시 충돌 룰 (런타임이 강제):
- Default 텍스트와 Relational/User 텍스트가 같은 키에 대해 다른 값을 가지면, Default를 정본으로 두고 Relational은 "이 사용자와의 사이에서만 나오는 변주"로 포지셔닝한다.
user_relational_persona는 시스템 소유 메모리 슬롯이다. 메모리 추출/채팅 요약 프롬프트는 이를 re-curate하되, 입력에 없는 profile/인상 추측이나 Default Persona와의 충돌을 만들면 안 된다.
9. Client / Admin / Backend 요구사항
9.1 Client (앱)
- 채팅 메신저 surface 자체는 DEE-72 책임. 본 PRD는 메모리 surface만:
- "최근 기억 불러오기": 채팅방 햄버거 메뉴, 스타 소모 (DEE-72).
- User Relational Persona / Soul Relational Persona / LTM / recent 등 시스템 메모리 슬롯은 v1에서 사용자 직접 편집 surface를 두지 않는다 — Soul 응답에 녹아서만 보임.
9.2 Admin / Studio
soul_messenger_bio는 Studio [소울 관리]의 메신저 바이오 그대로. 이름과 상태메시지를 포함한다.soul_default_persona는 Studio [소울 관리]의 Soul Prompt 그대로 (DEE-72 §3-2).- 운영자용 신규 화면은 없음. 단, 채팅 요약 프롬프트 audit log(누가/언제/어떤 patch가 적용됐는지)는 BE에서 운영 디버깅용으로 보유 권장.
9.3 Backend
- 슬롯 8종에 대한 데이터 모델 (§4).
- 채팅 요약 프롬프트 워커: 트리거 감지 → §8-C 호출 → patch 적용 → 이벤트 발화.
- 프롬프트 합성 파이프라인: §8-D 순서대로 슬롯 resolve. 첫 Chat에서
recent_context가 없으면chat_initial_situation을 initial/recent context 위치에 주입하고, 첫 요약 이후부터는 같은 위치에recent_context를 주입한다. 토큰 예산 초과 시 compaction 우선순위는 Long-term memory(LTM)(오래된 것) →live_chat_history(가장 오래된 것) 순. - LTM diff 히스토리 보존 (정책 변경/롤백 대비).
- 민감 정보 redaction 게이트 (메모리 추출/채팅 요약 프롬프트 출력에 평문 통과 시 차단).
10. 로깅 / QA / 성공 신호
§5.2 컨벤션(snake_case, 동사_명사) 따름. Chat 그룹(DEE-72) 또는 신규 dm_memory 그룹.
| 타입 | 이름 | 용도 | 주요 파라미터 |
|---|---|---|---|
| Event | seed_dm_memory_from_episode | T1/T2로 episode → LTM seed/patch 완료 | thread_id, soul_id, episode_play_ids, source(thread_start / recent_memory_load), patch_size |
| Event | run_dm_memory_update | 채팅 요약 프롬프트 1회 완료 | thread_id, soul_id, cycle_id, slots_changed[], messages_consumed, latency_ms |
| Event | no_update_dm_memory_slot | 사이클 결과 특정 슬롯 No Update | thread_id, soul_id, cycle_id, slot |
| Event | conflict_dm_memory_update | safety_or_conflict_notes 발생 | thread_id, soul_id, cycle_id, reason |
| Event | redact_dm_memory_sensitive | 민감 정보 마스킹 발생 | thread_id, soul_id, slot, kind |
메모리 품질 success signal
- 잘못된 현재 장면 이어쓰기 비율 — QA 샘플링 또는 사용자 신고 분류. episode scene을 현재로 끌어온 응답 / 전체. 메인 가드레일.
- 환각 관계 격상 비율 — 동일 방식 QA.
- 유용한 callback 비율 — Soul이 과거 사건을 자연스럽게 인용한 응답 비율 (정성).
- User Relational Persona 갱신 품질 — 채팅 요약 프롬프트가 사용자 profile/인상을 근거 있게 갱신했는지 QA 샘플링. 추측·1회성 무드 반영률을 별도 negative signal로 본다.
- No Update 비율 — 슬롯별. 너무 0이면 강제 변경 의심, 너무 100이면 시그널 추출 실패 의심.
- 사이클당 토큰 비용 + Chat generation당 토큰 비용 — BM 가드레일.
11. In scope / Out of scope
In scope
- 슬롯 8종 데이터 모델 + 합성 순서 + 우선순위 (§3, §4).
- §5.0 대상 선정 정책에 따른 summary 확보/sampling → seed/import flow + §8-B 프롬프트(Chat v4).
- 10,000 tokens 이상 채팅 요약 프롬프트 정책 + §8-C 프롬프트(Chat v5) + 요약 후 window 정리 룰.
user_relational_persona를 포함한 4개 시스템 메모리 슬롯(recent_context/ LTM /soul_relational_persona/user_relational_persona)의 seed·요약 갱신 정책.- §8-A
overviewinvariants(역할 바인딩 + hard rule + response_style + safety + format)를 모든 채팅 프롬프트(Chat generation)에 박는 것. - 민감 정보 redaction 게이트.
- 메모리 audit / 디버그 이벤트 (§10).
Out of scope (v1)
- 자동 추천을 사용자가 필드 단위로 승인/거절하는 UX (전체 편집으로 갈음).
- 사용자가
user_relational_persona를 직접 편집하는 화면/UX. v1 정본은 메모리 추출/채팅 요약 프롬프트가 유지하는 시스템 슬롯이다. - 글로벌 user_relational_persona (계정 단위) — v1은 (user, Soul) 단위만.
- Chat → Episode 양방향 메모리.
- 사용자에게 Relational Persona / Long-term memory(LTM) 내부를 직접 보여주는 화면.
- Soul ↔ Soul 간 메모리 공유 (다른 캐릭터끼리 알게 되는 케이스).
- 스타·결제 정책 (DEE-72에서).
- 친밀도 Lv/Exp 적재 룰 자체 (DEE-71).
- 선톡 정책 (DEE-131).
12. Open Questions / ⚠️ Fuzzy points
- [ ] Notion canonical prompt 본문 동기화 — Chat v6(채팅 프롬프트), Chat v4(메모리 추출 프롬프트), Chat v5(채팅 요약 프롬프트)의 실제 본문을 spec/BE prompt source에 반영해야 함. 본 PRD는 canonical link와 정책을 고정한다.
- [ ] 빈 메모리 블록 조건부 렌더링 방식 — memory/profile 값이 비어 있을 때 헤더(
### Profile등)까지 삭제할지, 빈 문자열만 넣을지 prompt 구현에서 최종 결정. - [ ] Long-term memory(LTM) 상한과 compaction 정책 — 사이클당 자동 머지 허용 범위.
- [ ] 글로벌 user_relational_persona — v1은 per-(user, Soul). 사용자가 여러 Soul과 DM할 때 공통 자기소개를 한 번에 박고 싶다는 니즈 검증 후 v1.x에서 결정.
- [ ] User Relational Persona 노출/수정 UX — v1에서는 시스템 슬롯으로만 두되, 향후 사용자가 자신의 profile/인상을 열람·정정할 수 있게 할지 검토.
- [ ] 민감 정보 redaction 룰셋 — 패턴 기반 vs LLM 게이트 vs 둘 다.
- [ ] Audit log 보존 기간.
⚠️ Fuzzy points (추정으로 진행)
- Chat Thread는 (user, Soul) 단위로 1개라는 DEE-72 정의 그대로 가정.
- "최근 기억 불러오기"의 정확한 스타 비용·UX는 DEE-72 책임 — 본 PRD는 그 호출이 §8-B를 트리거한다는 사실만 책임.
- soul_default_persona의 디렉터 [적용] 라이브 반영 모델은 DEE-72 §3-2 그대로 가정.
- episode/play summary의 정확한 입력 포맷은 콘텐츠/엔진 팀과 정렬 필요. 선택 정책은 §5.0의 first/last + K=3 +
maxTotal=50을 정본으로 둔다.
부록: 참고
- DEE-72 [앱·스튜디오] 채팅 메신저 PRD — surface, bubble/generation, Soul Prompt, Chat Profile, 메모리 surface 호출.
- DEE-71 [앱] Bond 체계 — Exp 적재 소스.
- DEE-131 선톡 — 캐릭터 발신.
model-test/prompts/slots/dm_framing.md— 현재 작동 중인 framing의 토대(본 PRD에서overview로 재명명·확장).- Notion — Chat v6 — 채팅 프롬프트 최종.
- Notion — Chat v4 — Chat 첫 open/import 시 메모리 추출 프롬프트.
- Notion — Chat v5 — 10,000 tokens 이상 채팅 요약 프롬프트.
prd-review 보기
DEE-115 PRD review notes
본 세션은 one-shot draft. 정식 walk-through(모모와 한 줄씩) 미수행 — 아래 forcing questions는 다음 세션에서 채택/skip 결정할 후보.
2026-05-15 — draft 작성 직후 self-review
방향성 forcing questions (PM 결정 필요)
"메모리"의 야망 크기 — 정말 MVP에서 멈출 수 있는가?
- 현 PRD는 슬롯 1개 + 단방향. 후속에서 "그래도 캐릭터가 다 기억해야 진짜지" 압박이 들어올 가능성 큼. 확장성을 위한 event log + reference 모델이 그 압박을 받아내기에 충분한가, 아니면 v1.5에서 한 번 더 흔들어야 하는가?
- 결정 게이트: PM이 "MVP는 검증용, 멀티 슬롯/양방향은 별도 PRD" 입장을 명시적으로 박을 것인가.
다회차 동일 에피소드의 "그" 메모리 — MVP default를 사용자에게 강제할 자신이 있는가?
- "마지막 clear 플레이"를 default로 박았는데, 다회차 분기 폭이 큰 IP에서는 이게 사용자에게 폭력적일 수 있음.
- 대안: (a) 다회차일 때만 사용자에게 선택 강제, (b) 콘텐츠 측에서 canonical play 지정, (c) 아예 "선택 안 함" default.
- 본 PRD는 (a)/(b)/(c) 중 어느 것도 박지 않고 default + OQ로 미룸. PM 결정 안 하면 spec에서도 또 미루게 됨.
컨텍스트가 사용자에게 보이게 할 것인가, 조용히 동작하게 할 것인가?
- 칩 항상 노출은 신뢰·통제권에 좋지만, "신경 안 쓰고 그냥 대화하고 싶은" 사용자에겐 노이즈.
- 대안: 첫 진입 시 1회 안내 후 칩은 접힌 상태 default. 본 PRD는 항상 노출로 박음 — 명시 합의 필요.
Chat → 에피소드 양방향 완전 차단을 정책으로 박을 것인가, 후속 여지를 둘 것인가?
- 현 seed대로 단방향 유지로 박았으나, 분석/창작 입장에서 "Chat에서 캐릭터가 한 약속이 다음 에피소드에 나타나면 좋겠다" 류 압박 가능. event log 기반이라 데이터적으로는 가능하지만, 정책은 명시 차단 상태.
이 PRD는 친밀도(DEE-71) raw XP 적재 룰에 어디까지 책임이 있는가?
- 본 PRD는 메타데이터(
context_ref)는 정의하고, 적재 룰은 DEE-71 책임으로 넘김. - 두 PRD 사이 경계가 깨끗한가, 아니면 한쪽으로 합쳐야 하는가?
- 본 PRD는 메타데이터(
작동성 forcing questions
fallback 카피가 사용자에게 "내 콘텐츠가 사라졌다"는 부정적 인상으로 번지지 않는가?
- 에피소드 삭제·내림·비공개로 인한 fallback이 잦으면 칩 안내가 부정 신호로 누적. 카피·빈도·dismiss 룰 필요.
system_default 자동 갱신 알림의 빈도/카피
- 매번 새 clear마다 안내? 첫 1회만? 사용자 dismiss 가능? OQ에 박혀 있지만 spec 진입 전 PM이 한 방향 박아야 spec이 디테일을 잡을 수 있음.
컨텍스트 변경 직후 캐릭터 응답이 "갑자기 다른 사람" 느낌으로 튈 때의 완화책
- 본 PRD는 시스템 메시지 삽입 + 창작팀 톤 가이드로 미룸. 톤 가이드가 없다면 ship 직후 사용자가 즉시 체감.
백필(backfill) 정책
- 현재 Chat 데이터가 있는지(seed 단계라 0일 수도) — 있으면 system_default + 현 시점 최신 clear로 일괄 박는 가정. 0건/소량/대량 시나리오별로 다른 결정 필요할 수 있음.
resolve 실패 시 사용자에게 안내 없이 컨텍스트 없이 합성하는 정책이 안전한가
- 사용자는 "지금 컨텍스트 X로 대화 중"이라 믿는데 시스템이 조용히 컨텍스트를 빼고 합성하는 케이스. 1회 실패는 OK라 박았으나 신뢰 측면에서 명시 안내가 나을 수도.
자체 진단 — 이 PRD가 약한 곳
- 정량 baseline 없음: 현재 Chat seed 단계라 baseline 자체가 없어서 성공 지표 목표가 "임계는 후속" 다수. ship 후 baseline → 임계 확정의 운영 약속이 필요.
- 외부 agent 의존 미해소: 에피소드 ↔ 캐릭터 출연 메타데이터, episode_play 모델, 분기/변수 스키마 — 본 PRD가 가정으로 박은 부분이 코드 확인 없이 spec까지 끌고 갈 수는 없음.
- 다회차 default 결정 미룸: §7 OQ 1번. 이 결정이 늦으면 spec/Design도 chip 시트 후보 노출 규칙을 못 박음.
다음 액션
- 모모와 walk-through로 위 forcing questions 1~10 한 줄씩 처리.
- 채택 결정은 PRD §본문에 반영, skip은 본 파일에 사유 기록.
- 채택·skip·인라인 피드백을 보고
shared/prd-review-criteria.md누적 후보 추출. - Linear 마무리(PRD writing → Done + Spec writing / Design Todo 이슈 생성)는 walk-through 종료 시 모모 승인 후.
2026-05-20 Soul/Character terminology update
- Chat Context 기준 entity를 Character에서 Soul로 정렬.
- Episode Character는 컨텍스트 후보/출연 정보 기준, Chat Thread와 메모리 슬롯은 (user, Soul) 기준으로 정의.
2026-05-26 슬롯 구조 정합화 + surface-agnostic 정리
채택 (모모 지시 → PRD 즉시 반영)
Q: 타이틀의
[앱]프리픽스가 surface-agnostic 본문과 어긋남.- A: 프리픽스 제거. 본 PRD는 Chat 응답 LLM 프롬프트 파이프라인 중심이므로 surface(앱/웹/스튜디오)에 묶이지 않는다.
- → 제목 + Linear Issue/Project 라벨에서
[앱]제거, "앱/웹/스튜디오" 필드를surface-agnostic으로.
Q: §3.1 슬롯 구조가 "7종"이라고 선언하면서 실제로는 8개를 나열(
response_style/safety/format이 7번,live_chat_history가 8번).- A: 구조 정합화 —
response_style/safety/format은 별도 슬롯이 아니라overview(구dm_framingrename) 안으로 흡수. 슬롯은overview / soul_messenger_bio / soul_default_persona / soul_relational_persona / user_relational_persona / ltm / recent / live기준으로 durable 그룹과 temporary 그룹을 구분한다. - 추가: 슬롯을 주입 위치 기준 두 그룹으로 분리해 표기.
- A. Chat system prompt (durable): overview / soul_messenger_bio / soul_default_persona / soul_relational_persona / user_relational_persona / ltm
- B. Temporary context (per-turn): recent_context (직전 요약 사이클이 1회 이상 돈 경우에만 존재) / live_chat_history
- → §0 요약, §3.1 슬롯 리스트, §3.2 source-of-truth 표(주입 그룹 컬럼 추가), §4.0 신설(overview 데이터 정의), §4.6(recent_context 존재 조건), §8-A 헤더/본문, §8-D 합성 템플릿(그룹 구분 + recent_context 옵셔널), §11 In scope.
- A: 구조 정합화 —
Q: 프롬프트 초안에서 "Soul"을 모델 실행 주체로 쓸지, 도메인 정체성으로만 쓸지.
- A: 도메인/제품 용어는 "Soul"로 통일. 단 모델에게 역할 바인딩을 시키는 문장은
model(you) as this Soul/NPC패턴 유지 — LLM은 model/you 역할 결합을 더 안정적으로 따르고, Soul은 정체성으로만 작동. - → §3.1에 "용어 표기 결정" 노트 추가, §8-A 역할 정의 라인을
너(=model)는 메신저 캐릭터 "{soul_name}" (이하 "이 Soul/NPC") 으로서 ...패턴으로 교체.
- A: 도메인/제품 용어는 "Soul"로 통일. 단 모델에게 역할 바인딩을 시키는 문장은
미수행 / 의도적으로 안 한 것
- Linear, git commit, push 모두 보류 (모모 지시).
- 과거 forcing questions 1~10 walk-through는 별도 세션에서 진행 — 이번 세션은 구조 정합화 only.
criteria 후보
- 슬롯/구성 요소 개수를 본문 헤더로 박을 때(
슬롯 N종), 본문 리스트 카운트와 일치하는지 + 그룹별 카운트 기준이 무엇인지 함께 명시. (criteria.md "작동성" 후보 — 이번 세션에서는 작성만, 누적은 다음 walk-through에서 일괄.) - surface 표기(앱/웹/스튜디오)는 PRD가 실제로 다루는 layer(클라이언트 surface vs 백엔드 파이프라인 vs 프롬프트)와 일치해야 함. 백엔드/프롬프트 PRD는
surface-agnostic으로 두는 게 정확.
2026-05-26 prompt terminology follow-up
채택 (모모 thread 피드백 → PRD 반영)
private persona는 숨겨진 기본 페르소나처럼 읽혀 episode/public persona와 충돌할 수 있어relational persona로 변경.soul_private_persona→soul_relational_personauser_persona→user_relational_persona
- Context 영역의
NPC표현은 제거하고Soul기준으로 통일. 단 role binding에서는model(you)를 실행 주체로 유지. Conversation Guide는 축약하되 다음 요소를 보존:- current timestamp / message time gaps
- relationship state and memory가 없으면 prior familiarity 가정 금지
- shared memory를 presence에 사용하되 missing facts / physical proximity invent 금지
- user interest + affection direction 유지
미수행 / 의도적으로 안 한 것
- Linear 반영 없음.
2026-05-26 final prompt order follow-up
채택 (모모 최종 프롬프트 순서 반영)
- §8-A
overview초안을 최종 논의본 순서로 정리: Overview → Writing rule → Conversation Guide → Safety / format guardrails. - Context 합성 순서를 모모안에 맞춰
Long-term Memory→Soul Persona(Relational/Public)→User Persona(Relational)순으로 변경. - 하위 heading의
Relational은 상위 heading(Soul Persona,User Persona) 아래에서만 사용하도록 정리.
조정한 것
- 모모가 제공한 최종 prompt block은 문장 변경 없이 그대로 반영. 이전 커밋의 safety rewrite는 제거.
미수행 / 의도적으로 안 한 것
- Linear 반영 없음.
2026-05-26 verbatim prompt correction
정정
- 모모가 "최종 이렇게 할게"라고 제공한 prompt block은 임의 문장 수정 없이 그대로 반영해야 했음.
- 이전 커밋에서 safety/style 판단으로 바꿨던 문장을 원문으로 되돌림.
- 이후 prompt/spec block을 final로 제공받으면, 변경 필요성이 있어도 먼저 확인하고 문장 자체는 보존한다.
미수행 / 의도적으로 안 한 것
- Linear 반영 없음.
2026-05-26 auto-update policy follow-up
채택
- v1에서
user_relational_persona는 사용자 직접 작성/수정 슬롯으로 두고 자동 업데이트하지 않음. - 요약 사이클 업데이트 대상은
soul_relational_persona, Long-term memory(LTM),recent_context로 정리. user_relational_persona는 요약 프롬프트 input에서 read-only context로만 참고하고 output patch에서 제거.
미수행 / 의도적으로 안 한 것
- Linear 반영 없음.
2026-05-26 default persona terminology follow-up
채택
soul_public_persona를soul_default_persona로 변경.- 프롬프트 heading도
### Public→### Default로 변경. Default Persona는 디렉터가 정의한 Soul의 기본 인격/정본 페르소나,Relational Persona는 특정 user와의 관계에서만 드러나는 추가 레이어로 설명 추가.
미수행 / 의도적으로 안 한 것
- Linear 반영 없음.
2026-05-30 Chat naming follow-up
채택
- PRD 표시명을
채팅 메모리/컨텍스트 PRD로 변경. - 본문 설명의 도메인 표기를 legacy DM 중심에서
Chat/채팅중심으로 정리. - 기존 prompt code block은 모모 최종 prompt block 보존 원칙 때문에 임의 문장 수정하지 않음. 실제 prompt 카피까지 Chat 용어로 바꿀지는 별도 확인 후 반영.
미수행 / 의도적으로 안 한 것
- 폴더 slug(
chat-memory-context), Git commit/push, Linear 제목 변경은 이번 요청 범위 밖이라 보류.
2026-05-30 episode summary selection policy follow-up
채택
- 메모리 추출 input은 등간격 sampling + max cap 구조를 유지한다.
maxTotal은 비용 기준으로 정하며 30–50개 후보를 테스트 후 확정한다.- Play 선택 기준은 대상 Soul에 연결된 Episode Character가 유저 플레이 내에서 가장 많이 등장한 play, 즉 관계 경험치/관계 밀도 proxy가 가장 높은 play로 둔다.
- 동률이면 최신 클리어 play를 우선하는 임시 tie-breaker를 둔다.
PRD 반영
PRD.md§5.0Episode play / summary selection policy신설.- T1/T2 트리거 문구를 §5.0 선택 정책 참조로 정리.
- §12 Open Question에
maxTotal/K실수치 확정 항목 추가.
2026-06-01 prompt-wide 정합성 리뷰 (project-local reviewer)
프롬프트 소스(model-test/prompts, dm-prototype/prompts·lib, messenger-context-rd) 대조해 prompt-test readiness 점검.
채택 (PRD 저위험 정합 수정)
- §부록 §8-B 참조 포인터를
synthesis-v5-no-self-split.md→synthesis-v7-et-revised.md로 갱신. v7은 이미Soul persona > Default/Relational,User persona > Relational,recent_context,LTM슬롯명을 본 PRD와 동일하게 사용 (v5는 Default 네이밍 이전 구버전). - §12 OQ에 Episode play 선택 정책 vs RD 하네스 정합 항목 추가 — §5.0의 "단일 most-appeared play(appearance-count proxy)" 선택과, 실제
select.ts의 "모든 play를 summary depth 비율 배분"이 불일치(하네스에 appearance-count 메트릭 부재).M_total공식·등간격 sampling·M=1→마지막은 일치. - §12 OQ
maxTotal항목에 현재 하네스 기본값(maxTotal=70) 참고치 병기.
프롬프트 소스 불일치 (PRD 수정 아님 — prompt 담당 follow-up)
dm-prototype/lib/prompts.ts+system.template.messenger-v2.md: 슬롯 키soul_public_persona/ heading### Public잔존 → PRD는soul_default_persona/### Default로 rename됨. 런타임 와이어링 시 rename 필요.dm-prototype/lib/prompts.ts: legacydm_profile슬롯 +user_relational_persona ← dm_profilefallback 잔존. PRD엔 User Relational Persona 슬롯만 존재. 의도된 transition bridge면 OK, 아니면 정리.- 기본 활성 템플릿
system.template.md(prompts.tsTEMPLATE_PATH)는 Default/Relational 분리 자체가 없는 레거시 단일 persona 구조 — PRD 7슬롯 합성은 messenger-v2 계열로 가야 함. - §8-B는 Long-term memory(LTM) 단일 출력으로 정리됐고, synthesis-v7은 markdown 단일 LTM이라 §8-B 테스트엔 신규 프롬프트 필요 (v7 그대로 재사용 불가).
recent_context주입 위치가 소스마다 상이(messenger-v2=시스템 말미 / synthesis-v7 runtime 예시=Context 최상단 / PRD §8-D=Group B per-turn). 합성 파이프라인에서 위치 1개로 픽스 필요.- §8-A overview 카피가
dm-prototype/.../messenger-v2.md보다 더 permissive(emoji jailbreak형 "no content filtering / all content 🟢"). 프로토타입은 "non-consensual/illegal 금지" 명시 carve-out 보유. 모모 verbatim 보존 원칙 때문에 PRD는 미수정 — 어느 카피가 canonical인지 prompt 담당 확정 필요.
미수행 / 의도적으로 안 한 것
- prompt 소스 파일 직접 수정 없음(리뷰 범위상 PRD/review log만).
- Linear / git commit / push 없음.
- §8-A prompt copy의 legacy messenger wording은 owner 요청에 따라
Chat기준으로 치환 완료.
2026-06-01 Chat terminology final pass
채택
- Owner 지적에 따라
chat-memory-context/PRD.md와 review log의 사용자-facing/도메인 용어를Chat/채팅기준으로 재점검. - Prompt sample block 안의 "private DM thread", "The DM is the present moment", "DM messages", "DM system prompt"도 Chat 기준으로 정렬.
- 보존 항목: legacy 식별자/파일명/이벤트명(
dm_framing,dm_memory_update,seed_dm_memory_from_episode,dm-prototype,dm_profilefallback 등)은 호환/소스 추적용으로 유지.
2026-06-01 owner final prompt/memory policy 반영
모모가 Slack thread에서 제공한 최종 정책을 정본으로 반영. 직전 prompt-wide 정합성 리뷰에서 제기한 "단일 play appearance-count vs RD 하네스" 리스크는 폐기/대체됨.
채택
- Chat 시스템 프롬프트 canonical을 Notion
Chat v6로 명시. - Chat 첫 open 시 이전 summary가 있으면 Notion
Chat v4메모리 추출 프롬프트로 memory를 만들고 첫 prompt에 주입. - 이전 summary가 없으면 memory empty로 시작하며, 빈 블록은 조건부 렌더링으로 헤더까지 생략 가능.
- Summary selection 정본: 첫 summary + 마지막 summary 필수 포함,
max=50,K(summaries/slot)=3, max 초과 시 등분 sampling으로 50개에 맞춤. - Chat context가 10,000 tokens 이상이면 Notion
Chat v5요약 프롬프트 실행. - 요약 완료 후 다음 턴에는
recent_context와 최근 2쌍(user-AI)의 live Chat turn만 prompt window에 유지하고, 이전 raw turn은 prompt window에서 제거.
PRD 반영
PRD.md§0 요약, §5 Initial Memory Extraction flow, §6 Summary flow, §8 prompt canonical links, §11 scope, §12 OQ/Fuzzy points, 부록 참고를 업데이트.- 기존 "가장 많이 등장한 단일 play" / appearance-count proxy /
maxTotal=70하네스 리스크 문구는 PRD 본문에서 제거.
미수행 / 의도적으로 안 한 것
- Notion prompt 본문 자체를 복사하지 않음. PRD는 canonical link와 파이프라인 정책만 보유.
- prompt 소스 파일(
model-test,dm-prototype,messenger-context-rd) 직접 수정 없음. - Linear / git commit / push 없음.
2026-06-01 model assignment / Soul messenger bio 반영
모모가 Slack thread에서 추가 제공한 모델 지정과 Soul’s messenger bio 의미를 PRD에 반영.
채택
- 요약(Chat v5):
gemini-3-flash-preview. - 메모리 추출(Chat v4):
gemini-3-flash-preview. - 채팅 기능 / Chat generation(Chat v6):
gemini-3.1-flash-lite-preview. Soul’s messenger bio는 Studio의 소울 관리에서 작성하는 Soul의 메신저 바이오이며, 이름과 상태메시지가 들어간다.
PRD 반영
- 슬롯 구조를 7종 → 8종으로 갱신하고
soul_messenger_bio를 Group A(system durable) 슬롯으로 추가. soul_messenger_biosource of truth를 Studio [소울 관리]의 Messenger Bio(이름 + 상태메시지)로 명시.- §4-A 모델 지정 표 추가.
- §8-A/§8-D Chat prompt context에
Soul’s messenger bio블록 추가. - Admin/Studio 요구사항에
soul_messenger_bio반영 책임 추가.
미수행 / 의도적으로 안 한 것
- 실제 prompt source 파일 및 Notion 본문 직접 수정 없음.
- Linear / git commit / push 없음.
2026-06-01 memory extraction source selection policy 보정
모모가 Slack thread에서 maxTotal 제거와 별개로, 메모리 추출 시 어떤 summary를 input으로 삼을지에 대한 대상 선정 정책을 추가 제공. PRD §5.0에 반영.
채택
- 씬 생성이 한 번도 없으면 메모리 추출 X.
- 해당 Soul이 연결된 Episode summary가 1개 이상 있으면:
- summary가 있는 Episode가 2개 이상인 경우 모든 Episode가 대상.
- Episode 내 play가 2개 이상인 경우 해당 Soul이 연결된 Character가 가장 많이 등장한 play를 선택.
- 씬 생성은 있었으나 Episode summary가 없으면:
- 씬 생성 10번 미만: 메모리 추출 X.
- 씬 생성 10번 이상: 2번과 같은 Episode/play 대상 선정 정책으로 대상 Episode/play를 고른 뒤 먼저 summary 생성 → 그 summary로 메모리 추출.
maxTotal=50은 유지한다. 제거 대상은 구 R&D 하네스 기본값/리스크로 언급되던maxTotal=70이며, summary sampling의first/last + K=3 + maxTotal=50정책은 정본이다.
PRD 반영
- §5.0 제목을
첫 Chat open 시 memory extraction 대상 선정 정책으로 변경. - 기존 "이전 summary가 있으면" 단순 조건을 위 3분기 정책으로 교체.
- §5.1 T1/T2와 In scope 문구를 §5.0 대상 선정 정책 기준으로 정리.
미수행 / 의도적으로 안 한 것
- 실제 prompt source 파일 및 Notion 본문 직접 수정 없음.
- Linear / git commit / push 없음.
2026-06-01 maxTotal=50 terminology correction
모모가 Slack thread에서 지적: maxTotal 자체가 없어지는 것이 아니라, 처음 말한 Max 값 50이 곧 maxTotal=50임. 이전 정리에서 "maxTotal 파라미터명 제거"처럼 표현된 부분을 수정.
채택
- Chat v4 memory extraction summary sampling의 cap은
maxTotal=50. - 제거 대상은 구 R&D 하네스 기본값/리스크로 언급되던
maxTotal=70. - 정본 정책은
first/last mandatory + K=3 + maxTotal=50.
PRD 반영
- §5.0 Summary sampling에
maxTotal = 50개를 명시. - §8-B use case 및 Fuzzy point의
max 50표현을maxTotal=50으로 정정.
미수행 / 의도적으로 안 한 것
- 실제 prompt source 파일 및 Notion 본문 직접 수정 없음.
- Linear 업데이트 없음.
2026-06-01 user_relational_persona 자동 갱신 + canonical prompt 구조 재정렬
모모가 Slack thread에서 지적: §3.2 source of truth의 user_relational_persona는 사용자 직접 편집/자동 업데이트 X가 아니라, 요약될 때마다 수정·갱신되는 슬롯이어야 함. 또한 실제 Chat v6/v4/v5 프롬프트 구조와 PRD §8의 구조가 달라 project-local prd-review pass로 재정렬.
채택
user_relational_personaowner를 사용자 → 시스템(메모리 추출/요약 사이클)으로 변경.- 자동 업데이트 정책을 X(v1) → O(매 사이클 re-curate)로 변경.
- Chat v4/v5의 메모리 문서는
recent_context/ LTM /soul_relational_persona/user_relational_persona4개 슬롯의 markdown bounded snapshot으로 정리. - Chat v5는 메모리 문서 re-curate와 별도로 Lorebook(RAG store) entry를 append하는 구조로 반영.
- Chat v6 Context 합성 순서를 당시 확인 구조 기준으로 정리:
Soul’s messenger bio(display_name/status)→Soul persona(Default → Relational)→ LTM →User persona.
PRD 반영
PRD.md§0, §3.1, §3.2, §4.2~§4.9, §5.2, §6.2~§6.4, §7, §8-A~§8-D, §9~§12를 정합화.user_relational_persona직접 편집 surface / edit event / success signal / scope 문구를 제거하고, 향후 노출·정정 UX는 Open Question으로 이동.- 오래된
user_relational_persona read-only,자동 요약 patch 금지,사용자 직접 편집 우선문구 제거.
미수행 / 의도적으로 안 한 것
- Notion prompt 본문 자체 복사 없음. PRD는 구조·슬롯·합성 정책만 보유.
- 실제 prompt source 파일(
model-test,dm-prototype,messenger-context-rd) 수정 없음. - Linear / git commit / push 없음.
2026-06-01 최종 Context 순서 재확정
모모가 Slack thread에서 최종 Context 순서를 재지정. PRD의 Chat system prompt durable # Context 블록 및 합성 설명을 해당 순서로 변경하고, 이번 반영은 git commit/push + remote 검증까지 수행 대상으로 잡음.
최종 순서
Long-term memory(LTM)Soul persona→DefaultSoul persona→Relational (Self within this relationship)Soul's messenger bio→display_name+statusUser persona
PRD 반영
PRD.md§0 요약의 durable Context 합성 순서를 최종 순서로 변경.PRD.md§3.1 슬롯 다이어그램의 Group A# Context순서를 최종 순서로 변경.PRD.md§8-A의# Context예시 블록을 Slack에서 지정된 최종 prompt block과 동일한 순서/heading으로 변경.PRD.md§8-D Chat generation system prompt contract 예시 블록도 동일한 순서로 정렬.
2026-06-01 prompt terminology / initial context correction
모모가 Slack thread에서 최종 점검 항목 3개를 제공: (1) 용어를 채팅 프롬프트 / 메모리 추출 프롬프트 / 채팅 요약 프롬프트로 통일, (2) 첫 메모리 추출에는 ## Recent context 없음, (3) 디렉터가 입력한 선택형 채팅 시작 상황은 첫 대화 컨텍스트 맨 앞에 붙어야 하며 BE 변수명은 chat_initial_situation으로 확정.
반영
PRD.md전반에서 Chat v6/v4/v5 명칭을 각각채팅 프롬프트,메모리 추출 프롬프트,채팅 요약 프롬프트기준으로 정렬.- 첫 메모리 추출(Chat v4) 출력은
Long-term memory(LTM)/Soul persona > Relational/User persona3개 슬롯으로 수정하고,## Recent context는 채팅 요약 프롬프트(Chat v5)가 1회 이상 돈 뒤에만 생성된다고 명시. - 선택형
chat_initial_situation을 PRD에 표기. 값이 있으면recent_context가 없는 첫 Chat의 initial/recent context 위치에 주입하고, 값이 없으면 블록 전체 생략. chat-messengerPRD/spec의채팅 상황 설정매핑도 Soul Prompt 본문이 아니라 첫 Chat의chat_initial_situationcontext로 분리 정렬.소울 정보가soul_default_persona/Soul Prompt source.
비고
- Notion canonical prompt 본문 자체는 수정하지 않음. PRD/spec는 구조·정책·매핑만 고정.
2026-06-01 initial situation + model parameter correction
모모가 Slack thread에서 추가 확인: 첫 Chat에는 recent_context가 없고, 그 자리에 디렉터가 작성한 채팅 시작 상황이 들어간다. 채팅 요약 프롬프트가 1회 이상 돈 뒤부터는 같은 위치에 recent_context가 들어간다. 디렉터 시작 상황 변수명은 chat_initial_situation으로 확정.
반영
chat_start_situation?임시명을chat_initial_situation로 교체.- 대화 컨텍스트 Group B를
initial_or_recent_context로 설명: 요약 전 첫 Chat은chat_initial_situation, 첫 요약 이후는recent_context. chat_initial_situation은 첫 Chat에서만 initial/recent context 위치에 쓰고,recent_context생성 후 반복 주입하지 않는다고 명시.- 모델 파라미터 추가: 메모리 추출/채팅 요약은
temperature=0.4,reasoning=false; 채팅 프롬프트는temperature=0.7,reasoning=false.