别被 LangChain 唬住了,其实用 80 行 Node.js 代码就能撸出一个 AI Agent
我最近尝试抛弃所有框架,直接用 Node.js 调用 API 实现了一个名为 Steve 的代码评审 Agent。这个 Agent 被设定为一个拥有 15 年经验且说话毒舌的资深工程师,主要任务是读取本地的 Git diff 并进行代码审查。在实操过程中,我发现这种“脱离框架”的开发方式反而让我对 Agent 的运行机制有了更深刻的掌控感。
很多所谓的 Agent 框架,本质上是在帮你处理对话记忆、工具调用(Tool Calling)和重试机制这些琐碎的工程问题。但如果你在开发一个特定场景的轻量化工具,直接写核心循环其实效率更高。
以 Steve 这个 Agent 为例,它的核心执行链路其实只有三步:
首先,LLM 接收到指令后,判断当前状态是否需要调用外部工具(比如读取文件的函数);
其次,如果 LLM 决定调用工具,程序执行本地函数并将返回的结果重新喂给 LLM;
最后,LLM 根据工具返回的结果,决定是继续调用下一个工具,还是直接给出最终结论。
在实现过程中,我注意到一个关键的技术细节:很多人在讨论 Agent 时会说它就是一个 while 循环,但如果在生产环境下直接用 while,一旦 LLM 陷入逻辑死循环或者工具返回异常,很容易在短时间内烧掉大量的 Token。为了规避这个风险,我将核心逻辑改写成了 for 循环,通过强行限制最大迭代次数(Max Iterations)来给 Agent 加上“保险丝”。
如果你想复现这个逻辑,可以参考 GitHub 上的 sylwia-lask/code-review-agent 仓库。你会发现,实现一个能跑通的 Agent 核心循环其实只需要 80 行左右的代码。
在这种轻量化实现中,最核心的挑战不再是框架的配置,而在于你如何定义 Tool 的描述以及 Prompt 的精度。因为没有了框架的预设模版,你需要非常清晰地告诉 LLM 什么时候该调用哪个函数,以及如何解析函数的返回结果。
当你习惯了直接调用 API 并通过简单的循环控制逻辑后,你会发现一个很有意思的现象:你反而能更客观地决定什么时候该引入框架。当你真正需要复杂的长短期记忆管理或多 Agent 协同编排时,框架的价值才会体现;而对于大多数单任务 Agent 来说,简单的 API 循环才是最高效的方案。
总的来说,不要被框架给“神话”了。尝试从零部署一个简单的 Agent,你会发现这种通过代码直接掌控逻辑流的感觉,远比在框架的配置文件里调试参数要爽得多。
