mcpField
E
engineering-principles

engineering-principles

github.com/jamespegg开发045 次安装2 天前更新
代码仓库

关于 engineering-principles

engineering-principles 是面向个人及编码 Agent 维护的小型项目的语言无关指南,强调便于局部理解、按实际需求控制复杂度、清晰的代码结构,以及与风险相称的验证方式。

主要功能

  1. 01便于局部理解与清晰导航
  2. 02复杂度须由实际需求支撑
  3. 03内聚且浅层的结构
  4. 04明确副作用和依赖
  5. 05与风险相称的验证
  6. 06轻量级设计检查

适用场景

  1. 01为功能选择简单设计
  2. 02组织包和文件
  3. 03判断测试是否值得编写
  4. 04审视运维与恢复需求

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/jamespegg/skills --skill engineering-principles

安装后在 Claude Code 中输入/engineering-principles确认已加载。

附带文件agents/openai.yaml

详细介绍

架构与工程原则

以便于本地推理为目标。 开发者应能通过查看代码库中一小块明显的区域,找到、理解、修改并验证某项能力,而无需在多层间接关系或隐藏依赖中摸索。

适用于由一人和未来的编码 Agent 维护的小型项目的语言无关默认原则。优先选择满足实际需求的最简单且连贯的设计。按比例严谨对待,切勿机械执行。有关构建时采用的技术,请参阅 tech-preferences;有关 AI 风险和权限边界,请参阅 verifiable-trust。

实现前先论证复杂性的必要性

  • 质疑需求,而不只是代码。 在添加组件、行为、依赖或防御机制前,明确具体需求和最简单的端到端结果。删除不必要的需求,往往胜过优雅地实现它。
  • 区分证据与假设。 根据可信故障发生的可能性、后果和可恢复性采取防护措施;不要为推测性的场景构建繁复机制。对于凭据、权限和不可逆的持久状态变更,应保留有力的防护措施。
  • 让复杂性物有所值。 每个新概念、验证、层、配置选项或测试,都应能降低实际风险或实现实际能力。如果利用平台或现有安装程序能减少工作,就应复用,而不是重新实现它们承担的职责。
  • 优先选择精简而完整的方案。 如果切换后就会移除临时代码,那么在未启用的替代实现中避免保留临时兼容代码,除非确有使用方或迁移步骤需要它。不要为了消除重复代码而引入比重复代码更难理解的框架。
  • 重新审视完成后的设计。 行为正常后,检查是否能移除某些职责、分支或依赖,同时不削弱必要行为。优化目标应是减少概念、加快理解,而非追求最少代码行或任意限制。

结构与导航

  • 按能力组织,而非按架构层组织。 包和目录应说明软件的用途,而不是使用 ports、adapters、models 或 services 等通用标签,除非某个架构术语确实是最清晰的领域专用名称。
  • 让命名和导航一目了然。 有意义的包、文件、类型和函数名称,应让贡献者能预判代码属于何处。
  • 优先选择更少且内聚的包。 将相关职责放在一起;在创建新的包边界前,先考虑在包内使用描述明确的独立文件。
  • 高内聚、松耦合。 因相同原因而变更的代码通常应放在一起;无关的能力应尽量减少显式依赖。
  • 保持结构扁平。 没有真实边界时,不要增加嵌套、拆分或额外层级。
  • 避免杂物堆。 不要创建囊括一切的 utils、common、helpers 或 misc。为行为指定明确的归属。
  • 关注点分离不等于必须拆分成多个包。 包的数量和文件大小都不是目标。

实现与依赖

  • 为使用者设计 API。 提供小巧、可预测的操作;隐藏使用者无需了解的实现细节。
  • 优先使用具体依赖。 除非有明确的边界、可替换实现或测试需求,否则直接调用。不要习惯性地创建接口。
  • 明确呈现副作用。 不要使用隐藏的可变全局状态、意外副作用或魔法式连接。
  • 清晰胜过巧妙或臆想式复用。 与其用共享抽象耦合无关功能,不如接受少量重复。不要构建虚构的扩展点。
  • 审慎处理错误。 清楚地报错,保留有用上下文,清理资源,并说明恢复方式。
  • 仅在确有必要时使用并发。 从顺序执行开始;如果确有需要,应让所有权、取消、超时和关闭逻辑易于理解。
  • 保持可部署服务边界清晰合理。 服务应拥有明确的能力,并在服务之间使用清晰的契约;独立部署不应要求过多内部层次。

