如何为 LLM 应用添加持久化内存(无需微调)——实用架构指南

发布: (2026年2月21日 GMT+8 15:51)
10 分钟阅读
原文: Dev.to

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 系统中谈到 持久内存 时,通常指:

  • 系统能够在 跨会话 中记住过去的交互
  • 它能够理解 长期用户目标
  • 它可以检索 相关的历史上下文
  • 它会 智能地 随时间更新记忆

实现这一点不需要微调。你需要:

  1. 一个 对话存储(数据库)
  2. 一个 语义记忆存储(向量 DB)
  3. 一个 上下文构建器
  4. 一个 结构化身份模型

让我们一步一步构建它。


高层架构

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步 — 构建上下文汇总器

当用户发送请求时:

  1. 从 Redis 加载 结构化记忆
  2. 从向量数据库检索 相关语义记忆
  3. 将所有内容与当前消息合并。
  4. 构建干净的系统提示。

提示构建器示例

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

  1. 存储结构化状态(Redis)。
  2. 存储语义片段(向量 DB)。
  3. 从两个来源以及新的用户消息中组装干净的提示
  4. 调用 LLM(OpenAI)。
  5. 智能地汇总并更新记忆。

使用此架构,您的 LLM 应用能够获得真正的持久记忆 而无需对模型进行微调。祝开发愉快!

# Memory

1. 定期总结

(此要点未提供额外内容。)


2. Context Overload

检索到的上下文过多会增加 token 成本并降低准确性。

解决方案:

  • 限制语义检索
  • 使用摘要层

3. 身份崩溃

如果系统提示经常更改,回复会变得不一致。

解决方案:

  • 保持稳定的身份系统提示
  • 将记忆视为增强,而非替代

为什么你不需要微调

  • 微调成本高且缺乏灵活性。
  • 对于大多数 LLM 应用,结构化记忆 + 检索已经足够。
  • 你并没有改变模型的智能,只是提升了其连续性。
  • 这属于 架构层 —— 而不是模型层。

最终思考

大多数开发者尝试通过以下方式解决 LLM 记忆问题:

  • 更大的提示
  • 更好的提示工程
  • 更多的嵌入

但持久化 AI 系统是通过 架构 而非技巧构建的。

如果你的 AI 应用在演示中表现聪明,却在生产环境中不可靠,请先问自己:

记忆位于何处?
不在 LLM 内部,而是在外部。


征求讨论

如果你为你的 LLM 应用构建了持久化记忆系统,我很想听听:

  • 你使用了什么技术栈?
  • 你遇到记忆漂移问题吗?
  • 你是如何处理上下文扩展的?

让我们一起讨论!

0 浏览
Back to Blog

相关文章

阅读更多 »

Subnetting 详解

什么是 Subnetting?可以把它想象成把一栋大型公寓楼拆分成不同的楼层。每层 subnet 拥有自己的编号主机(hosts),以及建筑……