Claude for Developers

Claude + LangChain.js: Building Reliable Agentic Workflows

Unlock powerful AI agents in JavaScript by combining Claude's superior reasoning with LangChain.js. Build reliable, multi-step workflows with tool calling and memory using TypeScript examples.

A

Andrew Snyder

AI & Automation Editor

December 22, 2025 min read
Share:

Why Claude + LangChain.js for Agentic Workflows?

Agentic workflows—where AI autonomously plans, executes tools, and iterates—represent the future of automation. Claude models from Anthropic shine here due to their exceptional reasoning, long context windows (up to 200K tokens in Claude 3.5 Sonnet), and native tool-calling support. But wiring everything manually via the Claude API can be tedious.

Enter LangChain.js: a JavaScript/TypeScript framework that abstracts chains, agents, memory, and retrieval into reusable components. It pairs perfectly with Claude, enabling robust agents that handle complex, multi-step tasks like research pipelines or customer support bots.

In this guide, we'll build from basics to advanced agents, contrasting LangChain.js approaches with native Claude API for clarity. Expect practical TypeScript code you can copy-paste.

Prerequisites

Install dependencies:

npm init -y
npm install @langchain/anthropic @langchain/core langchain @langchain/community zod
npm install -D typescript @types/node tsx

Create tsconfig.json:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "strict": true,
    "esModuleInterop": true
  }
}

Set your API key:

export ANTHROPIC_API_KEY=your_key_here

Basic Setup: Your First Claude Chain

Start simple: a conversational chain.

// basic-chain.ts
import { ChatAnthropic } from "@langchain/anthropic";
import { HumanMessage, AIMessage } from "@langchain/core/messages";

import { ChatPromptTemplate } from "@langchain/core/prompts";

async function simpleChain() {
  const model = new ChatAnthropic({
    model: "claude-3-5-sonnet-20240620",
    temperature: 0,
  });

  const prompt = ChatPromptTemplate.fromMessages([
    ["system", "You are a helpful assistant."],
    ["human", "{input}"],
  ]);

  const chain = prompt.pipe(model);

  const response = await chain.invoke({ input: "Explain quantum computing simply." });
  console.log(response.content);
}

simpleChain();

Vs. Native Claude API: LangChain handles prompt templating and message formatting automatically. Native API requires manual messages array construction:

// Native equivalent (simplified)
const response = await anthropic.messages.create({
  model: "claude-3-5-sonnet-20240620",
  max_tokens: 1024,
  messages: [{ role: "user", content: "Explain quantum computing simply." }],
});

LangChain shines for scaling to agents.

Building Agents with Tool Calling

Claude's tool use is state-of-the-art: it decides when to call tools and parses structured outputs.

Define a tool using Zod for schema validation:

// tools.ts
import { z } from "zod";
import { tool } from "@langchain/core/tools";

const calculatorSchema = z.object({
  operation: z.enum(["add", "subtract", "multiply", "divide"]).describe("The operation"),
  a: z.number().describe("First number"),
  b: z.number().describe("Second number"),
});

export const calculatorTool = tool(async ({ operation, a, b }) => {
  switch (operation) {
    case "add": return a + b;
    case "subtract": return a - b;
    case "multiply": return a * b;
    case "divide": return a / b;
    default: throw new Error("Invalid operation");
  }
}, {
  name: "calculator",
  description: "Performs basic math operations.",
  schema: calculatorSchema,
});

Create a ReAct agent (Reason + Act):

// agent.ts
import { createReactAgent } from "@langchain/core/agents";
import { ChatAnthropic } from "@langchain/anthropic";
import { pull } from "langchain/hub";

import { calculatorTool } from "./tools";

async function createAgent() {
  const model = new ChatAnthropic({
    model: "claude-3-5-sonnet-20240620",
    temperature: 0,
  });

  // Pull ReAct prompt from LangChain hub (optimized for Claude)
  const prompt = await pull("hwchase17/react");

  const agent = createReactAgent({
    llm: model,
    tools: [calculatorTool],
    prompt,
  });

  const agentRunnable = agent.asTool();
  // Or use with input
  const result = await agent.invoke({
    input: "What is (3 + 5) * 2 - 4?",
    tools: {}, // Internal
  });

  console.log(result.output);
}

createAgent();

Run with npx tsx agent.ts. Claude reasons: calls calculator multiple times, computes 12.

