让大模型“记住”你:从技术实现到产品设计

58 阅读3分钟

大模型为何“健忘”?如何为 LLM 添加记忆能力

在前面的文章中我们了解到:大语言模型(LLM)本身是没有记忆的
每一次请求对模型来说都是全新的对话,它无法自动记住你之前说过的内容。

来看一个例子:

import {
    ChatDeepSeek
} from '@langchain/deepseek';
import 'dotenv/config';

const model = new ChatDeepSeek({
    model:'deepseek-chat',
    temperature:0
});
// http api 请求
const res = await model.invoke('我叫张三,喜欢刷抖音');
console.log(res);
console.log("-------------------------------")
const res2 = await model.invoke('我叫什么名字');
console.log(res2);

我们先告诉模型:“我叫张三,喜欢刷抖音。”

image.png

紧接着再问它:“我叫什么名字?”

image.png

然而,大模型的回复却表明——它并没有记住刚才的信息。

这说明:大语言模型本身不具备记忆能力。每一次请求对它来说都是孤立的,除非我们主动将对话历史传递进去,否则它无法“记得”你之前说过什么。

如何解决这个问题呢?

InMemoryChatMessageHistory

消息历史存储 (InMemoryChatMessageHistory)

import {InMemoryChatMessageHistory} from '@langchain/core/chat_history'
const messageHistory = new InMemoryChatMessageHistory();

在内存中维护对话历史,存储用户与助手的消息。

在 Prompt 中注入历史消息 (ChatPromptTemplate)

通过 ChatPromptTemplate 的占位符 {history},我们可以将历史消息动态插入到提示词中:

const prompt = ChatPromptTemplate.fromMessages([
    ['system', "你是一个有记忆的助手"],
    ['placeholder','{history}'],
    ['human',"{input}"]
])

{history} 占位符用于注入历史消息,每次调用都会将历史记录插入到 prompt 中。

使用 RunnableWithMessageHistory 自动管理会话

为了简化流程,LangChain 提供了 RunnableWithMessageHistory 包装器,它能自动处理历史读取、注入和保存:

const chain = new RunnableWithMessageHistory({
    runnable,
    // 维护 
    getMessageHistory: async () => messageHistory,
    inputMessagesKey:'input',
    historyMessagesKey:'history'
});

RunnableWithMessageHistory 的作用:

  • 自动从 getMessageHistory() 获取历史
  • 将历史注入到 prompt 的 {history} 位置
  • 将当前输入放入 {input}
  • 调用完成后,将新的用户消息和助手回复保存到历史

支持多会话:通过 sessionId 区分不同用户或对话

const res1 = await chain.invoke(
    {
        input: '我叫徐行,喜欢刷抖音'
    },
    {
        configurable: {
            sessionId: 'makeFriend'
        }
    }
)

🔑 关键点:只要 sessionId 相同,历史就会被正确关联;不同 sessionId 则互不影响。

产品思维:从用户视角看“记忆”能力

我们打开 豆包(Doubao) ,可以看到一个非常自然的对话界面:

image.png 注意到右侧有一个 “会话历史”面板——这正是产品设计中对“记忆”能力的直观体现。

从用户的角度来看,他们天然期望:

“我刚才告诉过你我的名字,你怎么会不记得?”

但技术上我们知道:大模型本身是无状态的。每一次请求都是独立的。
而像豆包这样的成熟产品,在背后自动维护了对话上下文,将历史消息拼接到每次请求中,从而让用户感觉 AI “真的记住了”。

这背后其实融合了两项关键能力:

  1. 技术实现:通过类似 InMemoryChatMessageHistory + RunnableWithMessageHistory 的机制管理对话状态;
  2. 产品设计:将复杂的技术细节隐藏起来,提供流畅、连贯、符合直觉的交互体验。

好的 AI 产品,不是让模型变聪明,而是让用户感觉不到“它原本很笨”。

因此,在开发自己的 AI 应用时,除了关注模型能力,更要思考:
如何通过产品设计,弥补模型的“先天不足”,创造有记忆、有上下文、有温度的对话体验?