← 返回项目← Back to projects

深信服实习Sangfor Internship: Reducing 10,000 Security Alerts to 680 Review Candidates

为终端安全数据构建语义与行为图双维度的增量聚类管道,处理生长告警、簇心更新和运营 review 包交付。An incremental clustering pipeline for endpoint-security data, combining semantic and behavior-graph signals with growth-event deduplication and review-package delivery.

2026-02-01

PythonPython聚类Clustering图算法Graph Algorithms安全数据Security Data实习Internship

This project write-up is currently available in Chinese.

工作内容

AI 算法实习生 · 深信服科技 · 2026 年 2 月—4 月 · 深圳

当时面对的不是一个已经整理好的分类数据集,而是一批持续增长的终端安全告警。完整数据约 12 万条,其中包含大量重复事件、模板化研判文本和同一事件在不同时间点产生的“生长记录”。如果把它们全部交给运营人员逐条审查,绝大多数时间都会花在相似告警上。

项目目标因此被拆成两件事:

  1. 把相同或高度相似的告警归到一起,选出能够代表每个模式的样本;
  2. 保留与已有模式距离较远的 rare 候选,交给安全运营人员复核。

这里的 rare 只表示值得人工关注的稀有候选,不是模型已经确认的新型攻击,也不能直接等同于 Rare TTP。


从原始告警到 review 包

安全告警双维度增量聚类与运营交付流程

整条管道可以概括为:字段提取 → 语义聚类 → 行为图聚类 → 分数归一化与汇总 → 生长事件后处理 → 代表样本选择 → 原始记录回捞。

两条路径并不是把向量简单拼接后训练一个分类器:

这样既能看“这两条告警说的是不是同一类行为”,也能看“它们的进程结构是不是真的相似”。


语义路径:先去掉模板,再谈相似度

告警文本中有大量固定套话,例如“发现一起……攻击”或“攻击者通过……”。直接编码整段文本时,模型会被这些高频句式主导,不同攻击模式也可能得到很高的余弦相似度。

实际处理分成三步:

  1. 按优先级从 gptResponse 和 analyseAnswer 中回退提取有效文本;
  2. 过滤在多数样本中都出现的模板词,保留进程名、安全术语和关键英文 token;
  3. 使用 paraphrase-multilingual-MiniLM-L12-v2 生成 384 维向量。

为什么没有沿用 DBSCAN / HDBSCAN

早期方案考虑过密度聚类和 Union-Find,但真实数据中出现了明显的链式传递:A 接近 B,B 接近 C,并不代表 A 与 C 足够相似。最终采用簇中心法,每个新样本只与已有簇中心比较,超过 pattern_threshold 才加入最相近的簇,否则建立新簇。

这仍不是完美方案。875 条小样本实验中,420 条黑样本里出现过一个包含 305 条数据的超大簇,说明凭证窃取、恶意程序等描述在文本空间中仍会重叠。项目因此保留了二级聚类和人工复核,而不是把“成功聚成大簇”当成算法正确。


行为图路径:结构信息不能靠 DFS 字符串替代

每条告警的进程行为由 treeList 和 virtualEdges 表示。部分数据是嵌套树,如果不先展平,程序会误以为它只有一个根节点,后面的图相似度就失去意义。

行为图处理包含:

旧页面写成了“DFS 序列化 + 树编辑距离 / 子树同构”,这并不是最终落地路线,现已删除。

图路径也有自己的边界:进程树一旦新增节点,WL 特征就可能发生明显变化。对于随时间不断生长的同一事件,这种敏感性会把同一个 cgId 拆成大量图簇。因此图特征适合判断结构差异,但不能直接作为生长事件去重的强信号。


两个分数怎样汇总

语义相似度通常分布在一个较窄的连续区间,图相似度却可能接近二值。如果直接做固定权重平均,某一维很容易因为数值分布不同而主导结果。

当前方案分别计算:

semantic anomaly = percentile_rank(1 - semantic_similarity)
graph anomaly    = percentile_rank(1 - graph_similarity)

汇总后输出的是运营排序信号,而不是攻击概率。典型样本、簇边界样本、rare 候选和标签冲突样本会进入不同的 review 优先级。

这也修正了旧页面里并不存在的 0.65 × semantic + 0.35 × structural 固定权重,以及“两个分数都超过 0.8 就确认 Rare TTP”的伪代码。


最棘手的问题:同一个事件会一直长

同一次攻击事件可能在几十毫秒内连续触发多条记录。它们共享 cgId,但进程树和研判文本会随着新行为加入不断扩展。若逐条送进聚类:

所以项目在聚类完成后、生成 review 包之前增加 cgId 后处理。它依据语义簇跳变、文本变化和时间顺序保留关键 checkpoint,不把每次图结构变化都当成新模式。

在一组 1,118 条生长记录上:

策略 保留记录 结果
把图簇跳变作为强信号 993 几乎没有压缩,图结构过于敏感
以语义变化为主要触发条件 240 压缩约 78%,仍保留关键阶段

这次对比比“换一个更复杂的图模型”更有价值,因为它直接解释了业务数据为什么会重复,以及哪个信号适合做保留决策。


从全量聚类到增量处理

12 万条告警无法每次都重算完整相似度矩阵。首批数据用于建立语义簇心库和行为图代表库,后续批次只与已有簇心比较:

batch_0000
  └─ 全量聚类 → 初始化 semantic / graph centers

batch_0001+
  └─ 新样本 × 现有簇心 → 归并或建立 candidate center

新图簇不会立即升级为稳定簇心,而是先进入 candidate 状态,避免一个偶然离群点污染后续批次。每个 checkpoint 会冻结当前结果、执行生长数据后处理,并导出 review 包。

review 包不是简单截取异常分最高的若干行,而是组合:

最后根据 AIID 回到原始 JSONL 回捞完整字段,确保运营拿到的不是被特征工程裁剪后的中间记录。


已验证结果

在 12 万条数据的前两个真实批次中,管道完成了 10,000 条告警 → 680 条代表与待审样本 的压缩,约减少 93% 的人工审查量。

验证项 结果
输入记录 10,000
review 候选 680
AIID 原始记录回捞 680 / 680
产物闭环 聚类结果、去重结果、簇心库、checkpoint review 包均生成

这 680 条是运营待审候选,不是已经审核通过的训练样本。旧页面中的“识别准确率 >70%”“运营合格率 >80%”“生成 2,000+ 高价值训练样本”缺少与当前结果一一对应的验收记录,因此全部移除。


保密边界与项目收获

这项工作涉及真实终端安全数据,公开页面不会展示告警正文、客户信息、内部界面截图或私有代码。这里保留的是经过抽象的算法结构、排错过程和能够公开说明的规模结果。

这段实习最重要的收获不是“用聚类发现攻击”,而是学会把算法输出变成运营可以消费的交付物:既要控制 review 数量,又不能把稀有模式在压缩过程中一起删掉;既要支持增量运行,也要保留回溯到原始记录的路径。


项目说明