Developer Guides

Claude SDK with LangGraph: Orchestrating Complex Multi-Agent Workflows

Unlock the power of stateful multi-agent AI workflows by integrating the Claude SDK with LangGraph. This tutorial guides you through building, managing memory, and deploying complex agent graphs on Ve

J

Jennifer Yu

Workflow Automation Specialist

December 8, 2025 min read
Share:

Introduction

LangGraph is a powerful library from the LangChain ecosystem designed for building stateful, multi-actor applications powered by large language models (LLMs). It excels at orchestrating complex workflows where multiple agents collaborate, maintain context across interactions, and handle interruptions or human-in-the-loop scenarios.

When paired with the Anthropic Claude SDK, LangGraph leverages Claude's superior reasoning, tool-calling capabilities, and safety features—particularly Claude 3.5 Sonnet—to create robust AI agents. This tutorial walks you through integrating the Claude SDK via LangChain's Anthropic wrapper, constructing a multi-agent research workflow, implementing tool calling and persistent memory, and deploying to Vercel as a serverless API.

By the end, you'll have a production-ready system for tasks like automated research reports, where a supervisor routes queries to specialized researcher and writer agents.

Prerequisites

Before starting, ensure you have:

  • Node.js 18+ installed
  • An Anthropic API key (get one from console.anthropic.com)
  • A Vercel account for deployment
  • Basic familiarity with TypeScript, async/await, and npm

Project Setup

Create a new directory and initialize the project:

mkdir claude-langgraph-app
cd claude-langgraph-app
npm init -y
npm install @langchain/anthropic @langchain/core langgraph zod
npm install -D typescript @types/node tsx

Note: We're using @langchain/anthropic, which wraps the official @anthropic-ai/sdk for seamless LangGraph integration, handling messages, tools, and streaming natively.

Create tsconfig.json:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "node",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  }
}

Set your API key in a .env file:

ANTHROPIC_API_KEY=your-api-key-here

Defining Tools

Agents need tools for real-world actions. We'll define two: a web search simulator (using a mock for demo) and a file writer.

Create tools.ts:

import { z } from 'zod';
import { Tool } from '@langchain/core/tools';

// Mock web search tool
export class WebSearchTool extends Tool {
  name = 'web_search';
  description = 'Search the web for current information.';

  protected _call(input: string) {
    // In production, integrate with Tavily, SerpAPI, etc.
    return `Mock results for "${input}": Claude 3.5 Sonnet excels in agentic workflows. LangGraph.js v0.1+ supports checkpoints.`;
  }

  schema = z.object({
    query: z.string().describe('Search query'),
  });
}

export const tools = [new WebSearchTool()];

Building Single Agents

Define agent nodes: a researcher using tools and a writer for summarization.

Create agents.ts:

import { ChatAnthropic } from '@langchain/anthropic';
import { createReactAgent } from '@langchain/core/agents';
import { pull } from 'langgraph';
import { tools } from './tools';
import { STATE } from './graph';

const llm = new ChatAnthropic({
  model: 'claude-3-5-sonnet-20240620',
  temperature: 0,
  apiKey: process.env.ANTHROPIC_API_KEY,
}).bindTools(tools);

export const researcher = pull('researcher', createReactAgent({
  llm,
  tools,
}));

export const writer = pull('writer', createReactAgent({
  llm: new ChatAnthropic({
    model: 'claude-3-5-sonnet-20240620',
    temperature: 0.2,
  }),
  tools: [],
}));

Here, createReactAgent uses ReAct reasoning (Reason + Act), ideal for Claude's tool-use strengths.

Orchestrating Multi-Agent Graph

The core is a StateGraph with a supervisor routing tasks.

First, define the state schema in graph.ts:

import { Annotation, BaseMessage } from '@langchain/core/messages';
import { z } from 'zod';

export const AgentState = z.object({
  messages: z.array(Annotation<BaseMessage>()),
  next: z.string().optional(),
});

export type STATE = z.infer<typeof AgentState>;

Now, the full graph in graph.ts:

import { StateGraph, END } from '@langchain/langgraph';
import { Annotation, HumanMessage } from '@langchain/core/messages';
import { researcher, writer } from './agents';
import { STATE } from './state';
import { ToolMessage } from '@langchain/core/messages';

