FND-005:贡献文化:人际协作、AI 协作与团队成长
始于 v0.7.0 · 类型:文化 · 修订版 2
权威参考 · 经团队批准 · 修订版 2 原始 RFC 讨论:\#5615
在你们阅读此内容之前,给团队的一条提示。
这是 ZeroClaw 成熟度框架中的第五份文档。其余四份分别涉及架构、文档、治理和工程基础设施,即让项目得以运转的结构层。而这一份要探讨的,是前四份文档默认为前提、却从未明确传授的内容:如何协作。
其他 RFC 中的工具和流程的效果,完全取决于使用它们的团队。一个完美的 CI 流水线无法帮助那些无法提供诚实反馈的团队。一个清晰的架构无法在无法进行建设性分歧的团队中存活。一个治理模型也无法在从未被教导过“所有权”含义的人中建立主人翁意识。
本文档关注的是如何打造这样一个团队——不仅仅是培养技术能力出众的个体,更是培养懂得如何给予和接受反馈、如何寻求帮助、如何负责任地使用强大工具,以及如何随着时间共同成长的人。这些都是可以习得的技能。没有人天生就完全具备它们。本文档将这些技能清晰地一一列出,让你能够开始有意识地加以练习——就在这里,在真正重要的实际工作场景中。
本文档中的内容并非对您个人身份或起点的批评,而是我们共同致力于实现的目标的路线图。
成熟度框架套件
本 RFC 是五份文档中的第五份,这五份文档共同构成了 ZeroClaw 的成熟度框架。它们设计为整体阅读,但每份文档也可独立阅读。
| RFC | 范围 | 问题 |
|---|---|---|
| 刻意架构:微内核转型 | 我们正在构建的内容及其结构 | #5574 |
| 文档标准与知识架构 | 我们如何记录我们所构建的内容 | #5576 |
| 团队组织与项目治理 | 我们如何协调和做出决策 | #5577 |
| 工程基础设施:CI/CD 流水线 | 我们如何可靠地构建、测试和发布 | #5579 |
| 贡献文化:人类协作与 AI 协同 | 我们如何协作与成长 | FND-005 |
前四个 RFC 回答了结构性的问题。本文回答的是一个关于人的问题:在既定结构下,其中的人如何彼此互动,以及如何对待他们的工具?这个问题没有编译器、代码检查器或 CI 门禁来约束。它只依赖于我们养成的习惯、树立的榜样,以及我们对此投入的用心。
目录
修订历史
| 修订 | 日期 | 摘要 |
|---|---|---|
| 1 | 2026-04-11 | 初始草稿 |
| 2 | 2026-05-09 | 使审查权重契约与维护的 PR 审查协议保持一致,其中包括已解决的发现项(#6473) |
1. 本文档的存在原因
大多数贡献指南会告诉你如何提交 PR。它们会说明使用哪些标签、如何运行测试套件,以及提交信息中应包含的内容。这些都很重要,我们也有相关的文档来涵盖这些内容。
本文档涵盖的是另一方面的内容:那些决定一群有才华的人能否成为一个高效团队,还是仅仅成为共享同一个代码库的个体集合的技能。
这些都是可以习得的技能。它们并非那种你要么天生拥有、要么没有的性格特质,也不是随技术能力自然而然就会具备的东西。它们需要在反馈中、随着时间推移,缓慢地加以练习,就像学习任何其他技能一样。大多数软件工程教育几乎只关注技术层面,而把人的层面交给运气去决定。其结果是,许多技术能力出众的人最终所在的团队却无法良好协作,而他们对究竟缺少了什么、又该如何改进,毫无清晰的认识。
本文档的目标是清晰地命名这些技能,以便你能够在重要的实际工作背景下,开始有意识地练习它们。
2. 工作前的工作
在编写代码、提交 PR 或要求 AI 生成任何内容之前,你应该能够回答一组问题。本项目使用决策层级来描述这些问题:
Vision
└── Architecture
└── Design
└── Implementation
└── Testing
└── Documentation
└── Release
该层次结构在架构 RFC(#5574)中有完整描述。这里重要的是其背后的原则:你做出的每一个决策都应该能够追溯至顶层。
在实践中,这意味着在开始构建之前,先问自己:
- 我在解决什么问题? 不是“我在关闭哪个工单“,而是:这实际上为某人解决了什么问题?
- 这是否符合架构要求? 如果你无法描述它在系统结构中的位置,说明你对系统的理解还不够深入,不足以对其进行修改。
- 完成的标准是什么? 在编写代码之前,先写出验收标准。“它能运行”不是一个验收标准。“用户无需 Rust 工具链即可安装插件并正常运行”才是。
- 谁需要知道这件事? 涉及他人工作的变更,或者需要整个团队共同决策的事项,应在实施之前而非之后获得知晓。
这不是官僚主义,而是“构建某物”与“构建正确之物”之间的区别。这也直接适用于你如何使用 AI 工具,我们将在第 4 节中详细讨论。
当你跳过这一步时,会发生什么——说实话是这样的:你做出了一个能用的东西,开了 PR,然后在评审中才得知它解决的是错误的问题,或者它解决正确问题的方式与别处早已做出的决策相冲突。这浪费了你的时间、评审者的时间,并拖延了依赖这项工作的人。前期工作并不是额外的负担,而是你保护自己劳动成果的方式。
3. 与人协作
提供反馈
反馈是你能为其他工程师做的最有影响力的事情之一。一条写得好的评审评论可以教会别人多年才能自己学到的东西。而一条写得差的评论则可能让某人不再愿意贡献代码。
具体说明。 模糊的反馈只会带来焦虑,却缺乏明确的方向。
❌ “这很难阅读。”
✅ “这个函数处理了三个独立的关注点:输入校验、业务逻辑和响应格式化。建议将它们拆分开,让每个函数只做一件事。这样既便于单独测试每个部分,也能让人一眼看懂各自的功能。”
第二个版本更长,但它教会了读者一些东西。读者现在知道了问题是什么、为什么重要以及该如何解决。
解释原理,而不仅仅是结论。 如果你要求某人做出更改,请告诉他们原因。“将 X 更改为 Y”只能产生修复效果;而“将 X 更改为 Y,因为 Z”则能产生理解,这种理解会在接下来十个适用相同原理的情境中发挥作用。
将工作与人分开。 “这个方法有问题”和“你犯了一个错误”并不是同一回事。前者是关于代码的,后者则是针对个人的。请确保你的反馈集中在工作上。
指出好的地方。 这不是为了客气,而是为了实用。当你告诉别人他们哪里做对了,并解释为什么这样做是对的,你就在教他们应该重复哪些模式。泛泛的表扬(“干得好!”)什么也教不了。具体的表扬(“把这部分提取成独立的 crate 是正确的决定,因为这意味着我们现在可以隔离地测试这段逻辑,而不必启动整个 agent 循环”)则传授了原则,并强化了这个决策。
使用反馈分类法。 第 5 节中的分类法为每条评论赋予明确的权重。如果审阅者将阻塞性问题与次要建议混在一起而不加以区分,就会迫使作者去猜测哪些内容真正需要修改。不要让人去猜。
接收反馈
这对大多数人来说比提供反馈更难,而且诚实地说明原因很有价值。
当你在某件事上花费了数小时,攻克难题、做出决策、编写代码,而有人告诉你它存在问题时,人类的自然反应是觉得这些批评是针对你本人的。其实不然。批评针对的是工作成果。学会将这两者区分开来是一项技能,需要不断练习。
以下是一些有帮助的事项:
**先读完反馈,再作出回应。**不要只看摘要那一行,而要看完整条评论,包括其中的解释说明。很多反馈回应都是在还没有消化完原因之前,就针对结论作出的本能反应。先读懂“为什么“,再决定你对“是什么“的态度。
区分“我不同意”和“我不理解”。 这两种情况需要不同的回应方式。如果你不理解反馈内容,请提出澄清性问题;如果你理解反馈但不同意,请提供证据明确表达你的观点。这两种情况都是良好的结果。而当你有疑问时保持沉默,或者明明不同意却只说“好吧,行”,则毫无帮助。
你不必认同每一条反馈才能从中有所收获。 有时反馈是错误的。有时它反映的是与你所优化的目标不同的另一组权衡取舍。你完全可以提出异议。参见下文的“高效地表达异议“。但即便是你最终拒绝采纳的反馈,也值得在决定拒绝之前充分理解清楚。
形成闭环。 当有人花时间审查你的工作时,请在你处理完他们的反馈后告知他们。你不必过分致谢,一句简单的“已在最新提交中处理”就足够了。这能让他们知道自己的付出是有价值的,并推动 PR 持续进展。
对你的代码的反馈并不反映你的价值。 这听起来显而易见。但当你身处其中时,却并不明显。每一位经验丰富的工程师都会接受更有经验的人的代码审查,而这个过程每次都会让人感到不适。这种不适感正是学习的感觉。它不会消失;你只是逐渐学会与之共处。
请求帮助
在学校里,寻求帮助可能会让人觉得你落后于人,或者你不属于这个群体。而在团队中,寻求帮助是你所能做的最专业的事情之一。
陷入困境而不求助的代价,几乎总是高于求助的代价。 花三个小时在一个只需五分钟对话就能解决的问题上打转,意味着你和团队的时间白白浪费了。知道何时求助是一种技能,而不是弱点。
一个良好的帮助请求包含三个部分:
- **您想要实现的目标。**不要只说“它坏了“,而要说明您的目标是什么。
- 你已经尝试过的操作。 这表明你已投入精力解决问题,并为提供帮助的人提供了一个非零的起点。
- 你具体卡在哪里。 “我不知道哪里出了问题”与“我知道哪里出了问题,但不知道如何修复”以及“我修复了问题,但不知道为什么我的修复有效”是不同的问题。
包含这三个部分的问题求助会得到更快的解答,并且能让你学到更多,因为提供帮助的人可以准确地了解你当前的情况。
尽可能公开提问。 在共享频道或 PR 中提出的问题,能让日后遇到相同疑问的每个人受益。私下提出的问题只对你自己有益。有些情况下私下沟通才合适,比如敏感的反馈、个人状况,但关于代码库的技术性问题几乎总是公开提问更好。
不知道某件事并不丢人。 没有人无所不知。那些看似无所不知的工程师,是在漫长的时间里不断提问,才积累了这些答案。而通往这一境界的唯一途径,就是开始提问。
建设性地表达不同意见
架构上的分歧是健康的。它意味着人们关心系统的构建方式,并且在关注所做的决策。一个无人提出异议的团队,并不是一个所有人都意见一致的团队,而是一个人们已经停止参与的团队。
建设性分歧与无建设性分歧之间的差异通常在于表述方式。
先提出关切,而非结论。
❌ “这种方法是不正确的。”
✅ “我对这种方法有些担忧:具体来说,如果我们在这里把网关直接接入运行时,就会违反 RFC §4.2 中的依赖规则。我们能否讨论一下,是否有办法在不引入这种耦合的情况下达到同样的效果?”
第二个版本会打开一个对话。第一个版本会关闭一个对话。
提供证据。 基于测量事实、特定 RFC 章节或具体故障场景的架构分歧是一种贡献。而基于“我就是觉得”的架构分歧则是一种观点。两者都值得表达,但只有一种能推动对话快速进展。
真诚地接受自己可能是错的。 如果你在进入一场分歧时就已经认定自己是对的,那你并不是在交流,而是在游说。人们能分辨出这种区别,这会让他们不太愿意认真对待你的顾虑。我们的目标是为项目取得最佳结果,而不是证明自己正确。
当团队作出决定后,与团队一起行动。 你可以将自己的反对意见记录在案:在 issue 中、在 RFC 评论中、在 PR 讨论串中,然后你去构建已经决定好的方案。这不是妥协退让,而是团队运作的方式。一个不断重新争论已定决策的团队是无法交付成果的。
有些决策是可逆的,有些则不可逆。 明确你正在讨论的是哪一类决策。命名决策是可逆的,而一旦写入生产环境二进制文件并持续使用两年的协议决策则不可逆。请据此合理分配你的精力。
所有权
“所有权”是一个经常被使用但缺乏明确定义的词。以下是它在该项目中的实际含义:
拥有者意味着你在被要求之前就能看到问题。 这意味着阅读涉及你负责区域的 PR,并注意到作者未察觉的副作用。这意味着看到一个没有分配负责人的后续问题并主动接手。这意味着不等待被指示。
所有权意味着你的承诺是有分量的。 如果你提交了一个署有你名字的后续问题,那么这个问题就是你的承诺。不是“应该有人来做这件事“:而是你将完成这件事。如果情况发生变化,你无法完成,那么你要尽早说明,并找到接手的人。一个充斥着署名却被提交后即遗忘的问题的跟踪器,是一份破裂的信任记录。
当责并不是“我做完了我那部分”。 而是“我在乎整体能否正常运转”。你可以负责一个 crate,但这不意味着你可以对它所在系统是否健康漠不关心。你可以负责一项功能,但这不意味着你可以对用户是否真正用得上它漠不关心。狭隘的当责——“我做完了我那一块,剩下的是别人的问题”——会催生出这样的系统:每一块在名义上都有归属人,但在实际运作中却没有人对任何事情负责。
所有权包括后续跟进。 发布代码并不是所有权的终点,而是责任的开始——确保代码正常运行、修复出现的问题,并教会接下来在该领域工作的人你所学到的经验。
支持正在挣扎的人
在这个项目的某个阶段,你可能会比线程中的其他人更有经验。也许你在这里的时间更长,也许你恰好了解他们正在处理的代码部分,也许你之前见过这种特定的故障模式。
你如何使用这个职位很重要。
不要只是替他们修复问题。 在不解释问题所在或你的解决方案为何有效的前提下,直接给出一段可运行的代码,虽然能促成 PR 合并,但无法带来任何学习价值。下次他们遇到类似问题时,依然会陷入同样的困境。请多花五分钟时间,说明你发现的问题以及修复方案背后的原理。
带着传授的意图来评审。 一个糟糕的 PR 不仅仅是一个需要关闭的问题,它更是一次教学的机会。一个轻率敷衍的评审(“这不符合架构”)远不如一个能指出遗漏之处、解释其违反的原则、并指引贡献者从何处进一步学习的评审来得有用。这份额外的付出,是对一位贡献者的投资——从那时起,他将写出更好的 PR。
如果有人遇到了阻碍却没有寻求帮助,主动说点什么。 有时候人们不开口,是因为不想让自己看起来很吃力。有时候他们不确定该问谁。有时候他们已经卡了太久,以至于不再意识到自己有多么束手无策。一句轻声的“看起来这个问题已经搁置一段时间了,有什么我能帮忙解决的吗?”几乎不需要任何成本,但对一个正在原地打转的人来说可能意义重大。
营造“不知道也没关系”的安全感。 如果团队成员因为不了解某些事情而感到被评判,他们就会假装自己知道。这会导致更糟糕的决策,而不是更好的决策。那些能够让大家安心地说“我不知道,让我去查一下”的团队,会比那些每个人都表现得自信满满的团队做出更好的决策。
4. 使用 AI
本节涉及大多数贡献指南未涵盖的内容:如何以使你变得更强,而不仅仅是更快的方式使用 AI 编码工具。
委派心智模型
以下是与 AI 高效协作的最实用思维框架:
与 AI 协作的技能与向人委派任务相同。
当你将工作委托给同事或初级工程师时,你会提供上下文。你会解释目标、约束条件、什么是好的标准以及边界在哪里。你不会只是说“给我做一个功能”,而是会说:这是用户想要做的事情,这是它如何与系统契合,我们将如何知道它已经完成,以及你不应该做的事情。
然后,最关键的是,你要审查返回的结果。你不会不读就接受一位初级工程师的 PR。你要检查它是否实现了所要求的功能、是否符合架构、是否有测试覆盖、错误处理是否正确。你给出反馈。你可能需要多次迭代。
AI 工具的工作原理完全相同。你得到的结果质量几乎完全取决于你输入的内容质量。模糊的提示词会产生模糊的输出。而包含清晰上下文、具体约束条件和明确验收标准的提示词,则能生成真正有用的、可作为起点的输出。
那些在使用 AI 工具时举步维艰的工程师,通常仍在学习如何向任何对象——无论是人还是 AI——清晰地下达指令。而那些借助 AI 工具如鱼得水的工程师,则早在提出需求之前,就已经清楚地知道自己想要什么。
这种心智模型也意味着输出结果由你负责。你不能提交 PR 并说“是 AI 写的”。你审核了它,你提交了 PR。这是你的工作。
AI 在实现层工作
这是需要理解的最重要的技术限制。
AI 代码生成工作在决策层级的实现层:
Vision ← AI cannot set this. You must.
Architecture ← AI cannot make these decisions. You must.
Design ← AI will sometimes guess. You must verify.
Implementation ← AI can help here.
Testing ← AI can help, but you define what to test.
Documentation ← AI can draft. You must review for accuracy.
Release ← Human judgment required.
一个 AI 工具会生成一个实现你所描述功能的函数。但它不会告诉你该函数应该属于当前 crate 还是另一个 crate。它不会指出该方法与三个月前做出的架构决策相矛盾。它不会询问你是否考虑过安全影响。它也不会注意到你正在解决的是一个错误的问题。
ZeroClaw 本身就是一个有用的例子。其初始代码库是在 AI 辅助下快速搭建起来的。正如架构 RFC 所描述的那样,其结果是“功能上令人印象深刻,但架构上纯属偶然“。这些代码能完成当下所需的工作,但它并非经过设计,而是逐渐堆积而成的。这并不是 AI 工具的失败,而是在没有先完成愿景、架构和设计工作(这些工作为实现指明方向)的情况下使用实现层工具的可预见结果。
解决方案不是少用 AI,而是始终在要求 AI 构建任何内容之前,自己完成顶层层级的工作。
放大不是魔法
AI 工具放大了你现有的能力。这是对其作用的诚实描述。
如果你有清晰的愿景、明确的架构、能够清楚表达的质量标准,以及批判性评估输出的能力,AI 就是真正的力量倍增器。你的速度会更快。你会探索更多方案。你会编写更多测试。你会起草更多文档。
如果你没有这些东西,AI 会生成大量看似令人信服却经不起推敲的代码。它生成的测试虽然能通过,却没有测试任何有意义的内容。它生成的文档描述了代码本身,却没有体现意图。它生成的架构在局部是一致的,但在全局上却缺乏连贯性。
这种放大是中性化的。它以同样的热情放大好的输入和坏的输入。
这意味着在 AI 辅助工作流中,最有价值的技能不是提示工程,而是评估输出的能力。这要求你在提出任何请求之前,就清楚什么是好的结果。而这又让你一次次回到决策层级的顶端。
在使用 AI 工具实现某个功能之前,一个有用的自检步骤是:
- 可以,用一句话描述问题而不提及实现细节是完全可行的。
- 我可以为这个实现所服务的 RFC 章节或设计决策命名吗?
- 我可以在看到正确的实现之前,先描述一下它应该是什么样的吗?
- 在查看生成的实现后,我可以解释它是否正确或不正确吗?
如果其中任何一个问题的答案是否定的,那么您尚未准备好实施。您仍处于设计阶段。
审查纪律
AI 生成的代码需要与人工编写的代码相同的审查纪律。在某些方面,它甚至需要更多的审查,因为你需要检查的问题范围更广。
当你审查 AI 生成的输出(无论是你自己的还是他人的)时,请检查以下方面:
架构契合度。 这是否遵循了依赖规则?它是否位于正确的 crate 中?它是否引入了设计明确避免的耦合?
边界情况的正确性。 AI 模型在常见情况下表现良好,但在边界情况下经常出错。检查当输入为空、为 null、格式错误或达到最大预期大小时会发生什么。检查当依赖项不可用时会发生什么。
安全影响。 AI 工具默认不具备安全思维。它们会生成接受未验证用户输入的代码、记录敏感值、使用已弃用的密码学原语、以及在不检查文件路径的情况下打开文件路径。你必须明确引入安全视角。
测试质量。 AI 生成的测试经常测试实现而非行为。一个断言函数返回特定内部结构体值的测试并不是行为测试。它只是实现的一个快照,每当实现发生变化时就会失效。请自问:这个测试验证的是系统是否满足用户或调用方的需求,还是仅仅验证代码是否在做它当前所做的事情?
完整性。 AI 工具倾向于优化看似完整的代码。它们会生成详尽处理正常路径的代码,而对错误路径的处理则较为表面。请检查错误是否以真正对调用者有用的方式被传播、处理或暴露出来。
这对你的职业生涯意味着什么
这里所描述的技能——清晰地给出方向、批判性地评估输出、理解某个组件在更大系统中的定位、在动手构建之前就知道好的标准是什么样——并不是 AI 特有的技能。它们正是使一个人成为高效工程师、高效技术负责人,并最终成为高效工程经理的技能。
在一个被 AI 生成代码充斥的世界里,最有价值的工程师并不是那些能够最快编写最多代码的人,而是那些能够判断代码是否正确的人。这需要系统思维、架构判断力,以及根据内化的标准来评估工作的能力。
你在这里实践的每一件事——在动手实现前先理解 RFC,在构建前先追问“为什么“,以审视初级工程师 PR 的同样眼光去审查 AI 的输出——都是在锤炼那种判断力。它会日积月累、不断叠加。每一个你认真投入架构思考的 PR,都是一个数据点,让下一次架构决策变得更加从容。
本项目的贡献者拥有一个独特的优势:你正在一个真实的系统上构建这些习惯,面对真实的架构约束,并且会有人审查你的工作并解释原因。这种组合非常罕见,值得认真对待。
5. 反馈分类法
本项目中的每条评审意见都带有明确的权重等级。一致地使用这些权重等级,意味着评审者能够清晰地传达意见,而作者也能准确知道哪些内容需要处理。
下面的分类描述了项目的审查意图。PR 审查通过审查协议的表情符号标题来呈现该意图:🔴 阻塞、🟡 警告、🔵 建议、🟢 赞扬和 ✅ 已解决。请参阅 docs/book/src/contributing/pr-review-protocol.md 获取确切的 PR 审查格式。
✅ 表彰
作者做对的一件事,具体命名并加以解释,以便该模式得以重复。
这不是礼貌。泛泛的赞美(如“做得好!”)无法带来任何学习。具体的赞美并附带解释,能够阐明做得好的地方背后的原则,这些原则适用于未来同一类别的每一个决策。
表彰不需要任何操作。 其目的是强化。
示例:将工具调用解析器提取到独立的 crate 中是正确的决定:这段代码对 agent 状态零依赖,现在可以独立测试了。你新增的 91 个测试正是这类覆盖,而当这段逻辑还在
loop_.rs里时是不可能实现的。
🔴 阻塞
在 PR 合并之前必须解决的问题。阻塞项分为两类:
- 架构违规:代码违反了设计中明确禁止的依赖边界,或与 RFC 或 ADR 中记录的决策相矛盾。
- 质量回退:新行为缺少测试覆盖、安全问题、契约兼容性破坏,或引入缺陷的代码。
阻断性评论会说明问题是什么、为什么重要,以及在可能的情况下解决方案是什么样的。阻断性评论不是对作者的评判,而是审查者对代码库以及依赖该代码库的用户所应尽的责任。
作者不应将阻塞性评论视为拒绝。 这是一个具体且可解决的问题。解决它并继续前进。
🟡 条件
可以接受推迟处理,但前提是必须有一个已跟踪的问题(tracked issue)并指定了负责人。这种条件性要求是审查者所说的:“我相信这个问题会得到解决,但在合并之前,我需要这个承诺有记录。”
阻塞式与条件式的区别通常在于时机和风险。下一个 PR 中将交付的缺失功能是条件式。而存在安全漏洞的缺失功能则是阻塞式。
没有指派负责人的条件性延期不是延期,而是空想。 没有负责人的跟踪问题往往会无限期地保持开放状态。当审查者将某项内容标记为条件性时,他们要求的是明确指派的承诺,而非理论上的未来意向。
🔵 团队决策
PR 揭示出的、不应由任何单个评审者或作者单方面解决的问题。团队决策涉及影响项目方向、架构或用户的权衡取舍,应交由整个团队共同决定。
使用此标签是审阅者避免因那些实际上关乎共同方向的问题而拖延个人贡献者的方式。它将决策摆上台面,阐明各种权衡取舍,并请团队发表意见,同时不会让作者觉得自己的 PR 被某些超出其控制范围的事情所阻塞。
团队决策应在 PR 线程中以书面形式记录,并由需要对结果负责的人员作出。 任何未在 PR 线程中体现的私下讨论,对于后续查阅历史记录的人来说,都不存在。
6. 给评审者和导师的说明
如果你处于审阅他人工作的位置,无论是作为代码所有者、更有经验的贡献者,还是仅仅是来得更久的人,本节都适合你。
你正在塑造协作的样子。 你撰写的每一次评审都在教作者如何评审。你在 PR 讨论中提出的每一个问题,都在教导新加入的贡献者哪些问题值得提出。你无法置身事外:唯一的选择是有意为之,还是听之任之。
细致是对作者的尊重。 一份详尽且阐明其推理过程的审查,比草率的批准更能体现对作者付出的尊重。作者为这项工作投入了时间,他们理应了解代码为何尚未达到合并标准,以及可以从这次审查中获得哪些改进方向。
每次评审交互的目标,是让作者比之前更有能力。 不仅仅是合并一个 PR。不是为了展示你自己的知识。不是为了强制执行规则。而是给作者留下他们可以使用的东西:一条原则、一种模式、对某个权衡的理解,这些都能超越当前 PR 而发挥作用。
说明模式,而不仅仅是具体实例。 当你要求做出修改时,请解释其背后的原则。“将这个变量重命名为能描述其内容的名称”不如“变量名应当从调用者的视角描述其用途,而非从实现的视角:调用此函数的人真正关心的是这个值代表什么?”更有用。后一种说法适用于作者今后将编写的每个函数中的每个变量。
坦诚区分哪些是你的个人偏好,哪些是硬性要求。“我会用不同的方式来写“和“这必须修改“并不是一回事。如果你表达的是个人偏好,就明确说出来。如果你援引的是硬性要求:架构、安全、兼容性,那就列出具体原因。如果作者无法分辨审阅者的个人偏好和架构上的必然要求,他们要么会改动所有内容,要么什么都不改。这两种结果对他们都没有好处。
你正在帮助构建的团队,就是你将加入的团队。 你今天投入的细致、教育性的审查工作,会逐步培养出一个能写出更优质代码、提出更高质量 PR,并对他人进行更深思熟虑审查的贡献者。这会让整个项目变得更好。同时,它也会让你的工作更轻松,因为你身边的同事都在不断成长。
这不是软技能,而是工程工作。