feat(ssa): Complete Phase I-IV intelligent dialogue and tool system development

Phase I - Session Blackboard + READ Layer:
- SessionBlackboardService with Postgres-Only cache
- DataProfileService for data overview generation
- PicoInferenceService for LLM-driven PICO extraction
- Frontend DataContextCard and VariableDictionaryPanel
- E2E tests: 31/31 passed

Phase II - Conversation Layer LLM + Intent Router:
- ConversationService with SSE streaming
- IntentRouterService (rule-first + LLM fallback, 6 intents)
- SystemPromptService with 6-segment dynamic assembly
- TokenTruncationService for context management
- ChatHandlerService as unified chat entry
- Frontend SSAChatPane and useSSAChat hook
- E2E tests: 38/38 passed

Phase III - Method Consultation + AskUser Standardization:
- ToolRegistryService with Repository Pattern
- MethodConsultService with DecisionTable + LLM enhancement
- AskUserService with global interrupt handling
- Frontend AskUserCard component
- E2E tests: 13/13 passed

Phase IV - Dialogue-Driven Analysis + QPER Integration:
- ToolOrchestratorService (plan/execute/report)
- analysis_plan SSE event for WorkflowPlan transmission
- Dual-channel confirmation (ask_user card + workspace button)
- PICO as optional hint for LLM parsing
- E2E tests: 25/25 passed

R Statistics Service:
- 5 new R tools: anova_one, baseline_table, fisher, linear_reg, wilcoxon
- Enhanced guardrails and block helpers
- Comprehensive test suite (run_all_tools_test.js)

Documentation:
- Updated system status document (v5.9)
- Updated SSA module status and development plan (v1.8)

Total E2E: 107/107 passed (Phase I: 31, Phase II: 38, Phase III: 13, Phase IV: 25)

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-02-22 18:53:39 +08:00
parent bf10dec4c8
commit 3446909ff7
68 changed files with 11583 additions and 412 deletions

View File

