DEV Community

Cover image for Stop Using LangChain for Simple LLM Tasks: The Raw Anthropic SDK Is Cheaper and Clearer
Mudassir Khan
Mudassir Khan

Posted on

Stop Using LangChain for Simple LLM Tasks: The Raw Anthropic SDK Is Cheaper and Clearer

If you reach for LangChain every time you wire up a new LLM call, you are not alone. Most teams do it. The problem is that for simple tasks, that reach costs you in tokens, in debugging time, and in a monthly bill from LangSmith that you forgot you enabled.


The Default Reach for Abstraction

LangChain became the default choice because it made the first demo fast. You imported a model wrapper, chained a couple of prompts, and had something running in 20 minutes. That early speed creates a gravitational pull. When the next feature comes up, you reach for the same toolkit.

But demos and production are different environments. In production, you need to know exactly what is going into every API call. You need to trace a failure back to the token that caused it. You need to reason about cost at the individual request level.

LangChain's abstraction layers make all of that harder. The framework handles prompt templating, message formatting, retry logic, and model selection (sometimes with opinions you did not ask for). That is genuinely useful when your pipeline has six steps, conditional routing, and tool calls that need orchestration. It is a footgun when your use case is a single turn call to summarize a support ticket.


Same Task, Two Ways

Here is the same task implemented both ways. The task: take a support ticket string and return a one sentence summary.

// LangChain approach — @langchain/anthropic + @langchain/core
import { ChatAnthropic } from "@langchain/anthropic";
import { HumanMessage } from "@langchain/core/messages";

const model = new ChatAnthropic({
  model: "claude-3-5-sonnet-20241022",
  apiKey: process.env.ANTHROPIC_API_KEY,
});

const response = await model.invoke([
  new HumanMessage("Summarize this support ticket in one sentence: " + ticket),
]);

// response is an AIMessage — content is a string here, but
// the shape changes across invoke / stream / generate / batch
console.log(response.content);
Enter fullscreen mode Exit fullscreen mode
// Raw Anthropic SDK — @anthropic-ai/sdk
import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic();

const response = await client.messages.create({
  model: "claude-3-5-sonnet-20241022",
  max_tokens: 256,
  messages: [
    {
      role: "user",
      content: "Summarize this support ticket in one sentence: " + ticket,
    },
  ],
});

// response.content is a typed ContentBlock array — no shape surprises
console.log(response.content[0].text);
Enter fullscreen mode Exit fullscreen mode

The raw SDK version tells you everything: the model name, max_tokens (LangChain has a default you have to look up), and the exact message structure being sent. When something blows up, you know exactly where to look.

The LangChain version hides the request behind invoke, and the response shape silently changes depending on which invocation method you used. That is the kind of thing that bites you at 2am when one code path calls stream instead of invoke and suddenly response.content is a generator.


The Cost Reality

For LLM cost optimization, the raw SDK gives you direct control over prompt caching breakpoints. Anthropic offers a 90% discount on cached tokens vs OpenAI's 50%. When you set cache control points explicitly in the raw SDK, you capture that discount precisely. LangChain's message wrappers do not expose this at the same granularity, so you are often leaving money on the table.

The more concrete cost story is LangSmith. LangSmith adds $39 per month for 10,000 traces, with $0.50 per 1,000 after that. For a pipeline running 50,000 calls a month, that is an extra $59 on top of your LLM API bill.

// Rough monthly cost model for a simple summarization pipeline
// Scenario: 10,000 calls/month, ~2,000 tokens each

const llmCostPerMonth = 10_000 * 0.000003 * 2_000; // roughly $60/month in LLM costs

// Raw SDK only — pay the API cost
const costWithoutLangSmith = llmCostPerMonth; // $60

// With LangSmith at 10K traces/month (exactly at the base cap)
const langsmithBase = 39; // $39/month for 10K traces
const costWithLangSmith = llmCostPerMonth + langsmithBase; // $99

// At 50K calls/month, overage kicks in
const langsmithAt50K = 39 + 40 * 0.5; // $59 extra = $119 total non-LLM tooling cost
Enter fullscreen mode Exit fullscreen mode

Teams that have moved to the native SDK report roughly a 40% reduction in API expenses. Another case study found LangChain incurred 2.7x higher costs compared to a manual implementation for a simple RAG system. That delta is not from the LLM provider. It is from auxiliary tooling and inefficient prompt routing that disappears when you own the code path directly.


When LangChain IS the Right Call

This is not a LangChain hit piece. The framework earns its weight in specific scenarios.

If you are building a multistep agent that calls tools, decides which tool based on the last output, maintains memory across a conversation, and routes to different subchains based on intent, the raw SDK will make you hand roll all of that. For anything with tool use at that depth, check the function calling guide and then honestly evaluate whether LangChain's abstractions pay off for your pipeline shape.

Similarly, if your team is switching between OpenAI, Anthropic, and Gemini and you want a single interface, LangChain's model agnostic layer is worth it. The Vercel AI SDK is also worth a look if you are in a Next.js context and want native streaming and RSC integration at a lighter weight than LangChain.

The rough rule: fewer than three steps and a single model? Reach for the raw SDK. Conditional routing, tool use, or multiprovider switching? Evaluate the abstraction cost honestly before committing.


Making the Call

The teams I have seen migrate away from LangChain consistently name the same two friction points: debugging and production stability. When a call fails inside a LangChain chain, the stack trace gives you LangChain internals rather than the raw request that was sent. You end up adding log statements at multiple layers just to figure out what actually went to the model.

With the raw SDK, there is nothing between you and the API. The request body is a plain object you can log, diff, and replay. The response is typed and predictable. When costs spike, you can trace it to a specific call site without parsing through abstraction layers.

Start with the raw SDK for anything simple. You will understand your token usage better, debug faster, and avoid the LangSmith subscription until you genuinely need the observability it provides. Reach for an abstraction layer when your pipeline complexity demands it, not as the default starting point.


If you want a deeper look at LLM cost optimization, I cover it in more detail on my site.

If you want this wired up on your own site end to end, that is exactly the kind of work I take on.


Drop a comment if you have made the same switch. Curious what the migration looked like for your team.

Top comments (0)