有关函数式 API 的概念信息,请参阅函数式 API。
创建简单的工作流程
定义entrypoint 时,输入仅限于函数的第一个参数。要传递多个输入,您可以使用字典。
const checkpointer = new MemorySaver();
const myWorkflow = entrypoint(
{ checkpointer, name: "myWorkflow" },
async (inputs: { value: number; anotherValue: number }) => {
const value = inputs.value;
const anotherValue = inputs.anotherValue;
// ...
}
);
await myWorkflow.invoke({ value: 1, anotherValue: 2 });
Extended example: simple workflow
Extended example: simple workflow
import { v4 as uuidv4 } from "uuid";
import { entrypoint, task, MemorySaver } from "@langchain/langgraph";
// Task that checks if a number is even
const isEven = task("isEven", async (number: number) => {
return number % 2 === 0;
});
// Task that formats a message
const formatMessage = task("formatMessage", async (isEven: boolean) => {
return isEven ? "The number is even." : "The number is odd.";
});
// Create a checkpointer for persistence
const checkpointer = new MemorySaver();
const workflow = entrypoint(
{ checkpointer, name: "workflow" },
async (inputs: { number: number }) => {
// Simple workflow to classify a number
const even = await isEven(inputs.number);
return await formatMessage(even);
}
);
// Run the workflow with a unique thread ID
const config = { configurable: { thread_id: uuidv4() } };
const result = await workflow.invoke({ number: 7 }, config);
console.log(result);
Extended example: Compose an essay with an LLM
Extended example: Compose an essay with an LLM
This example demonstrates how to use the
@task and @entrypoint decorators
syntactically. Given that a checkpointer is provided, the workflow results will
be persisted in the checkpointer.import { v4 as uuidv4 } from "uuid";
import { ChatOpenAI } from "@langchain/openai";
import { entrypoint, task, MemorySaver } from "@langchain/langgraph";
const model = new ChatOpenAI({ model: "gpt-3.5-turbo" });
// Task: generate essay using an LLM
const composeEssay = task("composeEssay", async (topic: string) => {
// Generate an essay about the given topic
const response = await model.invoke([
{ role: "system", content: "You are a helpful assistant that writes essays." },
{ role: "user", content: `Write an essay about ${topic}.` }
]);
return response.content as string;
});
// Create a checkpointer for persistence
const checkpointer = new MemorySaver();
const workflow = entrypoint(
{ checkpointer, name: "workflow" },
async (topic: string) => {
// Simple workflow that generates an essay with an LLM
return await composeEssay(topic);
}
);
// Execute the workflow
const config = { configurable: { thread_id: uuidv4() } };
const result = await workflow.invoke("the history of flight", config);
console.log(result);
并行执行
可以通过并发调用任务并等待结果来并行执行任务。这对于提高 IO 密集型任务的性能很有用(例如,调用 LLM 的 API)。const addOne = task("addOne", async (number: number) => {
return number + 1;
});
const graph = entrypoint(
{ checkpointer, name: "graph" },
async (numbers: number[]) => {
return await Promise.all(numbers.map(addOne));
}
);
Extended example: parallel LLM calls
Extended example: parallel LLM calls
This example demonstrates how to run multiple LLM calls in parallel using This example uses LangGraph’s concurrency model to improve execution time, especially when tasks involve I/O like LLM completions.
@task. Each call generates a paragraph on a different topic, and results are joined into a single text output.import { v4 as uuidv4 } from "uuid";
import { ChatOpenAI } from "@langchain/openai";
import { entrypoint, task, MemorySaver } from "@langchain/langgraph";
// Initialize the LLM model
const model = new ChatOpenAI({ model: "gpt-3.5-turbo" });
// Task that generates a paragraph about a given topic
const generateParagraph = task("generateParagraph", async (topic: string) => {
const response = await model.invoke([
{ role: "system", content: "You are a helpful assistant that writes educational paragraphs." },
{ role: "user", content: `Write a paragraph about ${topic}.` }
]);
return response.content as string;
});
// Create a checkpointer for persistence
const checkpointer = new MemorySaver();
const workflow = entrypoint(
{ checkpointer, name: "workflow" },
async (topics: string[]) => {
// Generates multiple paragraphs in parallel and combines them
const paragraphs = await Promise.all(topics.map(generateParagraph));
return paragraphs.join("\n\n");
}
);
// Run the workflow
const config = { configurable: { thread_id: uuidv4() } };
const result = await workflow.invoke(["quantum computing", "climate change", "history of aviation"], config);
console.log(result);
调用图
Functional API 和 Graph API 可以在同一应用程序中一起使用,因为它们共享相同的底层运行时。import { entrypoint } from "@langchain/langgraph";
import { StateGraph } from "@langchain/langgraph";
const builder = new StateGraph(/* ... */);
// ...
const someGraph = builder.compile();
const someWorkflow = entrypoint(
{ name: "someWorkflow" },
async (someInput: Record<string, any>) => {
// Call a graph defined using the graph API
const result1 = await someGraph.invoke(/* ... */);
// Call another graph defined using the graph API
const result2 = await anotherGraph.invoke(/* ... */);
return {
result1,
result2,
};
}
);
Extended example: calling a simple graph from the functional API
Extended example: calling a simple graph from the functional API
import { v4 as uuidv4 } from "uuid";
import { entrypoint, MemorySaver } from "@langchain/langgraph";
import { StateGraph } from "@langchain/langgraph";
import * as z from "zod";
// Define the shared state type
const State = z.object({
foo: z.number(),
});
// Build the graph using the Graph API
const builder = new StateGraph(State)
.addNode("double", (state) => {
return { foo: state.foo * 2 };
})
.addEdge("__start__", "double");
const graph = builder.compile();
// Define the functional API workflow
const checkpointer = new MemorySaver();
const workflow = entrypoint(
{ checkpointer, name: "workflow" },
async (x: number) => {
const result = await graph.invoke({ foo: x });
return { bar: result.foo };
}
);
// Execute the workflow
const config = { configurable: { thread_id: uuidv4() } };
console.log(await workflow.invoke(5, config)); // Output: { bar: 10 }
调用其他入口点
您可以从入口点或任务内部调用其他入口点。// Will automatically use the checkpointer from the parent entrypoint
const someOtherWorkflow = entrypoint(
{ name: "someOtherWorkflow" },
async (inputs: { value: number }) => {
return inputs.value;
}
);
const myWorkflow = entrypoint(
{ checkpointer, name: "myWorkflow" },
async (inputs: { value: number }) => {
const value = await someOtherWorkflow.invoke({ value: 1 });
return value;
}
);
Extended example: calling another entrypoint
Extended example: calling another entrypoint
import { v4 as uuidv4 } from "uuid";
import { entrypoint, MemorySaver } from "@langchain/langgraph";
// Initialize a checkpointer
const checkpointer = new MemorySaver();
// A reusable sub-workflow that multiplies a number
const multiply = entrypoint(
{ name: "multiply" },
async (inputs: { a: number; b: number }) => {
return inputs.a * inputs.b;
}
);
// Main workflow that invokes the sub-workflow
const main = entrypoint(
{ checkpointer, name: "main" },
async (inputs: { x: number; y: number }) => {
const result = await multiply.invoke({ a: inputs.x, b: inputs.y });
return { product: result };
}
);
// Execute the main workflow
const config = { configurable: { thread_id: uuidv4() } };
console.log(await main.invoke({ x: 6, y: 7 }, config)); // Output: { product: 42 }
流式传输
Functional API 使用与 Graph API 相同的流式传输机制。请 阅读 流式传输指南 部分了解更多详细信息。 使用流式传输 API 流式传输更新和自定义数据的示例。import {
entrypoint,
MemorySaver,
LangGraphRunnableConfig,
} from "@langchain/langgraph";
const checkpointer = new MemorySaver();
const main = entrypoint(
{ checkpointer, name: "main" },
async (
inputs: { x: number },
config: LangGraphRunnableConfig
): Promise<number> => {
config.writer?.("Started processing");
const result = inputs.x * 2;
config.writer?.(`Result is ${result}`);
return result;
}
);
const config = { configurable: { thread_id: "abc" } };
for await (const [mode, chunk] of await main.stream(
{ x: 5 },
{ streamMode: ["custom", "updates"], ...config }
)) {
console.log(`${mode}: ${JSON.stringify(chunk)}`);
}
- 在计算开始前发出自定义数据。
- 在计算结果后发出另一个自定义消息。
- 使用
.stream()处理流式输出。 - 指定要使用的流式模式。
updates: {"addOne": 2}
updates: {"addTwo": 3}
custom: "hello"
custom: "world"
updates: {"main": 5}
重试策略
import {
MemorySaver,
entrypoint,
task,
RetryPolicy,
} from "@langchain/langgraph";
// This variable is just used for demonstration purposes to simulate a network failure.
// It's not something you will have in your actual code.
let attempts = 0;
// Let's configure the RetryPolicy to retry on ValueError.
// The default RetryPolicy is optimized for retrying specific network errors.
const retryPolicy: RetryPolicy = { retryOn: (error) => error instanceof Error };
const getInfo = task(
{
name: "getInfo",
retry: retryPolicy,
},
() => {
attempts += 1;
if (attempts < 2) {
throw new Error("Failure");
}
return "OK";
}
);
const checkpointer = new MemorySaver();
const main = entrypoint(
{ checkpointer, name: "main" },
async (inputs: Record<string, any>) => {
return await getInfo();
}
);
const config = {
configurable: {
thread_id: "1",
},
};
await main.invoke({ any_input: "foobar" }, config);
'OK'
缓存任务
import {
InMemoryCache,
entrypoint,
task,
CachePolicy,
} from "@langchain/langgraph";
const slowAdd = task(
{
name: "slowAdd",
cache: { ttl: 120 },
},
async (x: number) => {
await new Promise((resolve) => setTimeout(resolve, 1000));
return x * 2;
}
);
const main = entrypoint(
{ cache: new InMemoryCache(), name: "main" },
async (inputs: { x: number }) => {
const result1 = await slowAdd(inputs.x);
const result2 = await slowAdd(inputs.x);
return { result1, result2 };
}
);
for await (const chunk of await main.stream(
{ x: 5 },
{ streamMode: "updates" }
)) {
console.log(chunk);
}
//> { slowAdd: 10 }
//> { slowAdd: 10, '__metadata__': { cached: true } }
//> { main: { result1: 10, result2: 10 } }
ttl以秒为单位指定。缓存将在该时间后失效。
错误后恢复
pythonfrom langgraph.types import Command
# 继续执行
for event in graph.stream(Command(resume="baz"), config):
print(event)
print("\n")
import { Command } from "@langchain/langgraph";
// 继续执行
for await (const event of await graph.stream(
new Command({ resume: "baz" }),
config
)) {
console.log(event);
console.log("\n");
}
审核工具调用
若要在执行前审核工具调用,我们可以添加一个调用interrupt 的 review_tool_call 函数。当调用该函数时,执行会暂停,直到我们发出命令使其继续。
Connect these docs programmatically to Claude, VSCode, and more via MCP for real-time answers.