원클릭으로
langgraph-memory
LangGraph 中的内存:短期(线程范围)vs 长期(跨线程)内存,使用检查点器和存储
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
LangGraph 中的内存:短期(线程范围)vs 长期(跨线程)内存,使用检查点器和存储
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Mac 系统深度清理和优化工具。使用 Mole (mo 命令) 执行系统清理、磁盘分析、应用卸载、系统优化等任务。 触发场景(当用户提到以下任一内容时使用此 skill): - 清理 Mac、清理磁盘、释放空间、清理缓存、清理系统 - 卸载应用、删除应用、移除应用及其残留 - 磁盘分析、查看磁盘占用、大文件查找、空间分析 - 系统优化、系统维护、刷新系统、重建缓存 - 系统状态、系统监控、CPU/内存/磁盘监控 - 清理 node_modules、清理构建产物、清理项目依赖 - 清理安装包、删除 dmg/pkg 文件 - Mac 清理工具、类似 CleanMyMac 的功能 - "我的 Mac 太慢了"、"磁盘空间不足"、"电脑卡顿" - 即使没有明确说 "Mole",只要涉及上述场景就应使用
快速搭建和配置 pnpm monorepo 项目结构,包含 TypeScript、tsup 构建、私有 npm registry 配置。当用户需要"创建 monorepo"、"初始化 monorepo 项目"、"配置 pnpm workspace"、"设置 monorepo 构建"、"monorepo setup"时使用。特别适合需要统一管理多个包、配置构建工具、处理 TypeScript 路径问题的场景。即使用户只是说"帮我搭建项目结构"或"配置构建",如果涉及多包管理也应该使用此 skill。
智能拆分暂存区的代码变更为多个符合 Conventional Commits 规范的逻辑提交。当用户需要将大量变更按逻辑关系分组提交时使用,比如"拆分这些提交"、"把暂存区的变更分成多个 commit"、"按功能分别提交"、"split commits"等场景。特别适合处理包含多个模块、多种类型文件(配置、代码、测试、文档)的复杂变更集。
OKR 优化与质量评估专家。当用户需要:(1) 评估现有 OKR 的质量,(2) 优化模糊或不可量化的关键结果,(3) 检查 OKR 是否符合核心原则(聚焦、可量化、有挑战),(4) 将任务型 KR 转化为结果型 KR,(5) 提供具体的改进建议时使用。触发词包括"帮我优化 OKR"、"检查这个 OKR"、"这个 KR 写得好吗"、"如何量化这个目标"。
基于 git commits 自动生成 CHANGELOG.md 变更日志。支持语义化版本、分类整理、多格式输出。触发场景包括"生成变更日志"、"更新 CHANGELOG"、"版本记录"。
GitHub PR 代码审查技能。检查代码质量、安全性、性能和最佳实践,生成结构化审查报告。触发场景包括"审查 PR"、"代码检查"、"review pull request"。
| name | langgraph-memory |
| description | LangGraph 中的内存:短期(线程范围)vs 长期(跨线程)内存,使用检查点器和存储 |
| language | js |
LangGraph 为 Agent 提供两种类型的内存:
| 类型 | 范围 | 持久化 | 使用场景 |
|---|---|---|---|
| 短期 | 单个线程 | 通过检查点器 | 对话历史 |
| 长期 | 跨线程 | 通过存储 | 用户偏好、事实 |
import { MemorySaver, StateGraph, StateSchema, ReducedValue, START, END } from "@langchain/langgraph";
import { z } from "zod";
const State = new StateSchema({
messages: new ReducedValue(
z.array(z.string()).default(() => []),
{ reducer: (current, update) => current.concat(update) }
),
});
const respond = async (state: typeof State.State) => {
// 访问对话历史
const history = state.messages;
return { messages: [`I remember ${history.length} messages`] };
};
const checkpointer = new MemorySaver();
const graph = new StateGraph(State)
.addNode("respond", respond)
.addEdge(START, "respond")
.addEdge("respond", END)
.compile({ checkpointer });
// 第一轮
const config = { configurable: { thread_id: "user-1" } };
await graph.invoke({ messages: ["Hello"] }, config);
// 第二轮 - 记住第一轮
await graph.invoke({ messages: ["How are you?"] }, config);
// 响应: "I remember 3 messages" (Hello, 响应, How are you?)
import { InMemoryStore } from "@langchain/langgraph";
// 创建长期内存存储
const store = new InMemoryStore();
// 保存用户偏好(在所有线程中可用)
const userId = "alice";
const namespace = [userId, "preferences"];
await store.put(
namespace,
"language",
{ preference: "short, direct responses" }
);
// 在任何线程中检索
const getUserPrefs = async (state, config) => {
const store = config.store;
const userId = state.userId;
const namespace = [userId, "preferences"];
const prefs = await store.get(namespace, "language");
return { preferences: prefs };
};
// 使用存储编译
const graph = builder.compile({
checkpointer,
store,
});
// 在不同线程中使用
const thread1 = { configurable: { thread_id: "thread-1" } };
const thread2 = { configurable: { thread_id: "thread-2" } };
// 两个线程访问相同的长期内存
await graph.invoke({ userId: "alice" }, thread1); // 获取偏好
await graph.invoke({ userId: "alice" }, thread2); // 相同的偏好
import { InMemoryStore } from "@langchain/langgraph";
const store = new InMemoryStore();
// Put(创建/更新)
await store.put(
["user-123", "facts"],
"location",
{ city: "San Francisco", country: "USA" }
);
// Get
const item = await store.get(["user-123", "facts"], "location");
console.log(item); // { city: 'San Francisco', country: 'USA' }
// 带过滤器搜索
const results = await store.search(
["user-123", "facts"],
{ filter: { country: "USA" } }
);
// Delete
await store.delete(["user-123", "facts"], "location");
import { BaseStore } from "@langchain/langgraph";
const myNode = async (state, config: { store: BaseStore }) => {
const store = config.store;
const namespace = [state.userId, "memories"];
// 检索过去的记忆
const memories = await store.search(namespace, { query: "preferences" });
// 保存新记忆
await store.put(
namespace,
"new_fact",
{ fact: "User likes TypeScript" }
);
return { processed: true };
};
const graph = builder.compile({
checkpointer,
store,
});
const smartNode = async (state, config) => {
const store = config.store;
// 短期:对话上下文
const recentMessages = state.messages.slice(-5); // 最近 5 条消息
// 长期:用户档案
const userId = state.userId;
const profile = await store.get([userId, "profile"], "info");
// 使用两者生成个性化响应
const response = await generateResponse(recentMessages, profile);
return { messages: [response] };
};
const graph = new StateGraph(State)
.addNode("respond", smartNode)
.addEdge(START, "respond")
.addEdge("respond", END)
.compile({ checkpointer, store });
import { PostgresStore } from "@langchain/langgraph-checkpoint-postgres";
// 在生产环境中使用 PostgreSQL
const store = await PostgresStore.fromConnString(
"postgresql://user:pass@localhost/db"
);
const graph = builder.compile({
checkpointer,
store,
});
✅ 使用检查点器进行短期内存 ✅ 使用存储进行长期内存 ✅ 命名空间组织 ✅ 搜索和过滤记忆 ✅ 通过 config 在节点中访问存储 ✅ 选择存储后端
❌ 跨线程共享短期内存 ❌ 修改内存序列化格式 ❌ 存储机制内部
// ❌ 错误 - 没有检查点器,没有内存
const graph = builder.compile(); // 消息丢失!
// ✅ 正确
const checkpointer = new MemorySaver();
const graph = builder.compile({ checkpointer });
// ❌ 错误 - 试图在没有存储的情况下共享数据
// 仅靠检查点器无法访问来自其他线程的数据!
// ✅ 正确 - 使用存储
const store = new InMemoryStore();
const graph = builder.compile({ checkpointer, store });
// ❌ 错误 - 存储不可用
const myNode = async (state) => {
store.put(...); // ReferenceError!
};
// ✅ 正确 - 通过 config 访问
const myNode = async (state, config) => {
const store = config.store;
await store.put(...);
};
// ❌ 错误 - 重启时数据丢失
const store = new InMemoryStore(); // 仅内存!
// ✅ 正确 - 使用持久化后端
import { PostgresStore } from "@langchain/langgraph-checkpoint-postgres";
const store = await PostgresStore.fromConnString("postgresql://...");
// ❌ 错误
const item = store.get(namespace, key);
console.log(item); // Promise!
// ✅ 正确
const item = await store.get(namespace, key);
console.log(item);