import { MemorySaver, entrypoint, task, interrupt } from "@langchain/langgraph";const writeEssay = task("writeEssay", async (topic: string) => { // A placeholder for a long-running task. await new Promise((resolve) => setTimeout(resolve, 1000)); return `An essay about topic: ${topic}`;});const workflow = entrypoint( { checkpointer: new MemorySaver(), name: "workflow" }, async (topic: string) => { const essay = await writeEssay(topic); const isApproved = interrupt({ // Any json-serializable payload provided to interrupt as argument. // It will be surfaced on the client side as an Interrupt when streaming data // from the workflow. essay, // The essay we want reviewed. // We can add any additional information that we need. // For example, introduce a key called "action" with some instructions. action: "Please approve/reject the essay", }); return { essay, // The essay that was generated isApproved, // Response from HIL }; });
import { v4 as uuidv4 } from "uuid";import { MemorySaver, entrypoint, task, interrupt } from "@langchain/langgraph";const writeEssay = task("writeEssay", async (topic: string) => { // This is a placeholder for a long-running task. await new Promise(resolve => setTimeout(resolve, 1000)); return `An essay about topic: ${topic}`;});const workflow = entrypoint( { checkpointer: new MemorySaver(), name: "workflow" }, async (topic: string) => { const essay = await writeEssay(topic); const isApproved = interrupt({ // Any json-serializable payload provided to interrupt as argument. // It will be surfaced on the client side as an Interrupt when streaming data // from the workflow. essay, // The essay we want reviewed. // We can add any additional information that we need. // For example, introduce a key called "action" with some instructions. action: "Please approve/reject the essay", }); return { essay, // The essay that was generated isApproved, // Response from HIL }; });const threadId = uuidv4();const config = { configurable: { thread_id: threadId }};for await (const item of workflow.stream("cat", config)) { console.log(item);}
import { Command } from "@langchain/langgraph";// Get review from a user (e.g., via a UI)// In this case, we're using a bool, but this can be any json-serializable value.const humanReview = true;for await (const item of workflow.stream(new Command({ resume: humanReview }), config)) { console.log(item);}
import { entrypoint } from "@langchain/langgraph";const myWorkflow = entrypoint( { checkpointer, name: "workflow" }, async (someInput: Record<string, any>): Promise<number> => { // some logic that may involve long-running tasks like API calls, // and may be interrupted for human-in-the-loop return result; });
import { entrypoint, getPreviousState } from "@langchain/langgraph";const myWorkflow = entrypoint( { checkpointer, name: "workflow" }, async (number: number) => { const previous = getPreviousState<number>() ?? 0; // This will return the previous value to the caller, saving // 2 * number to the checkpoint, which will be used in the next invocation // for the `previous` parameter. return entrypoint.final({ value: previous, save: 2 * number, }); });const config = { configurable: { thread_id: "1", },};await myWorkflow.invoke(3, config); // 0 (previous was undefined)await myWorkflow.invoke(1, config); // 6 (previous was 3 * 2 from the previous invocation)
import { entrypoint, interrupt } from "@langchain/langgraph";import fs from "fs";const myWorkflow = entrypoint( { checkpointer, name: "workflow }, async (inputs: Record<string, any>) => { // This code will be executed a second time when resuming the workflow. // Which is likely not what you want. fs.writeFileSync("output.txt", "Side effect executed"); const value = interrupt("question"); return value; });
在这个例子中,副作用被封装在一个任务中,确保在恢复执行时保持一致性。
import { entrypoint, task, interrupt } from "@langchain/langgraph";import * as fs from "fs";const writeToFile = task("writeToFile", async () => { fs.writeFileSync("output.txt", "Side effect executed");});const myWorkflow = entrypoint( { checkpointer, name: "workflow" }, async (inputs: Record<string, any>) => { // The side effect is now encapsulated in a task. await writeToFile(); const value = interrupt("question"); return value; });