共计 2540 个字符,预计需要花费 7 分钟才能阅读完成。
背景痛点
ChatGPT 原生会话存在两个关键限制:

- 对话历史仅保留在当前会话窗口,关闭后无法追溯
- 企业级应用需要审计合规,原始日志缺乏结构化存储
这导致以下典型场景难以实现:
- 客户服务对话的质检复盘
- 跨部门知识共享
- 长期对话的连续性维护
技术选型对比
前端存储方案
- LocalStorage
- 优点:零延迟,无需后端
-
缺点:5MB 容量限制,同源策略约束
-
IndexedDB
- 优点:支持事务操作,存储量更大
- 缺点:复杂查询能力弱
云端数据库
- Firebase Realtime DB
- 适合:快速原型开发
-
注意:无 SQL 查询能力,按连接数计费
-
MongoDB Atlas
- 优势:文档结构灵活,适合对话树存储
- 成本:集群部署需要运维投入
推荐组合 :前端 IndexedDB 做离线缓存 + MongoDB 持久化
核心实现
Express.js 后端基础框架
// server.ts
import express from 'express';
import {ChatGPTPlugin} from './plugin';
const app = express();
app.use(express.json());
const plugin = new ChatGPTPlugin({
openaiKey: process.env.OPENAI_KEY,
mongoURI: 'mongodb+srv://<user>:<pass>@cluster.mongodb.net/chatlogs'
});
app.post('/api/save', plugin.authMiddleware, plugin.saveHandler);
app.get('/api/history', plugin.authMiddleware, plugin.historyHandler);
app.listen(3000, () => {console.log('Plugin running on port 3000');
});
BullMQ 消息队列配置
// queues.ts
import {Queue, Worker} from 'bullmq';
import {saveToMongo} from './db';
const saveQueue = new Queue('chatSave', {
connection: {
host: 'redis',
port: 6379
}
});
new Worker('chatSave', async job => {const { conversationId, messages} = job.data;
await saveToMongo({
_id: conversationId,
chunks: splitMessages(messages) // 分块处理
});
}, {
limiter: {
max: 1000, // 每秒最大任务数
duration: 1000
}
});
JWT 鉴权实现
// auth.ts
import jwt from 'jsonwebtoken';
import {RequestHandler} from 'express';
const JWT_SECRET = process.env.JWT_SECRET || 'plugin_secret';
export const authMiddleware: RequestHandler = (req, res, next) => {
try {const token = req.headers.authorization?.split(' ')[1];
if (!token) throw new Error('Missing token');
const decoded = jwt.verify(token, JWT_SECRET) as {
userId: string;
exp: number;
};
req.userId = decoded.userId;
next();} catch (err) {res.status(401).json({error: 'Invalid token'});
}
};
性能优化策略
分块存储设计
- 按对话轮次切分:每 5 组 Q &A 作为一个 chunk
- 元数据独立索引:
// db/schema.ts interface ConversationChunk { _id: string; // chunkId conversationId: string; sequence: number; tokens: number; createdAt: Date; messages: Array<{ role: 'user' | 'assistant'; content: string; }>; }
增量同步算法
- 客户端携带 lastSyncTimestamp
- 服务端返回比该时间戳新的 chunks
- 使用哈希校验避免重复传输
避坑指南
API 限流处理
- 实现指数退避重试:
async function callOpenAIWithRetry(prompt: string, retries = 3) { try {return await openai.createCompletion(prompt); } catch (err) {if (err.response?.status === 429 && retries > 0) { await new Promise(r => setTimeout(r, 2 ** (4 - retries) * 1000) ); return callOpenAIWithRetry(prompt, retries - 1); } throw err; } }
GDPR 合规要点
- 提供用户数据删除端点
- 对话内容加密存储:
import {encrypt, decrypt} from 'crypto-js'; const SECRET = process.env.ENCRYPTION_KEY; function encryptMessage(content: string) {return encrypt(content, SECRET).toString();}
上下文保持方案
- 每次请求携带最近 3 条对话
- 服务端维护 session 缓存
扩展思考
跨平台同步可考虑:
- 使用 WebSocket 实现实时推送
- 为每个用户设备分配唯一 clientId
- 采用 Operational Transformation 解决冲突
完整项目示例见 GitHub 仓库(虚构地址):
https://github.com/example/chatgpt-history-plugin
正文完
发表至: 未分类
近两天内
