结合项目上下文写代码
目标不是把新代码写得“像项目”,而是在动手前理解项目已经形成的业务约束、真实消费者和历史经验,减少重复踩坑。项目已有实现优先作为参考样本,但仍要判断它是否适用于当前需求、版本和调用链。
边界
- 只修改用户当前需求必需的代码、配置、测试和文档,不顺手重构或扩展未来能力。
- 先检查工作区、分支、worktree 和仓库说明,保留其他人或其他会话的未知改动。
- 删除文件、函数、注释、测试、兼容逻辑或数据前单独说明理由并取得确认。
- 实现授权不包含 commit、push、部署、创建 PR、外部评论或数据库写入;这些动作需要当前批次的明确授权。
- 仓库若提供专用开发 Skill 或规范工具,例如
goalfy-coding,按当前任务读取并组合使用,但不得让其自动扩大本次写入范围。
工作流
1. 固定目标与现场
读取适用的 AGENTS.md、CLAUDE.md、仓库级 Skill 和开发文档。检查 git status、当前分支、HEAD、worktree 和已有 diff;涉及远端基线时先 git fetch,仅审查当前未提交改动时不为形式强制刷新远端。
用可观察结果明确本次需求:谁在什么条件下触发,现有行为哪里偏离,完成后谁能看到什么变化。若信息能从代码、配置、测试或关联材料中确认,先自行读取;只有关键选择会实质改变方案时才询问用户。
2. 还原最小完整机制
追踪与改动有关的真实链路:
输入或触发
→ 入口与生产者
→ 状态或数据变化
→ 真实消费者
→ 用户可见结果
→ 失败、重试、恢复或终态
只展开与当前需求有关的上下游。不能根据函数名、字段名或注释猜用途;读取方法体、调用方、被调用方、注册点、配置来源和必要运行时契约。
共享配置还要与构造参数交叉检查:当同一个配置对象或字段被多个构造器、工厂或 wrapper 复用,而调用时又传入 bucket、tenant、region、namespace、资源 ID 等会改变语义的参数,列出全部生产调用方及其真实实参组合,区分“配置属于谁”和“本次 client 操作谁”。至少让默认消费者和一个非默认消费者走通同一验证链;默认实例的测试不能代表其他 bucket、租户或资源。
3. 按风险参考项目已有实现
使用 rg 从同仓库开始寻找最接近的样本,常用线索包括业务字段、接口路径、错误码、注册方法、消费者名称、配置键和测试名称。按以下优先级选择真正有参考价值的代码:
- 与本次改动共享真实消费者或协议链路;
- 同模块、同业务角色或同一状态生命周期;
- 有针对性测试或运行证据;
- 当前仍在使用且版本接近;
- 历史提交明确记录过踩坑原因。
简单文案、局部条件或单点字段改动,通常参考最邻近的一处实现即可,不做无边界考古。涉及协议、Schema、序列化、数据库约束、跨服务接口、并发、幂等、权限或兼容行为时,扩大到真实消费者、相关测试和必要 git log / git blame,确认项目曾经为何选择当前写法。
参考时回答三个问题:
- 哪部分约束与当前需求相同,可以沿用;
- 旧设计解决或规避了什么实际问题;
- 哪部分场景、版本或消费者不同,不能机械复制。
已有代码是经验,不是绝对规则。若它已过时、有缺陷或不适用于新场景,可以偏离;但要写清差异来自新需求、依赖版本还是消费者能力,并用针对性测试验证。不要因为某写法符合通用标准、看起来更优雅或外部项目流行,就跳过本项目真实链路。
找不到可靠样本时,记录搜索过的范围和关键词,再查真实消费者实现、官方当前契约或执行最小探针。不要为了满足流程强行选择不相关代码,也不要仅因没有先例就阻塞低风险实现。
4. 设计并实施最小改动
涉及新增或调整模块职责、接口与依赖方向时,使用 $codebase-design 检查高内聚、低耦合;普通局部修改不额外加载。
优先复用项目现有入口、抽象、错误处理、命名和测试结构,但只复用当前需求真正需要的部分。每个 diff hunk 都应能对应到需求、已确认根因、必要测试或项目强制工具输出;无法对应的格式化、helper 抽取、依赖升级和未来兼容应移除或先征求授权。
改动 Schema、API 或协议时,区分“标准允许”和“项目真实消费者支持”。例如某个 JSON Schema 关键字在规范中合法,不代表当前模型、SDK、网关或工具注册链路接受;使用与项目相同的消费路径和样例验证,不把单一历史结论错误推广到所有协议或版本。
遵循仓库现有结构完成最小实现,使用当前环境提供的精确编辑工具。不要覆盖未知改动,不修改无关文件,不为让测试变绿而放松断言、跳过测试或隐藏错误。
5. 用同一条真实链路验证
按风险选择最短但能证明行为的验证:
- 运行直接覆盖改动的单元或集成测试;
- 对照项目现有样本,确认输入、输出、错误和副作用语义一致;
- 涉及两层校验或不同库时,用同一组标准、兼容、非法和边界输入分别验证;
- 检查正常、失败和必要恢复路径,确认没有破坏旧消费者;
- 运行仓库要求的格式、静态检查和目标测试,再检查最终 diff 是否仍为最小范围。
测试绿灯只证明已覆盖的样例。无法运行真实消费者或关键环境时,明确写“未验证”,并给出会改变结论的最短验证动作,不以本地模拟冒充线上事实。
6. 完成前自审、修复与复审
首次实现和目标验证完成后,交付前必须读取并使用完整的 $peer-pr-review,对本次完整改动做一次独立自审。以步骤 1 固定的需求基线为起点,以当前最终状态为终点,覆盖属于本次任务的 commit、staged、unstaged 和相关 untracked 文件;把其他会话或用户原有改动单独识别出来,不能混入本次结论。peer-pr-review 在这一阶段保持只读,只负责固定事实、审查完整 diff 并形成 finding;其引用本 Skill 时仅复用步骤 1~5 的调查、设计和验证标准,不重新启动本步骤。
自审必须重新对照原需求、已确认根因和验收结果,至少核对真实生产者与消费者、正常/失败/恢复路径、状态与副作用、测试是否能抓住旧缺陷,以及每个 diff hunk 是否都属于必要范围。不能因为实现者和审查者是同一个 agent,就复用实现时的结论代替独立核验。
自审给出结论前,还必须从 $peer-pr-review 得到两项可核验结论:一是项目中最接近的现有实现、测试或历史修复能否直接复用,若选择偏离,差异是否由当前需求或消费者证明;二是新增的抽象、状态、helper、后台任务、缓存、兼容层或重试机制能否删除、合并或改用项目现有入口。若更小方案能保持相同验收、失败语义和测试保护,多出的设计应形成 finding,不能因已经写完而保留。
对自审发现的问题按下面的闭环处理:
- finding 有明确证据、属于原需求授权范围,且不需要新增产品选择、删除实质内容或其他单独授权时,退出只读审查阶段,回到步骤 4 自动修复,再执行步骤 5 的相关验证;
- 修复后基于最新完整 diff 重新执行整个自审,不能只回归上一条 finding;继续循环,直到没有证据支持的必须修复项;
- 建议项、低概率隐患、超出原需求的重构或优化不自动修改;证据不足时先执行安全的只读核验,仍无法确认则作为未验证缺口交付;
- finding 若要求扩大功能范围、改变接口/数据/用户体验、删除实质内容,或执行 commit、push、部署、外部通知、数据库写入等额外动作,先向用户说明并取得对应授权。
自审闭环的完成条件是:最新完整 diff 中没有仍可在原授权范围内修复的必须项,目标验证在最后一次修复后重新通过,剩余未验证事实已明确标注。交付时简要汇报自审结论、已自动修复的问题和未解决缺口;除非用户要求独立 Review 报告,不重复输出完整教学型审查文档。
交付
先说明完成结果,再简要列出:
- 改了什么以及影响范围;
- 哪些项目已有实现或历史经验实际影响了方案;
- 运行了什么验证,结果如何;
- 自审发现并自动修复了什么,最终复审结论是什么;
- 仍有哪些会影响正确性的未验证事实。
如果已有代码只提供了普通参考、没有改变实现决策,不必为展示流程罗列完整搜索记录。
完成条件
步骤 1~5 的适用要求已满足,步骤 6 的自审闭环已完成,剩余缺口已按“交付”说明;各步骤中的检查不再另行重复执行。