当前位置: 首页 > news >正文

S18|Worktree 隔离:多 Agent 平台 —— 独立目录,独立车道,让并行工作互不干扰

在前十七章,我们的 Agent 已经拥有循环、工具、计划、子代理、技能、压缩、权限、Hook、记忆、提示词流水线、错误恢复、任务系统、后台任务、定时调度、多 Agent 团队、团队协议、自主代理十七大核心能力,能拆任务、认领任务、让多个 Agent 并行推进不同工作。

但如果所有人都在同一个工作目录里改文件,很快就会出现问题:两个任务同时改同一个文件、一个任务的修改污染另一个任务的目录、无法单独回看某个任务的改动范围。

这一章 S18,我们给并行任务加上Worktree 隔离系统:为每个任务分配独立的执行车道,让任务系统回答 “做什么”,Worktree 系统回答 “在哪做而不互相踩到”,让多 Agent 并行工作互不干扰。


本章核心信息

  • 核心闭环:任务创建 → 分配 Worktree → 绑定任务 ID → 进入隔离目录执行 → 收尾决定保留 / 回收
  • 工具数量:18 个
  • 核心思想:task 管目标,worktree 管隔离执行车道和收尾状态;两者不能混成一个概念

先看懂本章所有名词

  1. Worktree
    同一个仓库的独立检出目录,一条属于某个任务的独立工作车道,和其他任务的修改默认隔离。

  2. 隔离执行
    任务 A 在自己的目录里跑,任务 B 在自己的目录里跑,彼此不共享未提交改动,修改互不影响。

  3. 绑定
    把某个任务 ID 和某个 Worktree 记录明确关联起来,让任务和执行车道一一对应。

  4. Closeout(收尾)
    任务完成后对 Worktree 的处理动作,决定保留目录方便复查,还是回收目录释放资源。

  5. Worktree 注册表
    记录所有 Worktree 的名称、路径、关联任务 ID、状态、最近活动等信息,让系统知道每个车道的情况。

  6. Worktree 状态
    执行车道的生命周期状态,包括 active(活跃)、kept(保留)、removed(已删除)、unbound(未绑定)。


这一章到底要解决什么问题?

到 S17,系统已经可以让多个 Agent 并行推进不同任务,但存在一个关键问题:所有任务都在同一个工作目录执行,导致:

  • 两个任务同时修改同一个文件,互相覆盖、冲突
  • 未完成的修改污染目录,影响后续任务的执行
  • 无法单独回看某个任务的改动范围,排查问题困难
  • 无法安全清理已完成任务的执行环境

本章要解决的核心问题:为每个任务分配独立的执行车道,让任务回答 “做什么”,Worktree 回答 “在哪做而不互相踩到”,实现并行工作的隔离执行。


最小心智模型:两张表看懂任务与 Worktree 的关系

1. 任务板(回答:做什么、谁在做、状态如何) .tasks/task_12.json { "id": 12, "subject": "Refactor auth flow", "status": "in_progress", "owner": "alice", "worktree": "auth-refactor", } 2. Worktree注册表(回答:在哪做、目录在哪、对应哪个任务) .worktrees/index.json { "worktrees": [ { "name": "auth-refactor", "path": ".worktrees/auth-refactor", "branch": "wt/auth-refactor", "task_id": 12, "status": "active" } ] }

一句话:任务记录工作目标,Worktree 记录执行车道,两者通过 task_id 关联,并行工作互不干扰。


关键数据结构(本章灵魂)

1. TaskRecord(任务记录,新增 Worktree 相关字段)

task = { "id": 12, "subject": "Refactor auth flow", "status": "in_progress", "owner": "alice", "worktree": "auth-refactor", "worktree_state": "active", "last_worktree": "auth-refactor", "closeout": None, }

新增关键字段:

  • worktree:当前绑定的执行车道名称
  • worktree_state:车道状态(active/kept/removed/unbound)
  • last_worktree:最近一次使用的车道
  • closeout:最后一次收尾动作

2. WorktreeRecord(Worktree 记录,不只是路径映射)

worktree = { "name": "auth-refactor", "path": ".worktrees/auth-refactor", "branch": "wt/auth-refactor", "task_id": 12, "status": "active", "last_entered_at": 1710000000.0, "last_command_at": 1710000012.0, "last_command_preview": "pytest tests/auth -q", "closeout": None, }

它回答的不只是 “目录在哪”,还包括:

  • 最近什么时候进入过(last_entered_at)
  • 最近跑过什么命令(last_command_preview)
  • 最后是怎么收尾的(closeout)

3. CloseoutRecord(收尾记录)

