# 天璇 (TianXuan) — Agent Knowledge Base

## Project Identity

| Field | Value |
|-------|-------|
| 项目名称 | 天璇 (TianXuan) |
| 原始名称 | tls-analyzer |
| 核心功能 | TLS 流数据分析、实体画像、聚类 3D 地球可视化、UMAP/SVD 降维散点图 |
| Python 版本 | 3.12 (embedded portable at `runtime/python/python.exe`) |
| Polars 版本 | 1.42.1 (精确锁定) |
| 数据框架 | Polars (LazyFrame + streaming) |
| 机器学习 | scikit-learn (HDBSCAN, KMeans, MiniBatchKMeans, IsolationForest), UMAP, TruncatedSVD, StandardScaler |
| Web 框架 | Django 4.2 + SQLite WAL |
| 前端 3D | Three.js (603KB, 离线, 地球贴图 1.4MB) |
| 前端图表 | 纯 Canvas 2D 散点图 / Canvas 地理分布 |
| LLM 协议 | MCP (stdio transport) + OpenAI 兼容 API |
| 启动方式 | `run.bat` (双击即用, 非阻塞, 打印 PID 后退出) / `runtime\python\python.exe manage.py runserver` (开发) |
| 目标设备 | Windows 10 1909+, 8GB RAM, 无独立显卡 (核显), 支持 2500 CSV × 10000 行 × 50~58 列 |

## Project Structure

