AI Agent 的四肢:Node.js 内置模块实战指南

不用装任何第三方包,Node.js 自带了一套"操作系统级"工具箱。这是 Agent 能干活的基础。


开发 AI Coding Agent 时,有一个很容易被忽略的事实:Agent 的"大脑"是模型,但"四肢"全是 Node.js 的内置模块。

读文件用 fs,拼路径用 path,执行命令用 spawn,读用户输入用 readline------全都是 import 就能用的东西,不需要 npm install

这篇文章逐一拆解 Agent 开发中最关键的六个内置模块,每个都附带项目中的真实代码。


一、fs/promises --- 文件系统

Agent 最核心的能力:读写文件。fs/promises 是 Promise 版本的 fs,配合 async/await 使用。

1.1 读取文件

js 复制代码
import fs from 'node:fs/promises'

const content = await fs.readFile('/project/src/App.tsx', 'utf8');
// 返回文件全部内容,编码 utf8
// 文件不存在会抛异常 → catch 后返回错误信息给模型

项目中的完整实现(readFileTool.js):

js 复制代码
export const readFileTool = tool(
    async ({ filePath }) => {
        try {
            const content = await fs.readFile(filePath, 'utf8');
            return content;  // 原样返回给模型
        } catch (err) {
            return `读取文件 ${filePath} 失败: ${err.message}`;  // 不抛异常
        }
    },
    { name: 'read_file', /* ... */ }
)

1.2 写入文件

js 复制代码
// 自动创建不存在的父目录
await fs.mkdir('/project/src/components', { recursive: true });
// recursive: true → 相当于 mkdir -p,父目录不存在就逐级创建

// 写入内容
await fs.writeFile('/project/src/App.tsx', content, 'utf8');

recursive: true 是精华:Agent 经常要在尚不存在的深层目录创建文件,这个参数让它不需要先检查目录是否存在。

1.3 列出目录

js 复制代码
const files = await fs.readdir('/project/src');
// → ['App.tsx', 'main.tsx', 'components', 'utils']

三个方法就构成了 Agent 的文件操作闭环:查看有哪些文件 → 读取内容 → 修改后写回


二、path --- 路径操作

Windows 用 \,Linux/Mac 用 /。手写字符串拼接迟早出问题。path 模块的存在意义就是跨平台处理路径

2.1 三个核心方法

js 复制代码
import path from 'node:path'

// 拼接路径 --- 自动适配系统分隔符
path.join('project', 'src', 'App.tsx')
// Windows → 'project\\src\\App.tsx'
// Linux   → 'project/src/App.tsx'

// 取文件所在目录
path.dirname('/project/src/App.tsx')
// → '/project/src'

// 取文件名
path.basename('/project/src/App.tsx')
// → 'App.tsx'

2.2 在 writeFileTool 中的应用

Agent 写文件时,需要从路径字符串提取目录部分来创建文件夹:

js 复制代码
// 用户想写 '/project/src/components/Header.tsx'
const dir = path.dirname(filePath);
// dir = '/project/src/components'

await fs.mkdir(dir, { recursive: true });
// 确保目录存在,不存在就逐级创建

await fs.writeFile(filePath, content, 'utf8');
// 写入文件

path.dirname 而不是正则或字符串替换,因为路径格式多变:./src/file/project/filesrc\\file------只有 path 模块能稳定处理所有情况。

2.3 扩展方法

js 复制代码
path.extname('/project/App.tsx')      // → '.tsx'
path.resolve('src', 'tools')          // → 'D:/project/min-cursor/src/tools'  (绝对路径)
path.relative('/a/b/c', '/a/b/d')     // → '../d'

三、child_process --- 执行命令

这是 Agent 最复杂的能力------替用户在终端里敲命令。

3.1 spawn:启动子进程

js 复制代码
import { spawn } from 'node:child_process'

const child = spawn('pnpm', ['install', '--save', 'react'], {
    cwd: '/project/subdir',     // 工作目录(相当于先 cd 进去)
    env: process.env,            // 继承当前环境变量(PATH 等)
    stdio: 'inherit',            // 子进程输出直接显示在终端
    shell: 'bash.exe',           // 用哪个 shell 解析命令
});

五个参数逐个解释:

参数 类型 含义
cmd string 要执行的程序名
args string\[\] 传给程序的参数
cwd string Current Working Directory,在哪个目录执行
env object 环境变量,通常传 process.env 继承当前
stdio string 'inherit' = 实时输出到终端;'pipe' = 用代码收集
shell string|boolean 用哪个 shell 解析命令

3.2 shell 为什么重要

AI 生成的不只是 pnpm install 这么简单的命令。它经常写:

bash 复制代码
echo -e "n\nn" | pnpm create vite app --template react-ts

这行命令包含:

  • echo:shell 内置命令,不是可执行文件
  • |:管道,把一个命令的输出传给另一个
  • -e:让 echo 解析 \n 为换行符

不加 shell 参数,这几个特性全不能工作。Windows 上默认 shell 是 cmd.exe(不兼容 bash 语法),所以要显式指定 Git Bash 路径。

3.3 监听子进程结果

js 复制代码
child.on('error', (error) => {
    // 子进程启动失败(如文件找不到)
});

child.on('close', (code) => {
    if (code === 0) {
        // 成功
    } else {
        // 失败,但不 reject------把错误作为文本返回给模型
    }
});

