Agent 新增的代码文件,经常会在 IDE 的 Unversioned 区域,没有被自动 git add,非常不优雅。
第一次尝试:Prompt 约束
我在 AGENTS.md 中立下了明确的规矩:"新增文件必须执行 git add <路径>,修改已有文件则不执行 "。
刚开始 Agent 还能乖乖照做,但随着对话轮次增加、上下文逐渐变长,LLM 出现了经典的上下文腐烂。它会完美地生成一个复杂的枚举文件,然后在自我总结中假装无事发生,彻底把 git add 抛在脑后。这种概率性的遗漏,对于自动化工作流是致命的。
第二次尝试:IDE 的Silent Add兜底
既然 AI 不靠谱,那就让 IntelliJ IDEA 来兜底。我在设置里勾选了 When files are created: Add silently ,期望 IDE 能静默处理。

但现实再次打脸:经常切回 IDE 时,文件依然是红色的。
问题根因在于: IDEA 的自动 Add 强依赖于操作系统底层的文件事件通知(如 Windows 的 ReadDirectoryChangesW 或 macOS 的 FSEvents)。传统开发中,人类新建文件是以"秒/分"为单位的;但在 Vibe Coding 场景下,Agent 往往在几百毫秒内并发落盘多个文件。这种高频的I/O,导致系统事件合并或丢失,IDEA 的虚拟文件系统(VFS)直接漏掉了同步事件。
一方面是指令遵循性差的 AI,另一方面是适应不了机器手速的 IDE。本来畅快的开发流,变成了每次提交前都要勾选遗漏的文件。
引入 AOP 切面拦截
我在系统底层拦截写文件的动作,只要 Agent 触发了落盘,底层的 Tool 工具链就在当前线程同步、静默地对目标路径执行一次 git add。把非确定性的状态同步,变成一定执行的系统调用。
基于上述思路,我在处理文件操作的底层框架中,针对 file.edited 事件增加了一个自定义 Hook。
代码实现如下:
bash
export const GitAutoAdd = async ({ $, worktree, client }) => {
// 1. 封装日志函数,方便在控制台观测 Agent 的静默行为
const log = (msg, data) => {
client.app.log({
body: { service: "git-auto-add", level: "debug", message: msg, extra: data || {} },
}).catch(() => {})
}
log("plugin loaded", { worktree })
// 2. 核心状态同步逻辑
const gitAdd = async (filePath) => {
if (!filePath || typeof filePath !== "string") return
try {
// 步骤 A:校验文件是否被 .gitignore 忽略
// 使用 check-ignore -q 静默探测。退出码为 0 说明被忽略,走 then;非 0 说明未被忽略,走 catch。
const isIgnored = await $`git -C ${worktree} check-ignore -q ${filePath}`
.then(() => true)
.catch(() => false);
if (isIgnored) {
log("file ignored by .gitignore, skipping git add", { filePath })
// 尊重规则,直接中止,既不加入暂存区,也不产生报错日志
return;
}
// 步骤 B:如果未被忽略,执行真正的静默 add
log("git add", { filePath })
await $`git -C ${worktree} add ${filePath}`
log("git add done", { filePath })
} catch (e) {
// 捕获并记录真正的异常(比如 git index.lock 导致的失败)
log("git add failed", { filePath, error: String(e) })
}
}
// 3. AOP 切面:暴露给框架的事件拦截器
return {
event: async ({ event }) => {
// 拦截文件变动事件(确保框架触发的事件类型是 file.edited)
if (event.type === "file.edited") {
const filePath = event.properties?.file
log("file.edited received", { filePath, properties: JSON.stringify(event.properties) })
// 触发同步逻辑
await gitAdd(filePath)
}
},
}
}
总结
AI 正在重塑我们的开发习惯,但现有的很多基础设施依然停留在"前 AI 时代"。
面对 Vibe Coding 中出现的新问题,试图用越来越冗长、严厉的 Prompt 去"教导" AI,往往治标不治本。真正的出路,是用工程化的手段(如拦截器、Hook、管道)去兜底 AI 的非确定性。 能用代码写死的规范,就绝对不要写在 Prompt 里。