```
天璇/
├── tianxuan/                     Django 项目配置
│   ├── settings.py               ALLOWED_HOSTS 自动检测, LOGGING 文件+stderr
│   ├── wsgi.py                   SQLite 启动自修复
│   ├── urls.py                   路由汇总
│   └── llm_orchestrator.py       LLM 编排 (策略式提示词, 自动错误恢复)
├── analysis/                     核心分析模块 (Django app)
│   ├── views/                    视图包 (12 模块, 原 views.py 拆分)
│   │   ├── __init__.py           重导出所有视图函数
│   │   ├── helpers.py            辅助函数
│   │   ├── dashboard.py          首页 + 运行记录
│   │   ├── pipeline.py           管道执行器
│   │   ├── clustering.py         聚类概览/详情/地球数据
│   │   ├── entity.py             实体画像页
│   │   ├── upload.py             CSV 上传
│   │   ├── manual.py             手动分析工作流构建器
│   │   ├── auto.py               LLM 自动分析
│   │   ├── globe.py              3D 地球数据接口
│   │   ├── config.py             配置编辑 + LLM 测试
│   │   ├── log_viewer.py         日志查看器
│   │   └── tools.py              工具实验室
│   ├── tools/                    工具包 (17 模块, 30 个 MCP 工具实现)
│   │   ├── __init__.py           重导出所有 handler
│   │   ├── _registry.py          工具元数据 (Tool descriptor + get_tools_meta)
│   │   ├── _dispatch.py          工具调用分发 (handle_call)
│   │   ├── _helpers.py           共享辅助 (过滤表达式构建/响应截断/数据集决议/数值列检测)
│   │   ├── load_data.py          工具 1: load_data
│   │   ├── profile.py            工具 2: profile_data
│   │   ├── filter.py             工具 3: filter_data
│   │   ├── preprocess.py         工具 4: preprocess_data
│   │   ├── clustering.py         工具 5+8: run_clustering, filter_and_cluster
│   │   ├── evaluate.py           工具 6: evaluate_clustering
│   │   ├── features.py           工具 7: extract_features (+ UMAP 嵌入)
│   │   ├── entities.py           工具 9+10: build_entity_profiles, compute_scores
│   │   ├── anomalies.py          工具 11+12: detect_anomalies, visualize_anomalies
│   │   ├── export.py             工具 13: export_results
│   │   ├── analysis.py           工具 14-19: analyze_patterns/temporal/fft/tls_health/geo_distribution/entity_detail
│   │   ├── diagnostics.py        工具 20-26: validate_data/explore_distributions/find_outliers/diagnose_clustering/compare_datasets/export_debug_sample/repair_schema
│   │   ├── data_mgmt.py          工具 27-29: list_datasets/drop_dataset/clone_dataset
│   │   └── distance_matrix.py    工具 30: compute_distance_matrix
│   ├── tool_registry.py          旧编排层 (薄包装, 重导出 tools/)
│   ├── mcp_server.py             MCP stdio server
│   ├── data_loader.py            CSV 加载底层 (BOM/编码/schema 容错/递归 glob/ZIP 解压)
│   ├── data_profiler.py          列统计 + 相关性矩阵
│   ├── data_validator.py         列校验 (缺失/异常值/IP 有效性)
│   ├── type_classifier.py        值优先类型检测 (MAC/端口/IPv4/URL/HEX/ENUM/LAT_LON/BOOL_ENUM/TIMESTAMP)
│   ├── geoip.py                  GeoIP 经纬度查询
│   ├── ip_clustering.py          IP 子网聚类与转换
│   ├── session_store.py          线程安全单例内存存储
│   ├── distance.py               距离计算 (IP 子网/地理/Levenshtein/Hamming/FFT 相位)
│   ├── models.py                 ORM: AnalysisRun, ClusterResult, EntityProfile, ClusterFeature
│   ├── urls.py                   路由注册
│   ├── nl_describe.py            自然语言数据描述
│   ├── profile_util.py           画像工具函数
│   ├── tls_ref.py                TLS 版本/加密套件参考数据
│   ├── db_utils.py               SQLite WAL 工具 + 锁重试
│   ├── constants.py              全局常量
│   ├── appdata.py                应用数据路径 (%APPDATA%/TianXuan)
│   └── management/commands/
│       ├── start_mcp.py          MCP 服务器启动命令
│       ├── run_pipeline.py       一键 CLI 管道命令
│       └── import_tlsdb.py       TLS 数据库导入
├── config/                       配置管理
│   ├── config.yaml               自动生成默认配置 (entity, server, data, clustering, llm)
│   ├── loader.py                 Pydantic 配置加载 + 文件修改检测 + 缓存
│   └── __init__.py
├── templates/                    页面模板 (13 个 HTML)
│   ├── base.html                 导航: 首页/上传/手动/LLM/记录/地球/配置
│   ├── analysis/                 分析页面 (6 个)
│   │   ├── dashboard.html        首页 — 最近运行
│   │   ├── run_list.html         运行记录列表
│   │   ├── run_detail.html       运行详情摘要
│   │   ├── cluster_overview.html 聚类概览 — Canvas 散点图 (PC1/PC2) + 地理分布 + Silhouette
│   │   ├── cluster_detail.html   簇详情 — 特征实体列表
│   │   └── entity_profile.html   实体画像 — 特征偏离 + Canvas 单点
│   └── tianxuan/                 功能页面 (6 个)
│       ├── upload.html           CSV 上传 — 拖拽+多文件删除+进度
│       ├── manual.html           手动分析 — 工作流构建器 (添加/排序/保存/执行)
│       ├── auto.html             LLM 自动分析 — 实时日志, thinking panel, 工具调用折叠
│       ├── globe.html            3D 地球 — Three.js 流量弧线 + 经纬线 + 国境线
│       ├── config.html           配置编辑 — LLM 连通性测试
│       └── log_viewer.html       日志查看
├── static/tianxuan/              离线静态资源
│   ├── three.min.js              Three.js 3D 引擎 (603KB)
│   ├── earth_atmos_2048.jpg      地球贴图 (1.4MB)
│   └── world_borders.js          177 国完整国境线 (269KB)
├── runtime/python/               便携 Python 3.12 运行时 (~593MB)
├── scripts/                      工具脚本
│   ├── gen_test_data.py          简单测试数据生成
│   ├── gen_complex_test.py       复杂数据生成 (5000 行 含 55% 缺失)
│   ├── column_survey.py          CSV 列结构调查
│   ├── diagnose_compare.py       跨机日志对比诊断
│   └── debug_db.py               DB 持久化调试
├── tests/                        测试
│   ├── test_e2e_full.py          全端到端测试
│   ├── test_e2e_batch.py         批量端到端测试
│   ├── start_srv.py              测试服务器启动辅助
│   └── _test_hdbscan.py          HDBSCAN 零样本降级测试
├── data/                         数据目录
│   └── geoip_data.txt            GeoIP 离线数据库
├── logs/                         日志输出
│   └── tianxuan.log              主日志文件
├── docs/
│   ├── 工作流.md                  完整分析流水线文档
│   └── 故障诊断手册.md            跨机问题诊断指南
├── run.bat                       用户启动入口 (含 PYTHONUTF8=1)
├── shell.bat                     Django shell
├── update.bat                    增量更新
├── rollback.bat                  更新回滚
├── build.bat                     构建打包
├── TlsDB.csv                     参考表头名清单
├── README.md
├── AGENTS.md
└── manage.py
```

