| name | code-dissect |
| description | "拆解和分析 AI/ML 实验项目代码库,生成完整的项目分析报告。当用户想要理解一个新的代码库、要求分析项目结构、想了解训练/推理流程、要求代码走读、或想弄清一个研究项目的工作原理时,使用这个 skill。触发场景包括但不限于:用户说"帮我看看这个项目"、"分析一下这个代码"、"拆解这个 repo"、"这个项目是怎么工作的"、"帮我理解这个实验代码",甚至只是打开一个不熟悉的 AI 项目目录然后问"这是什么"。" |
项目代码拆解分析
你的任务是对一个 AI/ML 实验项目进行全方位的代码拆解,输出一份结构化的 Markdown 分析报告。
这份报告的目标读者是一个懂 AI 但不了解这个具体项目的研究员——帮他在最短时间内建立对项目的完整理解。
分析流程
第一步:深入探索项目
在写任何分析之前,先彻底搞懂项目。这一步至关重要——分析的质量完全取决于你对代码的理解深度。
- 扫描全貌:用 Glob 获取完整的文件结构
- 读项目元信息:README、setup.py / pyproject.toml / requirements.txt、配置文件
- 定位入口:找到训练脚本(train.py, main.py, run.py 等)和推理脚本
- 追踪代码路径:从入口脚本出发,沿着 import 和函数调用链逐步深入,阅读每个核心模块的实现
- 理解数据流:弄清输入数据如何加载、预处理、进入模型、计算损失、反向传播
不要跳读,不要猜。如果某个模块的作用不确定,继续读它的代码和被调用的上下文,直到理解为止。
第二步:生成分析报告
将所有分析写入项目根目录下的 PROJECT_ANALYSIS.md,包含以下 7 个部分。
报告结构
一、项目概览
用一段自然语言概括整个项目的核心信息:
- 这个项目要解决什么问题
- 基于什么理论或方法
- 核心创新点是什么
- 与已有方法相比有什么不同
面向一个懂 AI 但不了解此项目的研究员。用自然语言把思路讲清楚,不要堆砌术语。如果项目基于某篇论文,关联论文的核心思想。
示例风格:
这个项目实现了一种基于扩散模型的文本到图像生成方法。核心思路是在潜空间(而非像素空间)进行去噪过程,通过预训练的 VAE 将图像压缩到低维潜空间后再进行扩散,大幅降低了计算成本。文本条件通过 cross-attention 机制注入 U-Net 的每一层,使用 CLIP 文本编码器提取语义特征。相比直接在像素空间操作的方法(如 DDPM),这种方式在保持生成质量的同时将训练成本降低了一个数量级。
二、项目文件结构
用树形图展示项目的文件结构,在每个文件/目录后用简短注释说明作用。
project/
├── train.py # 训练入口,解析参数并启动训练循环
├── inference.py # 推理入口,加载模型并生成输出
├── config/
│ └── default.yaml # 默认超参数配置
├── models/
│ ├── __init__.py
│ ├── encoder.py # 编码器:将输入映射到隐藏空间
│ └── decoder.py # 解码器:从隐藏表示生成输出
├── data/
│ ├── dataset.py # 数据集定义与加载逻辑
│ └── transforms.py # 数据预处理与增强
└── utils/
├── metrics.py # 评估指标(BLEU, FID 等)
└── distributed.py # 分布式训练工具
规则:
- 忽略
.git、__pycache__、.egg-info、node_modules 等非代码目录
- 大型项目中不重要的子目录可以折叠(用
... 标注),但核心代码模块必须完整展开
- 注释要具体——"工具函数"太模糊,"学习率调度与梯度裁剪工具"才有用
三、文件级训练与推理流程(Mermaid)
用 Mermaid 流程图展示训练和推理的主线流程,节点是文件名,边标注数据流向或调用关系。
训练流程和推理流程必须分开画成两张独立的 Mermaid 图,不要合并。即使两者有重叠的部分,也要各自独立完整地展示。
训练流程图要让读者一眼看出:"数据从哪来、经过哪些文件、模型在哪定义、损失在哪算、怎么更新参数"。
推理流程图要让读者一眼看出:"输入从哪来、模型怎么加载、推理怎么执行、输出怎么后处理"。
训练流程:
graph TD
subgraph 训练流程
A[train.py] -->|读取配置| B[config/default.yaml]
A -->|构建数据集| C[data/dataset.py]
C -->|数据增强| D[data/transforms.py]
A -->|构建模型| E[models/encoder.py]
E --> F[models/decoder.py]
A -->|计算损失 & 反向传播| G[losses/loss.py]
A -->|评估| H[utils/metrics.py]
A -->|保存检查点| I[utils/checkpoint.py]
end
推理流程:
graph TD
subgraph 推理流程
A[inference.py] -->|读取配置| B[config/default.yaml]
A -->|加载检查点| C[utils/checkpoint.py]
A -->|构建模型| D[models/encoder.py]
D --> E[models/decoder.py]
A -->|加载输入数据| F[data/dataset.py]
A -->|执行推理| G[models/model.py]
A -->|后处理 & 输出| H[utils/postprocess.py]
end
四、函数/类级训练与推理流程(Mermaid)
更细粒度的流程图,节点是类名或函数名,标注所在文件,展示实际的调用链。
训练和推理必须分开画成两张独立的 Mermaid 图。
训练流程图应该能回答:"当我执行 python train.py 时,代码依次调用了哪些类的哪些方法?"
推理流程图应该能回答:"当我执行推理脚本时,代码依次调用了哪些类的哪些方法?"
训练流程:
graph TD
subgraph 训练流程
A["main() — train.py"] -->|解析参数| B["parse_args() — train.py"]
A -->|初始化| C["Trainer.__init__() — engine/trainer.py"]
C -->|构建模型| D["build_model() — models/__init__.py"]
D --> E["Encoder() — models/encoder.py"]
D --> F["Decoder() — models/decoder.py"]
C -->|加载数据| G["build_dataloader() — data/dataset.py"]
C -->|开始训练| H["Trainer.train() — engine/trainer.py"]
H -->|单步训练| I["Trainer.train_step() — engine/trainer.py"]
I -->|前向传播| J["Model.forward() — models/model.py"]
I -->|计算损失| K["compute_loss() — losses/loss.py"]
I -->|反向传播| L["loss.backward() + optimizer.step()"]
end
推理流程:
graph TD
subgraph 推理流程
A["main() — inference.py"] -->|解析参数| B["parse_args() — inference.py"]
A -->|加载模型| C["load_checkpoint() — utils/checkpoint.py"]
C -->|构建模型| D["build_model() — models/__init__.py"]
D --> E["Encoder() — models/encoder.py"]
D --> F["Decoder() — models/decoder.py"]
A -->|加载输入| G["load_input() — data/dataset.py"]
A -->|执行推理| H["Model.forward() — models/model.py"]
H -->|生成输出| I["generate() / decode() — models/model.py"]
A -->|后处理| J["postprocess() — utils/postprocess.py"]
end
如果调用链很复杂(超过 20 个节点),拆成多个子图(如"模型构建"、"训练循环"、"数据加载"分开画),但保持子图之间的连接关系可见。
五、核心类与函数解析
逐个解析项目中对理解整体流程至关重要的类和函数。按模块分组。
每个条目包含:
- 名称和所在文件位置
- 作用:一句话说明它做什么
- 关键逻辑:核心实现细节。比如某个 attention 具体怎么算的、loss 的数学公式是什么、某个采样策略的具体步骤
- 输入/输出:关键参数和返回值的含义,包括张量的形状
聚焦于核心代码——模型定义、损失计算、关键算法步骤。日志、可视化、CLI 参数解析等辅助代码可以跳过。
格式示例:
MultiHeadAttention — models/attention.py:L25
- 作用:多头自注意力计算
- 关键逻辑:将输入线性投影为 Q/K/V,按头数拆分后计算 scaled dot-product attention,使用 RoPE 旋转位置编码。支持 causal mask 和 KV cache(推理时使用)。
- 输入:
x: [B, L, D] 输入序列,mask: [B, 1, L, L] 可选的注意力掩码
- 输出:
out: [B, L, D] 注意力输出
六、项目入口与使用方式
说明如何实际运行这个项目:
- 环境安装:依赖安装命令
- 训练命令:完整的训练启动命令,附关键参数说明
- 推理/评估命令:如何用训练好的模型做推理
- 配置体系:配置文件的结构和重要参数
- 多种模式:如果项目支持多种运行模式(单卡/多卡、不同任务等),都列出
基于项目中实际存在的脚本和配置,不要编造命令。如果 README 中有示例命令,可以引用但要核实其准确性。
七、伪代码总览
用伪代码将整个项目的核心流程串联起来。这段伪代码的目的是让读者在不看源码的情况下就能理解整个系统的工作原理。
伪代码的原则:
- 高层次抽象,省略不影响理解的实现细节
- 保留核心算法步骤和数据变换
- 关键位置用注释标注张量形状变化
- 训练和推理流程都要覆盖
# === 训练 ===
config = load_config("config/default.yaml")
model = Encoder(config) + Decoder(config) # 构建模型
dataset = load_dataset(config.data_path) # 加载并预处理数据
optimizer = AdamW(model.params, lr=config.lr)
for epoch in range(config.epochs):
for batch in dataset:
x, labels = preprocess(batch) # [B, L] -> [B, L, D]
h = model.encoder(x) # [B, L, D] -> [B, L, H]
logits = model.decoder(h) # [B, L, H] -> [B, L, V]
loss = cross_entropy(logits, labels)
loss.backward()
optimizer.step()
if epoch % config.eval_every == 0:
metrics = evaluate(model, val_set)
save_checkpoint(model, metrics)
# === 推理 ===
model = load_checkpoint("best_model.pt")
output = model.generate(input_text, max_len=512)
特殊情况处理
- 框架封装较深的项目(如使用 PyTorch Lightning、HuggingFace Trainer):指出框架隐藏了哪些步骤,并说明框架在背后做了什么
- 纯库/工具项目(没有训练循环):跳过训练/推理流程图,改为分析 API 调用流程和核心功能模块的协作方式
- 多任务/多模态项目:选取最核心的一条任务链路做详细分析,其他链路简要说明差异即可
- 代码中的不确定部分:如果某段代码的意图不明确,标注"⚠️ 待确认"并给出你的推测,而不是跳过或瞎猜
写作原则
- 所有文字用中文撰写
- Mermaid 图中的节点标签和边标签也用中文
- 保持客观,不做代码质量的主观评价
- 如果项目关联特定论文,在相关位置引用论文术语和公式编号
- 优先准确,其次完整——宁可标注"待确认"也不要写错误的分析