Comparison: Native Claude requires loop for tool calls:

  • Send message with tools.
  • Parse tool_use blocks.
  • Execute, append tool_result.
  • Repeat until stop_reason: 'end_turn'.

LangChain abstracts this into agent.invoke(), handling retries and parsing.

Adding Memory: Stateful Conversations

Agents forget without memory. Use ChatMessageHistory:

// memory-agent.ts
import { ChatMessageHistory } from "langchain/stores/message/in_memory";
import { BufferWindowMemory } from "langchain/memory";
import { createReactAgent } from "@langchain/core/agents";

// ... model, prompt, tools as above

const memory = new BufferWindowMemory({
  chatHistory: new ChatMessageHistory(),
  returnMessages: true,
  k: 5, // Last 5 exchanges
});

const agent = createReactAgent({ llm: model, tools: [calculatorTool], prompt });
const agentWithMemory = memory.pipe(agent);

// Simulate multi-turn
await agentWithMemory.invoke({
  input: "Remember this number: 42. Add 8 to it."
});
await agentWithMemory.invoke({
  input: "What was the original number?"
});

Claude recalls 42 seamlessly, thanks to context injection.

Pro Tip: For production, use RedisChatMessageHistory from @langchain/community for persistence across sessions.

Multi-Step Workflow: Research Agent Example

Combine tools for real-world use. Add a mock search tool:

// search-tool.ts
const searchSchema = z.object({
  query: z.string().describe("Search query"),
});

export const searchTool = tool(async ({ query }) => {
  // Mock; replace with TavilySearchResults or DuckDuckGo
  const results = {
    "claude langchain": "LangChain.js integrates Anthropic via ChatAnthropic.",
    "best claude model": "Claude 3.5 Sonnet for reasoning.",
  };
  return results[query] || "No results found.";
}, {
  name: "search",
  description: "Searches for info on Claude/LangChain.",
  schema: searchSchema,
});

Full agent:

// research-agent.ts
import { searchTool } from "./search-tool";
// ... other imports

const agent = createReactAgent({
  llm: model,
  tools: [calculatorTool, searchTool],
  prompt,
});

const result = await agent.invoke({
  input: "Using search, find best Claude model and compute its token price if 1M tokens cost $3 (per million).",
});
console.log(result.output);

Claude: Searches, reasons "Sonnet", calculates $3.

Reliability Best Practices

  • Model Selection: Sonnet for balance; Opus for complex reasoning; Haiku for speed.
  • Error Handling: Use handleParsingErrors: true in agent.
  • Max Iterations: Set maxIterations: 10 to prevent loops.
  • Structured Output: Bind tools with model.bindTools([tool]) for better parsing.
  • Streaming: agent.stream({ input }) for real-time UI.
  • Costs: Monitor via Anthropic dashboard; LangChain adds minimal overhead.

LangChain.js vs. Native:

AspectLangChain.jsNative API
Setup5 lines20+ lines loop
MemoryBuilt-inManual context mgmt
ToolsAuto-bindingManual parse/execute
DebuggingTracesConsole logs
ScalabilityGraphs/DeployCustom infra

LangChain wins for iteration speed.

Advanced: LangGraph.js for Complex Flows

For non-linear workflows, use LangGraph (LangChain's graph lib):

// Quick LangGraph intro
import { StateGraph, END } from "@langchain/langgraph";
import { Annotation } from "@langchain/langgraph";

const graphState = Annotation.Root({
  messages: Annotation<Message[]>(),
});

// Define nodes/tools, compile graph
const app = new StateGraph(graphState)
  .addNode("agent", agentNode)
  .addEdge("__end__", END);

const result = await app.invoke({ messages: [...] });

Ideal for conditional routing (e.g., if math → calculator, else search).

Conclusion

Claude + LangChain.js delivers production-ready agents with minimal boilerplate. Start with chains, scale to memory-enhanced ReAct agents, then graphs. Experiment with Claude 3.5 Sonnet—its tool precision outshines GPT-4o in benchmarks.

Repo: github.com/yourname/claude-langchain-examples (fork and extend).

Next: Integrate with n8n for no-code triggers or MCP servers for custom tools.

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 API
LangChain.js
AI Agents
JavaScript
TypeScript
ai-agents
A

About Andrew Snyder

AI & Automation Editor

Andrew covers practical AI automation, workflow design, and the tools teams use to streamline everyday operations.

Comments (0)