## 30 MCP Tools

系统现有 **30 个 MCP 工具**, 分四层, 实现于 `analysis/tools/` 包的 14 个 handler 模块:

### ⚡ 核心工具 (14 个) — 执行分析, 可修改数据

| # | 工具 | 实现模块 | 功能 | 必需参数 |
|---|------|---------|------|----------|
| 1 | `load_data` | tools/load_data.py | 加载 CSV 文件 (glob/递归/ZIP 解压/schema 容错) | `csv_glob` |
| 2 | `profile_data` | tools/profile.py | 数据集概要统计 + 相关性矩阵 | `dataset_id` |
| 3 | `filter_data` | tools/filter.py | 按条件过滤 (12 操作符 + AND/OR 逻辑) | `dataset_id`, `filters` |
| 4 | `preprocess_data` | tools/preprocess.py | 预处理 (StandardScaler/OneHot/填充/列删除) | `dataset_id`, `columns` |
| 5 | `run_clustering` | tools/clustering.py | 执行聚类 (HDBSCAN/KMeans + 自动特征过滤 + 质量评估) | `dataset_id`, `cluster_columns` |
| 6 | `evaluate_clustering` | tools/evaluate.py | 评估聚类质量 (Silhouette/DB/CH/噪声比/簇大小) | `cluster_result_id`, `dataset_id` |
| 7 | `extract_features` | tools/features.py | 提取各聚类区分特征 (Z-Score/ANOVA) + UMAP-2D 嵌入 | `dataset_id`, `cluster_result_id` |
| 8 | `filter_and_cluster` | tools/clustering.py | 一步完成: 过滤 + 自动选数值列 + 聚类 | `dataset_id`, `filters` |
| 9 | `build_entity_profiles` | tools/entities.py | 自动检测实体列 + 聚合特征 (多列复合键支持) | `dataset_id` |
| 10 | `compute_scores` | tools/entities.py | 自适应代理/异常/威胁评分 (SVD 权重 + IQR 阈值) | `dataset_id` |
| 11 | `detect_anomalies` | tools/anomalies.py | Isolation Forest 异常检测 (分块处理大数据集) | `dataset_id` |
| 12 | `visualize_anomalies` | tools/anomalies.py | UMAP-2D 嵌入 + 聚类可视化 (按风险等级/聚类着色) | `dataset_id` |
| 13 | `export_results` | tools/export.py | 导出结果到磁盘 (CSV/Parquet/JSON) | `result_id`, `output_path` |
| - | `export_entities_json` | tools/export.py | 导出实体画像为 JSON (附加工具) | `dataset_id`, `output_path` |

### 🔍 分析工具 (6 个) — 只读深潜, 安全随时调用

| # | 工具 | 实现模块 | 功能 |
|---|------|---------|------|
| 14 | `analyze_patterns` | tools/analysis.py | 流量模式: top 源/目标 IP、端口/TLS 版本/协议分布 |
| 15 | `analyze_temporal` | tools/analysis.py | 时间维度流量分析: 小时/日流量计数、繁忙/空闲时段 |
| 16 | `analyze_fft` | tools/analysis.py | FFT 频谱分析: 周期模式、频率特征、周期性评分 |
| 17 | `analyze_tls_health` | tools/analysis.py | TLS 安全态势: 旧版比例、弱加密、证书问题、SNI 异常 |
| 18 | `analyze_geo_distribution` | tools/analysis.py | 地理分布: top 来源国家、不可能旅行、ISP 多样性 |
| 19 | `analyze_entity_detail` | tools/analysis.py | 单实体深度调查: 流/版本/目标/时间模式/异常评分 |

### 🩺 诊断工具 (7 个) — 排查问题

| # | 工具 | 实现模块 | 功能 |
|---|------|---------|------|
| 20 | `validate_data` | tools/diagnostics.py | 数据质量: schema 一致性、缺失率、列类型冲突 |
| 21 | `explore_distributions` | tools/diagnostics.py | 列分布统计: 唯一值、空值率、min/max/mean/std、直方图 |
| 22 | `find_outliers` | tools/diagnostics.py | IQR 方法检测数值列统计异常值 |
| 23 | `diagnose_clustering` | tools/diagnostics.py | 聚类效果差时诊断: 方差/相关分析 + 参数建议 |
| 24 | `compare_datasets` | tools/diagnostics.py | 对比两数据集: schema 差异、行数变化、值分布偏移 |
| 25 | `export_debug_sample` | tools/diagnostics.py | 导出原始数据样本 JSON 供外部调试 |
| 26 | `repair_schema` | tools/diagnostics.py | 修复 schema 不匹配: 列名对齐、大小写合并、填充缺失 |

