如果你还在执着于通过精雕细琢的 Prompt(提示词)来榨取大模型的每一分潜力,那么你可能已经错过了 AI 开发的下一个风口。
回顾过去两年,我们对 AI 的认知经历了一场深刻的革命:
- LLM 时代(过去):我们将 AI 视为一个全知全能的“超级大脑”,试图通过复杂的指令让它输出完美答案。
- Agent 时代(现在):我们意识到,真正的智能不仅仅源于思考,更源于行动。AI 应当进化为一个智能体(Agent)。
正如业界共识所言,现代 AI 应用的公式已重构为:
AI Agent = LLM(思考核心) + Memory(记忆上下文) + Tools(执行手脚) + RAG(外部知识)
本文将剥离繁琐的理论,直接切入 Tools(工具调用) 与 Agent Loop(执行循环) 的核心机制。我们将利用 Node.js 和 LangChain,从零构建一个具备文件读取与代码分析能力的微型“Cursor”,带你领略 Agentic Engineering(智能体工程)的魅力。
🆚 第一部分:降维打击——基础对话 vs 智能体执行
为了直观展示两者的本质差异,我们通过两段代码对比来揭示“传声筒”与“实干家”的区别。
1. 基础版:被蒙住双眼的“思想家”
这是最传统的 LLM 调用模式。模型虽然博学,但与现实世界完全隔离。
import { ChatOpenAI } from '@langchain/openai';
// ... 初始化配置 ...
const model = new ChatOpenAI({ modelName: 'gpt-4o' });
// 单次交互:模型只能基于训练数据“幻觉”或通用知识回答
const response = await model.invoke("请分析当前目录下 package.json 的结构");
console.log(response.content);
// ❌ 结果:模型会抱歉地表示它无法访问你的本地文件系统,或者胡乱编造内容。
痛点诊断:
这种模式下,AI 是一个有脑无手的囚徒。它无法感知外部环境,无法读取实时数据,更无法执行任何实际操作。
2. 进阶版:拥有“手脚”的智能体
通过引入 Tool Calling,我们赋予了 AI 操作现实世界的能力。
import { tool } from '@langchain/core/tools';
import { z } from 'zod';
import fs from 'fs/promises';
// ✅ 定义工具:赋予 AI "读取文件" 的能力
const readFileTool = tool(
async ({ path }) => {
// 真实的文件系统操作
return await fs.readFile(path, 'utf-8');
},
{
name: 'read_file',
description: '当需要获取文件具体内容时调用此工具',
// 关键:使用 Zod 严格定义参数 Schema,让模型知道如何调用
schema: z.object({
path: z.string().describe('目标文件的绝对或相对路径')
})
}
);
核心变革:
此时,AI 不再仅仅是生成文本,它学会了规划。当用户提出需求时,它会判断:“我需要先读取文件,才能进行分析”,并主动发起工具调用。
⚙️ 第二部分:心脏跳动——揭秘 Agent Loop 执行闭环
赋予 AI 工具只是第一步,真正的智能诞生于 Agent Loop(智能体循环)。这是一个“思考 - 行动 - 观察”的无限闭环,直到任务完成。
1. 武器库绑定
首先,将定义好的工具“挂载”到模型上,使其知晓自己的能力边界。
const modelWithTools = model.bindTools([readFileTool]);
2. 上下文记忆构建
Agent 需要短期记忆来维持对话连贯性。我们维护一个 messages 数组,记录系统指令、用户输入及历史交互。
const messages = [
new SystemMessage("你是一个资深代码助手,擅长通过读取文件来分析项目结构。"),
new HumanMessage("请读取 package.json 并解释其依赖项。")
];
3. 核心循环:思考与行动的舞蹈
这是整个架构的灵魂所在。通过 while 循环,我们模拟了人类解决问题的过程。
let response = await modelWithTools.invoke(messages);
// 【核心逻辑】只要模型决定调用工具,循环就继续
while (response.tool_calls && response.tool_calls.length > 0) {
console.log(`🤖 [思考] 模型决定调用工具: ${response.tool_calls[0].name}`);
// Step 1: 并发执行工具调用 (高性能关键)
// 如果模型同时要求读取多个文件,Promise.all 让它们并行处理,而非串行等待
const toolResults = await Promise.all(
response.tool_calls.map(async (toolCall) => {
const targetTool = [readFileTool].find(t => t.name === toolCall.name);
if (!targetTool) throw new Error(`未找到工具: ${toolCall.name}`);
// 执行真实逻辑
return await targetTool.invoke(toolCall.args);
})
);
// Step 2: 反馈观察结果 (Observation)
// 将工具执行的“现实世界反馈”重新注入对话历史
response.tool_calls.forEach((toolCall, index) => {
messages.push(
new ToolMessage({
content: toolResults[index], // 工具返回的真实数据
tool_call_id: toolCall.id // 关联本次调用 ID
})
);
});
// Step 3: 基于新信息进行下一轮推理
// 模型现在拥有了文件内容,可以生成最终的分析报告了
response = await modelWithTools.invoke(messages);
}
// 循环结束,输出最终结论
console.log(`✅ [结论] ${response.content}`);
💡 第三部分:深度解构——为什么是这种架构?
这种看似简单的 while 循环设计,实则解决了传统 AI 开发的三大核心难题:
1. 突破“单步思维”局限
大模型本质上是自回归的,一次只能生成下一个 token 或做出一个决定。
- 无循环:模型说“我要读文件”,然后停止。任务中断。
- 有循环:模型说“我要读文件” -> 系统执行读取 -> 模型看到内容 -> 模型说“现在我知道了,分析如下”。
循环赋予了 AI“多步推理”和“自我修正”的能力。
2. 并发执行的性能飞跃
在复杂场景下,Agent 可能需要同时查询数据库、读取多个配置文件、搜索网络。
使用 Promise.all() 进行并发工具调用,能将原本串行的分钟级任务压缩至秒级,这是构建高性能 Agent 的关键细节。
3. 从 Cursor 到 Manus 的演进逻辑
- Cursor 的本质:
LLM+FileSystem Tools+Loop。它通过不断读取代码、修改代码、运行测试的循环,实现自动化编程。 - Manus 的本质:
LLM+Browser/OS Tools+Planning Loop。它能拆解宏大目标(如“帮我买一张机票”),自主规划步骤,调用浏览器、支付接口等完成复杂任务。
它们的底层逻辑是一致的:感知环境 -> 规划行动 -> 执行工具 -> 观察结果 -> 迭代优化。
🚀 结语:拥抱 Agentic Engineering 新时代
2026 年,AI 开发的重心已彻底从 Prompt Engineering(如何问得好) 转向了 Agentic Engineering(如何构建能做事的系统)。
作为新一代的全栈开发者,我们的角色也在发生转变:
- 我们不再是单纯的 API 调用者;
- 我们是 AI 架构师,负责设计大脑(LLM 选型)、构建记忆(Vector DB)、打造手脚(Tools 开发)以及编排流程(Agent Loop)。
工具已备,循环已启。现在,是时候让你的代码真正“活”起来了。
共同学习,写下你的评论
评论加载中...
作者其他优质文章