claude-architecture-skill — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited claude-architecture-skill (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
这份规则描述的是在面对架构设计或架构相关决策时的真实推理过程。架构决策的特殊性在于它们的影响是长期的、范围是广泛的、修改成本是高昂的。因此在架构层面的每一个决策都需要比代码层面的决策更充分的推理和更明确的权衡意识。这份文档的核心是:永远不做"最先进"的架构,只做"当前约束下最合适"的架构。
每一种架构模式都是在解决某些问题的同时引入另一些问题。微服务解决了大单体的扩展和部署问题,但引入了分布式系统的复杂性。事件驱动架构解耦了生产者和消费者,但引入了最终一致性和调试复杂性。
在做架构决策时,首先要明确:当前阶段最需要解决的问题是什么,当前阶段最难以承受的复杂性是什么。选择一种架构就是选择了它解决的问题和它引入的复杂性。
flowchart TD
A[面临架构决策] --> B[识别当前最需要解决的问题]
B --> C[识别当前最难以承受的复杂性]
C --> D[列出候选架构方案]
D --> E[评估每种方案解决的问题]
D --> F[评估每种方案引入的复杂性]
E & F --> G[与当前阶段的需要对比]
G --> H[选择解决目标问题且引入可承受复杂性的方案]
H --> I[明确记录选择的理由和已知的权衡]同样的业务功能,在不同的阶段应该有不同的架构。早期产品验证阶段的最大风险是没有找到正确的产品方向,此时最重要的是快速迭代,最需要回避的是过度设计的复杂性。规模增长阶段的最大风险是系统无法支撑业务增长,此时最重要的是可扩展性,最需要回避的是单点瓶颈。成熟稳定阶段的最大风险是大规模改动引入不可控的风险,此时最重要的是稳定性,最需要回避的是不必要的重构。
架构决策的一个常见问题是:决策背后的权衡信息随着人员更替而丢失,导致后来的人在不理解约束的情况下做出推翻原有决策的改动,然后发现原来的问题又回来了。
每一个重要的架构决策都应该有对应的记录,说明:面临的问题是什么,考虑了哪些选项,最终选择了什么,选择的理由是什么,这个选择的已知局限是什么,以及在什么条件下这个决策应该被重新评估。
分层不是为了让代码看起来有组织,而是为了在系统的某个部分发生变化时,不需要修改其他部分。每一层的边界对应一个可能发生变化的维度。
展示层隔离的变化:用户界面如何呈现,API 协议是 REST 还是 GraphQL,渠道是 Web 还是 Mobile。
业务逻辑层隔离的变化:业务规则如何运作,业务流程的顺序,权限和验证规则。
数据访问层隔离的变化:数据存储在哪里,使用什么数据库,查询如何优化。
flowchart TB
subgraph 展示层
direction LR
A1[Web 界面]
A2[REST API]
A3[GraphQL API]
end
subgraph 业务逻辑层
B1[用例\n业务流程编排]
B2[领域模型\n业务规则和状态]
B3[权限\n验证逻辑]
end
subgraph 数据访问层
C1[仓储接口\n定义访问契约]
C2[数据库实现]
C3[外部服务调用]
end
展示层 --> 业务逻辑层
业务逻辑层 --> 数据访问层上层只能调用下层,下层不能调用上层。这个规则防止了循环依赖,也确保了下层的可复用性(下层不依赖上层,所以可以被任意上层使用)。
层间通信必须通过定义好的接口,不允许跨层直接访问。展示层不能直接读取数据库,业务逻辑层不能直接依赖具体的数据库实现(只能依赖数据访问层的接口定义)。
展示层不应该包含业务规则。如果一段验证逻辑出现在了控制器或视图里,它应该被移到业务逻辑层。
业务逻辑层不应该包含 SQL 或 ORM 查询。这些东西应该在数据访问层。业务逻辑层只需要知道它想要什么数据,不需要知道数据从哪里来。
数据访问层不应该包含业务规则。如果数据库查询里有分支来处理不同的业务逻辑,这些分支应该被提取到业务逻辑层。
服务的边界应该对应一个业务能力(一个相对独立的业务功能域),而不是对应一个技术层次。
一个服务应该包含完成它负责的业务能力所需的所有技术组件:API 端点、业务逻辑、数据存储。不应该把所有服务的 API 层放在一起,所有服务的数据库层放在另一起。
判断一个服务边界是否正确的测试:在这个服务内部做一个功能改动,是否需要同步修改其他服务?如果改动一个服务经常需要修改另一个服务,说明这两个服务的边界划分可能有问题,它们应该被合并或者重新划分边界。
高内聚意味着:属于同一个服务的组件经常需要一起变化。如果在一次功能迭代中,某两个模块总是被同时修改,它们应该在同一个服务里。
低耦合意味着:不同服务之间的接口应该是稳定的,接口背后的实现可以独立演进。服务之间不应该共享数据库表,不应该通过直接读取对方的内部数据结构来交互,只应该通过定义好的接口(API 调用或消息队列)来交互。
flowchart LR
subgraph 用户服务
A1[用户 API]
A2[用户业务逻辑]
A3[用户数据库]
A1 --> A2 --> A3
end
subgraph 订单服务
B1[订单 API]
B2[订单业务逻辑]
B3[订单数据库]
B1 --> B2 --> B3
end
subgraph 通知服务
C1[通知 API]
C2[通知业务逻辑]
C3[通知数据库]
C1 --> C2 --> C3
end
A1 -- 用户信息接口 --> B2
B2 -- 触发通知 --> C1过早拆分比过晚拆分代价更高。一个单体应用可以在架构内部保持模块化,在需要时拆分出独立的服务。但一旦服务被拆分出去,它们的边界就变得难以调整,因为需要协调多个独立部署的系统。
拆分服务的合理时机:一个模块的扩展需求与其他模块明显不同;一个模块的部署频率与其他模块明显不同;一个模块需要使用与其他模块完全不同的技术栈;一个模块的团队完全独立,需要独立的开发和发布周期。
在一个系统中,任何一份数据都应该有清晰的流向:从哪里产生,经过哪些处理,存储在哪里,被哪些功能消费。数据流不清晰会导致数据一致性问题难以定位,也会让扩展新功能时不知道在哪个位置接入。
选择同步还是异步数据流的依据是:操作的性质和一致性要求,而不是实现的难易程度。
同步流适合:用户操作需要即时反馈;操作有明确的事务边界;下游操作失败时上游需要回滚。
异步流适合:操作耗时较长且用户不需要等待;操作不需要即时一致性;需要削峰填谷处理突发的大量请求。
flowchart TD
A[需要设计数据流] --> B{操作是否需要即时反馈}
B -- 是 --> C{下游失败是否需要上游回滚}
C -- 是 --> D[同步流\n事务性处理]
C -- 否 --> E[同步流\n独立错误处理]
B -- 否 --> F{下游是否需要保证执行}
F -- 是 --> G[异步流\n持久化消息队列\n至少一次投递]
F -- 否 --> H[异步流\n事件发布\n订阅方自行决定是否处理]在分布式系统中,同一份数据可能被多个服务持有。这种情况需要明确的一致性策略。
强一致性:每次访问都读取最新值,通过分布式锁或事务保证,性能代价高。
最终一致性:允许短暂的不一致,通过事件通知或定期同步使数据最终达到一致,性能更好,实现更复杂。
选择依据:用户体验对一致性的敏感程度,以及不一致时间窗口内发生错误的业务风险。
如果一个服务实例在内存中保存了请求相关的状态,那么这个服务就不能简单地通过增加实例来扩展,因为后续的请求如果被路由到不同的实例,无法访问之前实例的内存状态。
实现无状态服务的核心原则:会话状态存储在分布式缓存;文件临时存储在共享存储;任务状态存储在数据库;实例本地只保存配置,不保存运行时状态。
在大多数系统中,应用服务层可以通过水平扩展来应对流量增长,但数据库的扩展相对困难。减少数据库压力的设计策略:高频读取的数据通过缓存层提供;写操作通过队列异步处理;只读操作和写操作通过读写分离分离到不同实例。
当系统的某个部分出现故障时,故障不应该传播到其他部分。这需要在设计时为每个依赖关系定义故障隔离策略。
flowchart TD
A[服务 A 调用服务 B] --> B{服务 B 是否可用}
B -- 可用 --> C[正常处理]
B -- 不可用 --> D[熔断器打开\n停止调用服务 B]
D --> E{是否有降级方案}
E -- 有 --> F[执行降级逻辑\n返回安全的默认响应]
E -- 没有 --> G[快速失败\n返回明确的错误]
F & G --> H[记录故障日志和指标]
D --> I[定期探测服务 B 是否恢复]
I --> J{服务 B 是否已恢复}
J -- 是 --> K[关闭熔断器\n恢复正常调用]
J -- 否 --> I在分布式系统中,网络失败后的重试可能导致同一个操作被执行多次。需要在设计时确保关键操作是幂等的,即执行多次与执行一次的效果相同。
幂等性的实现方式:使用客户端生成的唯一请求 ID,服务端在处理请求前先检查这个 ID 是否已经被处理过,如果已经处理过则直接返回之前的结果而不重复执行。
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.