关于 codeprobe-architecture
用于分析软件架构与结构的 codeprobe 技能,检查依赖循环、分层边界、领域划分、目录规范和配置实践。
主要功能
- 01查找模块间循环依赖
- 02检查分层违规
- 03检测过大的文件与类
- 04审查领域和模块边界
- 05检查目录规范与配置实践
适用场景
- 01审查现有代码库的架构
- 02查找模块间循环导入
- 03评估成长中项目的领域划分
- 04检查框架目录结构与环境配置
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ machineroom-dev/ codeprobe --skill codeprobe-architecture安装后在 Claude Code 中输入/codeprobe-architecture确认已加载。
详细介绍
独立模式
如果直接调用(而非通过编排器调用),必须先:
- 读取
../codeprobe/shared-preamble.md(相对于此 SKILL.md 所在位置解析——即同级的codeprobe技能目录,而非用户的项目),了解输出约定、执行模式和限制。 - 根据项目的技术栈,从
../codeprobe/references/(以相同方式解析)加载适用的参考文件。 - 除非用户另有指定,否则默认使用
full模式。
架构与结构分析器
领域范围
此子技能可检测以下类别中的架构和结构问题:
- 分层违规 — 控制器中包含业务逻辑、模型中包含表示逻辑、视图中包含数据库访问
- 循环依赖 — 模块之间存在直接或传递的循环导入
- 上帝对象 — 文件和类过于庞大,承担过多职责
- 贫血领域模型 — 实体类没有行为,所有逻辑都放在服务类中
- 边界缺失 — 缺少清晰的模块/领域划分,功能之间存在耦合
- 目录结构 — 违反框架约定、扁平目录反模式
- 配置/环境 — 环境值硬编码、缺少配置抽象
不会标记的情况
- 少于 5 个文件的小型项目/脚本 — 扁平结构适用于小型代码库,增加分层会造成过度设计。
- 有意采用薄分层的微服务 — 按设计来说,只有一个控制器、一个服务和一个仓库的微服务没有问题。
- 符合框架标准且符合惯例的单体模式 — 例如,Laravel 面向中小型应用的默认结构、Rails 的约定优于配置模式、Next.js 的 app 目录约定。
- 明确标记为原型或概念验证的代码。
- 生成代码目录(例如
dist/、build/、.next/、__pycache__/)。
检测说明
分层违规
| ID 前缀 | 检测内容 | 检测方法 | 严重性 |
|---|---|---|---|
ARCH | 控制器中包含业务逻辑 | 扫描控制器目录中的文件(controllers/、Controllers/、routes/、api/)。标记包含以下内容的控制器:数据库查询(SQL、超出简单 find()/findById() 范围的 ORM 查询构建器)、包含业务规则的复杂条件判断(3 个以上分支)、计算、数据转换,或超出简单字段存在性检查的验证逻辑。控制器应将工作委托给服务/操作。 | 主要 |
ARCH | 模型/实体中包含表示逻辑 | 扫描模型/实体文件。标记包含以下内容的模型:HTML 生成、用于显示的字符串格式化(例如 toHtml()、formatForDisplay())、特定于视图的转换、CSS 类计算或响应格式化。模型应包含领域逻辑,而非表示逻辑。 | 主要 |
ARCH | 视图/组件直接调用数据库 | 扫描视图文件(.blade.php、.vue、.jsx/.tsx 组件、.ejs、.pug、Jinja 模板)。标记包含以下内容的视图:直接数据库查询、ORM 调用、原始 SQL 或仓库方法调用。视图应从控制器/props 接收数据,绝不能自行获取数据。 | 主要 |
循环依赖
| ID 前缀 | 检测内容 | 检测方法 | 严重程度 |
|---|---|---|---|
ARCH | 模块 A 导入 B,B 导入 A(直接或传递) | 优先使用预加载的依赖图(见下方“依赖图”小节)。如果存在依赖图,其中会包含 circular_dependencies 数组,列出每个循环依赖的完整文件路径链——针对每个循环依赖报告一项 ARCH 发现,并将该路径链作为证据。如果依赖图不存在(降级模式),则回退到跨文件追踪 import/require/use 语句,查找直接循环(A→B→A)和传递循环(A→B→C→A)。重点关注模块级(目录级)循环,因为其在架构上的重要性高于同一模块内的文件级循环。 | Major |
依赖图(预加载)
通过 /codeprobe audit 或 /codeprobe architecture 调用时,协调器会运行 scripts/dependency_mapper.py 预先计算导入图,并在 === DEPENDENCY_GRAPH === 和 === END DEPENDENCY_GRAPH === 标记之间提供 JSON 上下文。JSON 架构如下:
graph:{file_path: [files it imports]}— 完整的依赖图。circular_dependencies:循环依赖对象列表,每个对象都包含完整的文件路径链(例如,["a.py", "b.py", "c.py", "a.py"])。summary:{total_files, total_cycles, most_imported, most_dependencies}— 汇总统计数据。
存在依赖图时,将其视为事实依据:circular_dependencies 中的每个循环依赖都应成为一项 ARCH 发现。不要尝试自行检测循环依赖——该脚本使用确定性的 DFS,可靠性高于 LLM 导入追踪。
依赖图不存在时(脚本运行失败、缺少 Python 3 或处于降级模式),按上方“循环依赖”表中的说明,回退到基于 LLM 的导入追踪。
上帝对象
| ID 前缀 | 检测内容 | 检测方法 | 严重程度 |
|---|---|---|---|
ARCH | 文件超过 500 LOC | 统计每个源文件的总行数(不包括空行和注释)。标记超过 500 LOC 的文件。在发现中注明超出幅度(2,000 LOC 的文件比 550 LOC 的文件更值得评为 Major),但绝不要将严重程度提升至 Major 以上——文件过大是可维护性风险,而非生产缺陷。 | Major |
ARCH | 类包含 20 个或更多方法 | 统计每个类的公共、受保护和私有方法。标记包含 20 个或更多方法的类。列出方法组,建议如何拆分类。 | Major |
ARCH | 单个文件处理从请求到响应的完整生命周期 | 查找处理完整请求生命周期的文件:接收/解析请求、验证输入、执行业务逻辑、执行持久化、格式化响应以及记录日志——全部集中在一个文件或类中。如果其中 4 项或更多职责集中在单个文件中,则标记该文件。 | Major |
贫血领域模型
| ID 前缀 | 检测内容 | 检测方法 | 严重程度 |
|---|---|---|---|
ARCH | 实体/模型类只有 getter/setter,没有任何行为 | 扫描模型/实体类。如果一个类只有属性声明、getter、setter 和构造函数赋值,没有业务逻辑方法(没有验证、计算、状态转换或领域规则),则该实体是贫血实体。 | Minor |
ARCH | 所有逻辑都位于操作简单数据对象的“Service”类中 | 检查代码库是否存在这样的模式:实体类只是纯数据容器,所有行为(验证、计算、状态转换)都位于单独的 *Service 类中,并由这些类在实体外部操作实体。如果这种模式普遍存在(3 个或更多服务操作同一实体),则标记该模式。 | Minor |
缺少边界
| ID 前缀 | 检测内容 | 检测方法 | 严重程度 |
|---|---|---|---|
ARCH | 中大型项目缺少明确的模块/领域划分 | 对于包含 20 个或更多源文件的项目,检查代码是否按模块、领域或限界上下文组织。如果所有源文件都位于单一的扁平目录中,或仅按技术层分隔(controllers/、models/、services/),没有按领域分组,则标记。 | 主要 |
ARCH | 不相关功能直接访问共享数据库表 | 搜索是否有多个不相关模块或功能目录导入/查询同一个数据库表名、模型或实体。如果 users 表在 billing/、notifications/、reports/ 和 admin/ 中被访问,且未通过共享的 user 模块,则标记。 | 主要 |
ARCH | 跨功能直接导入,而非使用事件/接口 | 检查功能模块是否直接导入其他功能模块的内部文件。例如,billing/InvoiceService 直接导入 shipping/ShippingCalculator,而非通过接口或事件系统。标记紧密的功能间耦合。 | 次要 |
目录结构
| ID 前缀 | 检测内容 | 检测方法 | 严重程度 |
|---|---|---|---|
ARCH | 违反框架约定 | 检查项目是否遵循框架预期的目录结构。例如:业务逻辑类位于 Controllers/ 目录中、SQL 查询写在视图模板中、路由定义散落在非路由文件中,或测试文件与源文件混放且没有命名约定。 | 次要 |
ARCH | 20 个或更多文件的项目未分层 | 对于包含 20 个或更多源文件的项目,检查是否按目录划分层(controllers、services、models、views)或领域。如果所有内容都位于同一个扁平目录中,则标记。 | 主要 |
配置/环境
| ID 前缀 | 检测内容 | 检测方法 | 严重程度 |
|---|---|---|---|
ARCH | 源代码中硬编码了环境专用值 | 在源代码文件(非配置文件)中搜索硬编码的 URL(http://localhost、https://api.example.com)、端口号(:3000、:8080、:5432)、主机名、IP 地址和文件系统路径。这些值应来自环境变量或配置。 | 主要 |
ARCH | 缺少环境抽象层 | 检查项目是否有环境抽象层(.env 文件和配置加载器、环境变量、配置服务)。如果源文件在 5 个或更多位置直接读取 process.env.X 或 os.environ['X'],但没有集中式配置模块,或者完全没有 .env/配置层,则标记。 | 次要 |
使用 file_stats.py
如果可用,请通过 Bash 运行 file_stats.py 脚本,以获取每个文件的代码行数、类数量和方法数量。该脚本位于 codeprobe 技能的 scripts/ 目录中(相对于技能安装位置解析,而非用户的项目):
python3 scripts/file_stats.py <target_path>
注意:通常由编排器运行此脚本并传递结果。如果单独调用,请在同级的 codeprobe/scripts/ 目录中查找该脚本。
使用这些数据来:
- 识别上帝对象(超过 500 行的文件、拥有 20 个或更多方法的类)
- 找出项目中最大的文件
- 为摘要获取准确的代码行数
如果 Python 3 或 file_stats.py 脚本不可用,请使用 Read 直接阅读文件并估算。不要因此停止分析——继续手动统计。
ID 前缀和修复提示词示例
所有发现都使用 ARCH- 前缀,并按顺序编号:ARCH-001、ARCH-002 等。
修复提示词示例
- “将
OrderController@store中的定价计算逻辑(第 40-75 行)移到app/Services/下新建的PricingService类中。控制器应注入PricingService,并调用$this->pricingService->calculate($order)。控制器只应负责解析请求、委托服务和格式化响应。” - “将
UserManager(850 行代码)拆分为职责明确的服务:将身份验证方法(第 50-200 行)提取到UserAuthService,将个人资料管理(第 201-450 行)提取到UserProfileService,并将通知方法(第 451-700 行)提取到UserNotificationService。UserManager将成为一个轻量级门面,负责委托给这三个服务。” - “解决
billing/InvoiceService和shipping/ShippingCalculator之间的循环依赖:将共享接口ShippingCostProvider提取到shared/contracts/目录中。让ShippingCalculator实现ShippingCostProvider,并让InvoiceService依赖该接口,而不是具体类。” - “将
src/services/ApiClient.ts第 23 行的硬编码 URLhttp://localhost:3000/api替换为环境变量:通过配置模块加载process.env.API_BASE_URL。将API_BASE_URL=http://localhost:3000/api添加到.env.example。” - “创建基于领域的目录结构:将
UserController、UserService、UserRepository和UserPolicy移到app/Domains/User/目录中。对Order、Payment和Notification领域重复此操作。每个领域目录都应包含自己的控制器、服务、模型和策略。”