Token导航 LogoToken导航TokenDH.com
研究检索只读github未标认证来源可访问许可证需确认审计未展示

langgraph-persistence-%26-memorylanggraph 持久性 %26 内存

Agent Skill

langgraph-persistence-%26-memory 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

17,287

周安装

792

GitHub Stars

7

下载量

9,316
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:langgraph-persistence-%26-memory(langgraph 持久性 %26 内存)
来源仓库:https://github.com/jackjin1997/clawforge
仓库路径:skills/langgraph-persistence-%26-memory
安装命令:
npx skills add https://github.com/jackjin1997/clawforge --skill 'LangGraph Persistence & Memory'
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/jackjin1997/clawforge --skill 'LangGraph Persistence & Memory'

简介

用于查找、检索和筛选相关信息,支持关键词和任务场景快速定位结果。

  • 适合在需要围绕仓库状态、代码变更或协作事项进行整理时使用。
  • 可结合来源仓库和原始 README 核验具体用法。
  • 安装命令:npx skills add https://github.com/jackjin1997/clawforge --skill 'LangGraph Persistence & Memory'。
  • 安装前建议确认权限范围和维护状态,避免触发不必要操作。

SKILL.md

  • Checkpointer: Saves/loads graph state at every super-step
  • Thread ID: Identifies separate checkpoint sequences (conversations)
  • Store: Cross-thread memory for user preferences, facts

Two memory types:

  • Short-term (checkpointer): Thread-scoped conversation history
  • Long-term (store): Cross-thread user preferences, facts
CheckpointerUse CaseProduction Ready
MemorySaverTesting, developmentNo
SqliteSaverLocal developmentPartial
PostgresSaverProductionYes

Checkpointer Setup

class State(TypedDict): messages: Annotated[list, operator.add]

def add_message(state: State) -> dict: return {"messages": ["Bot response"]}

checkpointer = InMemorySaver()

