如何缓存耗时节点¶
节点缓存适用于您希望避免重复操作(例如执行耗时或耗费成本的操作)的情况。LangGraph 允许您为图中的节点添加个性化的缓存策略。
要配置缓存策略,请将 cachePolicy
参数传递给 addNode
方法。在下面的示例中,我们指定了一个生命周期(TTL)为 120 秒的缓存策略和默认的键序列化函数。然后,要为图启用节点级缓存,请在编译图时设置 cache
参数。以下示例使用 InMemoryCache
设置带有内存缓存的图。
import { StateGraph, Annotation, START } from "@langchain/langgraph";
import { InMemoryCache } from "@langchain/langgraph-checkpoint";
const StateAnnotation = Annotation.Root({
items: Annotation<string[]>({
default: () => [],
reducer: (acc, item) => [...acc, ...item],
}),
});
const cache = new InMemoryCache();
const graph = new StateGraph(StateAnnotation)
.addNode(
"node",
async () => {
// Simulate an expensive operation
await new Promise((resolve) => setTimeout(resolve, 3000));
return { items: ["Hello, how are you?"] };
},
{ cachePolicy: { ttl: 120 } }
)
.addEdge(START, "node")
.compile({ cache });
由于缓存为空,首次运行将需要 3 秒。后续使用相同输入的运行将被缓存并立即产出结果。
console.time("First run");
await graph.invoke({ items: ["Hello!"] });
console.timeEnd("First run");
console.time("Second run");
await graph.invoke({ items: ["Hello!"] });
console.timeEnd("Second run");
cachePolicy
参数。这可用于跳过序列化中的某些字段,例如消息 ID,它们在每次运行中可能是随机的。
import { StateGraph, MessagesAnnotation, START } from "@langchain/langgraph";
import { InMemoryCache } from "@langchain/langgraph-checkpoint";
import { BaseMessage } from "@langchain/core/messages";
const cache = new InMemoryCache();
const graph = new StateGraph(MessagesAnnotation)
.addNode(
"node",
async () => {
await new Promise((resolve) => setTimeout(resolve, 3000));
return { messages: [{ type: "ai", content: "Hello, how are you?" }] };
},
{
cachePolicy: {
ttl: 120,
keyFunc([{ messages }]: [{ messages: BaseMessage[] }]) {
// Cache based on the content and relative position of the messages
return JSON.stringify(messages.map((m, idx) => [idx, m.content]));
},
},
}
)
.addEdge(START, "node")
.compile({ cache });
// First run will take 3 seconds
console.time("First run");
await graph.invoke({ messages: [{ type: "human", content: "Hello!" }] });
console.timeEnd("First run");
// Second run will be cached and yield immediately
console.time("Second run");
await graph.invoke({ messages: [{ type: "human", content: "Hello!" }] });
console.timeEnd("Second run");