[Bug已解决] 代理任务后无可靠方式审查文件改动-变更快照与-diff-追踪方案

发布时间:2026/7/17 14:57:04
[Bug已解决] 代理任务后无可靠方式审查文件改动-变更快照与-diff-追踪方案 [Bug已解决] 代理任务后无可靠方式审查文件改动变更快照与 diff 追踪解决方案一、现象长什么样你用一个「AI 代理agent」帮你改代码。任务跑完后你想审查它到底改了哪些文件、改了什么——但发现没有可靠办法要么列不全漏了间接改的文件要么 diff 对不上缓存/时序问题要么只有最终状态没有过程。即 GitHub Issues (openai/codex) #31424Regression: No reliable way to review file changes after an agent task。本质是代理在执行任务时会跨多个文件、多次读写若没有一个「任务前快照 → 任务后快照 → 可靠 diff」的机制事后就无法可信地审查改动范围。这是个通用的「变更追踪 / 审计」问题。本文聚焦通用技术如何可靠地追踪「一段时间/一个任务内哪些文件被改了、改了什么」——用哈希快照 diff 工具 可选的 git 集成用真实可运行 Python 代码说明不依赖具体产品。二、背景为什么「审查改动」会不可靠代理改文件的方式多样导致事后审查难多文件、多次写代理可能改 10 个文件每个改 3 次最终 diff 只反映最后一次中间的「为什么这么改」丢了间接/隐藏改动代理改了配置文件、生成了缓存、动了.git之外的文件审查列表漏掉无任务边界快照任务开始前没记录「原始状态」任务后无法对比「谁变了」并发/时序多个代理子任务并发写审查时文件还在变diff 不一致只记录「代理说自己改了什么」代理自己上报的改动列表可能不全它也可能忘不是事实来源。本质审查的依据必须是「文件系统的事实状态对比」而不是「代理自述」。没有可靠的快照对比审查就不可信。三、为什么 diff 会对不上常见原因审查时点不对在代理还在后台写时就 diff看到半成品基于内容 mtime 而非哈希mtime 可能因拷贝/解压被改导致「误报改动」或「漏报」没排除无关文件node_modules、.git等噪声混入真正改动被淹没符号链接/特殊文件diff 工具对它们处理错导致假改动。可靠审查必须任务开始前对所有受监视文件算内容哈希快照任务结束后重算对比哈希差异这才是事实。四、最小可运行可靠的「任务前后文件改动追踪器」下面用 Python 实现一个变更追踪器任务前快照哈希任务后对比输出「新增/修改/删除」列表并可生成 diff。import hashlib, os, json, tempfile, time def file_hash(path): h hashlib.sha256() with open(path, rb) as f: for chunk in iter(lambda: f.read(8192), b): h.update(chunk) return h.hexdigest() def snapshot(root, ignoreNone): 对 root 下所有文件算 {相对路径: 哈希} 快照。 ignore ignore or {.git, node_modules, __pycache__} snap {} for dirpath, dirs, files in os.walk(root): dirs[:] [d for d in dirs if d not in ignore] for fn in files: full os.path.join(dirpath, fn) rel os.path.relpath(full, root) try: snap[rel] file_hash(full) except OSError: pass return snap def diff_snapshots(before, after): 对比两快照返回 (added, modified, deleted)。 added [k for k in after if k not in before] deleted [k for k in before if k not in after] modified [k for k in before if k in after and before[k] ! after[k]] return added, modified, deleted # 用法示意 if __name__ __main__: tmp tempfile.mkdtemp() # 任务前快照 with open(os.path.join(tmp, a.py), w) as f: f.write(x 1\n) before snapshot(tmp) time.sleep(0.01) # 代理「任务」改 a.py新增 b.py with open(os.path.join(tmp, a.py), w) as f: f.write(x 2\n) with open(os.path.join(tmp, b.py), w) as f: f.write(y 1\n) after snapshot(tmp) added, modified, deleted diff_snapshots(before, after) print(新增:, added, 修改:, modified, 删除:, deleted)要点基于内容哈希的快照对比不依赖 mtime结果可信。这就是「可靠审查」的事实来源。五、解决方案一任务边界强制快照在代理任务启动前无条件拍快照结束后再拍一次二者对比即为这次任务的全部改动class ChangeTracker: def __init__(self, root): self.root root self.before None def start_task(self): self.before snapshot(self.root) def end_task(self): after snapshot(self.root) return diff_snapshots(self.before, after) # 用法 tracker ChangeTracker(/path/to/project) tracker.start_task() # 任务前快照 run_agent_task() # 代理执行 added, modified, deleted tracker.end_task() # 可靠改动清单关键快照是「事实」不是代理自述。即使代理忘了上报某个改动快照对比也能抓到。六、解决方案二与 git 集成做权威 diff若项目在 git 里最可靠的审查是git 自身的状态# 任务前记录干净基线 git stash list # 或直接 git status # 任务后看真正改动 git status --porcelain # 列出改动文件 git diff # 看具体改动用 Python 调用import subprocess def git_changes(repo): status subprocess.run([git, -C, repo, status, --porcelain], capture_outputTrue, textTrue).stdout changed [line.split()[1] for line in status.splitlines() if line] return changed # git 的 diff 是「内容级权威」比自研快照更可信且能看逐行 diff建议优先用 git 作审查事实来源它天然记录内容变更、能 diff 任意两次提交自研哈希快照作为无 git 项目的兜底。七、解决方案三实时审计日志不仅是最终 diff除了「前后对比」还应记录每次写操作的审计日志便于事后理解「为什么这么改」import json, datetime audit [] def log_write(path, action): audit.append({ ts: datetime.datetime.now().isoformat(), path: path, action: action, # create / modify / delete }) # 代理每次写文件前调用 log_write最终审计日志可追溯全过程 with open(audit.json, w) as f: json.dump(audit, f, indent2)这样审查者既能看「改了什么」快照 diff也能看「改的顺序」审计日志可靠性大幅提升。八、解决方案四排除噪声 处理符号链接快照时要排除node_modules、.git、构建产物并对符号链接特殊处理记录指向而非内容避免假改动def snapshot_safe(root, ignoreNone): ignore ignore or {.git, node_modules, __pycache__, .venv} snap {} for dirpath, dirs, files in os.walk(root): dirs[:] [d for d in dirs if d not in ignore] for fn in files: full os.path.join(dirpath, fn) rel os.path.relpath(full, root) if os.path.islink(full): snap[rel] (link, os.readlink(full)) # 记指向 else: try: snap[rel] (file, file_hash(full)) except OSError: pass return snap九、排查清单代理改动审查任务后无法可信审查改动 → 缺「前后快照对比」#31424 类。事实来源用内容哈希快照 / git diff不依赖代理自述。任务边界启动前拍快照结束后对比得出 added/modified/deleted。优先 gitgit status --porcelaingit diff最权威能看逐行。审计日志记录每次写操作补「为什么改」的上下文。排除噪声忽略 node_modules/.git符号链接记指向防假改动。十、小结Regression: No reliable way to review file changes after an agent taskopenai/codex #31424的本质是代理任务跨多文件、多次读写若没有「任务前快照 → 任务后快照 → 可靠 diff」的机制事后就无法可信地审查改动范围依赖代理自述更不可靠它会漏报。审查依据必须是「文件系统事实对比」。通用解决方案适用于任何需要审计文件改动的系统哈希快照对比任务前后对所有文件算内容哈希对比得 added/modified/deleted事实来源优先 gitgit statusgit diff是内容级权威审查能看逐行改动任务边界快照启动前无条件拍快照结束后对比不依赖自述审计日志记录每次写操作补「改的顺序/原因」上下文排除噪声忽略 node_modules/.git符号链接记指向。记住审查文件改动事实只能来自「文件系统快照对比」或「版本控制系统」绝不能来自执行者的自述。哈希 git 双保险审查才可靠。这是变更管理/审计里「事实来源 vs 自述」的经典课题。