关键设计:退出码不为 0 也不 reject。返回错误文本让模型自己判断下一步怎么做------这是 ReAct Agent 的核心优势。

3.4 exec vs spawn

Node.js 还有个 exec,区别在于缓冲策略:

spawn exec
输出方式 流式(实时) 缓冲(全部完成后才返回)
适用场景 长时间运行(dev server) 短命令(ls、echo)
数据量 不限 默认限制 1MB

Agent 场景选 spawn:因为 pnpm run dev 这类服务需要持续运行,不能等它"结束"。


四、readline --- 交互式输入

让 Agent 不是硬编码任务,而是从用户那里"问"来任务。

js 复制代码
import { createInterface } from 'node:readline'

const rl = createInterface({
    input: process.stdin,    // 从键盘读
    output: process.stdout,  // 提示信息打到屏幕
});

rl.question('📝 请输入任务:', (answer) => {
    console.log(`收到:${answer}`);
    rl.close();  // 用完要关
});

项目中的实现支持三种输入方式:

bash 复制代码
node src/main.js                           # 交互式 --- 用 readline 问用户
node src/main.js "创建一个 Express 项目"     # 直接命令行传参
node src/main.js -f task.md                # 从文件读取

五、process --- 进程级信息

process 是全局变量,不需要 import,直接就能用。

5.1 三个最常用的

js 复制代码
// 当前工作目录 --- Agent 所有文件操作的"原点"
process.cwd()
// → 'D:/project/min-cursor'

// 环境变量 --- 读 API key、模型配置
process.env.DEEPSEEK_API_KEY
process.env.MODEL_NAME

// 命令行参数 --- 解析用户输入
process.argv
// → ['node', 'src/main.js', '创建一个项目']

5.2 在 Agent 中的角色

process.cwd() 是整个项目的"锚点":

js 复制代码
// execCommandTool 中
cwd: directoryPath || process.cwd()
//    ↑ 模型指定了就用它的    ↑ 没指定就用户启动 node 时的目录

// system prompt 中
当前工作目录: ${process.cwd()}
// 告诉模型它现在在哪个目录,所有操作据此展开

5.3 platform:判断操作系统

js 复制代码
process.platform
// 'win32' | 'darwin' | 'linux'

// 项目中用来判断 shell 路径
shell: process.platform === 'win32'
    ? 'D:\\Git\\Git\\bin\\bash.exe'
    : true

六、os --- 系统信息

js 复制代码
import os from 'node:os'

os.cpus().length   // CPU 核心数 → 16
os.platform()      // 同 process.platform → 'win32'
os.homedir()       // 用户目录 → 'C:\\Users\\27499'
os.totalmem()      // 总内存(字节)
os.freemem()       // 可用内存

在 Agent 场景中,os 的价值在于让模型了解运行环境:

js 复制代码
// 可以在 system prompt 里追加
操作系统: ${os.platform()}
CPU 核心: ${os.cpus().length}
用户目录: ${os.homedir()}

这样模型就知道自己在 Windows 上,不会试图用 /home/user/ 这种 Linux 路径。


七、六个模块的关系

把这些模块串起来,就是一个完整的 Agent 工作流:

lua 复制代码
readline 读取用户任务
    ↓
process.cwd() 确定工作锚点
    ↓
模型决策(大脑)
    ↓
┌─────────────────────────┐
│ spawn 执行命令           │ ← child_process
│ path 拼路径              │ ← path
│ fs 读写文件 / 列目录      │ ← fs
│ process.env 传递配置     │ ← process
│ os.platform 判断系统     │ ← os
└─────────────────────────┘
    ↓
结果反馈给模型 → 继续循环

八、总结

模块 Agent 中的角色 不用会怎样
fs/promises 读写文件、创建目录 Agent 没法碰文件
path 跨平台路径操作 Windows/Linux 路径不兼容
child_process 执行终端命令 Agent 只能聊不能干
readline 交互式输入 任务全靠硬编码
process 进程信息、环境变量 不知道在哪、不知道干嘛
os 系统信息 模型可能用错路径语法

这些模块每个都只有几十行,但它们组合起来,就是一个 Agent 全部的行动能力。

相关推荐
学渣超2 小时前
微服务日志智能诊断系统(七) 日志 RAG 引擎——蒸馏、索引与精准检索
java·后端·agent
掉鱼的猫2 小时前
代码审查 Agent Harness 实战:AI 自动 Code Review
java·llm·agent
学渣超2 小时前
微服务日志智能诊断系统(六) Fast Path vs Slow Path——双路径日志诊断策略
java·后端·agent
apprentice2 小时前
跳出余弦相似度陷阱:RAG检索本质是筛选
agent·ai编程
GrowthGPT2 小时前
平台自报的 ROAS 在骗你
agent
先吃饱再说2 小时前
手写一个 mini-cursor:LangChain Agent 开发完全实战
langchain·llm·agent
chanalbert3 小时前
Agent Skill 工程化指南(三):运行与生效 — 运行时的全链路机制
llm·agent
武子康3 小时前
调查研究-222 PagedAttention 详解:vLLM 如何像操作系统一样管理 KV Cache
人工智能·llm·agent
武子康3 小时前
调查研究-221 KV Cache:LLM 推理服务真正的显存黑洞
人工智能·llm·agent