从天然解耦到依赖链:并行开发的下一道坎
上一篇文章里,我用git worktree让Claude和Codex并行写了6个平台适配器。那次能并行,靠的是模块之间天然独立——每个适配器是单独文件,互不依赖。说白了,文件系统层面的隔离,谁都能做到。
但这次的情况完全不同。给house-cli加上自然语言搜索和智能比价,再把交互从命令行升级成TUI界面,任务之间存在着明确的依赖关系:parser的输出是comparator的输入,chat功能同时依赖两者。这不是"各写各的"就能解决的。
有依赖链的任务怎么拆成并行?我花了半小时跑通了一套方法,核心是四个字:接口契约。
Spec的四要素:依赖图、切割点、签名、分工
我一开始也没想清楚要什么,连需求文档都没写。让Claude自己去调研了Textual框架(和house-cli在用的Rich是同一个作者),参考了开源终端聊天UI项目elia,还扒了知乎和小红书上买房租房用户的痛点,整理出10个比价场景分三个梯队。我挑了第一梯队的三个做MVP:跨平台聚合比价、真实月供计算(包含物业费契税大修基金)、自定义权重排序。
这里有个关键点:我没有指定框架,没有定义数据模型,没有画页面布局。这些全是Claude调研后给出的建议,我只做审核。然后Claude生成了一份Spec,80行,核心是四样东西。
第一是依赖图。用户输入经过Intent Router分流到搜索、比价、成本计算、详情四条路径,每条路径的输入输出标得清清楚楚。这张图就是整个并行开发的基石——它把模糊的需求变成了清晰的边界。
第二是切割点。SearchFilter和House是已有模型,锁死不许改;新增UserIntent和CostReport两个数据模型,定义在Spec里。切割点就是"谁可以动、谁不能动"的明确划分。
第三是函数签名。四个函数,每个一行:recognize_intent、parse_natural_language、smart_compare、calculate_total_cost。有了这些签名,写parser的Agent和写comparator的Agent可以同时开工——约定好了"你给我SearchFilter,我给你list[HouseScore]",签名不变,内部实现各自决定。
第四是Agent分工。Opus做TUI框架(架构决策多,用最强模型),Sonnet做意图识别和DeepSeek集成,Codex GPT-5.4做四个面板组件和成本计算器(重复性高,用快模型)。
写Spec有几个实操原则值得记住。只锁切割点,不锁实现细节——Spec写"返回CostReport"就够了,不用写"用for循环遍历,先算月供再算契税"。你管的是模块之间的接口,不是模块里面怎么写代码。另一个原则是文件白名单比描述有效——写"可修改src/house_cli/tui/app.py"比写"请不要修改其他模块"靠谱得多。描述性约束Agent可以选择忽略,白名单是确定性的。
还有一点容易搞混:Spec不只是给人审核的,Agent也要读它。Spec审核通过后,Claude把它翻译成了4个.claude/agents/*.md文件,每个文件包含对应Agent的职责、可修改文件清单、输出契约。Spec是人机共用的需求源,约束文件只补充执行边界。
三个坑:沙盒、白名单、以及不听话的Haiku
Spec审核通过后,我在house-cli目录下开了新的Claude Code会话,输入一段prompt让四个Agent并行开发。然后就是踩坑环节。
第一个坑是Codex调不起来。Agent C用Haiku做调度,通过Bash调用codex exec让Codex写面板代码,结果Haiku报了sandbox限制——子Agent默认跑在沙盒里,没权限执行外部命令。修复很简单,在settings.local.json的权限白名单里加一行"Bash(codex:*)"。
第二个坑是Hook白名单过期。之前做规范化实验时写了一个文件守卫Hook,白名单里只有nlp/下的几个文件。TUI阶段要写tui/panels/下的文件,不在白名单里,全被拦了。更新白名单,加入所有TUI阶段的文件路径。
第三个坑最有意思:Haiku不听话。Agent定义文件里明确写了"调用Codex CLI来生成",Haiku看了看,觉得自己也能写,就跳过了codex exec,直接自己生成代码。这暴露了Agent自主性与可控性之间的根本矛盾——Agent判断"已经够好了",就抄了近路。
解决方法是在交互窗口明确指定要用什么Bash指令。光在约束文件里写"请调用Codex"不够,你得把具体命令写出来。Spec和约束文件是上下文,不是强制指令。Agent可以参考,也可以选择忽略。
重跑之后,tasklist里出现了5个codex.exe进程和10个codex-command-runner.exe。Codex真正跑起来了。
四个Agent跑完后,产出合并,修了两个小bug:一个是Textual的DataTable列宽在中文下溢出,一个是DeepSeek的tool_use返回格式和Anthropic的略有不同,需要多一层解析。整体改造不到半小时。
复盘:接口契约隔离,才是并行开发的真正钥匙
回头看这套流程:需求探索→Spec→Agent约束文件→并行执行→集成。范式本身是可复用的。
跟上一篇worktree方案的区别在于:worktree解决的是"文件系统隔离",适合天然解耦的模块;这次用Spec+Subagents解决的是"接口契约隔离",适合有依赖链的任务。画依赖图,找到数据模型作为切割点,定义函数签名,然后并行——不管任务之间有没有依赖,只要切割点定义清楚,就能并行。
有瑕疵吗?有。Subagent模式配合Spec容易不遵循指令,Haiku跳过Codex自己写就是例子。要让Agent严格执行特定操作,目前只能在交互窗口明确指定,心智负担比较大。这其实指向了一个更深层的问题:Agent的"自主性"和"可控性"如何平衡?目前看来,Spec定义了"做什么",约束文件定义了"不能做什么",但"具体怎么做"仍然需要人在关键时刻把关。
不完美,但能用。半小时从命令行升级到TUI,修两个bug就能跑。这个效率已经足够有说服力了。