// Supervisor node
function supervisor(state: STATE) {
  const llm = /* same Claude config as above */;
  const prompt = `You are a supervisor. Route to: researcher, writer, or END. Current: ${state.messages.slice(-1)[0].content}`;
  // Implement routing logic with Claude
  const response = llm.invoke([{ role: 'user', content: prompt }]);
  return { next: 'researcher' }; // Simplified; parse response
}

const workflow = new StateGraph(STATE)
  .addNode('supervisor', supervisor)
  .addNode('researcher', researcher)
  .addNode('writer', writer)
  .addEdge('__start__', 'supervisor')
  .addConditionalEdges('supervisor', (s) => s.next ?? END, {
    researcher: 'researcher',
    writer: 'writer',
  })
  .addEdge('researcher', 'supervisor')
  .addEdge('writer', END);

export const graph = workflow.compile();

This creates cycles: supervisor → researcher → supervisor → writer → END.

Memory Management

LangGraph supports checkpoints for state persistence. Use in-memory for dev:

const memoryGraph = workflow.compile({ checkpointer: new InMemorySaver() });

// Invoke with thread ID for persistence
const config = { configurable: { thread_id: 'abc123' } };
const result = await memoryGraph.invoke({ messages: [new HumanMessage('Research LangGraph with Claude')] }, config);

For production, swap to PostgresSaver or RedisSaver (via @langchain/langgraph-checkpoint-redis).

Claude's context window (200K tokens) shines here, retaining long histories without truncation issues common in other models.

Handling Tool Calling

Claude's native tool use is invoked via bindTools(). In ReAct agents, it automatically decides when to call tools, parses outputs, and continues reasoning.

Extend with custom tools:

// Add to tools.ts
class CalculatorTool extends Tool {
  name = 'calculator';
  description = 'Perform math calculations.';
  schema = z.object({ expression: z.string() });
  async _call({ expression }: { expression: string }) {
    return eval(expression).toString(); // Safe in prod with safe-eval
  }
}

Claude 3.5 Sonnet reliably handles parallel tool calls and error recovery.

Running the App Locally

Create index.ts:

import { graph } from './graph';

import dotenv from 'dotenv';
dotenv.config();

const input = { messages: [{ role: 'user', content: 'Generate a report on Claude SDK best practices.' }] };
const result = await graph.invoke(input);
console.log(result);

Run with npx tsx index.ts.

Deployment to Vercel

LangGraph apps deploy easily as serverless functions.

  1. Add vercel.json:
{
  "functions": {
    api/graph.ts": { "runtime": "nodejs18.x" }
  }
}
  1. Create api/graph.ts:
import { graph } from '../../graph';

export default async function handler(req: Request) {
  const { input, threadId } = await req.json();
  const config = { configurable: { thread_id: threadId } };
  const result = await graph.invoke(input, config);
  return Response.json(result);
}
  1. vercel deploy --prod

Vercel handles cold starts; use Upstash Redis for shared memory across invocations.

Best Practices

  • Model Selection: Use Claude 3.5 Sonnet for agents; Haiku for simple routing.
  • Prompt Engineering: Prefix with "You are a helpful agent." Claude follows XML-like tool formats precisely.
  • Error Handling: Wrap invokes in try-catch; Claude's safety reduces hallucinations.
  • Cost Optimization: Stream responses with graph.stream().
  • Scaling: Shard threads by user ID; monitor via Anthropic console.

Common Pitfalls and Solutions

IssueSolution
Tool parsing failsEnsure Zod schemas match tool descriptions
State loss on deployAlways use checkpointer
High latencyParallel edges with addParallelEdges
Context overflowSummarize history with a compressor node

Conclusion

Integrating the Claude SDK with LangGraph unlocks sophisticated multi-agent systems tailored for production. This setup handles research-to-report workflows scalably, with Claude's edge in reliability. Experiment with your use cases—add Slack integrations or n8n triggers next!

Source code: [GitHub repo link placeholder]

(Word count: ~1450)

The #1 Newsletter in AI

Stay ahead of the AI curve

The most important updates, news, and content — delivered in one weekly newsletter.

No spam. Unsubscribe anytime. Privacy policy

Claude SDK
LangGraph
Multi-Agent
AI Orchestration
Claude Agents
ai-agents
J

About Jennifer Yu

Workflow Automation Specialist

Jennifer covers workflow strategy, no-code platforms, and clear implementation guidance for teams adopting automation.

Comments (0)