@@ -1,9 +1,9 @@
# R 统计引擎架构与部署指南
> **版本:** v1.1
> **更新日期:** 2026-02-20
> **版本:** v1.3
> **更新日期:** 2026-02-22
> **维护者:** SSA-Pro 开发团队
> **状态:** ✅ 生产就绪Phase 2A 完成
> **状态:** ✅ 生产就绪Phase Deploy 完成 — 12 工具 + Block-based 标准化输出
---
@@ -15,8 +15,13 @@
4. [部署指南](#4-部署指南)
5. [API 参考](#5-api-参考)
6. [开发指南](#6-开发指南)
- 6.1 [添加新工具(含 Block-based 模板)](#61-添加新工具)
- 6.5 [各工具参数快速参考](#65-各工具参数快速参考)
- 6.6 [R 语言陷阱速查7 大坑)](#66-r-语言陷阱速查从实际-bug-中总结)
- 6.7 [开发环境新增 R 包](#67-开发环境新增-r-包)
7. [运维指南](#7-运维指南)
8. [常见问题](#8-常见问题)
9. [测试指南](#9-测试指南)
---
@@ -60,6 +65,9 @@ R 统计引擎是平台的**专用统计计算服务**,基于 Docker 容器化
| ggplot2 | 最新 | 数据可视化 |
| car | 3.1-2 | 高级统计检验 |
| dplyr/tidyr | 最新 | 数据处理 |
| gtsummary | 最新 | 基线特征表生成Phase Deploy 新增) |
| gt/broom | 最新 | 表格渲染/模型整理Phase Deploy 新增) |
| scales/gridExtra | 最新 | 坐标轴格式化/多图排版Phase Deploy 新增) |
| Docker | 24+ | 容器化部署 |
---
@@ -179,7 +187,7 @@ RUN apt-get update && apt-get install -y \
curl \
&& rm -rf /var/lib/apt/lists/*
# 直接安装 R 包
# 直接安装 R 包(含 Phase Deploy 新增依赖)
RUN R -e "install.packages(c( \
'plumber', \
'jsonlite', \
@@ -190,7 +198,12 @@ RUN R -e "install.packages(c( \
'base64enc', \
'yaml', \
'car', \
'httr' \
'httr', \
'scales', \
'gridExtra', \
'gtsummary', \
'gt', \
'broom' \
), repos='https://cloud.r-project.org/', Ncpus=2)"
# 安全加固:创建非特权用户
@@ -260,8 +273,8 @@ ssa-r-statistics 1.0.1 xxxxxxxxxxxx x minutes ago 1.81GB
|------|------|
| 基础镜像下载 | ~2 分钟(首次) |
| 系统依赖安装 | ~1 分钟 |
| R 包安装 | ~6 分钟 |
| **总计** | **~9 分钟** |
| R 包安装15 个包含 gtsummary/gt | ~10 分钟 |
| **总计** | **~13 分钟** |
---
@@ -380,19 +393,26 @@ GET /api/v1/tools
{
"status": "ok",
"tools": [
"anova_one",
"baseline_table",
"chi_square",
"correlation",
"correlation",
"descriptive",
"fisher",
"linear_reg",
"logistic_binary",
"mann_whitney",
"t_test_ind",
"t_test_paired"
"t_test_paired",
"wilcoxon"
],
"count": 7
"count": 12
}
```
#### 已实现的统计工具(Phase 2A
#### 已实现的统计工具(12 个
**Phase 2A 基础工具7 个)**
| tool_code | 名称 | 场景 |
|-----------|------|------|
@@ -401,9 +421,19 @@ GET /api/v1/tools
| `ST_T_TEST_PAIRED` | 配对 T 检验 | 前后对比 |
| `ST_CHI_SQUARE` | 卡方检验 | 分类变量关联 |
| `ST_CORRELATION` | 相关分析 | Pearson/Spearman 相关 |
| `ST_LOGISTIC_BINARY` | 二元 Logistic 回归 | 多因素分析 |
| `ST_LOGISTIC_BINARY` | 二元 Logistic 回归 | 多因素分析(二分类结局) |
| `ST_DESCRIPTIVE` | 描述性统计 | 基线表、数据概况 |
**Phase Deploy 新增工具5 个)**
| tool_code | 名称 | 场景 |
|-----------|------|------|
| `ST_FISHER` | Fisher 精确检验 | 小样本/稀疏列联表(卡方替代) |
| `ST_ANOVA_ONE` | 单因素方差分析 | 三组及以上均值比较(含 Kruskal-Wallis 降级) |
| `ST_WILCOXON` | Wilcoxon 符号秩检验 | 配对非参数检验(配对 T 替代) |
| `ST_LINEAR_REG` | 线性回归 | 连续结局多因素分析 |
| `ST_BASELINE_TABLE` | 基线特征表(复合工具) | 基于 gtsummary 的一键式基线表生成 |
### 5.3 执行技能
```http
@@ -511,6 +541,58 @@ Content-Type: application/json
- 根据 `suggested_tool` 自动切换到更合适的方法
-`checks` 结果展示给用户
### 5.5 复合工具示例基线特征表Phase Deploy 新增)
```http
POST /api/v1/skills/ST_BASELINE_TABLE
Content-Type: application/json
```
**请求体:**
```json
{
"data_source": {
"type": "inline",
"data": [
{"group": "Drug", "age": 45, "sex": "M", "sbp": 130, "bmi": 24.5, "smoking": "Yes"},
{"group": "Placebo", "age": 47, "sex": "F", "sbp": 128, "bmi": 23.8, "smoking": "No"}
]
},
"params": {
"group_var": "group",
"analyze_vars": ["age", "sex", "sbp", "bmi", "smoking"]
}
}
```
**成功响应(核心字段):**
```json
{
"status": "success",
"results": {
"n_total": 30,
"n_groups": 2,
"n_variables": 5,
"significant_vars": ["sbp"],
"method_info": [
{"variable": "age", "method": "Wilcoxon rank sum test"},
{"variable": "sex", "method": "Fisher's exact test"}
]
},
"report_blocks": [
{
"type": "table",
"headers": ["Characteristic", "Drug, N = 15", "Placebo, N = 15", "p-value"],
"rows": [["age", "49 (42, 55)", "47 (41, 54)", "0.6"]],
"title": "基线特征表 (按 group 分组)",
"metadata": { "is_baseline_table": true, "group_var": "group", "has_p_values": true }
}
]
}
```
> **特点:** `ST_BASELINE_TABLE` 是复合工具,基于 `gtsummary::tbl_summary()` 自动判断变量类型(连续/分类、选择统计方法T 检验/Mann-Whitney/卡方/Fisher输出标准三线表。`report_blocks[0].metadata.is_baseline_table = true` 触发前端特殊渲染P 值标星、rowspan 合并行)。
---
## 6. 开发指南
@@ -577,7 +659,16 @@ run_analysis <- function(input) {
log_add("执行分析...")
# result <- your_analysis_function(df, ...)
# ===== 生成图表 =====
# ===== 构建 report_blocks必须 =====
blocks <- list()
# Block: 检验结果key_value
blocks[[length(blocks) + 1]] <- make_kv_block(
list("方法" = "Your Method", "统计量" = "1.234", "P 值" = format_p_value(0.05)),
title = "检验结果"
)
# Block: 图表image
plot_base64 <- tryCatch({
p <- ggplot(df, aes(x = df[[my_var]])) + geom_histogram() + theme_minimal()
tmp_file <- tempfile(fileext = ".png")
@@ -587,6 +678,13 @@ run_analysis <- function(input) {
paste0("data:image/png;base64,", base64_str)
}, error = function(e) NULL)
if (!is.null(plot_base64)) {
blocks[[length(blocks) + 1]] <- make_image_block(plot_base64, title = "分析图表")
}
# Block: 结论markdown
blocks[[length(blocks) + 1]] <- make_markdown_block("分析结论...", title = "结论摘要")
# ===== 生成可复现代码 =====
reproducible_code <- glue('
# SSA-Pro 自动生成代码
@@ -611,6 +709,7 @@ df <- read.csv("data.csv")
p_value = jsonlite::unbox(0.05),
p_value_fmt = format_p_value(0.05)
),
report_blocks = blocks, # ⚠️ 必须!前端 DynamicReport 依赖此字段渲染
plots = if (!is.null(plot_base64)) list(plot_base64) else list(),
trace_log = logs,
reproducible_code = as.character(reproducible_code)
@@ -643,7 +742,12 @@ return(list(
message = "...",
warnings = c("...") | NULL,
results = list(
# 统计结果
# 统计结果(使用 jsonlite::unbox() 保证单值不被包装成数组)
),
report_blocks = list(
# Block-based 标准化输出Phase E+ 协议),前端 DynamicReport.tsx 统一渲染
# 支持 4 种 Block 类型markdown / table / image / key_value
# 通过 utils/block_helpers.R 的辅助函数构建
),
plots = list(
"data:image/png;base64,..."
@@ -653,6 +757,188 @@ return(list(
))
```
### 6.4 Block-based 输出协议Phase E+ 标准)
所有工具**必须**通过 `utils/block_helpers.R` 构建 `report_blocks[]`,前端 `DynamicReport.tsx` 根据 `block.type` 统一渲染。
| 辅助函数 | Block 类型 | 用途 |
|----------|-----------|------|
| `make_markdown_block(content, title)` | `markdown` | 文本结论、方法说明 |
| `make_table_block(headers, rows, title, footnote, metadata)` | `table` | 统计结果表、系数表、事后比较表 |
| `make_table_block_from_df(df, title, footnote, digits)` | `table` | 从 data.frame 快速构建表格 |
| `make_image_block(base64_data, title, alt)` | `image` | 图表base64 编码 PNG |
| `make_kv_block(items, title)` | `key_value` | 检验统计量、模型拟合指标 |
**示例:**
```r
blocks <- list()
blocks[[length(blocks) + 1]] <- make_kv_block(
list("检验方法" = "Welch t-test", "统计量" = "t = -2.35", "P 值" = "p = .021"),
title = "检验结果"
)
blocks[[length(blocks) + 1]] <- make_image_block(plot_base64, title = "组间比较箱线图")
blocks[[length(blocks) + 1]] <- make_markdown_block("两组差异具有统计学意义...", title = "结论")
```
### 6.5 各工具参数快速参考
> 调用 `POST /api/v1/skills/{tool_code}` 时,`params` 对象需要的字段速查。
| tool_code | 必需参数 | 可选参数 |
|-----------|---------|---------|
| `ST_T_TEST_IND` | `group_var`, `value_var` | `guardrails.check_normality` |
| `ST_MANN_WHITNEY` | `group_var`, `value_var` | — |
| `ST_T_TEST_PAIRED` | `before_var`, `after_var` | `guardrails.check_normality` |
| `ST_CHI_SQUARE` | `var1`, `var2` | — |
| `ST_CORRELATION` | `var_x`, `var_y` | `method` (`"auto"` / `"pearson"` / `"spearman"`) |
| `ST_LOGISTIC_BINARY` | `outcome_var`, `predictors` (数组) | — |
| `ST_DESCRIPTIVE` | `variables` (数组) | `group_var` |
| `ST_FISHER` | `var1`, `var2` | — |
| `ST_ANOVA_ONE` | `group_var`, `value_var` | `guardrails.check_normality` |
| `ST_WILCOXON` | `before_var`, `after_var` | — |
| `ST_LINEAR_REG` | `outcome_var`, `predictors` (数组) | `confounders` (数组) |
| `ST_BASELINE_TABLE` | `group_var` | `analyze_vars` (数组,不传则自动全选) |
### 6.6 R 语言陷阱速查(从实际 Bug 中总结)
> **Phase Deploy 开发中实际踩过的坑**,后续开发者必读。每条附真实错误信息和修复方法。
#### 陷阱 1JSON 数组参数在 R 中是 `list`,不是 `character` 向量
**错误信息:** `invalid subscript type 'list'`
**原因:** plumber 解析 JSON `["age", "sex", "bmi"]`R 拿到的是 `list("age", "sex", "bmi")`,不是 `c("age", "sex", "bmi")`。对 list 做 `%in%``[` 等操作都会报错。
```r
# ❌ 错误:直接使用 JSON 传入的数组参数
analyze_vars <- p$analyze_vars
missing <- analyze_vars[!(analyze_vars %in% names(df))] # 报错!
# ✅ 正确:先转换为字符向量
analyze_vars <- as.character(unlist(p$analyze_vars))
missing <- analyze_vars[!(analyze_vars %in% names(df))] # 正常
```
**影响范围:** 所有接收数组参数的工具(`predictors``variables``analyze_vars``confounders`)。
#### 陷阱 2`list()` 中不能用表达式做键名
**错误信息:** `unexpected '='`
**原因:** R 的 `list()` 构造器只接受**字面量**作为名称,不接受 `paste0()``glue()` 等函数调用。
```r
# ❌ 错误:用表达式做键名
items <- list(
paste0(var_name, " Median") = "5.2" # 语法错误!
)
# ✅ 正确:先创建 list 再用 [[ 赋值
items <- list()
items[[paste0(var_name, " Median")]] <- "5.2"
```
#### 陷阱 3`tryCatch` 会吞掉 warning 导致结果丢失
**错误信息:** 无明确错误,但返回 NULL 或非预期结果
**原因:** `tryCatch(expr, warning = function(w) {...})` 捕获第一个 warning 后**中断 expr 执行**,返回 warning handler 的返回值。gtsummary、car 等包常发 warning导致主计算被中断。
```r
# ❌ 错误tryCatch 捕获 warning 会中断执行
tbl <- tryCatch({
tbl_summary(df) %>% add_p() # 如果 add_p() 发 warningtbl 变成 NULL
}, warning = function(w) {
invokeRestart("muffleWarning") # 在 tryCatch 中无效!
})
# ✅ 正确withCallingHandlers 处理 warning不中断执行tryCatch 只捕获 error
tbl <- tryCatch(
withCallingHandlers(
{ tbl_summary(df) %>% add_p() },
warning = function(w) {
warnings_list <<- c(warnings_list, w$message)
invokeRestart("muffleWarning")
}
),
error = function(e) { return(NULL) }
)
```
#### 陷阱 4gtsummary `table_body` 的 p.value 是 list 列
**错误信息:** `invalid subscript type 'list'`
**原因:** `gtsummary` 的内部数据结构 `tbl$table_body$p.value` 是 list 列(每个元素可能是 NULL 或 numeric不能直接用 `<` 比较。
```r
# ❌ 错误:直接对 list 列做比较
p_rows <- body[body$p.value < 0.05, ] # 报错!
# ✅ 正确:先 unlist + as.numeric
p_vals <- as.numeric(unlist(body$p.value))
sig_idx <- which(!is.na(p_vals) & p_vals < 0.05)
```
#### 陷阱 5浮点数比较不能用 `==`
**错误信息:** 无明确错误,但条件判断逻辑错误
```r
# ❌ 错误:直接比较浮点数
if (sd(values) == 0) { ... } # 可能因精度问题漏判
# ✅ 正确:使用容差比较
if (isTRUE(sd(values) < .Machine$double.eps^0.5)) { ... }
```
#### 陷阱 6变量可能为 NULL 导致 glue/round 崩溃
**错误信息:** `non-numeric argument to mathematical function``subscript out of bounds`
**原因:** 某些统计结果字段(如 `fstatistic`)在边界条件下为 NULL。
```r
# ❌ 错误:直接使用可能为 NULL 的值
log_add(glue("F = {round(f_stat[1], 2)}")) # f_stat 为 NULL 时崩溃
# ✅ 正确:先检查再使用
if (!is.null(f_stat)) {
log_add(glue("F = {round(f_stat[1], 2)}"))
} else {
log_add("F = NA")
}
```
#### 陷阱 7新增 R 包后 `utils/` 修改需要重启容器
**现象:** `make_table_block()` 新增了 `metadata` 参数,但调用时报 `unused argument`
**原因:** `utils/*.R` 在服务启动时一次性加载,不像 `tools/*.R` 有热重载。修改后必须:
```bash
cd r-statistics-service
docker-compose restart
```
### 6.7 开发环境新增 R 包
当新工具依赖尚未安装的 R 包时,有两种方式:
**方式 1临时安装到运行中的容器开发测试用**
```bash
# 容器以 appuser 运行,无写权限,需用 root
docker exec -u root ssa-r-statistics R -e "install.packages('新包名', repos='https://cloud.r-project.org/', quiet=TRUE)"
```
> 注意:容器重启后丢失,仅用于开发验证。
**方式 2更新 Dockerfile 并重建镜像(正式方案)**
1.`Dockerfile``install.packages()` 中添加新包名
2. 重建:`docker-compose up -d --build`
---
## 7. 运维指南
@@ -810,6 +1096,38 @@ if (var_type == "numeric") { ... } # var_type 可能是 NA
if (identical(var_type, "numeric")) { ... } # ✅ 处理 NA
```
### Q11: 修改 utils/ 后新参数报 `unused argument`
**原因:** `utils/*.R`(如 `block_helpers.R`)在服务启动时加载进内存,不支持热重载(与 `tools/*.R` 不同)。
**解决:**
```bash
docker-compose restart
```
### Q12: Docker 已 build 但包仍不存在(`there is no package called 'xxx'`
**原因:** `docker-compose.yml` 中的 `volumes` 挂载会覆盖镜像中的文件,但**不影响已安装的 R 包**。常见场景是更新了 Dockerfile 却只用了 `docker-compose up -d` 而没有加 `--build`
**解决:**
```bash
# 确保 rebuild
docker-compose up -d --build
# 或临时装包(开发验证)
docker exec -u root ssa-r-statistics R -e "install.packages('xxx', repos='https://cloud.r-project.org/', quiet=TRUE)"
```
### Q13: 工具返回成功但 report_blocks 为空
**原因:** 返回结构中没有 `report_blocks` 字段或 blocks 列表为空。
**检查清单:**
1. 确认使用了 `utils/block_helpers.R` 的辅助函数构建 blocks
2. 确认 return 中包含 `report_blocks = blocks`
3. 确认每个 block 至少包含 `type` 字段
4. 用测试脚本验证:`node r-statistics-service/tests/run_all_tools_test.js`
---
## 9. 测试指南
@@ -838,9 +1156,23 @@ curl -s -X POST "http://localhost:8082/api/v1/skills/ST_T_TEST_IND" \
curl -s http://localhost:8082/health | jq
```
### 9.3 端到端测试脚本
### 9.3 R 工具集中测试脚本12 工具 + JIT
项目提供了完整的端到端测试脚本:
项目提供了 R 统计引擎的全工具测试脚本:
```bash
# 仅测试 R 服务层12 工具 + JIT 护栏 + report_blocks 校验)
node r-statistics-service/tests/run_all_tools_test.js
```
测试覆盖:
- 12 个统计工具Phase 2A × 7 + Phase Deploy × 5
- JIT 护栏检查ST_T_TEST_IND / ST_ANOVA_ONE / ST_FISHER / ST_LINEAR_REG
- `report_blocks` 协议校验类型、必填字段、metadata
### 9.4 端到端测试脚本(三层联调)
三层联调测试覆盖 R → Python → Node.js
```bash
cd docs/03-业务模块/SSA-智能统计分析/05-测试文档
@@ -848,9 +1180,9 @@ node run_e2e_test.js
```
测试覆盖:
- 7 个统计工具
- JIT 护栏检查
- 数据加载(行格式/列格式
- Layer 1: R 服务12 个统计工具 + JIT 护栏)
- Layer 2: Python DataProfile API
- Layer 3: Node.js 后端 API登录 → 会话 → 规划 → 执行
---
@@ -858,27 +1190,40 @@ node run_e2e_test.js
```
r-statistics-service/
├── Dockerfile # 生产镜像定义
├── Dockerfile # 生产镜像定义(含 gtsummary/gt/broom/scales/gridExtra
├── docker-compose.yml # 开发环境编排(含 volume 挂载)
├── renv.lock # R 包版本锁定(备用)
├── .Rprofile # R 启动配置(备用)
├── plumber.R # API 入口(含 JIT 护栏端点)
├── plumber.R # API 入口(含 JIT 护栏端点,自动发现 tools/ 目录
├── utils/
│ ├── data_loader.R # 数据加载(支持行格式/列格式)
│ ├── guardrails.R # 统计护栏 + JIT 检查
│ ├── guardrails.R # 统计护栏 + JIT 检查12 工具全覆盖)
│ ├── error_codes.R # 错误映射
── result_formatter.R # 结果格式化
├── tools/ # 统计工具Phase 2A: 7 个
── result_formatter.R # 结果格式化
│ └── block_helpers.R # Block-based 输出辅助函数Phase E+ 协议
├── tools/ # 统计工具12 个)
│ ├── t_test_ind.R # 独立样本 T 检验
│ ├── t_test_paired.R # 配对 T 检验
│ ├── mann_whitney.R # Mann-Whitney U 检验
│ ├── chi_square.R # 卡方检验
│ ├── correlation.R # 相关分析
│ ├── logistic_binary.R # 二元 Logistic 回归
── descriptive.R # 描述性统计
── descriptive.R # 描述性统计
│ ├── fisher.R # 🆕 Fisher 精确检验Phase Deploy
│ ├── anova_one.R # 🆕 单因素方差分析Phase Deploy
│ ├── wilcoxon.R # 🆕 Wilcoxon 符号秩检验Phase Deploy
│ ├── linear_reg.R # 🆕 线性回归Phase Deploy
│ └── baseline_table.R # 🆕 基线特征表 — 复合工具Phase Deploy
├── tests/
│ ├── run_all_tools_test.js # 🆕 全工具自动化测试12 工具 + JIT + blocks 校验)
│ ├── test_t_test.json # T 检验测试数据
│ ├── test_fisher.json # Fisher 测试数据
│ ├── test_anova_one.json # ANOVA 测试数据
│ ├── test_wilcoxon.json # Wilcoxon 测试数据
│ ├── test_linear_reg.json # 线性回归测试数据
│ ├── test_baseline_table.json # 基线表测试数据
│ └── fixtures/
│ └── normal_data.csv # 测试数据
│ └── normal_data.csv # 测试数据
├── metadata/ # 工具元数据(预留)
└── templates/ # 解释模板(预留)
```
@@ -889,6 +1234,8 @@ r-statistics-service/
| 版本 | 日期 | 更新内容 |
|------|------|----------|
| v1.3 | 2026-02-22 | 开发者体验增强:新工具模板补全 report_blocks§6.1)、各工具 params 速查表§6.5、R 语言 7 大陷阱实录§6.6)、新增 R 包操作指南§6.7)、新增 Q11-Q13 常见问题 |
| v1.2 | 2026-02-22 | Phase Deploy 完成:工具 7→12+Fisher/ANOVA/Wilcoxon/线性回归/基线表、Dockerfile 新增 gtsummary 等 5 包、Block-based 输出协议文档化§6.4)、全工具测试脚本 |
| v1.1 | 2026-02-20 | Phase 2A 完成7 个统计工具、JIT 护栏、热重载说明、常见问题补充 |
| v1.0 | 2026-02-19 | 初始版本架构设计、部署指南、T 检验工具 |