在 2026 年的今天,单纯调用大模型(LLM)接口已经不再是核心竞争力。Agent(智能体) 才是 AI 落地的关键。
很多开发者在面试或实战中容易陷入一个误区:认为 Agent 就是"直接调用大模型接口"。实际上,原生的 LLM 是无状态(Stateless) 的,它记不住你上周聊过什么,也无法直接访问你的私有数据库或操作你的电脑文件。
本文将带你深入剖析 Agent 的底层架构,并结合 LangChain 与 Node.js 代码,手撸一个高性能的 Agent 核心逻辑。
🧠 一、 什么是 Agent?不仅仅是聊天
LLM 就像一个被关在密室里的天才,它博学多才,但与世隔绝。Agent 的工作,就是给这个天才装上"眼睛"、"耳朵"和"手"。
1. Agent 的核心公式
一个完整的 Agent 系统由以下模块组成:
Agent = LLM(大脑) + Memory(记忆) + Tools(工具) + RAG(知识库) + Planning(规划)
- LLM (Large Language Model): 负责推理、规划和决策。
- Memory (记忆模块): 解决 LLM 无状态的问题。通过数据库(Redis/SQL)存储历史对话,让 Agent 记住上下文。
- Tools (工具调用): 让 LLM 能够执行动作。比如访问网页、读写文件、执行代码。
- RAG (检索增强生成): 解决 LLM 知识滞后的问题。通过查询私有文档或最新新闻,补充上下文。
- Skills/Planning: 复杂任务的拆解能力。
2. 市场上的 Agent 形态
- Claude Code / Codex: 专注于代码编写的 Agent。
- Manus / 小龙虾: 专注于自动化任务的通用 Agent。
🛠️ 二、 核心技术拆解:LangChain 与 Tool Use
在开发中,我们通常使用 LangChain 这样的框架来屏蔽底层差异。它兼容 OpenAI、DeepSeek 等各种模型,并提供了标准化的 Tool 接口。
1. 为什么需要 Tool?
LLM 只能输出文本,无法直接操作文件系统。我们需要定义一个 Tool,告诉 LLM:"如果你需要读文件,请按照这个格式告诉我,我来帮你执行。"
2. 代码实战:手写一个文件读取 Tool
结合你的笔记,我们来看如何用 LangChain.js 定义一个工具。这里涉及到了 Zod 进行参数校验,以及 fs/promises 进行异步文件操作。
typescript
编辑
javascript
1import { tool } from '@langchain/core/tools';
2import { z } from 'zod';
3import fs from 'node:fs/promises';
4
5// 定义一个读取文件的工具
6const readFileTool = tool(
7 // 1. 执行函数:真正干活的逻辑
8 async ({ filePath }) => {
9 const content = await fs.readFile(filePath, 'utf-8');
10 console.log(`[工具调用] 成功读取 ${filePath}`);
11 return content;
12 },
13 {
14 // 2. 元数据:告诉 LLM 这个工具是干嘛的
15 name: 'read_file',
16 description: `用此工具来读取文件内容。当用户要求读取文件、查看代码时调用。`,
17 // 3. Schema:严格的参数约束,LLM 必须按此格式输出
18 schema: z.object({
19 filePath: z.string().describe('要读取的文件路径,支持相对或绝对路径')
20 })
21 }
22);
面试考点:
- Zod 的作用? 它是类型安全的 Schema 定义库。它既给 LLM 看(告诉它参数长什么样),也给代码看(运行时校验参数是否合法)。
- Tool 的返回机制? LLM 不会直接执行函数,而是生成一个
tool_calls指令。系统捕获指令 -> 执行函数 -> 将结果作为ToolMessage传回给 LLM -> LLM 生成最终回复。
⚡ 三、 性能优化:Agent 的"多任务"处理
在构建复杂 Agent 时,我们经常需要同时调用多个工具(例如:同时搜索天气和新闻)。这就涉及到了 JavaScript 的异步并发控制。
这是面试中的高频考点:串行 vs 并行。
1. 场景模拟
假设我们有两个异步任务:
getWeather(): 耗时 2000msgetTweets(): 耗时 500ms
2. 错误示范:串行执行 (Serial)
如果你使用 await 逐个调用,总耗时将是两者之和。
javascript
编辑
javascript
1async function main() {
2 console.time("serial");
3 // 必须先等天气查完,才开始查推文
4 const weatherData = await getWeather(); // 等待 2000ms
5 const tweetsData = await getTweets(); // 再等待 500ms
6 console.timeEnd("serial"); // 总耗时 ≈ 2500ms
7}
3. 正确示范:并行执行 (Parallel)
使用 Promise.all,让任务同时启动。这是高性能 Agent 的必备技能。
javascript
编辑
javascript
1async function main() {
2 console.time("parallel");
3 // Promise.all 接收一个 Promise 数组,并发执行
4 const [weatherData, tweetsData] = await Promise.all([
5 getWeather(), // T=0ms 启动
6 getTweets() // T=0ms 启动
7 ]);
8 console.timeEnd("parallel"); // 总耗时 ≈ 2000ms (取决于最慢的那个)
9}
4. 深度解析:Promise 的状态与机制
- Promise 状态:
pending(进行中) ->fulfilled(成功) /rejected(失败)。状态一旦改变,就凝固了。 - async/await: ES8 提供的语法糖,让异步代码看起来像同步代码,但本质还是基于 Promise。
- 关键点:
Promise.all只有在所有 Promise 都 resolve 时才会 resolve;只要有一个 reject,整体就会报错(可以使用Promise.allSettled来避免这个问题)。
🏗️ 四、 全栈架构:Harness Engineering
要打造一个商业级的 Agent 产品,我们需要完整的全栈技术栈:
表格
| 层级 | 技术选型 | 作用 |
|---|---|---|
| 前端 | React + Vite | 极速的用户交互界面,展示 Agent 的思考过程 |
| 后端 | Node.js (NestJS) | 业务逻辑处理,API 网关,鉴权 |
| Agent 框架 | LangChain / LangGraph | 编排 LLM、Tools 和 Memory,处理复杂的多步任务 |
| 模型层 | DeepSeek / OpenAI | 提供基础智力 |
| 记忆/数据 | Redis / PostgreSQL | 存储长期记忆和向量数据 |
Harness Engineering (驾驭工程) 的核心在于:不仅仅是调用 API,而是通过工程化手段(如重试机制、缓存、并发控制、监控)让不稳定的 LLM 变成稳定的生产力工具。
📝 五、 总结与复习清单
如果你正在准备 AI 相关的面试,请确保你能回答以下问题:
- Agent 的组成是什么? (LLM + Memory + Tools + RAG)
- LangChain 中的 Tool 是如何工作的? (定义 Schema -> LLM 生成 Tool Call -> 执行函数 -> 回传结果)
- 如何处理多个异步任务? (区分
Promise.all并行和await串行的性能差异) - Zod 在 Agent 开发中的作用? (类型校验与 LLM 提示词生成的桥梁)
- 为什么 LLM 需要 Memory? (因为 LLM 本质是无状态的 Stateless)
掌握这些,你就掌握了通往 AI 全栈工程师 的钥匙。加油!