惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

W
WeLiveSecurity
The Last Watchdog
The Last Watchdog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
G
Google Developers Blog
博客园 - 叶小钗
雷峰网
雷峰网
人人都是产品经理
人人都是产品经理
博客园_首页
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 三生石上(FineUI控件)
Help Net Security
Help Net Security
Cloudbric
Cloudbric
AI
AI
N
News | PayPal Newsroom
博客园 - 聂微东
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 【当耐特】
Forbes - Security
Forbes - Security
美团技术团队
Stack Overflow Blog
Stack Overflow Blog
SecWiki News
SecWiki News
H
Heimdal Security Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
MyScale Blog
MyScale Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
P
Proofpoint News Feed
S
Security @ Cisco Blogs
Google DeepMind News
Google DeepMind News
V
V2EX
大猫的无限游戏
大猫的无限游戏
阮一峰的网络日志
阮一峰的网络日志
S
Security Affairs
L
LangChain Blog
The Hacker News
The Hacker News
F
Full Disclosure
aimingoo的专栏
aimingoo的专栏
Hacker News - Newest:
Hacker News - Newest: "LLM"
腾讯CDC
Webroot Blog
Webroot Blog
A
About on SuperTechFans
H
Hacker News: Front Page
Cyberwarzone
Cyberwarzone
WordPress大学
WordPress大学
L
LINUX DO - 热门话题
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Attack and Defense Labs
Attack and Defense Labs
M
MIT News - Artificial intelligence

博客园 - Zhentiw

[GenAI] Migration Plan: Flat API → Layered Architecture [Skill] Frontend Design Skill Claude Code Hooks: Complete Guide [GenAI] Pre-retieval overview [GenAI] About Indexing [GenAI] Indexing overview [Vibe Coding] 降低大模型幻觉 - 重试机制 [Vibe coding] 降低大模型幻觉 - JSON 安全输出提示词 [Node.js] WebSocket基础知识 [LangGraph] 应用结构 [LangGrpah] Unit testing [LangGraph] Functional API [LangGraph] 中断注意事项 [LangGraph] 中断相关细节 [LangGrpah] 静态断点 [LangGrpah] 非阻塞式中断 [LangGraph] 阻塞式中断 [LangGraph] 语义搜索 [LangGraph] 长期记忆 [LangGraph] 管理短期记忆 [LangGraph] 自定义checkpointer [LangGraph] 时间旅行 [LangGraph] checkpoint常用API [LangGraph] 元数据标记 [LangGraph] 流 [Vitest] mockClear, mockReset, mockRestore [LangGraph] 将子图添加为节点
[LangGraph] 短期记忆
Zhentiw · 2026-03-08 · via 博客园 - Zhentiw

这节课我们来介绍一下记忆。在 langgraph 中,记忆分为两种:

  • 短期记忆:Short-term Memory
  • 长期记忆:Long-term Memory

基本概念

所谓短期记忆,指的就是在某一个 thread 内持续演化的 State。只要 State 在同一个 thread_id 下被反复传入和更新,agent 就具备了多轮对话的能力。

举个例子,假设我们在 StateGraph 里定义了一个 State

type State = {
  messages: Message[];
  topic?: string;
  plan?: string;
}

State 里装的内容,本身就是短期记忆。多轮对话能成立,靠的是这三件事一起配合:

  1. State 会在同一个 thread_id 下持续存在
  2. 每一轮执行,都会把上一次的 State 传进来
  3. 新节点在旧 State 的基础上继续改

例如:

// 第 1 轮
State.messages = ["你好"]

// 第 2 轮
State.messages = ["你好", "你是谁"]

// 第 3 轮
State.messages = ["你好", "你是谁", "我们刚刚聊了什么"]

另外,这里一定要注意,短期记忆是和 thread 绑定的,也就是说:

  • thread_id = A 有一份独立的 State
  • thread_id = B 是另一份完全不同的 State

只要 thread 不同:短期记忆就不共享。这也是为什么官网说它是 short-term,因为它的生命周期是:

从 thread 开始 → 到 thread 结束

而不是:

  • 跨会话
  • 跨线程
  • 跨用户

快速上手

下面我们通过一个快速上手示例来验证:

  • 不同用户 → 不同 thread
  • 切换用户 → 短期记忆立即切换
  • 不使用 Store(长期记忆)
  • 只使用 State + MemorySaver

用户设计

用户名 密码 thread_id
aaa 111 thread-aaa
bbb 222 thread-bbb

每个用户固定使用一个 thread_id

import "dotenv/config";
import { ChatOpenAI } from "@langchain/openai";
import {
  MemorySaver,
  StateGraph,
  START,
  END,
  MessagesZodMeta,
} from "@langchain/langgraph";
import { z } from "zod/v4";
import readline from "readline-sync";
import { HumanMessage, BaseMessage } from "@langchain/core/messages";
import { registry } from "@langchain/langgraph/zod";

// 用户系统
const users = {
  aaa: { password: "111", thread_id: "thread-aaa" },
  bbb: { password: "222", thread_id: "thread-bbb" },
};

const Schema = z.object({
  messages: z.array(z.custom<BaseMessage>()).register(registry, {
    ...MessagesZodMeta,
    default: () => [],
  }),
});

type TState = z.infer<typeof Schema>;

const model = new ChatOpenAI({
  model: "gpt-4o",
  temperature: 0.5,
});

// 聊天的节点
async function chatNode(state: TState): Promise<Partial<TState>> {
  const res = await model.invoke(state.messages);

  return {
    messages: [res],
  };
}

const checkpointer = new MemorySaver();

// 图
const graph = new StateGraph(Schema)
  .addNode("chatNode", chatNode)
  .addEdge(START, "chatNode")
  .addEdge("chatNode", END)
  .compile({ checkpointer });

async function main() {
  while (true) {
    console.log("\n--- 登录 ---");
    const username = readline.question("请输入用户名:");
    const password = readline.question("请输入密码:", {
      hideEchoBack: true,
    });

    const user = users[username];

    if (!user || user.password !== password) {
      console.log("登录失败☹️");
      continue;
    }

    // 登录成功
    console.log(`✅ 登录成功,当前用户:${username}`);
    console.log("输入 /switch 可切换用户\n");

    const config = {
      configurable: {
        thread_id: user.thread_id, // 这个非常重要,这个保证了不同的用户拥有不同的state
      },
    };

    // 处理用户的对话
    while (true) {
      const input = readline.question(`${username}>`);

      if (input === "/switch") {
        console.log("切换用户中...");
        break;
      }

      // 这里只需要传入当前这一轮的输入消息
      const result = await graph.invoke(
        {
          messages: [new HumanMessage(input)],
        },
        config,
      );

      // 返回的结果就是完整的状态
      const aiMsg = result.messages.at(-1);

      console.log(`AI> ${aiMsg?.content}`);
    }
  }
}
main();


-EOF-