配置、运行时与运维

  • 将代码与部署设置分离。 将密钥和依赖环境的值外置。适当时,优先使用便于审查、纳入版本控制的结构化配置来管理应用策略。切勿嵌入凭据。
  • 确保构建与发布可复现。 声明并锁定依赖,构建一次,再推广不可变且可识别的制品。
  • 进程应可替换,持久状态应有意管理。 确保启动可预测、关闭平稳、恢复有序。区分临时进程状态与持久用户数据、身份信息和代码库。
  • 确保环境具有实质上的一致性。 开发、CI 和部署中的路径与依赖应尽可能相当,并明确说明差异。
  • 确保可观测、可运维。 提供有用的错误信息、结构化日志、健康检查,以及有文档记录且可重复执行的验证和恢复命令,避免依赖手动流程。

验证与演进

  • 测试可观察行为,而非偶然的实现细节。 行为变更应优先在约定的公共边界采用测试先行的红 → 绿垂直切片;通过有独立依据的预期结果,覆盖重要的成功、失败和恢复路径。不要为了满足流程而编写脆弱、与实现紧密耦合或自我验证的测试。静态检查必须确保真实的不变量。
  • 小而完整的变更。 解决问题时避免无关重构、假设性的基础设施或废弃的兼容层。除非有意变更,否则应保留既有契约。
  • 让决策持久留存且易于查找。 在维护者会查阅的地方记录不明显的约束、理由和操作方式,而不只是在聊天中说明。避免冗长或重复的指引。
  • 让代码库本身说明架构。 清晰的布局、契约和可执行约定应减少对 Agent 指令的需求。如果 Agent 反复失败,应先改进结构、文档或检查,再增加常设规则。
  • 优先让系统自明,而非依赖指令。 文档应保留设计意图和不明显的选择,而不是用来弥补令人困惑的代码。
  • 保持严谨程度适当。 实验应采用快速、可逆的探索方式;对于生产环境或影响重大的变更,则应加强安全性、可观测性、验证和恢复能力。

测试与 CI 投入

测试、固件和 CI 都是需要持续维护并会产生运行成本的软件。对于规模较小、易于恢复的业余项目,应优先追求有用的信心和快速反馈,而非尽可能庞大的测试清单。

  • 为每项不同的测试说明理由。 指出它能检测到的现实故障及其后果,并确认其他测试是否已覆盖相同行为。不要把每个分支、临时迁移或历史事件都变成永久的回归测试矩阵。对凭据、权限、破坏性写入和难以恢复的状态,应保留更强的覆盖。
  • 在成本最低且有意义的边界上测试一次。 优先测试本地行为和契约,用少量可执行测试或集成测试覆盖真实边界,并对打包进行最精简的组装镜像冒烟测试。在每一层重复运行相同场景,并不一定能增加信心。
  • 避免为合成时间付出真实时间。 在可行时,注入可控的重试延迟或时钟;只有当真实计时、进程信号和容器编排本身就是风险所在时,才测试这些行为。复杂的固件必须有明确且独特的存在理由。
  • 有意识地选择人工验收。 对低影响且易于恢复、发生频率较低的外部服务、历史版本升级及仅限运维人员执行的场景,简短且有文档记录的人工冒烟测试可能更合适。对于经常重复或难以准确检查的场景,应实现自动化。
  • 保持默认反馈循环精简。 在常规 PR 上运行快速且影响重大的检查。当额外信心值得等待时,可将大型迁移矩阵、耗时的全镜像测试及依赖环境的检查设为可选或仅在发布时运行。不要为了显得全面而凭空增设门禁或 CI 基础设施。
  • 先分析性能,再并行化。 测量测试、打包和作业所需时间,避免不必要的串行依赖;只有在资源限制和产物发布安全性允许时,才并行处理独立工作。在安全的情况下取消已过时的 PR 运行,但不要取消必需的不可变发布构建。
  • 删除已被取代的验证。 迁移完成后,或测试失败已不再影响当前契约时,应简化或移除该测试;更改所需验证级别时,也应更新过时的发布说明和决策记录。

快速设计检查

添加包、依赖、抽象或流程之前,请考虑:

  1. 底层需求是否必要?能解决问题的最小成果是什么?
  2. 人们通常会在哪里寻找此功能?能否在本地理解它?
  3. 这个边界是否对应真实的职责或变更原因?
  4. 与直接方案相比,这种复杂性是否能以更简单的方式解决有证据支持的需求或重大风险?
  5. 能否验证重要行为和故障,并恢复任何后果重大的变更?

这是一种轻量级决策辅助工具,并非每次编辑都必须完成的检查清单。如果某种惯例妨碍导航,请说明其中的取舍,并选择更简单的设计。

影响因素,而非强制框架

这些设计启发并不强制要求使用 Go、为每项设置都使用环境变量,也不要求在有意保留持久状态时实现无状态。

评论

支持 Markdown