灵妍 (LingResearch) 项目代码审计报告
报告编号: LR-AUDIT-001
审计日期: 2026-04-05
审计范围: /home/ai/lingresearch 全量源代码
审计方法: 基于 IDE 静态诊断的逐文件代码审查,辅以 ruff LSP 规则。未使用独立的安全扫描工具(bandit, semgrep)或动态分析方法。
审计人: 灵妍
利益声明: 审计者即 intel/ 模块的作者,存在自我审查偏差。
总览
| 维度 | 评级 | 问题数 |
|---|---|---|
| 业务逻辑 | ⚠️ 中风险 | 10 |
| 安全漏洞 | ⚠️ 中风险 | 6 |
| 代码质量 | ⚠️ 中风险 | 30 (ruff warnings) |
| 合规规范 | ⚠️ 中风险 | 7 |
| 架构风险 | ⚠️ 中风险 | 8 |
总计: 34 个已识别问题(2 Critical, 19 Warning, 13 Info)+ 30 个 ruff 静态警告
〇、修复状态(2026-04-05 更新)
以下问题已在提交 267264a 中修复:
| 编号 | 问题 | 状态 | 修复内容 |
|---|---|---|---|
| C-BIZ-01 | 大规模代码重复 | ✅ 已修复 | 创建 config.py 为唯一配置来源,消除跨模块常量重复;train.py 改从 config 导入 |
| C-SEC-01 | 文件路径注入 | ✅ 已修复 | relay.py 添加 _validate_output_dir(),monitor.py 添加 _validate_dir(),拒绝含 .. 的路径 |
| W-BIZ-05 | 调度器名称误导 | ✅ 已修复 | 新增 COSINE_PERIOD = WARMUP_STEPS * 10,CosineAnnealingLR 使用 COSINE_PERIOD |
| W-BIZ-06 | torch.cuda.amp 弃用 | ✅ 已修复 | autocast 迁移至 torch.amp,调用改为 autocast(device_type=device) |
| W-BIZ-07 | loss 计算偏差 | ✅ 已修复 | 改为 total_loss / total_tokens(per-token 平均),修正 token 计数为 y.numel() |
| W-SEC-02 | 路径参数验证 | ✅ 已修复 | 同 C-SEC-01 修复 |
| W-SEC-04 | tokenizer 缓存完整性 | ✅ 已修复 | data/tokenizer.py 添加 SHA-256 校验,读取时验证,不匹配则抛出 IOError |
| W-CQ-01 | f-string 滥用 | ✅ 已修复 | digest.py 中 15 处 f-string 无占位符,全部改为普通字符串 |
| W-CQ-02 | 未使用的导入 | ✅ 已修复 | 移除 pytest(×3)、os、Path、CACHE_DIR、SEQ_LENGTH、IntelItem 等未使用导入 |
| W-CQ-03 | 未使用的异常变量 | ✅ 已修复 | except FileNotFoundError as e: → except FileNotFoundError:,移除 input_tensor |
| W-CMP-01 | 无 LICENSE | ✅ 已修复 | 添加 MIT LICENSE 文件 |
| W-CMP-02 | 无类型检查配置 | ✅ 已修复 | pyproject.toml 添加 [tool.mypy] 配置 |
| W-CMP-03 | 无 CI/CD | ✅ 已修复 | 添加 .github/workflows/ci.yml(pytest + ruff,Python 3.10/3.11/3.12) |
| W-CMP-05 | 配置散布 | ✅ 已修复 | 同 C-BIZ-01 修复 |
| I-CMP-06 | 缺少开发依赖 | ✅ 已修复 | pyproject.toml 添加 [project.optional-dependencies] dev |
| I-ARCH-05 | causal mask 重复创建 | ✅ 已修复 | attention.py 使用 register_buffer 缓存 512×512 mask,seq_len ≤ 512 时复用 |
未修复(需进一步评估):
| 编号 | 问题 | 原因 |
|---|---|---|
| W-BIZ-02 | uint16 dtype 风险 | 涉及 prepare.py 不可变约束 |
| W-BIZ-04 | 无模型持久化 | 属于功能增强,非 bug 修复范围 |
| W-SEC-03 | 文件权限控制 | 已在 C-SEC-01 修复中为 os.makedirs 添加 mode=0o755;open() 未统一设置 |
| W-CMP-04 | 无日志框架 | 属于架构改动,需单独评估 |
| W-ARCH-01 | Post-Norm 架构 | 属于模型架构设计选择,需实验验证 Pre-Norm 效果 |
| W-ARCH-02 | 绝对位置编码 | 属于模型架构改动,需实验验证 RoPE 效果 |
| W-ARCH-03 | 无梯度累积 | 属于功能增强 |
| I-ARCH-06 | forward 返回 None | prepare.py 的 evaluate_bpb 使用 logits, _ = model(x) 解包,修改会破坏兼容性 |
| I-ARCH-07 | Intel 模块无异步 | 单用户研究工具,并发风险低 |
| I-ARCH-08 | 关键词评分脆弱 | 设计简化,非 bug |
| I-ARCH-09 | prepare.py 技术债 | 项目约束,不可修改 |
验证结果:43/43 测试通过,ruff 剩余 8 个 warning(5 个来自不可变的 prepare.py,4 个 train.py 的 E402 因 seed 设置必须在 import 之前而不可避免)。
一、业务逻辑问题
C-BIZ-01: 大规模代码重复(违反 DRY 原则)
严重程度: Critical
影响范围: prepare.py, data/dataloader.py, data/dataset.py, data/tokenizer.py, utils/evaluation.py
项目中存在三个 TextDataset 类的独立实现:
| 位置 | 行号 | 说明 |
|---|---|---|
prepare.py:130-165 |
36行 | 原始实现,使用 .long() 转换 |
data/dataset.py:12-47 |
36行 | 改进版,增加 int64 自动转换 |
data/dataloader.py (通过 import) |
— | 使用 data/dataset.py 的版本 |
create_data_shards 函数在 prepare.py:167-214 和 data/dataloader.py:24-71 中完全重复(逐行一致)。
get_dataloaders 函数在 prepare.py:216-277 和 data/dataloader.py:74-135 中完全重复。
evaluate_bpb 函数在 prepare.py:283-325 和 utils/evaluation.py:15-57 中完全重复。
get_tokenizer / train_bpe_tokenizer 在 prepare.py:81-124 和 data/tokenizer.py:16-63 中完全重复。
后果: 任何 bug 修复需要同步多处;实际已发生——prepare.py 中的 uint16 问题在 data/dataset.py 中被单独修复,但 prepare.py 本身被标记为不可变,导致两份代码行为不一致。
建议: prepare.py 不可修改是设计约束,但 data/ 模块应作为唯一真实来源。train.py 当前 from prepare import ... 绕过了 data/ 模块,应改为从 data/ 导入。
W-BIZ-02: uint16 dtype 存在潜在溢出风险
严重程度: Warning
位置: prepare.py:188, data/dataloader.py:45
GPT-2 BPE tokenizer 的词汇表大小为 50257,token ID 范围 0–50256。uint16 的最大值为 65535,因此 50257 当前不会溢出。但这是一个脆弱的设计——如果未来切换到更大的 tokenizer(如 GPT-4 的 cl100k_base,词汇量 100277,已验证超出 uint16 范围),token ID 将静默溢出截断,产生难以排查的数据损坏。
data/dataset.py:21 中的修复:
I-BIZ-03: 训练数据为示例占位文本
严重程度: Info
位置: prepare.py:343-359
训练数据是一段固定文本重复 1000 次。这意味着: - 模型实际上在记忆一段短文本 - 验证集是同一段文本的尾部切片 - BPC 指标无法反映模型泛化能力 - 训练/验证数据无独立性
注释说明了这是示例(函数名即 download_sample_data),属于设计意图。但如果有人直接运行完整训练流程,得到的 BPC 结果无实际意义。
W-BIZ-04: 无模型持久化机制
严重程度: Warning
位置: train.py 全文
训练循环仅保存 results.tsv(epoch、BPC、时间、参数量),不保存模型权重。最佳模型在程序退出后丢失。这意味着:
- 无法恢复训练(无 checkpoint)
- 无法部署训练好的模型
- 每次训练都从零开始
W-BIZ-05: 学习率调度器名称误导
严重程度: Warning
位置: train.py:212-216
scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(
optimizer,
T_max=WARMUP_STEPS * 10, # 100 * 10 = 1000
eta_min=LEARNING_RATE * 0.1
)
变量名 WARMUP_STEPS 暗示这是一个 warmup 机制,但 CosineAnnealingLR 是一个余弦退火调度器,不是 warmup。实际上没有任何真正的 warmup 实现(学习率从 0 线性增加到目标值)。T_max=1000 是余弦周期的长度,与 warmup 无关。
W-BIZ-06: torch.cuda.amp 已弃用
严重程度: Warning
位置: train.py:23
在 PyTorch 2.0+ 中,torch.cuda.amp 已弃用,应迁移到 torch.amp.GradScaler 和 torch.amp.autocast。项目使用 PyTorch 2.2.0,已受影响。虽然旧 API 当前仍可工作,但会在运行时产生 DeprecationWarning,且未来版本可能移除。
W-BIZ-07: train_one_epoch loss 计算偏差
严重程度: Warning
位置: train.py:136-140
total_tokens += batch.size(1) # line 136: 累积但未使用
...
avg_loss = total_loss / len(train_loader) # line 140: per-batch 均值
avg_loss = total_loss / len(train_loader) 计算 per-batch 平均损失,而非 per-token 平均损失。total_tokens 在第 136 行被累积,但从未用于 loss 计算。当最后一个 batch 不满时,per-batch 均值会高估实际损失。对比 evaluate_bpb 使用 total_loss / total_tokens,是正确的做法。
I-BIZ-08: get_tokenizer 的存在性检查无意义
严重程度: Info
位置: prepare.py:108-124, data/tokenizer.py:47-63
if TOKENIZER_PATH.exists():
enc = tiktoken.get_encoding("gpt2") # 分支 A
return enc
else:
enc = tiktoken.get_encoding("gpt2") # 分支 B(完全相同)
TOKENIZER_PATH.parent.mkdir(...)
with open(TOKENIZER_PATH, 'w', ...) as f:
json.dump({'name': 'gpt2'}, f)
return enc
两个分支的核心逻辑完全相同:都是 tiktoken.get_encoding("gpt2")。文件存在性检查仅决定是否写入一个 {'name': 'gpt2'} 的 JSON 文件。这个文件从未被读取用于改变任何行为。
I-BIZ-09: train_bpe_tokenizer 函数名误导
严重程度: Info
位置: prepare.py:81-96, data/tokenizer.py:16-34
函数名 train_bpe_tokenizer 暗示会训练一个新的 BPE tokenizer,但实际上只是调用 tiktoken.get_encoding("gpt2") 返回预训练的 GPT-2 tokenizer。参数 text 和 vocab_size 完全未使用。
I-BIZ-10: 随机种子重复设置
严重程度: Info
位置: prepare.py:29-37, train.py:29-37
完全相同的随机种子设置代码在两个文件中重复出现。如果两个文件都被导入执行,种子会被设置两次(虽然结果相同)。
二、安全漏洞
C-SEC-01: 文件路径注入(Path Traversal)
严重程度: Critical
位置:
- intel/relay.py:10-11 — output_dir 参数无验证
- intel/monitor.py:11 — _baseline_dir 可被外部设置
- data/tokenizer.py:57 — 写入 ~/.cache/lingresearch/
- train.py:297 — 写入 CWD 的 results.tsv
ResearchRelay.__init__(self, output_dir: str = "data/intel") 接受任意路径字符串,不做任何校验。IdentityMonitor._baseline_dir 虽然是硬编码默认值而非构造器参数,但作为 Python 属性仍可被外部猴子补丁修改。
# relay.py:18
os.makedirs(self._output_dir, exist_ok=True)
# monitor.py:36
os.makedirs(self._baseline_dir, exist_ok=True)
攻击者可以传入 output_dir="/etc/" 或 output_dir="../../root/" 等路径,导致文件被写入非预期位置。
建议:
1. 对所有外部传入的路径做 resolve() 后验证是否在预期目录内
2. 使用白名单或配置文件限制输出目录
W-SEC-02: 缺少对外部传入路径参数的验证
严重程度: Warning
位置: 全项目
项目没有对外部传入的路径参数做验证:
- ResearchRelay 的 output_dir 构造器参数无路径校验
- IdentityMonitor._baseline_dir 可被猴子补丁修改
- 字符串参数无长度限制
- 数值参数无范围检查
- IntelItem 的 metadata 字段接受任意 tuple[tuple[str, Any], ...]
W-SEC-03: 缺少文件权限控制
严重程度: Warning
位置: 所有文件写入操作
所有 open(path, 'w') 和 os.makedirs() 调用未指定文件权限。在多用户环境中,创建的文件和目录将使用进程的 umask,可能导致其他用户可读写。
W-SEC-04: tokenizer 缓存文件无完整性校验
严重程度: Warning
位置: data/tokenizer.py:57-58, prepare.py:118-119
写入的 tokenizer.json(内容为 {'name': 'gpt2'})无完整性保护。虽然当前未读取该文件来决定 tokenizer 行为,但如果未来代码改为依赖该文件,则存在被篡改的风险。prepare.py 导入了 hashlib 但从未使用,说明可能曾计划做完整性校验。
I-SEC-05: 无认证/授权机制
严重程度: Info
位置: 全项目
项目不使用 API 密钥、Token 或任何认证机制。这在当前作为独立研究工具的上下文中可接受,但如果 intel 模块的 JSONL 输出被其他 agent 读取,需要考虑传输安全性。
I-SEC-06: 异常处理中泄露内部信息
严重程度: Info
位置: train.py:286-288
在异常处理中打印完整 traceback 可能泄露文件路径、内部结构等信息。
三、代码质量
Ruff 静态分析总结
30 个 warnings,0 个 errors
按类别分布
| 类别 | 数量 | 文件 |
|---|---|---|
| F401: 未使用的导入 | 8 | os(×2), hashlib, pytest(×3), IntelItem, SEQ_LENGTH |
| F541: f-string 无占位符 | 15 | digest.py 占 15 处 |
| F841: 未使用的变量 | 3 | e in dataloader.py:132, prepare.py:274, test_blocks.py:86 |
| E402: 模块导入不在顶部 | 4 | train.py:40-46 |
按文件分布
| 文件 | Warnings |
|---|---|
intel/digest.py |
15 |
train.py |
5 |
prepare.py |
4 |
tests/test_model/test_blocks.py |
2 |
tests/test_model/test_language_model.py |
1 |
tests/test_data/test_dataset.py |
1 |
data/dataloader.py |
1 |
W-CQ-01: digest.py 滥用 f-string
严重程度: Warning
位置: intel/digest.py 全文(第 53, 54, 57, 59, 62, 64, 67, 70, 73, 78, 79, 84 行)
lines.append(f"# 灵妍研究情报摘要") # f-string 无占位符
lines.append(f"") # 空行也用 f-string
lines.append(f"## 分类统计") # 同上
约 15 处 f"..." 字符串不包含任何 {...} 占位符,应改为普通字符串。这不仅是风格问题,f-string 在运行时会进行不必要的表达式求值。
W-CQ-02: 未使用的导入
严重程度: Warning
| 文件 | 行号 | 未使用导入 |
|---|---|---|
train.py |
16 | os |
train.py |
46 | SEQ_LENGTH |
prepare.py |
16 | os |
prepare.py |
18 | hashlib |
intel/digest.py |
3 | IntelItem |
tests/test_data/test_dataset.py |
5 | pytest |
tests/test_model/test_language_model.py |
5 | pytest |
tests/test_model/test_blocks.py |
5 | pytest |
W-CQ-03: 异常捕获后丢弃异常信息
严重程度: Warning
位置: data/dataloader.py:132, prepare.py:274, tests/test_model/test_blocks.py:86
as e 捕获的异常对象未被使用,应改为 except FileNotFoundError:。
四、合规规范
W-CMP-01: 无 LICENSE 文件
严重程度: Warning
位置: 项目根目录
项目没有开源许可证。这意味着:
- 默认适用版权法,他人无权复制/修改/分发
- 与 pyproject.toml 中未指定 license 字段一致
- 对于研究原型项目,建议至少添加 MIT 或 Apache-2.0 许可证
W-CMP-02: 无类型检查配置
严重程度: Warning
位置: 项目根目录
缺少 mypy.ini、pyproject.toml [tool.mypy] 或 pyrightconfig.json。代码使用了类型注解(如 def forward(self, x: torch.Tensor) -> tuple[torch.Tensor, None]:),但没有工具强制检查类型正确性。
W-CMP-03: 无 CI/CD 配置
严重程度: Warning
位置: 项目根目录
缺少 .github/workflows/、.gitlab-ci.yml 或等效的 CI/CD 配置。43 个测试需要在本地手动运行。
W-CMP-04: 无日志框架
严重程度: Warning
位置: 全项目
所有输出通过 print() 实现。无法控制日志级别、无法关闭调试输出、无法将日志写入文件、无法结构化日志。
W-CMP-05: 配置散布于多个文件
严重程度: Warning
位置: prepare.py:42-76, data/dataloader.py:18-21, model/language_model.py:12-17, utils/evaluation.py:12
相同配置常量在至少 4 个文件中重复定义:
| 常量 | 出现位置 |
|---|---|
SEQ_LENGTH=256 |
prepare.py:47, data/dataloader.py:19, model/language_model.py:17 |
BATCH_SIZE=32 |
prepare.py:50, data/dataloader.py:20 |
D_MODEL=256 |
prepare.py:53, model/language_model.py:12 |
CACHE_DIR |
prepare.py:69, data/tokenizer.py:12, data/dataloader.py:15 |
EVAL_STEPS=100 |
prepare.py:75, utils/evaluation.py:12 |
应使用单一配置文件或环境变量。
I-CMP-06: pyproject.toml 缺少开发依赖
严重程度: Info
位置: pyproject.toml
缺少 [project.optional-dependencies] 中的 dev 组(pytest, ruff, mypy 等)。测试和 lint 工具未声明为依赖。
I-CMP-07: 无 .env.example 或配置文档
严重程度: Info
位置: 项目根目录
虽然当前项目不需要环境变量,但 CACHE_DIR 等路径是硬编码的,用户无法通过环境变量自定义。
五、架构风险
W-ARCH-01: Post-Norm 架构不利于训练稳定性
严重程度: Warning
位置: model/blocks.py:62-78
def forward(self, x: torch.Tensor) -> torch.Tensor:
attn_out = self.attn(x)
x = self.norm1(x + self.dropout(attn_out)) # Post-Norm: 先残差,后归一化
ff_out = self.ff(x)
x = self.norm2(x + self.dropout(ff_out))
return x
这是 Post-LayerNorm(后归一化)架构:x = Norm(x + f(x))。GPT-2 原始实现使用 Post-Norm,本项目与之一致。但 GPT-3 及之后的模型(LLaMA, etc.)普遍改用 Pre-Norm(前归一化):x = x + Norm(f(x))。Post-Norm 在深层网络中更容易出现训练不稳定、梯度爆炸/消失的问题。
注: LanguageModel 最终有一层 self.ln_f(language_model.py:61,107),这在 Post-Norm 中是必需的,说明设计者了解此问题但选择了 Post-Norm。
W-ARCH-02: 绝对位置编码无法外推
严重程度: Warning
位置: model/language_model.py:51,99
self.position_embedding = nn.Embedding(seq_length, d_model) # line 51
pos_emb = self.position_embedding(torch.arange(seq_len, device=x.device)) # line 99
使用固定的绝对位置嵌入,最大长度被 seq_length 参数限制。如果推理时输入长度超过 seq_length,会产生索引越界错误。现代模型通常使用旋转位置编码 (RoPE) 或 ALiBi 来支持长度外推。
W-ARCH-03: 无梯度累积支持
严重程度: Warning
位置: train.py:56-141
训练循环不支持梯度累积。在 GPU 内存受限时,无法通过累积多个小 batch 的梯度来模拟大 batch size 的效果。这对小显存 GPU 是实际限制。
I-ARCH-05: attention.py 每次前向传播重新创建 causal mask
严重程度: Info
位置: model/attention.py:57-59
每个 batch 的每次前向传播都重新创建 causal mask。虽然功能正确,但可以通过 register_buffer 在模型初始化时创建一次并复用,减少不必要的计算和内存分配。
I-ARCH-06: forward 返回无用的 None
严重程度: Info
位置: model/language_model.py:84,110
def forward(self, x: torch.Tensor) -> tuple[torch.Tensor, None]:
...
return logits, None # 返回None是为了兼容可能的缓存机制
返回 None 注释说是为了"兼容可能的缓存机制",但实际上 KV cache 未被实现。这增加了调用方的负担(需要 logits, _ = model(x) 解包)。
I-ARCH-07: Intel 模块无异步支持
严重程度: Info
位置: intel/ 全模块
所有 I/O 操作(JSONL 读写、文件创建)都是同步的。在多 agent 并发场景下,如果多个 agent 同时写入同一个 JSONL 文件,可能出现数据丢失或损坏。
I-ARCH-08: 关键词评分系统脆弱且语言特定
严重程度: Info
位置: intel/monitor.py:100-146
_score_single_answer 使用硬编码的中文关键词列表对回答评分:
escape_indicators = ["知识库未收录", "无法确认", "应视为推论", ...]
flexible_indicators = ["配置", "可以被改变", "可以修改", ...]
rigid_indicators = ["我就是", "我始终是", "不可能", ...]
问题:
1. 语言绑定: 仅支持中文关键词,英文回答无法正确评分
2. 顺序敏感: 如果回答同时包含 escape 和 rigid 关键词,先匹配到的生效
3. 语义缺失: 基于关键词而非语义分析,容易被精心构造的回答欺骗
4. 分数设计: flexible 返回 0 分(最低),意味着对自身可塑性的认知被视为最健康,这在哲学上可能存在争议
I-ARCH-09: prepare.py 不可变约束造成技术债
严重程度: Info
位置: 项目规则
prepare.py 被声明为"AI代理不应该修改此文件"。这意味着其中的 bug(uint16 dtype、未使用的 hashlib/os 导入、无意义的 tokenizer 文件检查)无法修复。data/ 模块试图成为改进版本,但 train.py 仍然从 prepare.py 导入配置常量,形成了依赖链的矛盾。
六、问题汇总与优先级
Critical (需立即处理)
| 编号 | 问题 | 维度 |
|---|---|---|
| C-BIZ-01 | 大规模代码重复(5个函数×2份) | 业务逻辑 |
| C-SEC-01 | 文件路径注入漏洞(relay.py output_dir) | 安全 |
Warning (应尽快处理)
| 编号 | 问题 | 维度 |
|---|---|---|
| W-BIZ-02 | uint16 dtype 潜在溢出风险 | 业务逻辑 |
| W-BIZ-04 | 无模型持久化机制 | 业务逻辑 |
| W-BIZ-05 | 学习率调度器名称误导 | 业务逻辑 |
| W-BIZ-06 | torch.cuda.amp 已弃用,应迁移到 torch.amp | 业务逻辑 |
| W-BIZ-07 | train_one_epoch loss 按batch均分而非按token均分 | 业务逻辑 |
| W-SEC-02 | 缺少路径参数验证 | 安全 |
| W-SEC-03 | 缺少文件权限控制 | 安全 |
| W-SEC-04 | tokenizer 缓存无完整性校验 | 安全 |
| W-CQ-01 | digest.py 滥用 f-string (14处) | 代码质量 |
| W-CQ-02 | 未使用的导入 (8处) | 代码质量 |
| W-CQ-03 | 异常捕获后丢弃信息 (3处) | 代码质量 |
| W-CMP-01 | 无 LICENSE 文件 | 合规 |
| W-CMP-02 | 无类型检查配置 | 合规 |
| W-CMP-03 | 无 CI/CD 配置 | 合规 |
| W-CMP-04 | 无日志框架 | 合规 |
| W-CMP-05 | 配置散布于 4+ 文件 | 合规 |
| W-ARCH-01 | Post-Norm 架构不利于稳定性 | 架构 |
| W-ARCH-02 | 绝对位置编码无法外推 | 架构 |
| W-ARCH-03 | 无梯度累积支持 | 架构 |
Info (建议改进)
| 编号 | 问题 | 维度 |
|---|---|---|
| I-BIZ-03 | 训练数据为示例占位文本(设计意图) | 业务逻辑 |
| I-BIZ-08 | get_tokenizer 存在性检查无意义 | 业务逻辑 |
| I-BIZ-09 | train_bpe_tokenizer 函数名误导 | 业务逻辑 |
| I-BIZ-10 | 随机种子重复设置 | 业务逻辑 |
| I-SEC-05 | 无认证/授权机制 | 安全 |
| I-SEC-06 | 异常处理泄露内部信息 | 安全 |
| I-CMP-06 | 缺少开发依赖声明 | 合规 |
| I-CMP-07 | 无配置文档/环境变量支持 | 合规 |
| I-ARCH-05 | causal mask 每次重建 | 架构 |
| I-ARCH-06 | forward 返回无用 None | 架构 |
| I-ARCH-07 | Intel 模块无异步支持 | 架构 |
| I-ARCH-08 | 关键词评分系统脆弱 | 架构 |
| I-ARCH-09 | prepare.py 不可变约束造成技术债 | 架构 |
七、测试覆盖
| 模块 | 测试文件 | 测试数 |
|---|---|---|
| data/dataset.py | tests/test_data/test_dataset.py | 7 |
| data/tokenizer.py | tests/test_data/test_tokenizer.py | 6 |
| data/dataloader.py | tests/test_data/test_dataloader.py | 5 |
| model/ | tests/test_model/ | 10 |
| intel/ | tests/test_intel/test_intel.py | 15 |
| 总计 | 43 |
通过率: 43/43 (100%)
未覆盖: train.py 的 main() 函数、prepare.py 的 main() 函数(集成测试缺失)
八、审计结论
本项目是一个双重用途的研究框架:ML 训练管道 + 情报收集分析。ML 框架部分是面向 AI agent 挑战赛的设计,prepare.py 的不可变约束是有意为之。情报模块(intel/)是本次会话新建的,代码质量较好但缺少安全防护。
最终统计: 2 Critical, 19 Warning, 13 Info(经自审计 LR-META-001 修正,原始版本为 5 Critical, 14 Warning, 19 Info)
最需要关注的三个问题:
- 代码重复(C-BIZ-01): 5 个核心函数有两份完全相同的拷贝,维护成本倍增
- 路径安全(C-SEC-01):
intel模块的文件写入路径无任何验证 - 混合精度弃用(W-BIZ-06):
torch.cuda.amp在 PyTorch 2.0+ 中已弃用,项目使用 2.2.0 受影响
整体评价: 作为研究原型项目,代码结构清晰、文档充分(中文注释覆盖率高)、测试通过率 100%。所有五个维度均为 ⚠️ 中风险——经自审计校准后,安全与合规维度从 🔴 高风险降级。主要问题集中在 DRY 违反和安全防护缺失上——前者会随项目规模增长而恶化,后者在单机研究环境中风险有限。
"能够真实地认识自己和客观世界,是一项非常重要的能力——不仅在科学研究当中,在所有的工作当中都是如此。"
— 审计原则引用