Low-level orchestration framework for building stateful, multi-actor applications with LLMs
Complete examples of agent architectures.
import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { ChatOpenAI } from "@langchain/openai";
import { tool } from "@langchain/core/tools";
import { z } from "zod";
// Define tools
const searchTool = tool(async (input) => {
return `Search results for: ${input.query}`;
}, {
name: "search",
description: "Search the web",
schema: z.object({
query: z.string().describe("Search query")
})
});
const calculatorTool = tool((input) => {
return eval(input.expression).toString();
}, {
name: "calculator",
description: "Evaluate math expressions",
schema: z.object({
expression: z.string()
})
});
// Create agent
const agent = createReactAgent({
llm: new ChatOpenAI({ model: "gpt-4" }),
tools: [searchTool, calculatorTool],
messageModifier: "You are a helpful assistant."
});
// Use agent
const result = await agent.invoke({
messages: [{ role: "user", content: "What is 25 * 4 and search for Python tutorials?" }]
});
console.log(result.messages[result.messages.length - 1].content);import { StateGraph, MessagesAnnotation, START } from "@langchain/langgraph";
import { ToolNode, toolsCondition } from "@langchain/langgraph/prebuilt";
import { ChatOpenAI } from "@langchain/openai";
const model = new ChatOpenAI({ model: "gpt-4" }).bindTools(tools);
const callModel = async (state: typeof MessagesAnnotation.State) => {
const response = await model.invoke(state.messages);
return { messages: [response] };
};
const graph = new StateGraph(MessagesAnnotation)
.addNode("agent", callModel)
.addNode("tools", new ToolNode(tools))
.addEdge(START, "agent")
.addConditionalEdges("agent", toolsCondition)
.addEdge("tools", "agent")
.compile();
const result = await graph.invoke({
messages: [{ role: "user", content: "Calculate 15 * 23" }]
});const State = Annotation.Root({
messages: Annotation<BaseMessage[]>({
reducer: messagesStateReducer,
default: () => []
}),
task: Annotation<string>()
});
// Supervisor decides routing
const supervisor = async (state: typeof State.State) => {
const lastMessage = state.messages[state.messages.length - 1];
const content = lastMessage.content;
if (content.includes("research")) return { next: "researcher" };
if (content.includes("code")) return { next: "coder" };
return { next: "finish" };
};
// Research agent
const researcher = async (state: typeof State.State) => {
const research = await researchAgent.invoke(state.messages);
return { messages: [research] };
};
// Coder agent
const coder = async (state: typeof State.State) => {
const code = await coderAgent.invoke(state.messages);
return { messages: [code] };
};
const router = (state: any) => state.next;
const graph = new StateGraph(State)
.addNode("supervisor", supervisor)
.addNode("researcher", researcher)
.addNode("coder", coder)
.addEdge(START, "supervisor")
.addConditionalEdges("supervisor", router, {
researcher: "researcher",
coder: "coder",
finish: END
})
.addEdge("researcher", "supervisor")
.addEdge("coder", "supervisor")
.compile();See: Prebuilt Agents API for API reference. See: Multi-Agent Guide for orchestration patterns.