🧠 LangChain Agent 入门:为什么直接调大模型 API 远远不够?
摘要:你是不是也以为 Agent 就是调个 OpenAI API?本文从一个真实场景出发,带你理解 Agent 的本质 ------ 给大模型装上"记忆"、"工具"和"知识库",让它从"只会说"变成"能做事"。
📌 前言
上周有个朋友问我:"我想做个能帮我写代码的 AI 助手,直接调 OpenAI 的 API 不就行了?"
我反问了他几个问题:
- 你上周和它聊过的代码,它还记得吗?
- 让它帮你创建一个 React 项目,它能做到吗?
- 你们公司的内部技术文档,它知道吗?
他沉默了。
这就是为什么我们需要 Agent。
🎯 本文适合谁
- 用过 ChatGPT / OpenAI API,但想更进一步的同学
- 听过 Agent 但不太清楚它和普通 API 调用有什么区别的同学
- 想用 JavaScript/Node.js(而非 Python)做 AI 开发的前端/全栈工程师
📚 一、直接调 LLM API 的五大痛点
很多人做 AI 应用的第一步就是:
javascript
import OpenAI from 'openai';
const client = new OpenAI();
const response = await client.chat.completions.create({
model: 'gpt-4',
messages: [{ role: 'user', content: '你好' }]
});
能跑通,但很快你会遇到这些问题:
痛点 1:无记忆(Stateless)
大模型是无状态的。每次调用都是独立的,它不记得你上一轮说了什么。
用户:我叫张三
AI:你好,张三!
用户:我叫什么?
AI:抱歉,我不知道你叫什么。
解决方案:Memory 模块 ------ 把历史消息存下来,每次调用时带上。
痛点 2:不能执行(只能想,不能做)
你让大模型"帮我读一下 src/index.mjs 的内容",它会给你一段思路:
"你可以用 Node.js 的 fs.readFile 方法来读取文件......"
但它不会真的去读。它只能告诉你怎么做,不能帮你做。
解决方案:Tool 模块 ------ 给大模型装上"手脚",让它能调用函数。
痛点 3:知识有限(不知道你的私有数据)
大模型的训练数据是公开的。你们公司的内部文档、私有的 API 接口、项目的配置文件 ------ 它一概不知。
解决方案:RAG(检索增强生成)------ 让大模型先查知识库,再回答。
痛点 4:信息过时(训练数据有截止日期)
"2026 年世界杯冠军是谁?" ------ 如果模型的训练数据截止到 2024 年,它就答不上来。
解决方案:MCP(Model Context Protocol)------ 让大模型能调用第三方工具(搜索、API 等)获取实时信息。
痛点 5:不会规划(复杂任务一步到位)
你让它"帮我创建一个 React 项目,添加 TodoList 功能,安装依赖,启动开发服务器",它可能直接给你一坨代码,但不会分步骤执行。
解决方案:Skills / Planning ------ 让大模型能拆解任务、分步执行。
📚 二、Agent 的本质
把上面的解决方案组合起来,就是 Agent 的公式:
ini
Agent = LLM + Memory + Tool + RAG + MCP + Skills
用一张图来理解:
markdown
用户提出复杂任务
↓
┌─────────────────────────────────┐
│ Agent(智能体) │
│ │
│ 🧠 LLM → 大脑(思考/推理) │
│ 💾 Memory → 记忆(上下文) │
│ 🔧 Tool → 手脚(执行操作) │
│ 📚 RAG → 知识库(私有数据) │
│ 🔌 MCP → 外部接口(第三方) │
│ ⚡ Skills → 技能(任务编排) │
│ │
└─────────────────────────────────┘
↓
返回结果给用户
一句话总结:Agent 就是给大模型装上记忆、工具和知识库,让它从"只会说"变成"能做事"。
📚 三、Agent 的工作流程
markdown
用户提交任务(Prompt)
↓
Agent 接收任务
↓
LLM 规划/推理(Planning/Reasoning)
↓
┌──────────────────────────────────┐
│ 需要加载 Memory? → 加载历史上下文 │
│ 需要调用 Tool? → 执行工具获取结果 │
│ 需要查询 RAG? → 检索知识库 │
└──────────────────────────────────┘
↓
组装结果 → 返回给用户
关键点:LLM 负责"想",Tool 负责"做"。
- LLM 决定:我需要调用哪个工具?传什么参数?
- Tool 执行:读文件、写代码、调 API......
- LLM 再决定:拿到结果后,下一步做什么?
这个"想 → 做 → 想 → 做"的循环,就是后面我们要讲的 ReAct 模式。
📚 四、LangChain.js ------ Agent 开发框架
为什么需要框架?
你可以从零手写 Agent(直接调 OpenAI API + 自己管理消息 + 自己处理 tool_calls),但会很痛苦:
- 要自己拼 messages 数组
- 要自己解析 tool_calls
- 覣自己处理工具执行结果
- 要自己做错误处理和重试
LangChain 帮你封装了这些脏活累活。
框架对比
| 框架 | 语言 | 定位 | 适合场景 |
|---|---|---|---|
| LangChain | Python / JS | 单智能体开发框架 | Agent、Chain、Tool 开发 |
| LangGraph | Python / JS | 多智能体开发框架 | 复杂工作流、多 Agent 协作 |
| Vercel AI SDK | TypeScript | 前端 AI SDK | 前端集成、流式输出 |
| Semantic Kernel | C# / Python / Java | 微软 AI 框架 | 企业级应用 |
我们选 LangChain.js,原因:
- 前端工程师用 JS/TS 更顺手
- Tool 抽象做得非常好
- 社区生态最完善
📚 五、LangChain.js 快速上手
安装依赖
bash
pnpm add @langchain/core @langchain/openai zod dotenv
| 包 | 作用 |
|---|---|
@langchain/core |
LangChain 核心,提供 Tool、Message、Chain 等抽象 |
@langchain/openai |
OpenAI 兼容的 LLM 封装(支持自定义 baseURL) |
zod |
TypeScript 优先的参数校验库,给 Tool 定义 schema |
dotenv |
环境变量管理,读取 .env 文件 |
环境变量配置
创建 .env 文件:
env
MIMO_MODEL=gpt-4
MIMO_API_KEY=sk-xxxx
MIMO_API_BASE_URL=https://api.openai.com/v1
💡 提示 :
MIMO_API_BASE_URL可以改成任何 OpenAI 兼容的 API 地址,比如 DeepSeek、Moonshot、本地 Ollama 等。这就是 LangChain "模型无关"的优势。
第一次调用 LLM
javascript
import { ChatOpenAI } from '@langchain/openai';
import 'dotenv/config';
// 创建模型实例
const model = new ChatOpenAI({
modelName: process.env.MIMO_MODEL,
apiKey: process.env.MIMO_API_KEY,
configuration: {
baseURL: process.env.MIMO_API_BASE_URL,
}
});
// 调用模型
const response = await model.invoke('你好,请介绍一下你自己');
console.log(response.content);
model.invoke() 返回了什么?
javascript
{
content: '你好!我是一个AI助手...', // 文本内容
tool_calls: [], // 工具调用列表(后面会讲)
response_metadata: { ... }, // 元数据
usage_metadata: { ... }, // token 使用量
}
现在 tool_calls 是空的,因为我们还没给模型绑定工具。下一篇讲 Tool 的时候,你就会看到它有值了。
📚 六、LangChain 的 Message 体系
LangChain 定义了 4 种消息类型,对应 OpenAI API 的 role:
javascript
import {
SystemMessage, // role: 'system' → 系统提示词,定义 AI 的行为
HumanMessage, // role: 'user' → 用户消息
AIMessage, // role: 'assistant' → AI 回复(可能包含 tool_calls)
ToolMessage, // role: 'tool' → 工具执行结果
} from '@langchain/core/messages';
| 消息类型 | 对应 role | 谁发的 | 用途 |
|---|---|---|---|
SystemMessage |
system |
开发者 | 定义 AI 的角色、行为规则 |
HumanMessage |
user |
用户 | 用户的输入 |
AIMessage |
assistant |
AI | AI 的回复,可能包含 tool_calls |
ToolMessage |
tool |
开发者 | 工具执行的结果,回传给 AI |
使用示例
javascript
const messages = [
new SystemMessage('你是一个代码助手,可以使用工具读取文件'),
new HumanMessage('请帮我读取 src/index.mjs 文件'),
];
const response = await model.invoke(messages);
🔑 为什么要用 LangChain 的 Message 类? 而不是直接传
{ role: 'user', content: '...' }?因为 LangChain 的 Message 类提供了类型安全、额外的元数据支持,以及和 Tool 系统的无缝集成。
💡 重点总结
-
直接调 API 的五大痛点:无记忆、不能执行、知识有限、信息过时、不会规划。
-
Agent 的本质 :
Agent = LLM + Memory + Tool + RAG + MCP + Skills,给大模型装上"能力扩展"。 -
Agent 的核心逻辑:LLM 负责"想"(规划、推理),Tool 负责"做"(执行操作)。
-
LangChain.js 的价值:封装了消息管理、Tool 调用、错误处理等脏活累活,让你专注于业务逻辑。
-
模型无关 :通过
baseURL可以对接任何 OpenAI 兼容的 API,不被某个模型绑定。
🔗 参考资料
💬 交流讨论
这是 LangChain Agent 系列的第一篇。下一篇我们会深入讲解 Tool Calling 机制 ------ 让大模型真正"动手做事"的核心原理。
你对 Agent 开发有什么疑问?欢迎评论区交流!
觉得有用?点个赞👍收藏⭐关注👆,下一篇深入 Tool Calling 的底层逻辑!
📎 标签 :
LangChain、AI Agent、JavaScript、Node.js、大模型