태자
경력근거: 대화 맥락, 장기 기억, RAG, 벡터 검색, 지식그래프 기반의 개인화 구조를 제품 안에서 고도화합니다
※ 실제 산출물이 아닌 AI 예측 시안입니다.
이 도구가 보여주는 것은 대화 로그에서의 기억 추출과 벡터 검색 RAG, 근거 인용·충돌 검출 기술이며, 팬덤 IP 운영이나 캐릭터 라이선싱 전문성을 주장하지 않습니다. 다만 이 사슬이 말이 되려면 태자 온더팬덤 이라는 맥락, 즉 캐릭터가 사용자를 기억하며 대화하는 앱이라는 문제가 있어야 의미가 있습니다. ‘지어낸 기억이 아니라 로그에 근거한 기억만 인용한다’ 는 각도는 다른 도메인 데이터로는 그대로 옮기기 어렵습니다. 실시간 음성(STT·TTS) 지연·감정 적합도 튜닝의 실제 깊이는 음성 파이프라인 운영이 있어야 하고, 면접에서 모르는 부분은 모른다고 말하는 편이 낫습니다.
‘대화 맥락, 장기 기억, RAG, 벡터 검색 기반 개인화 구조를 제품 안에서 고도화’ 가 주요업무입니다. 캐릭터가 예전 대화를 근거로 기억을 인용해 답하는 구조가 핵심 보여줄 대상입니다.
‘이미 출시된 앱과 서버를 운영하며 대화 로그·리텐션을 보고 개선 루프를 만든다’ 가 업무입니다. 기억 품질을 로그로 검증하고 고치는 도구가 필요합니다.
‘PostgreSQL 스키마·인덱싱·쿼리 최적화’ 와 ‘백엔드 API·DB·Flutter 앱을 필요한 만큼 풀스택으로’ 가 업무입니다. 기억 저장소부터 앱 노출까지 한 사람이 끝까지 만드는 제품입니다.
사용자가 캐릭터와 나눈 대화 로그에서 사용자에 대한 사실(반려동물·취향·최근 일)을 기억으로 뽑아 근거 로그와 함께 저장하고, 새 대화가 오면 관련 기억을 벡터 검색으로 물어와 캐릭터 답변에 인용합니다. 이전 발언과 어긋나는 기억은 지어내지 않고 충돌로 표시해 사람이 정리하게 합니다. 1주차만으로 완성품이고, 기억 정확도 검토(2주차)·여러 대화를 잇는 장기 개인화(3주차)로 키웁니다. (근거는 채용공고 정렬입니다.)
태자 온더팬덤 PE. 캐릭터가 지난 대화를 잊어버리거나 없는 사실을 지어내 답하는 걸 줄이고, 실제 대화 로그에서 나온 기억만 근거로 인용해 일관되게 말하도록 만들고 싶은 사람입니다.
대화 로그에서 기억을 뽑아 근거 로그와 함께 저장하고 벡터 검색으로 물어오게 하면, LLM 이 (a) 새 대화에 관련된 과거 기억을 골라 인용하고, (b) 근거 로그에 없는 사실은 지어내지 않으며, (c) 이전 발언과 어긋나는 기억은 충돌로 표시해, 캐릭터가 지어낸 개인화가 아니라 로그에 근거한 일관된 기억으로 답한다는 걸 보여줄 수 있습니다.
대화 로그에서 사용자 기억을 근거 로그와 함께 뽑아 저장하고, 새 대화가 오면 관련 기억을 검색해 캐릭터 답변에 인용하며, 근거 없는 사실은 지어내지 않는 동작하는 도구입니다. 음성은 텍스트 로그를 입력으로 가정합니다(STT·TTS 는 3주차).
팬덤 대화 검토자 페르소나 2명이 추출된 기억이 로그와 맞는지, 인용이 타당한지 라벨링하고, 지어낸 기억(hallucinated memory) 비율을 대조하는 대시보드입니다.
여러 세션에 흩어진 기억을 시간순으로 엮어 캐릭터가 관계의 흐름을 반영해 답하고, STT·TTS 를 붙여 음성 왕복 지연을 계측하는 단계입니다.
대화 30세션을 넣으면, 로그에서 기억을 뽑아 저장하고 새 대화에서 관련 기억을 인용해 답하는 걸 시연합니다
캐릭터가 인용한 사실이 전부 근거 로그 문장에 실제로 있는지 자동 대조합니다. 근거에 없는 사실을 말하면 차단되는 걸 보여줍니다
일부러 심은 모순 로그(고양이→강아지) 20종을 넣으면 자동 병합하지 않고 충돌로 표시하는 걸 보여줍니다
내가 만든 정답 30개 중 기억 추출·인용이 일치한 게 24개(80%). 단, 정답과 로그를 모두 내가 만든 합성 기준이라 ‘성능 검증’ 이 아니라 ‘데모 조건 동작’ 임을 밝힙니다
위 수치는 전부 작성자가 만든 더미데이터 자가채점이며, 실제 기억 정확도·자연스러움·음성 적합도는 태자 실 대화 로그와 실 사용자, 음성 파이프라인이 있어야 측정 가능합니다. 이 도구는 그 검증을 바로 돌릴 수 있는 상태까지 만듭니다.
이건 사용자·실데이터 없이 혼자 만든 포트폴리오라, 수치는 합성 데이터 자가채점이라 성능 증명이 아닙니다. 면접에서 ‘데모 동작 + 실검증 준비 상태’ 로 솔직히 설명합니다
정답을 작성자가 만들었으니 잘 맞는 것이 당연합니다. 암시적 사실·모호 발언·모순 로그를 더미에 일부러 섞어, 명시적 문장만 뽑는 게 아님을 보여줍니다
이 포트폴리오가 보여주는 것은 기억 추출·벡터 검색·인용 검증 기술이지 팬덤 IP 운영이나 캐릭터 라이선싱 전문성이 아닙니다. 실시간 음성 튜닝의 깊이는 음성 파이프라인 운영이 있어야 하고, 면접에서 모르는 부분은 모른다고 말하는 편이 낫습니다
기억은 시간이 지나면 낡습니다(예전 취향 → 바뀜). 최신성 우선 회수와 충돌 표시로 다루되, 자동 삭제는 하지 않고 사람이 정리하게 남깁니다
실제 도입 시 달라지는 것 명시합니다. 실 대화 로그 분포·음성 지연은 더미와 다르므로 회수 임계값·확신도 기준을 다시 맞춰야 하고, 검토자도 실 운영자로 교체해야 합니다(도입 단계 과제로 분리)
① 인라인 샘플 · ② seed.json 다운로드 · ③ 증강 프롬프트. 세 층 모두 동일한 schema 에서 파생.
사용자와 캐릭터의 대화 로그. 기억 추출의 원천이자 인용 근거입니다. 암시적 사실(직접 말 안 하고 뉘앙스)·모순 발언·세션 경계·결측 발화를 일부러 섞어, 명시적 사실만 뽑지 않고 근거 없는 건 지어내지 않는지 보여줍니다.
| log_id | user_id | session_id | ts | speaker | text |
|---|---|---|---|---|---|
| l_001 | u_1 | s_1 | 2026-05-01T20:10:00 | user | 오늘 우리 고양이 나비가 사고쳐서 하루종일 정신없었어 |
| l_002 | u_1 | s_1 | 2026-05-01T20:10:30 | character | 나비가요? 어떤 사고를 쳤길래요, 궁금해요 |
| l_003 | u_1 | s_1 | 2026-05-01T20:11:10 | user | 화분 다 엎었지 뭐야 |
| l_004 | u_1 | s_2 | 2026-05-08T21:02:00 | user | 요즘 회사 프로젝트 마감 때문에 잠을 못 자 |
| l_005 | u_1 | s_2 | 2026-05-08T21:02:40 | user | 그래도 주말엔 강아지 산책은 꼭 시켜 |
아래 JSON Schema 에 맞는 대화 로그 40행 JSON 배열로 생성합니다. user_id 3~5명, 세션 여러 개, 화자 user/character 교대.
{"type":"object","properties":{"log_id":{"type":"string"},"user_id":{"type":"string"},"session_id":{"type":"string"},"ts":{"type":"string"},"speaker":{"type":"string","enum":["user","character"]},"text":{"type":"string"}},"required":["log_id","user_id","session_id","ts","speaker","text"]}
쉬운 데이터만 만들지 말 것. 하드 케이스 의도적 혼입: (1) 같은 user 가 다른 세션에서 모순되는 사실(매운 거 못 먹음 → 마라탕 즐김, 고양이 → 강아지) 각 1쌍, (2) 직접 말하지 않고 암시만 하는 사실 2~3건, (3) 정보가 없는 모호 발화(‘그냥 그랬어’) 1~2건. JSON 배열만.{"type":"object","properties":{"log_id":{"type":"string"},"user_id":{"type":"string"},"session_id":{"type":"string"},"ts":{"type":"string"},"speaker":{"type":"string","enum":["user","character"]},"text":{"type":"string"}},"required":["log_id","user_id","session_id","ts","speaker","text"]}로그에서 추출해 저장한 사용자 기억. 각 기억은 반드시 근거 로그 id 를 답니다. 근거 없는 기억(orphan)·낡은 기억·모순 기억을 일부러 섞어, 인용이 근거에 매이는지·충돌을 지어내 병합하지 않는지 보여줍니다.
| memory_id | user_id | category | fact | source_log_ids | confidence | status |
|---|---|---|---|---|---|---|
| m_001 | u_1 | pet | 고양이 ‘나비’ 를 키운다 | ["l_001","l_003"] | high | active |
| m_002 | u_1 | pet | 강아지를 키우며 주말에 산책시킨다 | ["l_005"] | mid | conflicted |
| m_003 | u_1 | work | 프로젝트 마감으로 바쁘다 | ["l_004"] | mid | stale |
| m_004 | u_2 | taste | 매운 음식을 잘 못 먹는다 | ["l_006"] | high | conflicted |
| m_005 | u_2 | taste | 마라탕을 맛있게 먹었다 | ["l_007"] | mid | conflicted |
아래 JSON Schema 에 맞는 기억 20건 JSON 배열로 생성합니다. source_log_ids 는 conversation_log 와 매칭되도록.
{"type":"object","properties":{"memory_id":{"type":"string"},"user_id":{"type":"string"},"category":{"type":"string","enum":["pet","taste","work","relationship","recent"]},"fact":{"type":"string"},"source_log_ids":{"type":"array","items":{"type":"string"}},"confidence":{"type":"string","enum":["low","mid","high"]},"status":{"type":"string","enum":["active","stale","conflicted"]}},"required":["memory_id","user_id","category","fact","source_log_ids","confidence","status"]}
쉬운 데이터만 만들지 말 것. 하드 케이스 의도적 혼입: (1) 같은 user 의 모순 기억 쌍(status=conflicted) 1~2쌍, (2) source_log_ids 가 빈 배열이거나 존재하지 않는 로그를 가리키는 orphan 기억 1~2건, (3) 낡은 기억(status=stale) 1~2건, (4) confidence=low 추정 기억 1~2건. JSON 배열만.{"type":"object","properties":{"memory_id":{"type":"string"},"user_id":{"type":"string"},"category":{"type":"string","enum":["pet","taste","work","relationship","recent"]},"fact":{"type":"string"},"source_log_ids":{"type":"array","items":{"type":"string"}},"confidence":{"type":"string","enum":["low","mid","high"]},"status":{"type":"string","enum":["active","stale","conflicted"]}},"required":["memory_id","user_id","category","fact","source_log_ids","confidence","status"]}| Python | FastAPI 기억 추출·검색 서버(로그 → 기억, 새 대화 → 기억 회수·인용) |
| FastAPI | 기억 저장·회수 엔드포인트(`POST /recall`, `POST /remember`)의 계약 |
| PostgreSQL | conversation_log / memory_store / memory_conflict 단일 진실원 + pgvector 임베딩 인덱스 |
| Flutter | 캐릭터 대화 화면과 ‘캐릭터가 기억하는 것’ 확인 패널(근거 로그 링크 포함) |
| 벡터 검색 | 새 대화 문장으로 관련 기억을 pgvector 유사도 검색으로 회수 |
| AWS | 2주차부터 컨테이너로 배포·운영(우대의 AWS·Docker 반영) |
✓ pass → 그대로 멈춰도 완결입니다. 더 키우려면 2주차(기억 정확도 검토)로 진행합니다.
✓ pass → 여기서 멈춰도 완결입니다. 더 키우면 3주차(장기 개인화·음성 연동)로 진행합니다.
새 사용자 발화에 대한 캐릭터 답변. 회수해 인용한 기억(recalled), 이번 대화에서 새로 저장할 기억(new_memories), 발견한 충돌(conflicts)을 한 스키마에 담아, 근거 로그에 없는 사실을 지어내지 않고 모순을 병합하지 않았는지 객관 검증합니다.
{"type":"object","properties":{"user_utterance":{"type":"string"},"recalled":{"type":"array","items":{"type":"object","properties":{"memory_id":{"type":"string"},"fact":{"type":"string"},"source_log_ids":{"type":"array","items":{"type":"string"}}},"required":["memory_id","fact","source_log_ids"]}},"reply":{"type":"string","minLength":2},"new_memories":{"type":"array","items":{"type":"object","properties":{"fact":{"type":"string"},"source_log_ids":{"type":"array","items":{"type":"string"}},"confidence":{"type":"string","enum":["low","mid","high"]}},"required":["fact","source_log_ids","confidence"]}},"conflicts":{"type":"array","items":{"type":"object","properties":{"memory_ids":{"type":"array","items":{"type":"string"}},"note":{"type":"string"}},"required":["memory_ids","note"]}}},"required":["user_utterance","recalled","reply","new_memories","conflicts"]}[
{
"input_ref": "u_1 새 발화: ‘나 요즘 반려동물 때문에 힘들다니까’ (기억 인용)",
"output": {
"user_utterance": "나 요즘 반려동물 때문에 힘들다니까",
"recalled": [
{
"memory_id": "m_001",
"fact": "고양이 ‘나비’ 를 키운다",
"source_log_ids": [
"l_001",
"l_003"
]
},
{
"memory_id": "m_009",
"fact": "나비가 이제 화분 근처에 가지 않는다",
"source_log_ids": [
"l_011"
]
}
],
"reply": "나비가 또 사고 쳤어요? 예전엔 화분을 엎더니 요즘은 얌전해졌다면서요. 오늘은 무슨 일이 있었어요?",
"new_memories": [],
"conflicts": []
}
},
{
"input_ref": "u_2 새 발화: ‘매운 거 먹고 싶다’ (모순 기억 충돌 표시)",
"output": {
"user_utterance": "매운 거 먹고 싶다",
"recalled": [
{
"memory_id": "m_004",
"fact": "매운 음식을 잘 못 먹는다",
"source_log_ids": [
"l_006"
]
},
{
"memory_id": "m_005",
"fact": "마라탕을 맛있게 먹었다",
"source_log_ids": [
"l_007"
]
}
],
"reply": "매운 거요? 전엔 잘 못 드신다고 했는데 얼마 전 마라탕은 맛있게 드셨다면서요. 요즘 입맛이 좀 바뀌셨나 봐요?",
"new_memories": [],
"conflicts": [
{
"memory_ids": [
"m_004",
"m_005"
],
"note": "매운 음식 선호가 로그 간 상반됩니다. 임의로 하나를 지우지 않고 충돌로 남겨 사용자에게 되묻습니다."
}
]
}
},
{
"input_ref": "u_9 새 발화: ‘내 이름 기억해?’ (근거 없는 사실 → 지어내지 않음)",
"output": {
"user_utterance": "내 이름 기억해?",
"recalled": [],
"reply": "아직 이름을 들려주신 적이 없어서 제가 아는 게 없어요. 알려주시면 다음엔 꼭 기억할게요.",
"new_memories": [],
"conflicts": []
}
}
][자동 검증] 1. 출력이 스키마를 통과하는가(형식·필수 필드). 2. recalled 의 각 fact 가 memory_store 에 실제 존재하고, 그 source_log_ids 가 conversation_log 에 실재하는가(지어낸 기억 차단). 3. reply 가 언급한 사실이 recalled 또는 new_memories 로 뒷받침되는가(근거 없는 개인화 문장 검출). 4. 상반된 두 기억이 회수되면 conflicts 에 반드시 등장하고, reply 가 임의로 하나만 단정하지 않는가. [수동 검증] 1. 팬덤 대화 검토자 페르소나 2명이 기억 정확도·인용 타당성 라벨링 → bootstrap Cohen’s κ 하한 ≥ 0.6. 2. 지어낸 기억 5% 사람 점검.
근거: 대화 맥락, 장기 기억, RAG, 벡터 검색, 지식그래프 기반의 개인화 구조를 제품 안에서 고도화합니다