合并冲突是 agent 在并行分支上工作时最常见的摩擦点之一。大多数冲突不是随机的——它们可以追溯到可预测的代码模式,可以通过结构、lint 规则和 PR 纪律来预防。

#为什么 Agent 会加剧冲突

人类开发者会本能地避免编辑相同的行。Agent 没有这种直觉。当两个 agent 会话在同一文件上工作时,它们倾向于:

结果是技术上简单但频繁到足以拖慢工作流的冲突。

#冲突易发的代码模式

#不断增长的函数调用参数

当函数调用积累了大量内联参数时,每个添加新参数的 PR 都会触及相同的行。

// 冲突易发:每个新变量都扩展这个块
const fullHtml = render(baseTemplate, {
  title, lang, body, base, description, canonicalUrl,
  pairCanonicalUrl, pairLang, ogLocale, noindex, jsonLd,
  ogType, rssUrl, markdownUrl, siteName, siteTagline,
});

修复:提取一个辅助函数来组装对象,这样每个 PR 修改的是辅助函数而不是调用点。

const fullHtml = render(baseTemplate, {
  title, lang, body, base,
  ...seoVars({ lang, title, description, canonicalUrl, ... }),
});

#按位置传参

参数过多的按位置传参函数比对象参数更糟糕,因为插入新参数会移动所有后续位置。

Lint 阈值:当函数超过 4-5 个参数时,重构为单个选项对象。

#共享常量块

当多个常量在单个块中声明时,任何添加新常量的 PR 都会触及相邻行。

修复:将常量分组到配置对象中。新属性在对象内部添加,减少行级冲突。

#仅追加文件

每次更改都是追加的文件(日志文件、变更记录、不断增长的数组)在两个分支同时追加时会冲突。

修复:使用条目独立的结构化格式(每个条目一个文件,或用清晰分隔符分隔的段落)。

#预防冲突的 Lint 规则

一些冲突易发模式可以通过静态分析捕获:

这些规则不提"冲突"——它们是标准的代码质量规则。但它们的副作用是直接减少合并冲突频率。

#PR 边界策略

最有效的冲突预防不在代码中——而在于如何拆分工作。

#文件重叠检查

在开始并行工作之前,列出每个 PR 将触及的文件。如果两个 PR 修改同一文件,声明依赖关系并定义合并顺序。

#纵向切片

按功能边界拆分工作,而不是按层。一个触及"所有模板"的 PR 会与任何其他模板 PR 冲突。一个"端到端添加 sitemap 生成"的 PR 触及更少的共享文件。

#最小化 diff

PR 改变的行越少,冲突的可能性越低。抵制在实现功能时顺便清理相邻代码的冲动。

#Agent 特定建议

#在任务中声明文件所有权

当向 agent 分配并行任务时,明确说明每个任务应该修改哪些文件。这防止两个 agent 独立决定"改进"同一文件。

#推送前 rebase,而不是冲突后

Agent 应该在推送前 rebase 到最新 main,而不是在报告冲突后才做。这在 diff 仍在上下文中时就能及早发现冲突。

#使用预工作检查清单

在创建分支之前,验证更改是可以用一句话描述的单一关注点。这是最简单也最有效的冲突预防措施。