← Blog

Claude API LangChain Integration Tutorial

2026-10-26 · 5 min read · SubToAPI Team

If you're searching for how to connect Claude to LangChain, you want a working setup fast: the right package, the right client class, and a pattern for chains, memory, and tools that doesn't break on the next LangChain release. This tutorial covers exactly that — installing the pieces, authenticating, building a basic chain, adding memory and streaming, and wiring up tool calling.

LangChain talks to Claude through the ChatAnthropic class in the langchain-anthropic package. Under the hood it calls Anthropic's Messages API, so anything that speaks that API — including a key-managed proxy like SubToAPI — can be dropped in by changing the base URL and key. The rest of this guide assumes you're using Python, since that's where most LangChain + Claude tutorials end up, with a Node.js note at the end.

Installing and Authenticating

Install the core LangChain package plus the Anthropic integration:

pip install langchain langchain-anthropic

Set your API key as an environment variable:

export ANTHROPIC_API_KEY="sk-ant-..."

Then instantiate the model:

from langchain_anthropic import ChatAnthropic

llm = ChatAnthropic(
    model="claude-sonnet-4-5-20250929",
    temperature=0.3,
    max_tokens=1024,
)

response = llm.invoke("Summarize what LangChain's Runnable interface does.")
print(response.content)

That's the whole integration for a single-turn call. Everything else in this article is composition on top of this llm object.

Using SubToAPI as the Backend

If you're already issuing app-scoped keys through SubToAPI instead of sharing a raw Anthropic key across services, point the same ChatAnthropic class at your SubToAPI endpoint and key:

from langchain_anthropic import ChatAnthropic

llm = ChatAnthropic(
    model="claude-sonnet-4-5-20250929",
    anthropic_api_url="https://api.subtoapi.app/v1",
    anthropic_api_key="sub_live_...",
    max_tokens=1024,
)

This keeps your LangChain code identical while giving you per-application keys, usage metadata, and team seat management from one dashboard — useful when several services or environments share a single underlying Claude plan. See /docs/quickstart for key setup and /docs/messages for the request format SubToAPI mirrors.

Building a Chain

LangChain's modern syntax uses the pipe operator to compose prompts, models, and output parsers:

from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

prompt = ChatPromptTemplate.from_messages([
    ("system", "You are a concise technical writer."),
    ("human", "{question}"),
])

chain = prompt | llm | StrOutputParser()

result = chain.invoke({"question": "Explain idempotent HTTP methods in two sentences."})
print(result)

This Runnable chain pattern replaces the older LLMChain class and is what current LangChain versions expect. If you're following an older tutorial that imports LLMChain, swap it for this pipe syntax — it's more composable and avoids deprecation warnings.

Adding Conversation Memory

For multi-turn conversations, use RunnableWithMessageHistory rather than the deprecated memory classes:

from langchain_core.chat_history import InMemoryChatMessageHistory
from langchain_core.runnables.history import RunnableWithMessageHistory

store = {}

def get_history(session_id: str):
    if session_id not in store:
        store[session_id] = InMemoryChatMessageHistory()
    return store[session_id]

chat_with_memory = RunnableWithMessageHistory(chain, get_history)

chat_with_memory.invoke(
    {"question": "What's the capital of Portugal?"},
    config={"configurable": {"session_id": "user-42"}},
)

For production, swap InMemoryChatMessageHistory for a database-backed history class (LangChain ships Redis, Postgres, and other adapters) so sessions survive restarts.

Streaming Responses

Claude supports token streaming, and ChatAnthropic exposes it directly:

for chunk in llm.stream("Write a haiku about distributed systems."):
    print(chunk.content, end="", flush=True)

If you're calling Claude through SubToAPI instead of raw Anthropic credentials, streaming works the same way — it's covered in detail at /docs/streaming, including how partial chunks are framed over HTTP.

Tool Calling in LangChain

LangChain's tool-calling abstraction maps onto Claude's native tool use. Define a tool with @tool, bind it to the model, and let LangChain handle the request/response loop:

from langchain_core.tools import tool

@tool
def get_weather(city: str) -> str:
    """Return current weather for a city."""
    return f"It's 18°C and cloudy in {city}."

llm_with_tools = llm.bind_tools([get_weather])

response = llm_with_tools.invoke("What's the weather in Lisbon?")
print(response.tool_calls)

When Claude decides to call get_weather, LangChain surfaces the call in response.tool_calls. You execute the function yourself, then feed the result back as a tool message to continue the turn. This maps directly to the tool_use / tool_result content blocks in Claude's Messages API — if you want to see the raw request/response shape without the LangChain abstraction, /docs/tools walks through it explicitly.

Common Integration Issues

Model not found errors usually mean you're using a model string that doesn't match the current Claude model naming convention — check Anthropic's model list rather than copying an outdated tutorial's string verbatim.

Silent truncation happens when max_tokens is too low for the response you're expecting. LangChain won't warn you — Claude just stops mid-output. Set it generously for summarization or code-generation tasks.

Rate limit errors inside a chain are harder to debug than a raw API call because the error surfaces through several LangChain abstraction layers. Wrapping your chain invocation in LangChain's built-in retry logic (llm.with_retry()) smooths over transient 429s without custom exception handling.

Node.js Equivalent

The JavaScript LangChain package mirrors the Python API closely:

import { ChatAnthropic } from "@langchain/anthropic";

const llm = new ChatAnthropic({
  model: "claude-sonnet-4-5-20250929",
  anthropicApiKey: process.env.ANTHROPIC_API_KEY,
});

const response = await llm.invoke("Give me a one-line summary of REST.");
console.log(response.content);

Swap in anthropicApiUrl and a SubToAPI key the same way as the Python example if you're centralizing keys across a Node.js service fleet. New accounts can grab a key in minutes at /signup, and plan details are at /pricing.

questions

Does LangChain support Claude's full feature set, including tool use and streaming? Yes. ChatAnthropic supports tool calling, streaming, system prompts, and multi-turn conversation history. A few very new Claude-specific features may land in the Anthropic SDK before LangChain's wrapper catches up, so check the langchain-anthropic changelog if something seems missing.

Can I use a proxy or key-management service instead of a raw Anthropic key? Yes, as long as the service speaks the Messages API format — set anthropic_api_url (Python) or anthropicApiUrl (JS) to the proxy's base URL and pass its key as anthropic_api_key.

Why does my LangChain chain throw deprecation warnings? Most warnings come from using the older LLMChain or legacy memory classes. Migrate to the Runnable pipe syntax and RunnableWithMessageHistory shown above — they're the supported pattern in current LangChain versions and won't be deprecated soon.

Turn your Claude access into an HTTPS API

SubToAPI gives you application API keys, streaming, tool use and usage insights on top of your existing Claude access — set up in minutes.

Start free  Read the quickstart →