最近 OpenClaw、Claude Code 特别火,我当时就在想,能不能写个自己的Agent,让它自动根据我的需求文件干活?比如我改个 tasks.md,它就自动跳出来把代码写了。这不比怼着ide开发高级多了?
最开始的想法非常简单粗暴:用 Node.js 写个脚本,利用 chokidar 盯着一个 todo 文件夹。只要文件一变,脚本就通过 child_process 里的 exec 去调 claude 命令。
初版脚本核心逻辑:
javascript
const chokidar = require('chokidar');
const { exec } = require('child_process');
chokidar.watch('./todo/tasks.md').on('change', () => {
console.log('检测到需求变动,Claude 准备上工...');
exec('claude "根据 tasks.md 写代码"');
});
翻车现场: 这个版本跑起来简直是"盲人摸象"。因为 exec 是在后台静默运行的,我完全看不见 Claude 输出了啥。最尴尬的是,之前Claude 经常会问我"是否允许写入文件?"或者"是否运行测试?",但这里我看不见窗口,没法点 y,结果它等不到输入直接报错退出。
进阶之路------从"盲人摸象"到"多窗接力"
既然 Agent 需要交互,那就给它"名分"------直接弹出独立的命令行窗口。
我意识到,在 Windows 下必须用 start 命令来调起新的交互界面。同时,为了让流程可控,我引入了"文件接力"的状态机思想:
01_requirement.md存在 -> 触发 需求 Agent -> 生成02_todo.md。02_todo.md存在 -> 触发 代码 Agent -> 产出代码并生成03_dev_log.md。
进化后的脚本逻辑:
javascript
function launchAgent(name, command, nextFile) {
if (isAgentRunning) return; // 加锁,防止重复弹窗
isAgentRunning = true;
const fullCommand = `start /wait cmd /k "${command}"`;
exec(fullCommand, (error) => {
isAgentRunning = false;
if (!error && nextFile) {
// 只有窗口关闭后,才生成下一个阶段的 MD 文件
fs.writeFileSync(nextFile, '# 下一步任务已就绪');
}
});
}
新的挑战: 虽然能看到窗口了,但 start /wait 意味着我必须手动关掉上一个窗口,下一个才会弹出来。而且这种"单向终点"的逻辑很难搞迭代,我想加个需求,还得手动去文件夹里删文件重来,非常不程序员。
终极形态------版本化迭代与"对话式"需求收集
为了实现真正的生产力,我决定引入**"版本化思维"和"双轨并行"**机制。
1. 自动版本管理 脚本不再盯死一个文件,而是扫描 v1, v2, v3...。系统始终以版本号最大的文件作为当前活动任务。
2. 需求收集器 (Collector) 专门开一个常驻窗口,我就像平时聊天一样跟它说:"我想加个功能"。它确认明白后,自动帮我创建下一版的 v(N+1)_requirement.md。
3. 增量上下文指令 在指令里强制加入"结合之前版本的记录"和"增量开发"的提示。
终极版核心架构:
javascript
// 核心逻辑:始终盯住当前最高版本 vN
function orchestrate() {
const v = getCurrentMaxVersion();
const prefix = `v${v}_`;
// 只要 vN_requirement 出来了,Req-Agent 自动弹窗分析清单
if (hasFile(`${prefix}requirement.md`) && !hasFile(`${prefix}todo.md`)) {
launchAgent('Req-Agent', `claude "分析 ${prefix}requirement,写出 v${v} 的清单"`);
}
// 只要清单出来了,Coder-Agent 自动接力
if (hasFile(`${prefix}todo.md`) && !hasFile(`${prefix}dev_log.md`)) {
launchAgent('Coder-Agent', `claude "根据清单进行增量开发"`);
}
}
// 专门的需求录入窗口,实现"对话生版本"
function maintainCollector() {
const nextV = getCurrentMaxVersion() + 1;
launchAgent('Collector', `claude "我是您的需求助手,请描述 v${nextV} 的需求"`);
}
写在最后:
从最开始一个简单的 exec 报错,到最后折腾出这套版本化流水线,我最大的感悟是:不要试图把 AI 关在后台当苦力 ,那怕你用cli也要可以看到它的工作流程,毕竟背锅的还是人。AI 更像是一个"非常有能力但需要盯着看"的初级开发。我们要做的不是取代沟通,而是用脚本优化或者固化沟通的路径,这其实就是工作流的思想。还可以继续迭代,你可以拆分你工作中实际步骤,然后用agent去替代它,这个小小的工作流能爆发出的生产力绝对超乎想象。
上面涉及的源码只是一个思路,差不多是伪代码,如果想要我的完整代码,关注我的公众号,私信发:多Agent源码即可。