@tapdb/tapdb-data-analysis 0.1.25 → 0.1.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tapdb/tapdb-data-analysis",
3
- "version": "0.1.25",
3
+ "version": "0.1.26",
4
4
  "description": "TapDB 游戏数据分析 AI Agent Skill - 查询和分析 TapDB 中的游戏运营数据(活跃/留存/付费/来源/LTV 等)",
5
5
  "keywords": [
6
6
  "tapdb",
@@ -3,7 +3,7 @@ name: tapdb-data-analysis
3
3
  description: >
4
4
  TapDB 游戏数据分析技能。用于查询和分析 TapDB 中的游戏运营数据,包括活跃(DAU/WAU/MAU)、
5
5
  留存(1日留存-180日留存)、付费(收入/ARPU/ARPPU)、来源(新增/转化)、用户价值(LTV)、版本分布、
6
- 玩家行为、广告变现等指标。支持国内和海外两套数据源。
6
+ 玩家行为、广告变现等指标。
7
7
  当用户需要查询游戏数据、分析运营指标、对比项目表现、检测数据异常、生成数据报告时使用此技能。
8
8
  触发关键词:TapDB、DAU、MAU、留存、付费、收入、ARPU、LTV、活跃、新增、来源、玩家行为、
9
9
  版本分布、鲸鱼用户、广告变现、游戏数据分析。
@@ -13,16 +13,16 @@ description: >
13
13
 
14
14
  > Skill 版本:v0.1.25
15
15
 
16
- 通过 Python 脚本调用 TapDB 运营数据查询接口,获取游戏的活跃、留存、付费、来源等指标数据并分析。
16
+ 通过 Python 脚本调用 TapDB 运营数据查询接口,获取游戏指标数据并分析。
17
17
 
18
18
  ## 环境要求
19
19
 
20
- - 查询脚本: `<SKILL_DIR>/scripts/tapdb_query.py`(纯标准库,无外部依赖)
21
- - Python 3(优先用 `python3`;如环境仅有 `python`,则用 `python`)
20
+ - 查询脚本: `<SKILL_DIR>/scripts/tapdb_query.py`
21
+ - Python 3(优先用 `python3`;否则用 `python`)
22
22
  - npm(用于 Skill 更新检查)
23
23
  - 认证密钥 `TAPDB_MCP_KEY_CN` / `TAPDB_MCP_KEY_SG`
24
24
 
25
- ## 运行前检查(每次会话首次使用)
25
+ ## 运行前检查(每次讨论一个新话题或新一轮数据查询时使用)
26
26
 
27
27
  ### 1. Skill 更新
28
28
 
@@ -30,25 +30,13 @@ description: >
30
30
  npm view @tapdb/tapdb-data-analysis version --registry https://registry.npmjs.org/
31
31
  ```
32
32
 
33
- 与本文件顶部 `Skill 版本` 对比,不同则更新:
33
+ 与本文件顶部 `Skill 版本` 对比,不同则更新本 Skill
34
34
 
35
- ```bash
36
- cd /tmp && \
37
- npm pack @tapdb/tapdb-data-analysis@latest --registry https://registry.npmjs.org/ && \
38
- tar -xzf tapdb-tapdb-data-analysis-*.tgz && \
39
- cp -r package/tapdb-data-analysis/* <SKILL_DIR>/ && \
40
- rm -rf package tapdb-tapdb-data-analysis-*.tgz
41
- ```
42
-
43
- 更新后**重新读取** `<SKILL_DIR>/SKILL.md`,以新版本为准。告知用户"TapDB 数据分析 Skill 已更新到 vX.X.X"。详情:https://www.npmjs.com/package/@tapdb/tapdb-data-analysis
35
+ 更新后**重新读取** `<SKILL_DIR>/SKILL.md`,以新版本为准。告知用户"TapDB 数据分析 Skill 已更新到 vX.X.X",并给出更新内容。
44
36
 
45
37
  ### 2. 环境变量
46
38
 
47
- ```bash
48
- [ -z "$TAPDB_MCP_KEY_CN" ] && echo "❌ CN 未设置" || echo "✅ CN 已配置"
49
- [ -z "$TAPDB_MCP_KEY_SG" ] && echo "❌ SG 未设置" || echo "✅ SG 已配置"
50
- ```
51
-
39
+ 检查 `TAPDB_MCP_KEY_CN` 和 `TAPDB_MCP_KEY_SG` 环境变量是否存在。
52
40
  缺少则**停止操作**,引导配置:秘钥在 **TapDB 页面右上角 → 账号设置 → 秘钥管理**。国内 CN/海外 SG 各需独立秘钥。用户提供后按步骤 3 写入 shell 配置文件并验证。
53
41
 
54
42
  ### 3. 持久化检查
@@ -57,15 +45,14 @@ rm -rf package tapdb-tapdb-data-analysis-*.tgz
57
45
 
58
46
  ## 工作流程
59
47
 
60
- 1. **确认项目**: `list_projects` 获取项目列表(含 `id/name/appid/sticky/remark`)
48
+ 1. **确认项目**: `list_projects` 获取项目列表(含 `id/name/appid/sticky/remark`,若返回列表过长则先保存到本地再查找,避免截断导致找不到需要的项目)
61
49
  - 在 `name` 和 `remark` 中检索匹配,任一命中即为候选
62
50
  - 多候选时优先 `sticky: true`;仍有多个则对每个做轻量探测(如 7 天 DAU):仅一个有数据→直接用;多个有数据→列出让用户选;全零→同样列出让用户选
63
51
  2. **识别场景**: 按「场景路由」判断分析路径
64
52
  3. **查看能力**: `describe <接口名>` 确认支持的指标/分组/过滤
65
53
  4. **调用脚本**: 查询数据
66
- 5. **利用截断**: 输出中 `_truncation` 含总行数和 min/max/avg 统计量
67
- 6. **分析**: `references/metrics_glossary.md`(指标定义)、`references/analysis_guide.md`(方法论)和 `references/output_rules.md`(输出规范)
68
- 7. **输出报告**: 按 `references/output_rules.md` 生成结论优先、可追溯的结构化报告
54
+ 5. **分析**: `references/metrics_glossary.md`(指标定义)、`references/analysis_guide.md`(方法论)
55
+ 6. **输出报告**: `references/output_rules.md` 生成结论优先、可追溯的结构化报告
69
56
 
70
57
  ## 场景路由
71
58
 
@@ -169,13 +156,11 @@ python3 <SKILL_DIR>/scripts/tapdb_query.py raw /op/active '{"project_id":2588,"s
169
156
 
170
157
  | 场景 | 阈值 | 方式 |
171
158
  |------|------|------|
172
- | 时间序列 | > 30 行 | 首5 + 尾5 |
159
+ | 时间序列 | > 30 行 | 首15 + 尾15 |
173
160
  | 分组维度 | > 20 行 | 前20 |
174
161
  | 鲸鱼用户 | > 20 条 | 前20 |
175
- | 留存列 DR1-DR180 | 自动 | 仅 DR1/3/7/14/30/60/90 |
176
- | LTV 列 1-60_LTV | 自动 | 仅 LTV1/3/7/14/30/60/90 |
177
162
 
178
- - 不加 `--all-retention` 通常仅返回 `DR1-DR30 + DR60/90/120/150/180`;加上后会额外补齐 `DR31-DR59`(及对应 `_newDevice/_rate` 列)。对比列差异需同时加 `--no-truncate`。
163
+ - 不加 `--all-retention` 通常仅返回 `DR1-DR30 + DR60/90/120/150/180`;加上后会额外补齐 `DR31-DR59`(及对应 `_newDevice/_rate` 列)。
179
164
 
180
165
  - 分析时利用 `_truncation.summary` 统计量,不要仅基于可见行下结论
181
166
  - 多次查询:每次先提取关键数值再下一个查询,不累积原始数据
@@ -12,7 +12,6 @@
12
12
  import argparse
13
13
  import json
14
14
  import os
15
- import re
16
15
  import sys
17
16
  import urllib.request
18
17
  import urllib.error
@@ -74,18 +73,14 @@ def output(data):
74
73
 
75
74
  # ── 数据截断 ────────────────────────────────────────────────
76
75
 
77
- _RE_DR = re.compile(r'^DR(\d+)')
78
- _RE_N_LTV = re.compile(r'^(\d+)_LTV$')
79
- _RETENTION_KEEP = {1, 3, 7, 14, 30, 60, 90}
80
- _LTV_KEEP = {1, 3, 7, 14, 30, 60, 90}
81
76
  _TIME_FIELDS = frozenset(("date", "time", "activation_time", "start_time",
82
77
  "date_", "time_", "activation_time_", "start_time_"))
83
78
 
84
79
  _MAX_TIME_ROWS = 30
85
80
  _MAX_GROUP_ROWS = 20
86
81
  _MAX_WHALE_ROWS = 20
87
- _HEAD = 5
88
- _TAIL = 5
82
+ _HEAD = 15
83
+ _TAIL = 15
89
84
 
90
85
 
91
86
  def _numeric_summary(rows, limit=6):
@@ -102,33 +97,6 @@ def _numeric_summary(rows, limit=6):
102
97
  return out
103
98
 
104
99
 
105
- def _slim_columns(rows, cmd_type):
106
- """Drop intermediate DR/LTV columns, keep key day columns only."""
107
- if not rows or not isinstance(rows[0], dict):
108
- return rows, None
109
- sample = rows[0]
110
- if cmd_type == "retention":
111
- regex, keep_set, label = _RE_DR, _RETENTION_KEEP, "DR"
112
- elif cmd_type == "user_value":
113
- regex, keep_set, label = _RE_N_LTV, _LTV_KEEP, "LTV"
114
- else:
115
- return rows, None
116
-
117
- matched = {}
118
- for k in sample:
119
- m = regex.match(k)
120
- if m:
121
- matched[k] = int(m.group(1))
122
- kept_count = sum(1 for d in matched.values() if d in keep_set)
123
- if len(matched) <= kept_count + 2:
124
- return rows, None
125
- keep_keys = {k for k in sample if k not in matched or matched.get(k) in keep_set}
126
- removed = len(matched) - kept_count
127
- rows = [{k: v for k, v in r.items() if k in keep_keys} for r in rows]
128
- days = "/".join(str(d) for d in sorted(keep_set))
129
- return rows, f"kept {label}{days}, removed {removed} other {label} columns"
130
-
131
-
132
100
  def _slim_rows(rows, cmd_type):
133
101
  """Truncate row count; time-series keeps head+tail, others keep head."""
134
102
  if not rows:
@@ -218,9 +186,6 @@ def truncate_response(resp, cmd_type=None):
218
186
  return resp
219
187
 
220
188
  info = {}
221
- rows, col_msg = _slim_columns(rows, cmd_type)
222
- if col_msg:
223
- info["columns"] = col_msg
224
189
  rows, row_info = _slim_rows(rows, cmd_type)
225
190
  if row_info:
226
191
  info.update(row_info)