玩具版:
项目目录和文件内容如下:
├── index.js
├── tools.js
├── package.json
├── .env.example
├── README.md
├── node_modules\ (37 个依赖包)
└── package-lock.json
index.js — Agent 主循环:
import OpenAI from 'openai';
import readline from 'node:readline';
import { toOpenAITools, runTool } from './tools.js';
const client = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
baseURL: process.env.OPENAI_BASE_URL, // 可选,兼容 Kimi/DeepSeek 等
});
const MODEL = process.env.MODEL || 'gpt-4o-mini';
const MAX_ROUNDS = 10; // 单轮提问中最多允许的工具调用轮数,防止死循环
const systemPrompt = '你是一个乐于助人的智能助手,可以使用工具来回答用户问题。';
async function chat(history, userInput) {
history.push({ role: 'user', content: userInput });
for (let round = 0; round < MAX_ROUNDS; round++) {
const resp = await client.chat.completions.create({
model: MODEL,
messages: history,
tools: toOpenAITools(),
});
const msg = resp.choices[0].message;
history.push(msg);
// 没有工具调用 → 得到最终回答
if (!msg.tool_calls?.length) {
return msg.content;
}
// 执行所有工具调用,把结果塞回对话
for (const call of msg.tool_calls) {
const result = await runTool(call.function.name, call.function.arguments);
console.log(` [tool] ${call.function.name}(${call.function.arguments}) → ${result}`);
history.push({ role: 'tool', tool_call_id: call.id, content: result });
}
}
return '(工具调用次数过多,已停止)';
}
async function main() { /* 命令行交互循环,输入 exit 退出 */ }
main();
tools.js — 内置 3 个工具(截取关键部分):
export const tools = [
{
name: 'get_current_time',
description: '获取当前日期和时间',
parameters: { type: 'object', properties: {} },
async execute() {
return new Date().toLocaleString('zh-CN', ...);
}
},
{
name: 'calculator', description: '计算一个数学表达式',
parameters: { ..., properties: { expression: { type: 'string' } } },
async execute({ expression }) { ... } },
{ name: 'read_file', description: '读取当前工作目录下某个文本文件的内容',
parameters: { ..., properties: { filePath: { type: 'string' } } },
async execute({ filePath }) { ... } },
];
Agent 的核心确实就是一个循环,这不是偷懒,这就是事实。业界把 Agent 定义为 “LLM + tools + loop”:模型决定下一步动作 → 执行 → 观察结果 → 再决定,直到任务完成。Claude Code、Cursor、Devin 这些看起来很强大的 Agent,骨架也都是这个循环。
真正的差距不在循环本身,而在围绕循环的那一层工程:
| 维度 | 玩具版(现在这个项目) | 生产级 Agent |
|---|---|---|
| 工具 | 3 个本地函数 | 几十个工具 + 权限控制 + 结果截断 |
| 记忆 | 无限堆积的对话历史 | 上下文压缩、长期记忆、向量检索 |
| 规划 | 模型即兴发挥 | 显式的 TODO/plan 步骤、子任务分解 |
| 健壮性 | try/catch 打日志 | 重试、超时、token 预算、循环检测 |
| 输出 | 等最终结果 | 流式输出、可中断、人机协作确认 |
| 架构 | 单 Agent | 多 Agent 分工(规划者/执行者/评审) |
所以这个”简单”版本的价值在于:它已经是真 Agent 了,能真实完成”现在几点→查时间→回答”这种工具驱动的任务,只是没有上面那些增强。