### 📦 数据管理 (3 个)

| # | 工具 | 实现模块 | 功能 |
|---|------|---------|------|
| 27 | `list_datasets` | tools/data_mgmt.py | 列出所有活跃数据集和结果 |
| 28 | `drop_dataset` | tools/data_mgmt.py | 删除数据集释放内存 (支持 dataset/cluster/feature 三种类型) |
| 29 | `clone_dataset` | tools/data_mgmt.py | 浅拷贝数据集 (LazyFrame 查询计划, 不复制数据) |

### 🧠 LLM 驱动 (1 个)

| # | 工具 | 实现模块 | 功能 |
|---|------|---------|------|
| 30 | `compute_distance_matrix` | tools/distance_matrix.py | LLM 编写 Python 距离函数, 逐行执行并返回评分摘要 |

**工具注册流程**: `tools/_registry.py` (Tool 元数据) → `tools/_dispatch.py` (分发到对应 handler) → `analysis/mcp_server.py` (暴露 MCP stdio 接口)

### 手动分析工作流

手动分析页面 (manual.html) 为**工作流构建器**:
- 添加/移除/重排步骤
- 每步选择工具 + 填写参数
- **保存/加载/删除**方案 (存储于 `.omo/plans/<name>.json`)
- 单步执行 / **全部执行** (自动串行)
- 执行结果显示在每一步下面

### 标准分析流程

```
load_data → filter_data → profile_data → build_entity_profiles → compute_scores → run_clustering → extract_features
```

LLM 自动模式由 `tianxuan/llm_orchestrator.py` 驱动, 策略式提示词: 先 profile 了解数据 → 根据数据决策 → 失败自动诊断 → 重复调用检测 + 自动错误恢复。

## Config.Entity

`config/loader.py` 中的 Pydantic 模型:

```python
class Entity(BaseModel):
    subnet_masks: list[int] = []                     # 子网掩码列表, 如 [24, 28]
    ip_columns: list[str] = ['src_ip', 'dst_ip']     # 需聚合的 IP 列
```

config.yaml 默认配置:
```yaml
entity:
  subnet_masks: [24, 28]
  ip_columns: ["src_ip", "dst_ip"]
```

IP 子网聚合逻辑位于 `analysis/ip_clustering.py`, `tools/entities.py::_handle_build_entity_profiles` 在 group_by 前对 IP 列自动应用子网掩码。

---

## Architecture

- **views 包拆分**: 原单体 `views.py` (2000+ 行) 拆分为 12 个模块: dashboard, pipeline, clustering, entity, upload, manual, auto, globe, config, log_viewer, tools, helpers
- **tools 包拆分**: 原 `tool_registry.py` 拆分为 17 个模块 (14 个 handler + 3 个基础设施: _registry/_dispatch/_helpers)
- **tuple 替代 frozenset**: 避免跨机 PYTHONHASHSEED 差异
- **PYTHONUTF8=1**: 跨机编码一致性 (run.bat 内置)
- **类型安全聚合**: 聚合前检查 dtype, 非数值列 cast
- **sync_to_async ORM**: 异步上下文中 Django ORM 安全调用
- **纯 Canvas 图表**: 零外部 JS 依赖 (散点图/地理分布/Silhouette 柱状图)
- **上传目录隔离**: `%APPDATA%/TianXuan/data/uploads/`, 与项目路径无关
- **通用数值清理 _coerce_to_float**: 处理 `+` / `-` / 空白 / N/A 等伪值
- **值优先类型检测**: config → 值 → 名称 → STRING (type_classifier.py)
- **地球深度测试**: depthTest: true, depthWrite: false, r=5.5
- **完整国境线**: Natural Earth 110m, 177 国 286 多边形 269KB
- **UMAP 降维**: extract_features 中为实体数据计算 UMAP-2D 嵌入, 存储到 EntityProfile 表 (embedding_x/embedding_y), 训练 10K 样本 + 批量变换 1K 批次
- **TruncatedSVD**: 聚类时特征 > 50 维自动降维; compute_scores 中学习自适应评分权重
- **LLM 驱动距离计算**: compute_distance_matrix 工具允许 LLM 编写 Python 函数在受限命名空间 (math, numpy) 中逐行执行
- **距离计算多策略**: tools/distance_matrix.py 中的 compute_distance_matrix 和 analysis/distance.py 中的 IP 子网/地理/Levenshtein/Hamming/FFT 相位距离