closeout = { "action": "keep", # keep/remove "reason": "Need follow-up review", "at": 1710000100.0, }

显式记录收尾动作和原因,区分 “保留目录方便复查” 和 “回收目录释放资源”。

4. EventRecord(Worktree 事件日志)

event = { "event": "worktree.closeout.keep", "task_id": 12, "worktree": "auth-refactor", "reason": "Need follow-up review", "ts": 1710000100.0, }

记录 Worktree 的创建、进入、运行、保留、删除等全生命周期事件,方便排查问题。


最小实现代码(极简可运行)

第一步:先有任务,再有 Worktree

不要先开目录再回头补任务,顺序必须是:先创建任务,再为任务分配 Worktree。

# 1. 创建任务 task = tasks.create("Refactor auth flow") # 2. 为任务分配Worktree worktrees.create("auth-refactor", task_id=task["id"])

第二步:创建 Worktree 并写入注册表

def create(self, name: str, task_id: int): # 生成隔离目录路径和分支名 path = self.root / ".worktrees" / name branch = f"wt/{name}" # 创建git worktree run_git(["worktree", "add", "-b", branch, str(path), "HEAD"]) # 写入Worktree注册表 record = { "name": name, "path": str(path), "branch": branch, "task_id": task_id, "status": "active", "last_entered_at": time.time(), } self.index["worktrees"].append(record) self._save_index()

第三步:同时更新任务记录,绑定 Worktree

def bind_worktree(task_id: int, name: str): task = tasks.load(task_id) # 更新任务与Worktree的绑定关系 task["worktree"] = name task["last_worktree"] = name task["worktree_state"] = "active" if task["status"] == "pending": task["status"] = "in_progress" tasks.save(task)

关键:必须同时更新任务记录,让任务板知道 “这个任务在哪个隔离目录里做”。

第四步:显式进入车道,再在对应目录执行命令

def enter(self, name: str): # 更新进入时间 self._update_entry(name, last_entered_at=time.time()) # 记录进入事件 self.events.emit("worktree.enter", name=name, ts=time.time()) def run(self, name: str, command: str): worktree_path = self._get_path(name) # 在隔离目录中执行命令 subprocess.run(command, cwd=worktree_path, shell=True) # 更新最后命令记录 self._update_command(name, command)

cwd=worktree_path是隔离的核心,同一个命令在不同目录执行,影响范围完全不同。

第五步:收尾时显式走 Worktree Closeout

def closeout(self, name: str, action: str, reason: str, complete_task: bool = False): record = self._get_record(name) task_id = record["task_id"] # 1. 更新Worktree状态 record["status"] = "kept" if action == "keep" else "removed" record["closeout"] = { "action": action, "reason": reason, "at": time.time() } # 2. 处理目录(保留或删除) if action == "remove": run_git(["worktree", "remove", name, "--force"]) shutil.rmtree(record["path"], ignore_errors=True) # 3. 更新任务记录 task = tasks.load(task_id) task["worktree_state"] = record["status"] task["closeout"] = record["closeout"] if complete_task: task["status"] = "completed" tasks.save(task) # 4. 记录收尾事件 self.events.emit(f"worktree.closeout.{action}", task_id=task_id, worktree=name, reason=reason)

统一的 Closeout 接口,明确处理保留 / 回收,同时更新任务记录、Worktree 记录和事件日志。


为什么关键设计必须这样做?

1. 任务状态和 Worktree 状态必须分开

任务状态回答 “这件工作现在是 pending/in_progress/completed”,Worktree 状态回答 “这条执行车道现在是 active/kept/removed”。例如任务已经 completed,但 Worktree 可以保留给 Reviewer 查看,两者不能混成一个字段。

2. 必须同时更新任务记录和 Worktree 注册表

如果只更新 Worktree 注册表,不更新任务记录,系统就无法从任务板一眼看出 “这个任务在哪个隔离目录里做”,失去了绑定的意义。

3. 必须显式进入车道再执行命令

让读者清楚 “分配车道” 和 “真正进入并工作” 是两件事,这样last_entered_atlast_command_at这些观察字段才有意义。

4. Closeout 必须是显式动作

统一的 Closeout 接口让收尾逻辑清晰,区分保留和回收动作,同时记录原因,方便后续排查和复盘。


如何接到前面章节的系统里

S18 是前面多 Agent 系统的 “隔离层”,和前面几章强耦合:

  • S12 提供任务 ID(需要隔离执行的工作目标)
  • S15-S17 提供队友和认领机制(并行推进任务的执行者)
  • S18 为这些任务提供独立执行车道(让并行工作互不干扰)

完整链路:

任务被创建 -> 队友认领任务 -> 系统为任务分配Worktree并绑定 -> 进入隔离目录执行命令 -> 任务完成时决定保留/回收Worktree

初学者最容易犯的 7 个坑

  1. 有 Worktree 注册表,但任务记录里没有 Worktree 字段任务板无法知道任务的执行目录,绑定关系失效。

  2. 有任务 ID,但命令仍然在主目录执行不设置cwd参数,Worktree 形同虚设,修改还是会污染主目录。

  3. 只会 Worktree 删除,不解释 Closeout 的含义只记住 “删目录” 动作,不知道系统真正想表达的是 “保留 / 回收” 两种收尾逻辑。

  4. 删除 Worktree 前不检查未提交改动直接删除有脏改动的目录,导致任务修改丢失,无法恢复。

  5. 没有 Worktree 状态 / Closeout 字段无法区分车道是活跃、保留还是已删除,也不知道最后是怎么收尾的。

  6. 把 Worktree 当成长期垃圾堆从不清理已完成任务的目录,导致目录越来越多,状态越来越乱。

  7. 没有 Worktree 事件日志创建、删除失败或任务关系错乱时,无法排查问题,只能靠人猜。


S17 → S18 升级了什么?

模块S17S18
并行执行多个任务在同一个目录执行每个任务在独立 Worktree 目录执行
修改隔离任务修改互相污染任务修改默认隔离,互不干扰
执行边界无明确执行目录,无法区分任务改动任务与执行车道一一绑定,可单独查看改动
目录清理无统一收尾逻辑,目录混乱显式 Closeout 动作,统一处理保留 / 回收
架构地位多 Agent 自治运转层多 Agent 并行隔离执行层

本章教学边界

本章先只把主干分工讲透:

  • task 记录 “做什么”
  • worktree 记录 “在哪做”
  • enter /execute/closeout 串起隔离执行车道

崩溃恢复、删除安全检查、全局缓存区、非 git 回退这些运维细节,都应该放在这条主干之后。


一句话总结本章

任务系统管 “做什么”,Worktree 系统管 “在哪做而不互相踩到”。它给多 Agent 并行工作加上了隔离执行车道,让每个任务都在独立目录中执行,修改互不干扰,让团队真正实现安全、有序的并行协作。

http://www.jsqmd.com/news/823556/

相关文章:

  • 优峰技术:N7711A 可调谐激光器选型与光通信测试应用方案
  • 如何用BilibiliDown实现跨平台B站视频高效下载?3个核心优势解析
  • 别再为离线安装发愁了!手把手教你用pkgs.org搞定Linux所有依赖包
  • 2026 年合肥验配医院推荐哪家:安徽医科大学康视眼科医院行 - 17322238651
  • NotebookLM生物学研究辅助落地手册(实验室已验证的7个不可公开的Prompt工程模板)
  • MPLAB Harmony框架实战:从驱动抽象到复杂嵌入式系统开发
  • 【技术底稿 35】低配单机混跑 Dev/Test 微服务环境,Jenkins 部署包错乱踩坑全复盘
  • Trick 4.0
  • 别再手动移植了!用STM32CubeMX+Keil AC6,5分钟搞定QP状态机到STM32F4
  • Steam Deck Windows控制器驱动深度配置指南
  • 各高校论文AI率标准差异解读:从10%到30%不同学校标准差距2026年免费达标方案
  • 2026年最新:AI率怎么降?10款降AI工具及自降AIGC攻略 - 降AI实验室
  • 2026 年合肥验配医院哪家值得信任:安徽医科大学康视眼科医 - 13425704091
  • 优化sVLM 的计算效率:轻量级注意力机制
  • 叶绿体注释翻车实录:Geseq vs. NCBI格式差异与特殊基因处理实战
  • D2R Pixel Bot:暗黑破坏神2重制版像素级自动化解决方案
  • 创业公司如何借助Taotoken多模型能力快速进行AI产品原型验证
  • 嘎嘎降AI全平台综合评测:2026年知网维普万方Turnitin达标率完整深度分析报告
  • 口腔执业医师技能考试,哪门课程讲得最全?一份分人群的客观测评 - 医考机构品牌测评专家
  • 4. 大型场馆大空间挡烟垂壁选型与布设
  • 【最新 v2.7.1 版本】5 分钟搞定 OpenClaw Windows 环境部署配置
  • 如何在Keil5中集成大模型API助手提升嵌入式开发效率
  • py之fonttool实现ttf裁剪和合并
  • S19|MCP 与插件:多 Agent 平台 —— 外部能力总线,让外部工具安全接入
  • 北京就医挂号攻略|外地患者必看,官方渠道+抢号技巧,告别号贩子 - 品牌排行榜单
  • 别再手动导数据了!用Python的pandas+pyarrow,3行代码搞定Parquet转JSON
  • RK3588平台IMX415摄像头驱动调试全流程与实战指南
  • Boss-Key:Windows下一键隐藏窗口的终极隐私保护工具
  • 3个MuJoCo物理仿真优化技巧:从卡顿到流畅的完整指南
  • 嘎嘎降AI和笔灵AI哪个更适合毕业论文:2026年达标率改写质量售后完整测评对比报告