$cat ~/blog/abstraction-is-cope.md | glow

Abstraction Is Cope (LangChain Is Proof)

3 min read

If you've spent any time with LangChain, you know the feeling. You wanted to call an LLM API. You ended up in a class hierarchy trying to figure out what a SequentialChain does differently from a SimpleSequentialChain and whether either of them matters.

It's a good example of what happens when abstraction goes wrong. And abstraction goes wrong constantly.

#The Bet

Every abstraction is a bet that the details you're hiding won't matter later.

ORM over raw SQL: betting query shape won't matter. Repository pattern over direct DB calls: betting you'll never need a specific operation. Clean API wrapper over a messy service: betting the mess stays contained.

Most of these bets pay off. The ones that don't are expensive.

Joel Spolsky called this the Law of Leaky Abstractions: all non-trivial abstractions leak. The details you buried will surface, usually at a bad time and always in a confusing way.

#LangChain: A Case Study in Losing the Bet

The OpenAI API is not complicated. You send a list of messages, you get a response back.

LangChain looked at this and said: what if we added chains, agents, tools, memory, callbacks, retrievers, document loaders, output parsers, and enough custom classes that the GitHub repo needs a map?

The abstraction was supposed to make LLM apps easier. Instead you spend your time learning LangChain instead of learning the actual problem you're solving. When it calls your model in an unexpected way, when the prompt template does something weird, when you need to do anything slightly off the happy path, you're reading source code trying to figure out which of the four base classes is responsible.

The underlying API is simple. They kept adding layers until the abstraction cost more than the boilerplate it replaced.

#Why We Do It Anyway

Because you can't hold full system complexity in your head. So you abstract, knowing the abstraction is incomplete, because a useful approximation beats paralysis.

The problem isn't abstracting. It's forgetting that you made a bet. At some point the abstraction becomes the thing you're working around instead of the thing helping you work.

#The Part That Actually Matters

When you build an abstraction, ask what details you're hiding and what happens when those details matter.

The best abstractions leak in obvious places you can handle. The worst hide complexity behind more complexity, so when something breaks you're debugging the wrapper instead of the problem.

Know what you're hiding. Know when to stop hiding it.

$tail -f comments.log
Loading comments...