88b26f16fe
- Update README.md: new architecture (views/ 12 modules, tools/ 17 modules), remove simple_analysis refs, 30 MCP tools, 8GB RAM spec - Update AGENTS.md: project structure tree, 30 tools organized by implementation module, remove entity_detector/entity_aggregator refs - Update docs/工作流.md: full pipeline v3.0, code references to tools/ package, remove simple_analysis section (note moved to master) - Update docs/故障诊断手册.md: fix code location references, add WebGL2 tips, remove Leaflet/simple_analysis refs Branch: beta-clean
414 lines
14 KiB
Markdown
414 lines
14 KiB
Markdown
# 天璇 (TianXuan) 分析工作流
|
||
|
||
> 从原始 TLS 流 CSV 到实体画像、聚类结果、区分特征、UMAP 可视化的完整流水线文档。当前版本 v3.0。
|
||
|
||
---
|
||
|
||
## 目录
|
||
|
||
1. [工具总览](#1-工具总览)
|
||
2. [标准分析流程](#2-标准分析流程)
|
||
3. [数据准备与加载](#3-数据准备与加载)
|
||
4. [类型检测与数据校验](#4-类型检测与数据校验)
|
||
5. [实体识别与聚合](#5-实体识别与聚合)
|
||
6. [自适应评分](#6-自适应评分)
|
||
7. [聚类分析](#7-聚类分析)
|
||
8. [特征提取与 UMAP 嵌入](#8-特征提取与-umap-嵌入)
|
||
9. [可视化](#9-可视化)
|
||
10. [LLM 集成](#10-llm-集成)
|
||
11. [手动分析工作流](#11-手动分析工作流)
|
||
12. [跨机部署](#12-跨机部署)
|
||
|
||
---
|
||
|
||
## 1. 工具总览
|
||
|
||
系统现有 **30 个 MCP 工具**, 分四层, 实现于 `analysis/tools/` 包的 14 个 handler 模块。完整列表见 [AGENTS.md](../AGENTS.md) 中的「30 MCP Tools」表。
|
||
|
||
**标准分析链 (`load_data → filter_data → profile_data → build_entity_profiles → compute_scores → run_clustering → extract_features`)** 覆盖从 CSV 加载到 UMAP 可视化的全流程。LLM 自动模式由 `tianxuan/llm_orchestrator.py` 驱动, 策略式提示词: 先 profile 了解数据 → 根据数据决策下一步 → 失败自动调诊断工具 → 最终中文总结。
|
||
|
||
### 降维方案: UMAP + TruncatedSVD
|
||
|
||
| 方法 | 用途 | 触发条件 | 代码位置 |
|
||
|------|------|---------|------------|
|
||
| **UMAP** (n_components=2) | 实体 2D 嵌入可视化, 存入 EntityProfile 表 (embedding_x/y) | `extract_features` 执行时自动计算 | `tools/features.py::_handle_extract_features` |
|
||
| **TruncatedSVD** (n_components=50) | 聚类前高维特征降维 (>50 维时) | `run_clustering` / `filter_and_cluster` 执行时 | `tools/clustering.py::_handle_run_clustering` |
|
||
| **TruncatedSVD** (n_components=1) | 自适应评分权重学习 (SVD 第一分量 loading) | `compute_scores` 被调用时 | `tools/entities.py::_add_adaptive_scores` |
|
||
| **PCA-2D** (legacy) | 前端 cluster_overview 散点图 (Canvas 绘制) | CLI pipeline 步骤 6 | `views/pipeline.py` / `run_pipeline.py` |
|
||
|
||
**距离计算**: `analysis/distance.py` 提供 IP 子网距离、地理距离 (Haversine)、Levenshtein、Hamming、FFT 相位距离。`compute_distance_matrix` 工具额外允许 LLM 编写 Python 距离函数体 (签名 `def distance_fn(row: dict) -> float:`), 在受限命名空间 (math, numpy) 中逐行执行, 用于现有工具无法表达的一次性度量。
|
||
|
||
---
|
||
|
||
## 2. 标准分析流程
|
||
|
||
```
|
||
load_data → profile_data → build_entity_profiles → compute_scores → run_clustering → extract_features
|
||
```
|
||
|
||
### 2.1 加载数据 (`load_data`)
|
||
|
||
```python
|
||
load_data(
|
||
csv_glob="data/*.csv", # glob 支持递归 **/*.csv
|
||
schema_strict=False, # 自动并集合并, 缺失列填 null
|
||
recursive=False,
|
||
encoding="utf-8",
|
||
)
|
||
# 返回: dataset_id, schema, row_count, file_count, memory_mb
|
||
```
|
||
|
||
实现: `tools/load_data.py::_handle_load_data` → `data_loader.py::load_csv_directory` (BOM 检测、编码回退、schema 容错合并)。
|
||
|
||
### 2.2 了解数据 (`profile_data`)
|
||
|
||
```python
|
||
profile_data(dataset_id="ds_...", sample_size=1000)
|
||
# 返回: 列类型/统计/空值率/相关性矩阵 (自动截断 64KB)
|
||
```
|
||
|
||
实现: `tools/profile.py::_handle_profile_data` → `data_profiler.py` 列统计 + 相关性矩阵计算。
|
||
|
||
### 2.3 构建实体画像 (`build_entity_profiles`)
|
||
|
||
```python
|
||
build_entity_profiles(
|
||
dataset_id="ds_...",
|
||
auto_detect=True, # 自动检测 IP/SNI/host/MAC/domain 列
|
||
# 或手动指定:
|
||
# entity_columns=["src_ip", "dst_ip"] # 多列复合键
|
||
)
|
||
# 返回: dataset_id (entity_前缀), entity_columns, n_entities, n_features
|
||
```
|
||
|
||
实现: `tools/entities.py::_handle_build_entity_profiles`, 融合了原 entity_detector (列检测) 和 entity_aggregator (聚合) 的逻辑。
|
||
|
||
### 2.4 计算异常分数 (`compute_scores`)
|
||
|
||
```python
|
||
compute_scores(dataset_id="entity_ds_...")
|
||
# 内部流程:
|
||
# 1. 采样 10K 行 → TruncatedSVD(n_components=1) 学习特征权重
|
||
# 2. 加权求和 → proxy_score (0-1)
|
||
# 3. IQR 阈值 → risk_level (normal/watch/suspicious/critical)
|
||
# 4. 复合 → threat_score
|
||
```
|
||
|
||
实现: `tools/entities.py::_handle_compute_scores` + `_add_adaptive_scores`。
|
||
|
||
### 2.5 聚类分析 (`run_clustering`)
|
||
|
||
```python
|
||
run_clustering(
|
||
dataset_id="entity_ds_...",
|
||
cluster_columns=["flow_count", "unique_dst_ips", ...], # 或自动选数值列
|
||
algorithm="hdbscan", # 或 "kmeans"
|
||
random_state=42,
|
||
)
|
||
```
|
||
|
||
预处理链: 列过滤 → NaN 填充 (列均值) → StandardScaler → 方差过滤 (< 1e-10) → 相关过滤 (> 0.95 Pearson) → **TruncatedSVD (>50 特征时降维至 50)** → 聚类
|
||
|
||
实现: `tools/clustering.py::_handle_run_clustering`。
|
||
|
||
### 2.6 提取特征 (`extract_features`)
|
||
|
||
```python
|
||
extract_features(
|
||
dataset_id="entity_ds_...",
|
||
cluster_result_id="clust_...",
|
||
method="zscore", # 或 "anova"
|
||
top_k=10,
|
||
)
|
||
```
|
||
|
||
执行: Z-Score/ANOVA 特征重要性 → **UMAP-2D 嵌入** (训练 10K 样本, 批量变换 1K 批次) → EntityProfile 表存储坐标 → ClusterFeature 表存储区分特征。
|
||
|
||
实现: `tools/features.py::_handle_extract_features` + `_save_features_to_db`。
|
||
|
||
---
|
||
|
||
## 3. 数据准备与加载
|
||
|
||
### 3.1 CSV 格式要求
|
||
|
||
| 要求 | 说明 |
|
||
|------|------|
|
||
| 分隔符 | 逗号 `,` (默认), 支持自定义 |
|
||
| 文件扩展名 | `.csv` |
|
||
| 多文件 | glob 通配符、`**/*.csv` 递归扫描、自动合并 |
|
||
| 压缩包 | `.zip` 文件自动解压 (上传界面) |
|
||
| 文件数量 | 无硬性限制 (Polars `diagonal_relaxed` 合并) |
|
||
|
||
### 3.2 编码支持
|
||
|
||
| 编码 | BOM | 自动检测 |
|
||
|------|-----|---------|
|
||
| UTF-8 (推荐) | 无 / `EF BB BF` | 默认 |
|
||
| UTF-8 with BOM | `EF BB BF` | 自动 |
|
||
| UTF-16LE | `FF FE` | 自动 |
|
||
| UTF-16BE | `FE FF` | 自动 |
|
||
|
||
> **生产建议**: 始终使用 UTF-8 无 BOM 编码。`run.bat` 已内置 `PYTHONUTF8=1`。
|
||
|
||
### 3.3 Schema 容错
|
||
|
||
| 模式 | 行为 |
|
||
|------|------|
|
||
| `schema_strict: false` (默认) | 自动并集合并, 缺失列填 null |
|
||
| `schema_strict: true` | 列名不一致时报 ValueError |
|
||
|
||
实现: `data_loader.py::load_csv_directory` 中的 `diagonal_relaxed` 合并策略。
|
||
|
||
---
|
||
|
||
## 4. 类型检测与数据校验
|
||
|
||
### 4.1 值优先类型检测
|
||
|
||
`analysis/type_classifier.py` 实现六阶段类型推断:
|
||
|
||
```
|
||
配置指定 (config.yaml columns section) → 值采样检测 (85%+ 合规即判定)
|
||
→ 名称推断 (下划线分词关键词匹配) → STRING 回退
|
||
```
|
||
|
||
支持类型: MAC, PORT, IPv4, URL, HEX, ENUM, LAT_LON, BOOL_ENUM, TIMESTAMP, INT, FLOAT, STRING。
|
||
|
||
### 4.2 数据校验
|
||
|
||
`analysis/data_validator.py::validate()` 检查: 列类型矛盾、缺失率 (>50% 高风险)、异常值 (Z-score > 5 比例)、枚举分布、IPv4 有效性。
|
||
|
||
### 4.3 自动清洗
|
||
|
||
在 `load_csv_directory()` 中自动执行: BOOL_ENUM 标准化 (`"+"` → True, `""` → null)、HEX 列添加 `hex_pairs_count` 辅助列、通用数值清洗 (`_coerce_to_float` 处理 `+`/`-`/空白/N/A 等伪值)。
|
||
|
||
---
|
||
|
||
## 5. 实体识别与聚合
|
||
|
||
### 5.1 实体列检测
|
||
|
||
`tools/entities.py::_handle_build_entity_profiles` 中的自动检测逻辑 (合并了原 `entity_detector.py` 的功能):
|
||
|
||
- **关键词匹配**: 列名下划线分词后匹配 `_ENTITY_KEYWORDS` 集合 (IP, SNI, host, MAC, domain, user, id, name, ...)
|
||
- **数据类型判断**: IPv4 列、ENUM 列自动纳入候选
|
||
- **唯一值比率**: 高唯一率 (>50%) 加权, 极高唯一率 (>90%) 惩罚
|
||
- **空值惩罚**: 高空值率 (>50%) 大幅降权
|
||
- **多列复合键**: 多个 IP 列 (src_ip + dst_ip) 自动组合为复合实体键
|
||
|
||
### 5.2 IP 子网聚合
|
||
|
||
对 `DataType.IPv4` 列自动生成子网 (如 `192.168.1.0/24`), `unique_24_networks` 反映网络分布广度。`config.yaml` 可配置子网掩码列表。
|
||
|
||
实现: `ip_clustering.py::ip_to_subnet` 和 `apply_subnet_aggregation`。
|
||
|
||
### 5.3 类型感知聚合
|
||
|
||
数据类型到聚合函数的映射位于 `tools/entities.py`:
|
||
|
||
| 数据类型 | 聚合函数 |
|
||
|---------|---------|
|
||
| INT | mean, sum |
|
||
| FLOAT | mean |
|
||
| ENUM | mode |
|
||
| HEX | hex 对均值 |
|
||
| URL | 唯一域名数 |
|
||
| IPv4 | 子网多样性 |
|
||
| LAT_LON | mean |
|
||
| TIMESTAMP | min, max |
|
||
|
||
---
|
||
|
||
## 6. 自适应评分
|
||
|
||
`tools/entities.py::_add_adaptive_scores()`:
|
||
|
||
1. 采样 ≤10K 行
|
||
2. **TruncatedSVD(n_components=1)** 学习特征权重 (第一分量 loading 的绝对值归一化)
|
||
3. 全量加权求和 → `proxy_score` (0-1), `modern_tls_rate` 取反
|
||
4. IQR 阈值: q75 + 1.5×IQR → suspicious, q75 + 3.0×IQR → critical
|
||
5. 从数据分布自动推断, 无人工阈值
|
||
|
||
---
|
||
|
||
## 7. 聚类分析
|
||
|
||
### 7.1 算法选择
|
||
|
||
| 算法 | 适用场景 |
|
||
|------|---------|
|
||
| HDBSCAN (默认) | 未知簇数、存在噪声点、自动确定 k |
|
||
| KMeans (MiniBatch) | 已知簇数、球形分布、大数据集快速收敛 |
|
||
|
||
### 7.2 预处理链
|
||
|
||
1. 列过滤 → 2. 全 NaN 列丢弃 → 3. 列均值填充 NaN → 4. StandardScaler → 5. 方差过滤 (< 1e-10) → 6. 相关过滤 (> 0.95) → 7. **TruncatedSVD (>50 维时)** → 8. min_cluster_size 自适应 (n//20) → 9. 聚类
|
||
|
||
实现: `tools/clustering.py::_handle_run_clustering`。
|
||
|
||
### 7.3 低内存保护
|
||
|
||
可用内存 < 2GB 时自动降采样到 50K 行。样本数 > 100K 时采样 100K。样本数 > 50K 时采样 50K。
|
||
|
||
### 7.4 质量评估
|
||
|
||
| 指标 | 范围 | 说明 |
|
||
|------|------|------|
|
||
| Silhouette Score | [-1, 1] | >0.5 良好, >0.7 优秀 |
|
||
| Davies-Bouldin Index | [0, +∞) | 越低越好 |
|
||
| Calinski-Harabasz Score | [0, +∞) | 越高越好 |
|
||
| Noise Ratio | [0, 1] | HDBSCAN 噪声点比例 |
|
||
|
||
实现: `tools/evaluate.py::_handle_evaluate_clustering`。
|
||
|
||
---
|
||
|
||
## 8. 特征提取与 UMAP 嵌入
|
||
|
||
### 8.1 Z-Score 方法
|
||
|
||
`(μ_cluster − μ_global) / σ_global` — 簇中心 vs 全局均值的标准差偏离。
|
||
|
||
### 8.2 UMAP-2D 嵌入
|
||
|
||
在 `extract_features` 执行时自动计算 (`tools/features.py`):
|
||
- **训练**: 采样 ≤10K 行 → StandardScaler → UMAP(n_components=2, n_neighbors=15, min_dist=0.1)
|
||
- **批量变换**: 1K 行批次 → 全量数据坐标
|
||
- **持久化**: `EntityProfile` 表的 `embedding_x` / `embedding_y` 字段
|
||
- **用途**: 前端散点图 (cluster_overview.html Canvas 2D 渲染, 按聚类着色)
|
||
|
||
### 8.3 区分特征解读
|
||
|
||
| 分数范围 | 含义 |
|
||
|---------|------|
|
||
| \|Z\| < 1.0 | 无明显区分力 |
|
||
| 1.0 ≤ \|Z\| < 2.0 | 中等区分力 |
|
||
| \|Z\| ≥ 2.0 | **强区分特征** (Web 界面颜色高亮) |
|
||
|
||
---
|
||
|
||
## 9. 可视化
|
||
|
||
### 9.1 聚类概览 (`/clusters/<display_id>/`)
|
||
|
||
Canvas 2D 绘制的 UMAP/PCA 散点图 (实体在二维嵌入空间的分布) + 地理分布图 + Silhouette 柱状对比。点颜色按聚类标签区分。
|
||
|
||
### 9.2 3D 地球 (`/globe/`)
|
||
|
||
Three.js 绘制: TLS 流量弧线 (v1.3 蓝/v1.2 粉/其他 青)、弧线高度自适应距离、鼠标拖拽旋转、滚轮缩放 (3-30)、经纬线 (10° 间隔)、177 国境线、脉冲动画 (背面剔除, 不穿透地球)、多数据源叠加复选框。
|
||
|
||
### 9.3 实体画像 (`/entity/<display_id>/`)
|
||
|
||
聚合特征展示 + Z-Score 簇偏离量 + Canvas 单点散点图。
|
||
|
||
---
|
||
|
||
## 10. LLM 集成
|
||
|
||
### 10.1 API 配置
|
||
|
||
通过 `config/config.yaml` 或 Web 配置页面设置:
|
||
|
||
```yaml
|
||
llm:
|
||
enabled: true
|
||
base_url: "https://api.openai.com/v1"
|
||
api_key: "sk-..."
|
||
model: "deepseek-v4-flash"
|
||
max_tokens: 2048
|
||
temperature: 0.1
|
||
```
|
||
|
||
支持 OpenAI 兼容 API (OpenAI / Azure / Ollama / vLLM / LM Studio)。
|
||
|
||
### 10.2 32B 模型优化
|
||
|
||
`tianxuan/llm_orchestrator.py` 中的优化: Step Guidance (每步提示下一步)、工具结果截断 (1200 chars)、超时 90s、最大步数 15、中文一行工具描述、`_truncate_response()` 自动将返回压缩到 64KB 以内。
|
||
|
||
### 10.3 日志标记
|
||
|
||
| 标记 | 含义 |
|
||
|------|------|
|
||
| `[LLM]` | LLM 调用 (model, latency_ms) |
|
||
| `[LLM REQUEST]` | 请求内容 (缩减后) |
|
||
| `[LLM RESPONSE]` | 响应状态 |
|
||
| `[TOOL]` | LLM 调用的工具名 |
|
||
| `[SCORE]` | 自适应评分参数 (权重/阈值) |
|
||
| `[CLUSTER_INPUT]` | 聚类输入 (行数/列数/特征列) |
|
||
| `[CLUSTER_SCALE]` | StandardScaler 状态 |
|
||
| `[UMAP_ERR]` | UMAP 计算异常 |
|
||
| `[DB_SAVE_ERROR]` | DB 持久化失败 |
|
||
| `[DB_LOCKED]` | SQLite 锁重试 |
|
||
|
||
---
|
||
|
||
## 11. 手动分析工作流
|
||
|
||
手动分析页面 (`templates/tianxuan/manual.html`) 为**工作流构建器**:
|
||
|
||
1. 用户添加/移除/重排分析步骤
|
||
2. 每步选择 MCP 工具并填写参数
|
||
3. 方案可保存/加载/删除 (JSON 文件, 存储于 `.omo/plans/`)
|
||
4. 支持单步执行或全部自动串行执行
|
||
5. 每步执行结果实时显示在步骤下方
|
||
|
||
后端实现: `views/manual.py::manual_page` (页面渲染) + `views/manual.py::manual_run_analysis` (执行引擎)。
|
||
|
||
---
|
||
|
||
## 12. 跨机部署
|
||
|
||
### 12.1 运行时验证
|
||
|
||
```bash
|
||
# 两台机器各自执行
|
||
runtime\python\python.exe manage.py run_pipeline data\complex_test.csv
|
||
# 对比日志
|
||
runtime\python\python.exe scripts\diagnose_compare.py log_a.txt log_b.txt
|
||
```
|
||
|
||
### 12.2 跨机一致性检查清单
|
||
|
||
```bash
|
||
runtime\python\python.exe --version
|
||
runtime\python\python.exe -c "import sys; print(sys.getdefaultencoding(), sys.getfilesystemencoding())"
|
||
runtime\python\python.exe -c "import polars; print(polars.__version__)"
|
||
runtime\python\python.exe -c "import numpy, sklearn; print(numpy.__version__, sklearn.__version__)"
|
||
```
|
||
|
||
### 12.3 关键架构决策 (已修复的跨机问题)
|
||
|
||
| 决策 | 原因 |
|
||
|------|------|
|
||
| tuple 替代 frozenset | PYTHONHASHSEED 差异导致迭代顺序不确定 |
|
||
| PYTHONUTF8=1 | 跨机编码一致性 |
|
||
| sync_to_async ORM | async 上下文中的 Django ORM 安全调用 |
|
||
| 纯 Canvas 图表 | 零外部 JS 依赖, 离线可用 |
|
||
| 上传目录隔离 (%APPDATA%) | 与项目路径无关, 跨机部署路径不一致 |
|
||
| min_cluster_size 自适应 (n//20) | 数据量差异不影响聚类结果 |
|
||
| random_state=42 | 所有随机操作固定种子 |
|
||
|
||
### 12.4 故障诊断流程
|
||
|
||
```
|
||
出现跨机差异
|
||
├─ Step 1: 收集两台机器的 logs/tianxuan.log
|
||
├─ Step 2: diagnose_compare.py 对比, 找首个 [DIFF]
|
||
├─ Step 3: 判断差异类型
|
||
│ ├─ [LOAD_SCHEMA] 列类型不同 → 检查 Polars 版本/PYTHONUTF8
|
||
│ ├─ [FIND_COL] 关键词匹配不同 → tuple 修复已应用
|
||
│ └─ [CLUSTER_INPUT] 聚类结果不同 → 检查 random_state/StandardScaler
|
||
└─ Step 4: 归档诊断信息 → 诊断报告_%COMPUTERNAME%.txt
|
||
```
|
||
|
||
---
|
||
|
||
## 附录: 模块历史
|
||
|
||
> **simple_analysis 模块**: 原独立 Django app (`/simple/` 路由) 提供简化的上传→筛选→Leaflet 地图工作流。在 beta-clean 分支重构中已删除, 独立维护于 master 分支。当前版本不再包含此模块。
|
||
|
||
---
|
||
|
||
> **更多技术细节**: 请参阅 `AGENTS.md` 了解完整配置、架构决策和操作流程。
|