核心概念

任务与会话

为什么工作流里的每个任务都是一次全新的 Agent 会话,以及这对拆分任务、传递结果和授权意味着什么。

内测即将开始,CodeDAG 暂未开放安装。可以先加入 Waitlist,邀请会分批通过邮件发出。
在 GitHub 上编辑

工作流里的每个任务,都交给一个全新的 Claude Code 或 Codex 会话去完成,因为会话越长,上下文里与眼前这件事无关的信息越多,Agent 的判断就越不可靠。全新的会话只知道任务的 prompt 和它自己从工作区里读到的文件;上游任务的对话和推理传不过来,传得过来的只有仓库里的文件。所以任务要拆到一个会话能可靠做完的大小,prompt 要写到不了解任何背景的会话也能独立完成,要交给下游的结论要写进文件。

任务

为什么要做任务拆分,以及拆分的标准

你平时和 Claude Code 或 Codex 交互时,会话刚开始,上下文里只有你交代的事,Agent 的判断最准。随着对话拉长,读过的文件、试过又放弃的方案、早已过时的中间结论都留在上下文里,和眼前这件事无关的信息越积越多,它就越容易遗漏约束、前后矛盾;压缩上下文能腾出空间,却也可能丢掉关键的约束。所以,无论模型多强,目标大到一定程度,就不能指望一个会话把它做好,而要拆成几个任务,让每个任务都能在一个会话里可靠地做完。

拆到什么程度为止,有一个实用的判断标准:把一个任务交给 Agent 在一个会话里做完,拿到结果时,你是否有足够的信心,不做任何人工修改它也令人满意。有这份信心,就不必再拆;没有,就继续拆小。信心在哪里跌破你能接受的底线,哪里就是拆分的边界。

这条边界会随着模型进步往上移,但你总可以设置比它大得多的目标,因而任务的拆分总有存在的必要。

拆分后的任务如何组织

要把拆出来的任务组织起来,常见的做法是让一个主 Agent 边做边派子 Agent:每个子 Agent 的上下文是干净的,但主会话要收下每一份汇报,还要记着整盘计划,任务一多,它自己的上下文同样越积越多;派多少、派给谁也都在现场决定,计划只存在于主会话里,事后既看不清,也没法照原样再跑一遍。

CodeDAG 的做法与此不同:拆好的任务和它们之间的依赖事先写进工作流,执行时由 CodeDAG 按依赖为每个任务启动一个干净的会话。

CodeDAG 中的任务是什么

在 CodeDAG 里,任务是工作流里的一段工作:它有一个明确的目标和一段交给 Agent 的指令,还可以依赖其他任务。写进工作流文件,它就是 tasks 列表中的一项:title 是给人看的名字,prompt 是交给 Agent 的指令,dependencies 列出它要等待的上游任务。轮到它执行时,CodeDAG 为它启动一个全新的 Claude Code 或 Codex 会话,prompt 就是这个会话收到的第一条消息。

怎样把目标拆成任务、prompt 怎样写,见拆分任务与编写 prompt。

依赖

CodeDAG 中的依赖是什么

在构建系统、数据管道这类按依赖执行的系统里,依赖通常是数据流(dataflow):上游产出一份结果,下游把它当作输入。CodeDAG 的任务没有这样一份单独交给下游的输出,它做的事情是修改仓库,依赖的含义也因此不同。

在 CodeDAG 里,依赖表示下游继承上游的仓库状态:上游的结果被接受之后,下游从上游改完的那份代码出发,在它上面继续修改,就像 Git 里一个提交接在它的父提交之后。在默认的隔离分支模式下,CodeDAG 会在下游启动前把上游已接受的结果合并进它的任务分支,间接依赖的上游的结果也随之而来。

上游不止一个时,下游要继承的是几份各自改过的仓库状态,得先合并成一份,有冲突也要先解决;数据流里的多个输入只是并列的几份数据,没有这一步。合并与冲突怎样处理,见汇聚节点的合并与冲突。

也就是说,在隔离分支模式下,分支合并的拓扑结构与依赖的拓扑结构基本相同;主要区别是,分支合并最后还会把叶子节点,也就是没有下游的任务,汇到一条集成分支上。

反过来,没有依赖关系的两个任务各在各的分支上,即使其中一个早已做完,另一个也看不到它的改动,所以要用到另一个任务的结果,就必须声明依赖。

哪些内容能传给下游

每个任务都是独立的会话,能传给下游的只有仓库里的文件,也就是上游改过的代码和写下的文档;上游会话里的对话、推理过程和没有写下来的结论都传不过去。所以上游要把结论写进文件,下游的 prompt 要指名去读这份文件,这个文件路径就是两个任务之间的接口,做法见把结论传给下游。

任务 Agent 的视野与权限

任务 Agent 就是在你仓库的工作区里启动的一个普通 Claude Code 或 Codex 会话。

任务 Agent 能看到什么

任务 Agent 的视野只有 prompt 和它自己读到的文件。CodeDAG 交给它的只有 prompt:工作流里的 title、description 和其他任务的内容不会发给它,你和编排 Agent 的对话也不会带进它的上下文。

文件主要来自它所在的工作区。在默认的隔离分支模式下,工作区检出的是这个任务的任务分支,内容是工作流起点那次提交,加上上游已被接受的结果。在共享工作区模式下,所有任务直接在同一个工作区里执行,看到的就是这个目录当时的内容。

所以 prompt 要写到一个不了解任何背景的新会话也能独立完成,点名要读的材料,要么在工作流开始前已经提交,要么由上游任务产出。

任务 Agent 能做什么

任务 Agent 的权限由任务的 mode 决定,它直接对应这个 Agent 自己的权限设置。不写 mode 时,CodeDAG 不替它决定,Agent 按它自己的配置运行。

权限模式要求 Agent 在改文件或运行命令前先征得同意时,它会在会话里停下来等人应答,任务也跟着停在那里。这时需要进入它的原生会话来批准。想让任务无人值守地跑完,就要给它一个不必逐步确认的模式,并接受这份授权带来的风险。两种 Agent 各有哪些取值、无人值守与值守怎样取舍,见选择 Agent、模型与权限模式。

任务不是子 Agent

任务不是子 Agent:没有一个主会话在等它,它也不把结果交还给谁。

子 Agent 由一个主会话派出,做完之后把结果汇报回主会话,由主会话决定下一步。任务没有这样的主会话,替你写工作流、提交工作流的编排 Agent 也不是它的主会话。任务由 CodeDAG 按依赖启动,做完的结果只留在仓库里,下游任务再从仓库里读取。

反过来,任务 Agent 在自己的会话里照样可以派子 Agent。那是它完成这个任务的手段,属于任务内部的事;这些子 Agent 全部结束之前,这个任务不算完成。


最后更新