---

## Testing Protocol

### 运行测试

```bash
# 端到端测试 (自动启动后端、模拟前端行为、监控 stderr)
runtime\python\python.exe tests\test_e2e_full.py
runtime\python\python.exe tests\test_e2e_batch.py

# HDBSCAN 零样本降级测试
runtime\python\python.exe tests\_test_hdbscan.py
```

### 跨机一致性测试

```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
```

### DB 持久化测试

```bash
runtime\python\python.exe scripts\debug_db.py
# 期望: n_features=30 db_saved=True
# 验证: AnalysisRun, ClusterFeature 表有数据
```

### LLM 编排测试

```bash
runtime\python\python.exe scripts\test_llm_full.py
```

### 生成测试数据

```bash
# 简单数据
runtime\python\python.exe scripts\gen_test_data.py --rows 1000

# Globe 模式 (IP 在真实 GeoIP 范围)
runtime\python\python.exe scripts\gen_test_data.py --globe

# 复杂数据 (5000 行 4 列含 55% 缺失)
runtime\python\python.exe scripts\gen_complex_test.py --rows 5000
```

### 列结构调查

```bash
runtime\python\python.exe scripts\column_survey.py --csv "data/*.csv"
```

---

## Polars Version Compatibility

| API | 旧版 (<1.0) | 新版 (>=1.0) |
|-----|-----------|-----------|
| mode | `pl.mode()` | `pl.col(col).mode()` |
| encoding | `encoding='utf-8'` | `encoding='utf8'` |
| value_counts col | `'index'` | 原列名 |
| streaming | `collect(streaming=True)` | `collect(engine='streaming')` |
| truth value | `if series:` | `if series.item():` |

## 32B LLM Optimization

- **Step guidance**: 每步告诉模型下一步做什么, 减少 32B 模型推理发散
- **Truncation**: 工具结果截断 1200 chars (避免上下文窗口溢出)
- **Timeout**: 90s (32B 推理更慢)
- **Max steps**: 15
- **Tool description**: 一行简洁描述 (中文)
- **策略式提示词**: 先 profile → 根据数据决策 → 失败自动诊断 → 重复调用检测 + 自动错误恢复
- **工具结果自动截断**: `_truncate_response()` 确保单次返回不超过 64 KB, 长列表/矩阵自动压缩

---

## Operating Procedures

1. **非阻塞启动后端** — `run.bat` 使用 `start /B` 启动 Django, 打印 PID 后退出, 不阻塞终端。日志写入 `logs/tianxuan.log`。

2. **全量测试** — 所有改动完成后, 运行完整 E2E 测试: 生成测试 CSV, 上传前端, 验证全流水线。

3. **更新文档和 Git** — 测试通过后: 更新 AGENTS.md, 提交所有更改, 清理临时文件和残留进程。不留脏状态 (孤儿进程、临时文件、未提交更改)。

4. **同步依赖** — 使用 `git pull` 同步最新代码, 然后 `runtime\python\python.exe -m pip install -r requirements.txt` 安装新依赖。每次新工作会话前执行。

5. **编码前缀** — 所有终端命令加 `chcp 65001` 避免 Opencode 编码错误。PowerShell/CMD 编码问题是命令失败的首要原因。

6. **Python UTF-8** — 运行 Python 时始终加 `set PYTHONUTF8=1`。确保跨机 Unicode 处理一致, 防止编码漂移。

## 近期变更 (beta-clean 分支)

- views.py (2000+ 行单体) → `analysis/views/` 包 (12 模块)
- tool_registry.py → `analysis/tools/` 包 (17 模块)
- 删除 `simple_analysis/` 模块 (已移至 master 分支独立维护)
- 工具数量从 27 升至 30 (新增 export_entities_json, diagnostic toolbox 扩展)
- 模板目录重组: 6 个分析页面在 `analysis/`, 6 个功能页面在 `tianxuan/`
- 新增 `analysis/distance.py` (距离计算) 和 `analysis/nl_describe.py` (自然语言描述)
