如何为 LLM 应用添加持久化内存(无需微调)——实用架构指南
Source: Dev.to
请提供您希望翻译的具体文本内容,我将为您翻译成简体中文并保留原有的格式、Markdown 语法以及技术术语。谢谢!
大多数 LLM 应用在演示中表现完美
You send a prompt.
你发送一个提示。
You get a smart response.
你得到一个智能回复。
Everyone is impressed.
所有人都印象深刻。
Then a user comes back the next day — and the system forgets everything.
然后用户第二天回来——系统却忘记了一切。
That’s not a model problem.
这 不是 模型的问题。
It’s an architecture problem.
而是 架构问题。
In this guide, I’ll walk through how to add persistent memory to an LLM app without fine‑tuning, using a practical, production‑ready approach with:
在本指南中,我将演示如何在不进行微调的情况下为 LLM 应用添加 持久记忆,采用实用的、可投产的方案,包括:
- Node.js
- OpenAI API
- Redis (for structured memory)
Redis(用于结构化记忆) - A vector store for semantic retrieval
用于语义检索的 向量存储
This pattern works whether you’re building a SaaS tool, AI assistant, or domain‑specific LLM app.
无论你是在构建 SaaS 工具、AI 助手,还是特定领域的 LLM 应用,这种模式都适用。
为什么 LLM 默认是无状态的
大型语言模型(LLMs)是 无状态 的。
它们只能了解你在当前提示中发送的内容。请求完成后,除非你将其存储在某处,否则这些上下文就会消失。
我常见的错误
- 在每个提示中塞入完整的聊天记录
- 仅仅依赖 RAG(检索增强生成)
- 假设 embeddings = memory
它们并不是同一件事。持久记忆需要 架构,而不仅仅是提示工程。
什么是“持久内存”
当我们在 LLM 系统中谈到 持久内存 时,通常指:
- 系统能够在 跨会话 中记住过去的交互
- 它能够理解 长期用户目标
- 它可以检索 相关的历史上下文
- 它会 智能地 随时间更新记忆
实现这一点不需要微调。你需要:
- 一个 对话存储(数据库)
- 一个 语义记忆存储(向量 DB)
- 一个 上下文构建器 层
- 一个 结构化身份模型
让我们一步一步构建它。
高层架构
User Request
↓
API Layer (Node.js)
↓
Memory Layer
├── Redis (structured memory)
└── Vector DB (semantic retrieval)
↓
Context Builder
↓
LLM (OpenAI API)
↓
Response
↓
Memory Update
关键要点
- 👉 内存是 外部 于 LLM。
- 👉 LLM 成为 推理引擎,而不是存储引擎。
Source: …
第一步 — 存储结构化内存(Redis)
我们将使用 Redis 来存储长期的结构化用户状态。
安装依赖
npm install openai redis uuid
基本 Redis 设置(memory.js)
// memory.js
import { createClient } from "redis";
const redis = createClient({
url: process.env.REDIS_URL
});
await redis.connect();
export async function getUserMemory(userId) {
const data = await redis.get(`user:${userId}:memory`);
return data ? JSON.parse(data) : {};
}
export async function updateUserMemory(userId, memory) {
await redis.set(`user:${userId}:memory`, JSON.stringify(memory));
}
示例结构化内存对象
{
"goals": ["launch AI SaaS"],
"preferences": ["technical explanations"],
"pastMistakes": ["over‑engineered MVP"],
"summary": "User building an LLM‑based SaaS product."
}
这种方法轻量且快速。
Step 2 — 添加语义记忆(向量存储)
结构化记忆还不够;我们还需要 语义检索 来处理以下内容:
- 先前的对话
- 重要的决策
- 长期笔记
你可以使用 Pinecone、Weaviate、Supabase 或任何向量数据库。下面是使用 OpenAI 嵌入的简化示例。
嵌入助手
import OpenAI from "openai";
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
export async function embedText(text) {
const response = await openai.embeddings.create({
model: "text-embedding-3-small",
input: text
});
return response.data[0].embedding;
}
使用元数据存储嵌入
{
"userId": "123",
"type": "conversation",
"content": "User decided to pivot to B2B SaaS."
}
稍后,在构建提示时检索前 k 个相似记忆。
注意: 许多 LLM 应用会混淆 RAG 与记忆。
- RAG 检索 文档。
- 记忆 检索 用户演变。
第3步 — 构建上下文汇总器
当用户发送请求时:
- 从 Redis 加载 结构化记忆。
- 从向量数据库检索 相关语义记忆。
- 将所有内容与当前消息合并。
- 构建干净的系统提示。
提示构建器示例
function buildPrompt(userMemory, semanticMemories, userInput) {
return `
You are a domain‑specific AI assistant.
User Profile:
${JSON.stringify(userMemory, null, 2)}
Relevant Past Context:
${semanticMemories.join("\n")}
Current Question:
${userInput}
Provide a consistent and context‑aware response.
`;
}
调用 LLM
const systemPrompt = buildPrompt(userMemory, semanticMemories, userInput);
const completion = await openai.chat.completions.create({
model: "gpt-4o-mini",
messages: [{ role: "system", content: systemPrompt }]
});
现在 LLM 具备了连续性。
第4步 — 智能更新记忆
生成响应后,更新记忆。
重要规则: 不要存储所有内容。 对有意义的更改进行摘要。
简单更新助手
function updateMemoryFromConversation(memory, userInput, response) {
if (userInput.toLowerCase().includes("pivot")) {
memory.summary = "User pivoted business direction.";
}
// Add more heuristics as needed
return memory;
}
持久化更新后的记忆
const updatedMemory = updateMemoryFromConversation(
userMemory,
userInput,
completion.choices[0].message.content
);
await updateUserMemory(userId, updatedMemory);
记忆应当演进,而不是仅仅累积噪声。
实际系统中会出现的问题
1. 记忆漂移
旧的目标会一直保留。用户方向改变了,但系统没有适应。
解决方案:
- 对较旧的条目使用 time‑weight 或衰减因子。
- 定期修剪或汇总过时的数据。
2. 无界增长
存储每一次交互很快就会变得昂贵。
解决方案:
- 只保留 most recent N 条目或 top‑k 最相关的嵌入。
- 将长对话汇总为简明的要点。
3. 上下文格式不一致
如果提示变得凌乱,LLM 的输出会下降。
解决方案:
- 使用 template engine(例如 Mustache、Handlebars)来强制统一结构。
- 在发送到 API 之前验证组装好的提示。
4. 延迟开销
从 Redis + 向量数据库获取数据会增加显著的延迟。
解决方案:
- 将最常访问的语义向量缓存到内存中。
- 并行化 Redis 与向量数据库的调用。
TL;DR
- 存储结构化状态(Redis)。
- 存储语义片段(向量 DB)。
- 从两个来源以及新的用户消息中组装干净的提示。
- 调用 LLM(OpenAI)。
- 智能地汇总并更新记忆。
使用此架构,您的 LLM 应用能够获得真正的持久记忆 而无需对模型进行微调。祝开发愉快!
# Memory
1. 定期总结
(此要点未提供额外内容。)
2. Context Overload
检索到的上下文过多会增加 token 成本并降低准确性。
解决方案:
- 限制语义检索
- 使用摘要层
3. 身份崩溃
如果系统提示经常更改,回复会变得不一致。
解决方案:
- 保持稳定的身份系统提示
- 将记忆视为增强,而非替代
为什么你不需要微调
- 微调成本高且缺乏灵活性。
- 对于大多数 LLM 应用,结构化记忆 + 检索已经足够。
- 你并没有改变模型的智能,只是提升了其连续性。
- 这属于 架构层 —— 而不是模型层。
最终思考
大多数开发者尝试通过以下方式解决 LLM 记忆问题:
- 更大的提示
- 更好的提示工程
- 更多的嵌入
但持久化 AI 系统是通过 架构 而非技巧构建的。
如果你的 AI 应用在演示中表现聪明,却在生产环境中不可靠,请先问自己:
记忆位于何处?
不在 LLM 内部,而是在外部。
征求讨论
如果你为你的 LLM 应用构建了持久化记忆系统,我很想听听:
- 你使用了什么技术栈?
- 你遇到记忆漂移问题吗?
- 你是如何处理上下文扩展的?
让我们一起讨论!