目录
- 为什么你的 AI 总像金鱼?
- 内存、磁盘与宇宙热寂
- 把聊天记录塞进"琥珀"------三种持久化姿势
- 给历史加上"时光机"------版本控制与差分同步
- 彩蛋:用 ASCII 画一张"聊天宇宙"
- 尾声:让代码替你记得
1. 为什么你的 AI 总像金鱼?
传说金鱼的记忆只有七秒,而没做持久化的 AI 只有七纳秒。
当你刷新页面,浏览器里的 let chat = []
瞬间归零。
就像《寻梦环游记》里被忘记的灵魂,AI 的"思想"也随之消散。
2. 内存、磁盘与宇宙热寂
存储介质 | 速度 | 持久性 | 比喻 |
---|---|---|---|
CPU 寄存器 | 光速 | 断电即无 | 初恋的微信消息,没截图 |
RAM | 高铁 | 关机就没 | 宿醉后的朋友圈,醒来秒删 |
SSD | 绿皮火车 | 十年不腐 | 刻在硬盘里的《还珠格格》 |
纸质日记 | 蜗牛 | 可能发霉 | 外婆的抽屉,有樟脑丸味 |
目标:把 RAM 里的聊天记录,搬到 SSD 的"琥珀"里,
让它在宇宙热寂后仍能告诉外星人:
"地球人曾用 AI 问'如何做番茄炒蛋'。"
3. 把聊天记录塞进"琥珀"------三种持久化姿势
3.1 浏览器本地存储:localStorage("抽屉里的日记本")
js
// 保存
function saveChat(history) {
localStorage.setItem('chatHistory', JSON.stringify(history));
}
// 读取
function loadChat() {
const raw = localStorage.getItem('chatHistory');
return raw ? JSON.parse(raw) : [];
}
// 清空(慎用,堪比格式化 C 盘)
function nukeChat() {
localStorage.removeItem('chatHistory');
}
缺点:5MB 容量,且只能存字符串。
就像把《红楼梦》抄在厕纸上,字大行稀。
3.2 IndexedDB("地下仓库")
js
// 用 Dexie 库,省得和原生 API 打架
import Dexie from 'dexie';
const db = new Dexie('ChatDB');
db.version(1).stores({ history: '++id, timestamp, role, content' });
async function saveMessage(msg) {
await db.history.add({ ...msg, timestamp: Date.now() });
}
async function getAllMessages() {
return await db.history.orderBy('timestamp').toArray();
}
优点:容量≈用户磁盘 6%,支持二进制。
缺点:API 像《克苏鲁的呼唤》,看一眼掉理智值。
3.3 远程同步:GitHub Gist 版"云漂流瓶"
js
// 把历史压缩成 gist,全球可读
async function backupToGist(history) {
const token = prompt('GitHub Token(放心,不会上传给 NSA)');
const body = {
description: 'AI 聊天记录:' + new Date().toLocaleString(),
public: false,
files: { 'chat.json': { content: JSON.stringify(history, null, 2) } }
};
const res = await fetch('https://api.github.com/gists', {
method: 'POST',
headers: { Authorization: `token ${token}` },
body: JSON.stringify(body)
});
return res.json();
}
优点:异地容灾,还能给后人考古。
缺点:GitHub 被封时,你只能对着 404 页面背诵聊天记录。
4. 给历史加上"时光机"------版本控制与差分同步
4.1 差分压缩("只记你变了什么")
js
// 用 Myers 差分算法,把新版 vs 旧版变成操作序列
import { diff } from 'fast-diff';
function compressHistory(oldArr, newArr) {
const oldStr = oldArr.map(m => m.content).join('\n');
const newStr = newArr.map(m => m.content).join('\n');
return diff(oldStr, newStr); // 返回 [0, '保留'], [-1, '删除'], [1, '新增']
}
效果:把 1MB 的聊天记录压成 20KB,
像把《三体》缩写成"不要回答"。
4.2 时间旅行(撤销/重做)
js
class TimeMachine {
constructor() {
this.stack = [[]]; // 初始空历史
this.ptr = 0;
}
commit(history) {
this.stack = this.stack.slice(0, this.ptr + 1);
this.stack.push(JSON.parse(JSON.stringify(history)));
this.ptr++;
}
undo() {
if (this.ptr > 0) this.ptr--;
return this.stack[this.ptr];
}
redo() {
if (this.ptr < this.stack.length - 1) this.ptr++;
return this.stack[this.ptr];
}
}
用户体验:Ctrl+Z 不再只是"撤销输入",
而是"撤销整个对话"------
妈妈再也不用担心我手滑把"我爱你"发成"我矮你"。
5. 彩蛋:用 ASCII 画一张"聊天宇宙"
text
┌──────────────┐
│ Browser RAM │
└────┬─────────┘
│ save()
↓
┌──────────────┴──────────────┐
│ localStorage │
│ ["你好", "我是AI", ...] │
└──────────────┬──────────────┘
│ sync()
↓
┌──────────────┴──────────────┐
│ IndexedDB │
│ id: 42, role: "user" │
└──────────────┬──────────────┘
│ backup()
↓
┌─────┴─────┐
│ GitHub │
│ Gist │
└───────────┘
每个箭头都是一次"记忆的星际穿越"。
6. 尾声:让代码替你记得
"我们写代码,不是为了控制机器,
而是为了在硅片上留下人类的回声。"
把聊天记录持久化,不只是技术需求,
更是数字时代的"立碑"行为:
当服务器关机、数据中心沉没、
最后一台浏览器卸载,
那些 .json
文件仍会在某个硬盘扇区里闪烁,
像远古洞穴的壁画,
告诉未来的 AI:
"嘿,我们曾经这样聊过天。"
附录:一键复制版(把下面塞进你的 app.js
)
js
// 终极懒人包:本地 + 远程双保险
import Dexie from 'dexie';
const db = new Dexie('ChatDB');
db.version(1).stores({ history: '++id, timestamp, role, content' });
export const chat = {
async add(msg) {
await db.history.add({ ...msg, timestamp: Date.now() });
const all = await this.all();
localStorage.setItem('chat', JSON.stringify(all));
},
async all() {
return await db.history.orderBy('timestamp').toArray();
},
async backup(token) {
const data = await this.all();
return await fetch('https://api.github.com/gists', {
method: 'POST',
headers: { Authorization: `token ${token}` },
body: JSON.stringify({
description: 'AI Chat Backup ' + new Date().toISOString(),
public: false,
files: { 'chat.json': { content: JSON.stringify(data, null, 2) } }
})
});
}
};
现在,去和你的 AI 聊天吧------
记忆已上锁,宇宙也偷不走。