graph = (StateGraph(State).add_node("respond", add_message).add_edge(START, "respond").add_edge("respond", END).compile(checkpointer=checkpointer) # Pass at compile time)

ALWAYS provide thread_id

config = {"configurable": {"thread_id": "conversation-1"}}

result1 = graph.invoke({"messages": ["Hello"]}, config) print(len(result1["messages"])) # 2

result2 = graph.invoke({"messages": ["How are you?"]}, config) print(len(result2["messages"])) # 4 (previous + new)

</python>
<typescript>
Set up a basic graph with in-memory checkpointing and thread-based state persistence.

import { MemorySaver, StateGraph, StateSchema, MessagesValue, START, END } from "@langchain/langgraph"; import { HumanMessage } from "@langchain/core/messages";

const State = new StateSchema({ messages: MessagesValue });

const addMessage = async (state: typeof State.State) => { return { messages: [{ role: "assistant", content: "Bot response" }] }; };

const checkpointer = new MemorySaver();

const graph = new StateGraph(State) .addNode("respond", addMessage) .addEdge(START, "respond") .addEdge("respond", END) .compile({ checkpointer });

// ALWAYS provide thread_id const config = { configurable: { thread_id: "conversation-1" } };

const result1 = await graph.invoke({ messages: [new HumanMessage("Hello")] }, config); console.log(result1.messages.length); // 2

const result2 = await graph.invoke({ messages: [new HumanMessage("How are you?")] }, config); console.log(result2.messages.length); // 4 (previous + new)


# from_conn_string returns a context manager in v3+

with PostgresSaver.from_conn_string("postgresql://user:pass@localhost/db") as checkpointer: checkpointer.setup() # only needed on first use to create tables graph = builder.compile(checkpointer=checkpointer)

</python> <typescript> Configure PostgreSQL-backed checkpointing for production deployments.

import { PostgresSaver } from "@langchain/langgraph-checkpoint-postgres";

const checkpointer = PostgresSaver.fromConnString(
  "postgresql://user:pass@localhost/db"
);
await checkpointer.setup(); // only needed on first use to create tables

const graph = builder.compile({ checkpointer });

Thread Management

graph.invoke({"messages": ["Hi from Alice"]}, alice_config) graph.invoke({"messages": ["Hi from Bob"]}, bob_config)

Alice's state is isolated from Bob's

</python>
<typescript>
Demonstrate isolated state between different thread IDs.

// Different threads maintain separate state const aliceConfig = { configurable: { thread_id: "user-alice" } }; const bobConfig = { configurable: { thread_id: "user-bob" } };

await graph.invoke({ messages: [new HumanMessage("Hi from Alice")] }, aliceConfig); await graph.invoke({ messages: [new HumanMessage("Hi from Bob")] }, bobConfig);

// Alice's state is isolated from Bob's


result = graph.invoke({"messages": ["start"]}, config)

# Browse checkpoint history

states = list(graph.get_state_history(config))

# Replay from a past checkpoint

past = states[-2] result = graph.invoke(None, past.config) # None = resume from checkpoint

# Or fork: update state at a past checkpoint, then resume

fork_config = graph.update_state(past.config, {"messages": ["edited"]}) result = graph.invoke(None, fork_config)

</python> <typescript> Time travel: browse checkpoint history and replay or fork from a past state.

const config = { configurable: { thread_id: "session-1" } };

const result = await graph.invoke({ messages: ["start"] }, config);

// Browse checkpoint history (async iterable, collect to array)
const states: Awaited<ReturnType<typeof graph.getState>>[] = [];
for await (const state of graph.getStateHistory(config)) {
  states.push(state);
}

// Replay from a past checkpoint
const past = states[states.length - 2];
const replayed = await graph.invoke(null, past.config);  // null = resume from checkpoint

// Or fork: update state at a past checkpoint, then resume
const forkConfig = await graph.updateState(past.config, { messages: ["edited"] });
const forked = await graph.invoke(null, forkConfig);

Modify state before resuming

graph.update_state(config, {"data": "manually_updated"})

Resume with updated state

result = graph.invoke(None, config)

</python>
<typescript>
Manually update graph state before resuming execution.

const config = { configurable: { thread_id: "session-1" } };

// Modify state before resuming await graph.updateState(config, { data: "manually_updated" });

// Resume with updated state const result = await graph.invoke(null, config);


---

## Long-Term Memory (Store)

store = InMemoryStore()

# Save user preference (available across ALL threads)

store.put(("alice", "preferences"), "language", {"preference": "short responses"})

# Node with store injection

def respond(state, *, store): prefs = store.get((state["user_id"], "preferences"), "language") return {"response": f"Using preference: {prefs.value}"}

# Compile with BOTH checkpointer and store

graph = builder.compile(checkpointer=checkpointer, store=store)

# Both threads access same long-term memory

graph.invoke({"user_id": "alice"}, {"configurable": {"thread_id": "thread-1"}}) graph.invoke({"user_id": "alice"}, {"configurable": {"thread_id": "thread-2"}}) # Same preferences!

</python> <typescript> Use a Store for cross-thread memory to share user preferences across conversations.

import { InMemoryStore } from "@langchain/langgraph";

const store = new InMemoryStore();

// Save user preference (available across ALL threads)
await store.put(["alice", "preferences"], "language", { preference: "short responses" });

// Node with store - access via config
const respond = async (state: typeof State.State, config: any) => {
  const item = await config.store.get(["alice", "preferences"], "language");
  return { response: `Using preference: ${item?.value?.preference}` };
};

// Compile with BOTH checkpointer and store
const graph = builder.compile({ checkpointer, store });

// Both threads access same long-term memory
await graph.invoke({ userId: "alice" }, { configurable: { thread_id: "thread-1" } });
await graph.invoke({ userId: "alice" }, { configurable: { thread_id: "thread-2" } });  // Same preferences!

store = InMemoryStore()

store.put(("user-123", "facts"), "location", {"city": "San Francisco"}) # Put item = store.get(("user-123", "facts"), "location") # Get results = store.search(("user-123", "facts"), filter={"city": "San Francisco"}) # Search store.delete(("user-123", "facts"), "location") # Delete

</python>
</ex-store-operations>

<boundaries>
### What You CAN Configure

- Choose checkpointer implementation
- Specify thread IDs for conversation isolation
- Retrieve/update state at any checkpoint
- Use stores for cross-thread memory

### What You CANNOT Configure

- Checkpoint timing (happens every super-step)
- Share short-term memory across threads
- Skip checkpointer for persistence features
</boundaries>

<fix-thread-id-required>
<python>
Always provide thread_id in config to enable state persistence.

WRONG: No thread_id - state NOT persisted!

graph.invoke({"messages": ["Hello"]}) graph.invoke({"messages": ["What did I say?"]}) # Doesn't remember!

CORRECT: Always provide thread_id

config = {"configurable": {"thread_id": "session-1"}} graph.invoke({"messages": ["Hello"]}, config) graph.invoke({"messages": ["What did I say?"]}, config) # Remembers!


// CORRECT: Always provide thread_id const config = {configurable: {thread_id: "session-1"}}; await graph.invoke({messages: [new HumanMessage("Hello")]}, config); await graph.invoke({messages: [new HumanMessage("What did I say?")]}, config); // Remembers!

</typescript> </fix-thread-id-required>

<fix-inmemory-not-for-production> <python> Use PostgresSaver instead of InMemorySaver for production persistence.

# WRONG: Data lost on process restart
checkpointer = InMemorySaver()  # In-memory only!

# CORRECT: Use persistent storage for production
from langgraph.checkpoint.postgres import PostgresSaver
with PostgresSaver.from_conn_string("postgresql://...") as checkpointer:
    checkpointer.setup()  # only needed on first use to create tables
    graph = builder.compile(checkpointer=checkpointer)

// CORRECT: Use persistent storage for production import {PostgresSaver} from "@langchain/langgraph-checkpoint-postgres"; const checkpointer = PostgresSaver.fromConnString("postgresql://..."); await checkpointer.setup(); // only needed on first use to create tables

</typescript>
</fix-inmemory-not-for-production>

<fix-resume-with-none>
<python>
Pass None to resume from checkpoint instead of providing new input.

WRONG: Providing new input restarts from beginning

graph.invoke({"messages": ["New message"]}, config) # Restarts!

CORRECT: Use None to resume from checkpoint

graph.invoke(None, config) # Continues from where it paused


// CORRECT: Use null to resume from checkpoint await graph.invoke(null, config); // Continues from where it paused

</typescript> </fix-resume-with-none>

<fix-update-state-with-reducers> <python> Use Overwrite to replace state values instead of passing through reducers.

from langgraph.types import Overwrite

# State with reducer: items: Annotated[list, operator.add]
# Current state: {"items": ["A", "B"]}

# update_state PASSES THROUGH reducers
graph.update_state(config, {"items": ["C"]})  # Result: ["A", "B", "C"] - Appended!

# To REPLACE instead, use Overwrite
graph.update_state(config, {"items": Overwrite(["C"])})  # Result: ["C"] - Replaced

// State with reducer: items uses concat reducer // Current state: {items: ["A", "B"]}

// updateState PASSES THROUGH reducers await graph.updateState(config, {items: ["C"]}); // Result: ["A", "B", "C"] - Appended!

// To REPLACE instead, use Overwrite await graph.updateState(config, {items: new Overwrite(["C"])}); // Result: ["C"] - Replaced

</typescript>
</fix-update-state-with-reducers>

<fix-store-injection>
<python>
Inject store via keyword parameter to access it in graph nodes.

WRONG: Store not available in node

def my_node(state): store.put(...) # NameError! store not defined

CORRECT: Inject store via keyword parameter

from langgraph.store.base import BaseStore

def my_node(state, *, store: BaseStore): store.put(...) # Correct store instance injected


// CORRECT: Access store via config parameter const myNode = async (state, config) => {await config.store.put(...); // Correct store instance};

</typescript> </fix-store-injection>

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

38.2%
按下载量换算3,559

Claude

26.73%
按下载量换算2,490

Cursor

17.97%
按下载量换算1,674

Gemini CLI

8.78%
按下载量换算818

安全审计

暂无安全审计结果可展示。

权限和风险

只读

该 Skill 主要提供规则、说明或参考内容,本身偏只读;真正读写文件、联网或执行命令仍取决于宿主 Agent 的任务。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills