feat: 完成 M 群組 — 既有作品考據與輕小說章節管線
共用場景資料庫(Scene/ScenePresence/SceneLine/SceneFact/SceneInteraction, 角色中立客觀記錄)與投影(ProjectionService 寫入 EpisodicMemory/ SemanticMemory/PersonalityTraitSnapshot/CharacterRelationshipEventLog, 逐一可追溯到來源場景)完全分層。歸屬信心分數(明示標記決定性、語言指紋 從已歸屬語料統計、場景名冊硬約束、對話輪替)與隔離區/指紋冷啟動(低信心 或樣本不足一律隔離,指紋精煉後可重新嘗試釋放)。多角色投影與修正(改一處 場景資料庫、reprojectScene 同步更新所有受影響角色,使用者互動記憶因為 從不帶 sourceSceneId 而結構性地不受影響,發現得晚的歸屬錯誤額外記一筆 CORRECTION 事件)。作品名冊建置門檻(達標自動建置,門檻檢查排在投影完成 之後才做,避免用到投影前的舊統計)。錨定點知識邊界(雙向:前進載入、 後退遺忘)與矛盾偵測(同優先序來源待人工確認,跨優先序可依小說原文> 官方設定集>動畫改編自動裁決)。插圖索引與衍生服裝目錄/姿勢語彙表。 刻意簡化:章節→場景切分與互動正負權重皆採結構化輸入(不做自動 NLP 場景邊界偵測與情感分析),比照 F-7 MockProvider 的做法——機制先做對, 之後有真實 NLP/LLM 能力再替換輸入來源。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
cd948f0026
commit
c66799ee7c
+245
-8
@@ -24,6 +24,7 @@ enum MemorySource {
|
||||
INTERACTION // 互動
|
||||
OFFLINE_GENERATED // 離線生成
|
||||
SOURCE_EXTRACTION // 原作萃取
|
||||
CORRECTION // M-10 回溯修正:發現記錯了,以「想起來其實不是這樣」的新事件消化,不竄改既有的 INTERACTION 記憶
|
||||
}
|
||||
|
||||
// 情緒標籤類型:對應情緒子系統六種狀態(見 D 群組)
|
||||
@@ -124,15 +125,19 @@ model User {
|
||||
}
|
||||
|
||||
model Work {
|
||||
id String @id @default(cuid())
|
||||
title String
|
||||
volumeProgress String? // 卷數進度
|
||||
worldview String? // 世界觀
|
||||
progressAnchor String? // 作品進度錨定點(M-9/N 群組使用;描述作品實際描寫過的時期)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
id String @id @default(cuid())
|
||||
title String
|
||||
volumeProgress String? // 卷數進度
|
||||
worldview String? // 世界觀
|
||||
progressAnchor String? // 作品進度錨定點(M-9/N 群組使用;描述作品實際描寫過的時期,人類可讀)
|
||||
anchorStoryOrder Int @default(0) // M-9 錨定點的數值刀口:對應 Scene.storyOrder,之前是親身經歷,之後不存在
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
characters Character[]
|
||||
characters Character[]
|
||||
scenes Scene[]
|
||||
illustrations Illustration[]
|
||||
contradictions SceneContradiction[]
|
||||
|
||||
@@map("works")
|
||||
}
|
||||
@@ -174,6 +179,14 @@ model Character {
|
||||
ageEvidence CharacterAgeEvidence[]
|
||||
romanceEventLogs RomanceEventLog[]
|
||||
adultContentAttempts AdultContentAttemptLog[]
|
||||
scenePresences ScenePresence[]
|
||||
spokenLines SceneLine[]
|
||||
costumeCatalogEntries CostumeCatalogEntry[]
|
||||
poseVocabularyEntries PoseVocabularyEntry[]
|
||||
languageCorpusEntries LanguageCorpusEntry[]
|
||||
personalityTraitSnapshots PersonalityTraitSnapshot[]
|
||||
relationshipEventLogsFrom CharacterRelationshipEventLog[] @relation("EventLogFrom")
|
||||
relationshipEventLogsTo CharacterRelationshipEventLog[] @relation("EventLogTo")
|
||||
|
||||
@@map("characters")
|
||||
}
|
||||
@@ -325,6 +338,10 @@ model EpisodicMemory {
|
||||
relatedUserId String? // 這段記憶與哪位使用者相關(E-5 關係加權檢索用)
|
||||
relatedUser User? @relation(fields: [relatedUserId], references: [id], onDelete: SetNull)
|
||||
isPrivate Boolean @default(false) // K-3 隱私邊界:一對一聊過的私密內容,群聊中不主動洩漏(口風不緊原型除外)
|
||||
// M-7/M-10 可追溯性:這筆記憶是否由某個場景投影而來。只有這裡非 null 的記錄會被「重新投影」刪除重建;
|
||||
// 使用者互動記憶(source=INTERACTION)永遠不會設這個欄位,因此重新投影永遠不會動到使用者互動記錄。
|
||||
sourceSceneId String?
|
||||
sourceScene Scene? @relation(fields: [sourceSceneId], references: [id], onDelete: SetNull)
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@map("episodic_memories")
|
||||
@@ -336,6 +353,8 @@ model SemanticMemory {
|
||||
character Character @relation(fields: [characterId], references: [id], onDelete: Cascade)
|
||||
fact String // 去情境化事實
|
||||
about String // 對象(關於誰/什麼)
|
||||
sourceSceneId String? // M-4/M-7 可追溯性:由哪個場景萃取而來(新登場設定)
|
||||
sourceScene Scene? @relation(fields: [sourceSceneId], references: [id], onDelete: SetNull)
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@map("semantic_memories")
|
||||
@@ -457,3 +476,221 @@ model ProactiveCareLog {
|
||||
|
||||
@@map("proactive_care_logs")
|
||||
}
|
||||
|
||||
// M-1 插圖類型:對立繪的用途不同——封面定基礎氣質、彩頁給服裝差分、黑白插圖給表情/姿勢差分。
|
||||
enum IllustrationType {
|
||||
COVER
|
||||
COLOR_PAGE
|
||||
BW_ILLUSTRATION
|
||||
}
|
||||
|
||||
// M-1 插圖索引:不儲存受版權保護的原圖本身,只登錄「畫面描述」供服裝目錄/姿勢語彙/表情差分參考使用。
|
||||
model Illustration {
|
||||
id String @id @default(cuid())
|
||||
workId String
|
||||
work Work @relation(fields: [workId], references: [id], onDelete: Cascade)
|
||||
volume Int
|
||||
page Int?
|
||||
type IllustrationType
|
||||
sceneId String? // 對應場景(插圖與文本的交叉索引)
|
||||
scene Scene? @relation(fields: [sceneId], references: [id], onDelete: SetNull)
|
||||
description String // 畫面描述:表情/姿勢/服裝等文字記錄
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
costumeCatalogEntries CostumeCatalogEntry[]
|
||||
poseVocabularyEntries PoseVocabularyEntry[]
|
||||
|
||||
@@map("illustrations")
|
||||
}
|
||||
|
||||
// M-1 服裝目錄:逐卷登錄角色出現過的服裝,立繪服裝層只能從這個目錄取用,不可自創。
|
||||
model CostumeCatalogEntry {
|
||||
id String @id @default(cuid())
|
||||
characterId String
|
||||
character Character @relation(fields: [characterId], references: [id], onDelete: Cascade)
|
||||
illustrationId String?
|
||||
illustration Illustration? @relation(fields: [illustrationId], references: [id], onDelete: SetNull)
|
||||
label String // 例如「制服」「便服」「禮服」
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@map("costume_catalog_entries")
|
||||
}
|
||||
|
||||
// M-1 姿勢語彙:繪師畫該角色時慣用的身體語言(總是抱著書、習慣性歪頭),納入立繪姿勢差分的官方認證來源。
|
||||
model PoseVocabularyEntry {
|
||||
id String @id @default(cuid())
|
||||
characterId String
|
||||
character Character @relation(fields: [characterId], references: [id], onDelete: Cascade)
|
||||
illustrationId String?
|
||||
illustration Illustration? @relation(fields: [illustrationId], references: [id], onDelete: SetNull)
|
||||
label String // 例如「總是抱著書」「習慣性歪頭」
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@map("pose_vocabulary_entries")
|
||||
}
|
||||
|
||||
// M-4 場景內逐行的類型:對應五類萃取產物裡「事件」以外,需要逐行分類才能各自導向正確目的地的部分。
|
||||
enum SceneLineType {
|
||||
DIALOGUE // 台詞 → 語言風格語料
|
||||
ACTION // 動作描寫 → 事件的一部分
|
||||
MONOLOGUE // 內心獨白/心理描寫 → 性格參數證據
|
||||
NARRATION // 敘述/新登場設定 → 語意記憶
|
||||
}
|
||||
|
||||
enum SceneLineStatus {
|
||||
PENDING // 尚待歸屬判定
|
||||
CONFIRMED // 信心分數達門檻且指紋一致,已寫入場景資料庫
|
||||
QUARANTINED // 低信心或指紋矛盾,隔離、不寫入任何角色
|
||||
}
|
||||
|
||||
// M-3 共用場景資料庫:章節文本以場景為單位切分後的客觀記錄單位,角色中立,不含主觀詮釋。
|
||||
// M-8/M-9 的共用年表以 storyOrder 排序——同作品所有場景共用一條數線,錨定點即在此數線上切一刀。
|
||||
model Scene {
|
||||
id String @id @default(cuid())
|
||||
workId String
|
||||
work Work @relation(fields: [workId], references: [id], onDelete: Cascade)
|
||||
volume Int
|
||||
chapterLabel String
|
||||
storyOrder Int // 全作品共用年表排序鍵
|
||||
sourceType String @default("NOVEL") // M-8 矛盾裁決優先序用:NOVEL/OFFICIAL_SETTEI/ANIME_ADAPTATION
|
||||
summary String // 場景摘要(客觀記錄:在場者、誰說了哪句、誰做了什麼)
|
||||
rawText String // 匯入的原始場景文本(僅供測試/自製文本使用,不得為受版權保護原文)
|
||||
projected Boolean @default(false) // M-9:是否已投影進角色記憶(只有 storyOrder <= 錨定點的場景會被投影)
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
participants ScenePresence[]
|
||||
lines SceneLine[]
|
||||
illustrations Illustration[]
|
||||
facts SceneFact[]
|
||||
episodicMemories EpisodicMemory[]
|
||||
semanticMemories SemanticMemory[]
|
||||
relationshipEventLogs CharacterRelationshipEventLog[]
|
||||
personalityTraitSnapshots PersonalityTraitSnapshot[]
|
||||
interactions SceneInteraction[]
|
||||
|
||||
@@unique([workId, storyOrder])
|
||||
@@map("scenes")
|
||||
}
|
||||
|
||||
// M-3/M-5 場景名冊(硬約束):不在場的角色不可能說話,歸屬候選只限在場者。
|
||||
model ScenePresence {
|
||||
id String @id @default(cuid())
|
||||
sceneId String
|
||||
scene Scene @relation(fields: [sceneId], references: [id], onDelete: Cascade)
|
||||
characterId String
|
||||
character Character @relation(fields: [characterId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([sceneId, characterId])
|
||||
@@map("scene_presences")
|
||||
}
|
||||
|
||||
// M-4/M-5/M-6 場景內逐行記錄:每一行都有獨立的歸屬信心分數與狀態,是隔離區機制運作的最小單位。
|
||||
model SceneLine {
|
||||
id String @id @default(cuid())
|
||||
sceneId String
|
||||
scene Scene @relation(fields: [sceneId], references: [id], onDelete: Cascade)
|
||||
lineIndex Int
|
||||
lineType SceneLineType
|
||||
rawText String
|
||||
hasExplicitMarker Boolean @default(false) // 是否有「○○說道」等明示標記(決定性證據)
|
||||
markerCharacterId String? // 明示標記指向的角色(若有)
|
||||
speakerCharacterId String? // 目前歸屬(可能是明示、也可能是推論後確認的結果)
|
||||
speakerCharacter Character? @relation(fields: [speakerCharacterId], references: [id], onDelete: SetNull)
|
||||
confidence Float @default(0)
|
||||
status SceneLineStatus @default(PENDING)
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@map("scene_lines")
|
||||
}
|
||||
|
||||
// M-8 場景事實:客觀、可檢查的事實標記(例如天氣),跨場景比對同一事件標籤下的事實是否矛盾。
|
||||
model SceneFact {
|
||||
id String @id @default(cuid())
|
||||
sceneId String
|
||||
scene Scene @relation(fields: [sceneId], references: [id], onDelete: Cascade)
|
||||
eventLabel String // 事件標籤:同一事件標籤下的事實理應一致(例如「秋季運動會」)
|
||||
factKey String // 例如「天氣」
|
||||
factValue String // 例如「雨天」
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@map("scene_facts")
|
||||
}
|
||||
|
||||
// M-4 互動的中立記錄:場景資料庫階段只記錄「發生了什麼互動」,尚未套用到任何角色的關係帳本——
|
||||
// 套用(寫入 CharacterRelationshipEventLog)是投影階段的職責,一樣受 M-9 錨定點知識邊界節制。
|
||||
model SceneInteraction {
|
||||
id String @id @default(cuid())
|
||||
sceneId String
|
||||
scene Scene @relation(fields: [sceneId], references: [id], onDelete: Cascade)
|
||||
characterId String
|
||||
otherCharacterId String
|
||||
delta Float
|
||||
description String
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@map("scene_interactions")
|
||||
}
|
||||
|
||||
enum ContradictionStatus {
|
||||
PENDING_HUMAN_REVIEW
|
||||
RESOLVED
|
||||
}
|
||||
|
||||
// M-8 矛盾偵測:不同場景描寫衝突時標記待人工確認;裁決優先序見 ContradictionDetectionService。
|
||||
model SceneContradiction {
|
||||
id String @id @default(cuid())
|
||||
workId String
|
||||
work Work @relation(fields: [workId], references: [id], onDelete: Cascade)
|
||||
eventLabel String
|
||||
factKey String
|
||||
description String
|
||||
status ContradictionStatus @default(PENDING_HUMAN_REVIEW)
|
||||
resolution String?
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@map("scene_contradictions")
|
||||
}
|
||||
|
||||
// M-4/M-6 語言風格語料:已確認歸屬的台詞樣本,供語言指紋統計(人稱/語尾/口癖頻率)使用。
|
||||
model LanguageCorpusEntry {
|
||||
id String @id @default(cuid())
|
||||
characterId String
|
||||
character Character @relation(fields: [characterId], references: [id], onDelete: Cascade)
|
||||
sceneId String?
|
||||
text String
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@map("language_corpus_entries")
|
||||
}
|
||||
|
||||
// M-8 性格演變追蹤:參數不是單一值而是帶時間戳的序列,依錨定點取用當時的性格參數。
|
||||
model PersonalityTraitSnapshot {
|
||||
id String @id @default(cuid())
|
||||
characterId String
|
||||
character Character @relation(fields: [characterId], references: [id], onDelete: Cascade)
|
||||
sourceSceneId String? // M-4/M-7 可追溯性:由哪個場景的獨白/心理描寫萃取而來
|
||||
sourceScene Scene? @relation(fields: [sourceSceneId], references: [id], onDelete: SetNull)
|
||||
atStoryOrder Int // 對應的年表位置
|
||||
note String // 描述性文字:這個時間點角色參數上的變化說明
|
||||
expressivenessOverride Float? // 可選:覆寫 G-1 外顯度參數,模擬成長軌跡
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@map("personality_trait_snapshots")
|
||||
}
|
||||
|
||||
// M-4 互動→關係帳本(角色對角色版):每次原作互動評正負向權重,累積出她對每個角色的信任/親密度,
|
||||
// 可追溯到來源場景;同一事件寫入雙方視角,權重可以不對稱。
|
||||
model CharacterRelationshipEventLog {
|
||||
id String @id @default(cuid())
|
||||
characterId String
|
||||
character Character @relation("EventLogFrom", fields: [characterId], references: [id], onDelete: Cascade)
|
||||
otherCharacterId String
|
||||
otherCharacter Character @relation("EventLogTo", fields: [otherCharacterId], references: [id], onDelete: Cascade)
|
||||
sceneId String?
|
||||
scene Scene? @relation(fields: [sceneId], references: [id], onDelete: SetNull)
|
||||
delta Float
|
||||
description String
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@map("character_relationship_event_logs")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user