跪拜 Guibai
← All articles
Agent · JavaScript

An LLM Alone Is a Stateless Chatbot. Five Plugins Turn It Into an Agent.

By bonechips ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

Most developers still treat LLMs as chatbots. The Agent architecture is what turns them into autonomous workers that can read files, query APIs, and chain actions. The performance gap between serial and parallel tool execution is the difference between a demo and something that ships.

Summary

Large language models are stateless next-token predictors. They don't remember past conversations, can't open files, and know nothing about your internal docs. The Agent pattern fixes this by attaching five external modules: Memory for recall, Tools for executing functions, RAG for document retrieval, MCP for real-time data, and Skills for reusable multi-step workflows. Claude Code and Manus both follow this same architecture of planning, tool selection, and execution.

LangChain provides a unified layer that makes swapping between DeepSeek, GPT, or other models a one-line config change. Tools are defined as a handler function paired with a name, a Zod schema, and a description that the LLM reads to decide when to invoke it. A poorly written description means the model will miss or misuse the tool.

When an LLM returns multiple independent tool calls, running them serially adds up every delay. Promise.all executes them concurrently so total latency equals the slowest call, not the sum. That single change is the first rule of Agent performance tuning.

Takeaways
An LLM alone is stateless and cannot call external functions; an Agent adds Memory, Tools, RAG, MCP, and Skills to give it state and action capabilities.
LangChain's ChatOpenAI class accepts any OpenAI-compatible endpoint, so swapping DeepSeek for GPT requires only a baseURL and API key change.
A tool in LangChain is a function plus a Zod schema plus a description string; the LLM reads the description to decide when and how to call it.
Tool descriptions are the UI between the model and your code — vague descriptions cause missed or incorrect tool invocations.
After an LLM returns tool_calls, the runtime must execute the tools, inject the results back into the message history as ToolMessage objects, and call the LLM again for a final answer.
Promise.all runs independent tool calls concurrently, capping total latency at the slowest call rather than adding every call's duration.
Logging inside tool functions with console.log gives users visibility into long-running Agent tasks and prevents them from abandoning the session.
Conclusions

The five-plugin model (Memory, Tool, RAG, MCP, Skills) is a useful taxonomy, but MCP is really just a standardized subset of Tools — the distinction matters less in practice than the article suggests.

LangChain's value proposition has shifted from 'framework for chaining prompts' to 'model-agnostic Agent runtime,' which explains why it remains relevant even as OpenAI's own SDK improves.

The emphasis on tool descriptions as the critical interface between LLM reasoning and code execution is underappreciated in most Agent tutorials, which focus on function signatures instead.

Promise.all for tool execution is obvious in hindsight, but many LangChain examples still use sequential for...of loops, creating a performance trap that's easy to fall into.

Concepts & terms
Agent
An LLM augmented with external modules — Memory, Tools, RAG, MCP, and Skills — that allow it to plan, call functions, retrieve information, and execute multi-step tasks autonomously rather than just generating text.
Tool (in LangChain)
A function wrapped with a name, a natural-language description, and a Zod schema. The LLM reads the description to decide when to invoke the tool, and the schema constrains what arguments it can pass.
Promise.all
A JavaScript method that takes an array of Promises and returns a single Promise that resolves when all input Promises have resolved. It runs them concurrently, so total time equals the slowest operation rather than the sum of all operations.
tool_calls
A field in an AIMessage where the LLM specifies which tools to invoke and with what arguments. The runtime reads this field, executes the corresponding functions, and returns the results as ToolMessage objects.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