Why most AI agent frameworks are elaborate solutions to problems you probably don't have — and why Claude Code in a terminal window beats all of them.
Somewhere around 2023, the AI tooling world collectively decided that "agent" was a word that required infrastructure. Suddenly, building an AI that does something useful meant choosing between LangChain, AutoGPT, CrewAI, LlamaIndex, Flowise, n8n, AgentGPT, BabyAGI, SuperAGI, or whichever one was trending on Hacker News that Tuesday. Each promised to abstract away the complexity of "agentic AI" behind a clean, composable, production-ready™️ framework.
What they actually delivered was a new layer of complexity between you and the thing you were trying to build.
This is the story of how a Telegram support bot for a DeFi platform ended up being the clearest argument against all of it.
Let's be generous. The pitch for AI agent frameworks is real:
Orchestration — chain multiple LLM calls together
Memory — persist context across turns
Tool use — let the model call functions, search the web, query databases
RAG pipelines — retrieve relevant knowledge before answering
Multi-agent coordination — have agents delegate to sub-agents
Observability — see what your agents are doing
Impressive list. Now let's look at what you actually get when you install one.
LangChain, to pick the most famous example, ships with over 200 integrations, its own expression language (LCEL), a separate server product (LangServe), a tracing platform (LangSmith), and enough abstractions that a simple "summarize this document" task requires understanding Runnable, Chain, AgentExecutor, BaseTool, PromptTemplate, and at least three different ways to configure memory. The documentation is roughly the length of a small novel. The GitHub issues are rougher.
AutoGPT, the viral 2023 project that promised "autonomous AI agents," shipped with a requirements.txt that reads like a pharmaceutical insert. It also had a habit of looping indefinitely and spending your entire API budget on tasks that could have been a single prompt.
CrewAI is newer and more sensible, but the moment you want to do anything non-standard, you're reading source code and filing issues.
The pattern is consistent: these frameworks were built for the general case. You are not the general case. You have a specific problem, and you're now maintaining someone else's abstraction layer on top of it.
Here is a real production system. It replies to support questions in a Telegram group for a DeFi trading platform. It has local knowledge retrieval. It handles question classification, issue detection, and reply routing. It has been running reliably since v1.
The entire architecture fits in one diagram:
Telegram group → polling
↓
detectQuestion / detectIssue
↓
memvid.find() ← knowledge.mv2 (local BM25)
↓
stdout (JSON + memvidContext)
↓
Claude Code /loop
(reads context, crafts reply)
↓
POST /send → TelegramThe relay is ~150 lines of TypeScript. There is no LLM SDK in the package.json. The dependencies field lists four packages: dotenv, express, node-telegram-bot-api, and a local BM25 search library. That's it.
The "AI" part — the bit that reads messages, reasons about them, and decides what to say — is Claude Code running in a terminal, executing a /loop skill every two minutes. The loop reads a JSON file, skips already-processed messages, classifies each one against a skill definition in a markdown file, and fires a curl command to send the reply.
The "RAG pipeline" is a BM25 search over a .mv2 file that runs entirely on-device in sub-milliseconds. No vector database. No embedding API. No Pinecone/Weaviate/Qdrant instance to provision and pay for.
The "memory" is a JSON array of processed message IDs written to .processed_ids.json. Delete the file to reprocess. Add an ID to skip a message. It is the least impressive memory system in the history of AI agents, and it works perfectly.
What this architecture is, at its core, is a Unix pipeline.
The relay is a program that reads from one source (Telegram polling) and writes to one destination (stdout). It does one thing and does it well. The LLM consumer is a separate process that reads from a file and writes HTTP requests. It also does one thing. They are connected by a file on disk, which is the most battle-tested inter-process communication mechanism ever invented.
Ken Thompson and Dennis Ritchie worked this out in 1969. The AI agent framework community is still catching up.
ClaudeCode slots into this pattern naturally because it is a terminal tool. It doesn't need to own your infrastructure. It doesn't need to be the orchestrator. You can hand it a JSON file, a markdown spec, and a curl command, and it will run your support operation indefinitely. The /loop skill is just a cron job that speaks English.
What do you get with this approach that you don't get from a framework?
Debuggability. Every message that flows through the system is a plain JSON object in a flat file. You can read it with cat. You can filter it with grep. You can replay it by deleting .processed_ids.json. There is no framework state to inspect, no graph execution trace to decode.
Replaceability. Want to swap Claude for GPT-4o? The relay doesn't care. It speaks stdout. Want to add a human review step before replies go out? Intercept the curl calls. Want to log everything to a database? Pipe stdout somewhere else. Every piece is independently swappable because no piece owns the others.
Zero dependency rot. LangChain has broken its own API multiple times across major versions. The ecosystem around it moves fast and deprecates aggressively. This project's package.json has four runtime dependencies, three of which are utilities that have been stable for years.
Honest complexity. The code is as complex as the problem requires. There is no base class to extend, no interface to implement, no plugin architecture to navigate. When something breaks, the stack trace points directly at your code.
The inevitable objection: this works for a small Telegram bot, but what about a real agentic system? Multi-step reasoning, parallel tool calls, complex workflows?
Fair question. Here is a direct answer: most production AI applications are not doing multi-step reasoning across five parallel sub-agents. They are doing one of three things:
Answering a question based on a knowledge base
Classifying some input and taking an action
Generating content given a structured prompt
For all three, you need a good LLM, a clear system prompt, and a mechanism to feed it context. You do not need a framework.
When you genuinely need orchestration — say, a code review pipeline that runs static analysis, generates suggestions, and posts to GitHub — Claude Code handles this natively. The /schedule skill creates cron jobs. The Agent tool spawns specialized sub-agents. You can chain these with shell pipes and environment variables, tools every developer already knows.
The framework is Claude Code itself, and it runs in a terminal you already have open.
Here is the part the framework READMEs don't show you: operational overhead.
When you deploy a LangChain application to production, you're also deploying LangChain. That means:
Keeping the framework version pinned or riding the upgrade treadmill
Debugging failures that originate inside framework abstractions you didn't write
Explaining to new team members how the framework's mental model maps to your actual use case
Paying for LangSmith or building your own observability because the framework made the execution opaque
When you deploy a TypeScript relay + Claude Code loop, you're deploying TypeScript and a shell command. The operational surface area is proportional to what you actually built.
There is a concept in systems design called accidental complexity — complexity introduced by your tools rather than your problem. Framework-heavy AI stacks are accidental complexity machines. They take an inherently simple problem (call an LLM, do something with the result) and wrap it in enough ceremony that the original problem becomes hard to see.
Not all LLM-as-terminal tools are equal. Claude Code earns its place here for specific reasons.
It reads files natively. The entire pattern of "pipe JSON to a file, let the AI read it" only works if the AI actually understands files as a first-class primitive. Claude Code does. It can read messages.json, cross-reference SKILL.md, check .processed_ids.json, and compose a decision without you writing a single line of orchestration code. The file system is the interface.
Skills are markdown. The classification rules for this bot are defined in SKILL.md — a markdown file describing when to respond, how to respond, and what tone to use. No Python classes. No JSON schema. No DSL. Just prose, which Claude Code reads, interprets, and applies. When the rules need updating, you edit a markdown file.
/loop is a production-grade cron. The loop skill isn't a demo feature. It tracks state across runs, respects processed IDs, and handles edge cases (system messages, missing context, null fields) because the model reasons about them rather than routing through a decision tree you hardcoded.
The terminal is the debugger. When the loop misbehaves, you watch it run. The output is visible. The reasoning is visible. You can interrupt, adjust the prompt, and restart. Compare this to debugging a LangGraph execution trace.
The AI agent framework market is, to be blunt, a lot of yak shaving dressed up as infrastructure. The frameworks exist because framework-building is a legible engineering contribution that produces GitHub stars and VC slides. Actually solving the problem with the minimal viable toolset is less visible but more effective.
This Telegram bot replies to DeFi support questions accurately, classifies issues without false positives, retrieves relevant knowledge without a vector database, and runs unattended. It was built in a weekend. The code fits in a few hundred lines. It has no framework dependencies.
Two terminals, one JSON file, and Claude Code.
You probably don't need more than that either.

