日记
模拟最直观的输出。每个 NPC 每天写一篇。
为什么是日记?
日记是玩家窥探 NPC 内心世界的窗口。它是:
- 📖 玩家阅读的主要内容
- 🪞 表达情感和反思的最自然方式
- 🎭 观察性格和记忆发挥作用的最佳场所
如果日记写得好,模拟就是好的。如果日记写得差,底层再精妙的 AI 也无济于事。
什么时候写?
每个游戏日的 22:00。
此时刚过晚餐,还未入睡。NPC 独自在家,准备休息。这是一个自然的反思时刻。
日记的内容
输入
Prompt 结构
ts
const prompt = `
You are ${npc.name}, a ${npc.age}-year-old ${npc.profession}.
Your personality: ${formatPersonality(npc.personality)}.
Your home: ${npc.home}.
Your family: ${formatFamily(npc.family)}.
Today is Day ${worldTime.day} (${worldTime.season}).
The weather today was: ${todayWeather}.
Your mood today was mostly: ${avgMood}.
Today's events (compressed):
${todayEvents}
Recent memories worth noting:
${recentMemories}
You are writing tonight's diary entry. It should be:
- 2-4 paragraphs
- Written in first person
- In your voice (${npc.styleHints})
- Reflecting on the day honestly
- Mentioning any people you interacted with
- Ending with a brief thought about tomorrow
Important:
- Do NOT invent events that didn't happen.
- Do NOT be overly dramatic. Ordinary days are fine.
- Be true to your personality.
- Keep it under 400 words.
Begin:
`;风格提示
每个 NPC 有自己的风格提示,偏置 LLM 的输出:
| NPC | 风格提示 |
|---|---|
| Margaret | "冷幽默、善于观察、略带忧伤" |
| Tom | "务实、话少、偶尔冷笑话" |
| Eleanor | "温暖、有点八卦、母亲般的" |
| Sam | "豪爽、爱提喝酒的事" |
这些提示来自 NPC 的性格 + 自定义特质。
长度
- 目标: 200-400 字
- 硬上限: 500 字(由 prompt + 后处理强制执行)
- 最低: 100 字(不允许"今天还行。"这种一行了事)
如果 LLM 生成的日记太短或太长,系统会调整 prompt 指令后重试。
基调校准
为了防止"AI 戏剧化"问题(每篇日记都像过山车),我们对基调进行校准:
ts
const toneCalibration = {
baseline: 'ordinary day, modest reflection',
overrides: {
if (avgMood === 'happy' && intensity < 0.6) return 'quietly content';
if (avgMood === 'sad' && intensity < 0.6) return 'slightly subdued';
if (avgMood === 'angry' && intensity < 0.6) return 'mildly irritated';
}
};在 prompt 中这样使用:
"Tone: ${toneCalibration}"
校验
生成后,每篇日记都会被校验:
ts
function validateDiary(entry: string, todayEvents: Event[]): ValidationResult {
// 1. Length check
if (entry.length < 100) return { ok: false, reason: 'too short' };
if (entry.length > 2500) return { ok: false, reason: 'too long' };
// 2. No fabricated events
// (LLM-based check: does the diary mention anyone who wasn't actually present?)
// 3. No clichés
const bannedPhrases = ['and so it was', 'as the sun set', 'another day in paradise'];
for (const phrase of bannedPhrases) {
if (entry.includes(phrase)) return { ok: false, reason: 'cliché' };
}
// 4. Style check
// (LLM-based: does this match the NPC's style hints?)
return { ok: true };
}校验失败的日记会重新生成,最多重试 2 次。
存储
ts
interface DiaryEntry {
id: string;
npcId: string;
worldTime: { day: number, hour: number };
text: string;
mood: Emotion;
promptHash: string; // for reproducibility
generatedAt: ISO8601;
generationCost: number; // LLM tokens used
}存储在 D1 表 npc_diary 中。按 (npcId, day) 索引以便快速检索。
玩家看到什么
- 世界地图上每个 NPC 最新一篇日记。
- 可滚动浏览的历史日记时间线。
- 跨所有 NPC 的日记全文搜索。
日记是 AI World Sim 的内容核心。其他一切都是为生产日记而存在的基础设施。
示例
一篇好日记(Margaret,第 47 天)
"上午下了大半天的雨,正好待在家里看书。我读完了那本勃朗特的小说——下雨天读太伤感了,但就是放不下。下午雨停了,走去市场。Maria 在那,看起来很疲惫。她说最近生意不好。我买了韭葱,聊了聊她儿子,听说在学校表现不错。晚上差点不想去酒馆,但还是去了。Eleanor 在那。我们没聊什么特别的,挺好的。有时候,最好的聊天就是这样。"
一篇差日记(被校验拒绝)
"今天是我人生中最最最最棒的一天!!!一切都很完美,每个人都太好了,我太感恩能活着了!!!"
拒绝原因:
- 感叹号过度使用
- 不符合 Margaret 的性格(内敛)
- 没有提及具体事件
- 违反基调校准