关于 category-trend-analyzer
用于预算分析的技能,可比较当前期间、近 6 个月均值、预算及去年同期的分类支出。它筛出达到重要性门槛的异常,并列出相关交易,供支出分析使用。
主要功能
- 01当前、滚动、预算及同比比较
- 02按重要性门槛识别异常
- 03列出异常对应的主要交易
- 04按金额影响排列异常
- 05季节性及年度账单规则
适用场景
- 01检查每月分类支出的变化
- 02查找异常支出的相关交易
- 03区分重大变化与小幅波动
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ lyndonkl/ claude --skill category-trend-analyzer安装后在 Claude Code 中输入/category-trend-analyzer确认已加载。
详细介绍
分类趋势分析器
目录
概览
对交易进行分类的意义在于每个月都能看出变化。此技能会计算每个类别的比较数据——当前与滚动平均、当前与预算、当前与去年同月的对比——识别异常值,并列出导致这些异常的交易。它不会将噪声标记为异常:低于重要性下限的小类别会被排除。
输入约定
调用方提供:
transactions— 至少 13 个月的分类交易。budget— 包含各类别目标的budget.json。period_start、period_end— 当前期间(通常为一个日历月)。materiality_floor_cents— 默认为5000($50)。当前支出低于此值的类别会纳入汇总,但不会标记为异常。outlier_thresholds— 默认值:{ rolling_multiple: 1.5, budget_pct: 130 }。
工作流
Trend Analysis Progress:
- [ ] Step 1: Roll up transactions by category for the current period
- [ ] Step 2: Roll up the prior 6 calendar months by category
- [ ] Step 3: Roll up the same-month-last-year by category
- [ ] Step 4: Compute deltas and percent changes
- [ ] Step 5: Apply outlier rules
- [ ] Step 6: Identify driver transactions for each outlier
- [ ] Step 7: Emit ranked list and totals
步骤 1 — 当前期间总额
对每个 category 和 category.subcategory,汇总 [period_start, period_end] 期间的支出(负数 amount_cents)。排除:
income.*savings_investment.*financial.transfers_internal
这些不属于支出,会在现金流和储蓄视图中单独跟踪。
步骤 2 — 滚动 6 个月平均值
对每个类别,汇总此前 6 个日历月各自的支出,然后取平均值。按日历月对齐,而不是按最近 180 天计算,这样“月度”对比才符合用户的直觉。
如果此前的数据不足 3 个月,则将 rolling_avg_confidence: low,并且只标记超过预算阈值的异常值(跳过滚动倍数测试)。
步骤 3 — 同比
汇总一年前同一日历月的支出。如果数据不存在(数据不足一年),则将 yoy_delta_cents: null。
步骤 4 — 计算差值
| 指标 | 公式 |
|---|---|
vs_rolling_pct | (current − rolling_avg) / rolling_avg × 100 |
vs_budget_pct | current / budget × 100(仅在存在预算时计算) |
vs_yoy_pct | (current − yoy) / yoy × 100 |
步骤 5 — 异常值规则
符合以下任意条件的类别均视为异常值:
vs_rolling_pct ≥ (rolling_multiple − 1) × 100(默认高于 6 个月平均值至少 50%)且current_cents ≥ materiality_floor_cents。vs_budget_pct ≥ budget_pct(默认达到预算的 130% 或以上)且存在预算。current_cents ≥ 2 × rolling_avg_cents且current_cents ≥ materiality_floor_cents→ 严重级别为high(根据 spending-analyst 规范触发实时提醒)。
每个异常值都包含:
severity—high(≥ 2× 滚动平均)、medium(≥ 1.5× 滚动平均或 ≥ 预算的 130%)、low(高于重要性下限但未达到阈值——仅作为背景信息展示)。reason— 触发的规则。
步骤 6 — 影响因素
对每个异常值,按金额绝对值降序排列,找出金额最高的 3–5 笔交易。这些就是简报中说明“是什么导致异常值”的内容。
如果某一笔交易占异常值金额的 > 60%,则标记 single_driver: true,以便分析师准确表述原因(“你在 IKEA 花了 $850——只去了一次——而家居维护的平均支出为 $120”)。
步骤 7 — 排序
按 dollar_impact_cents = |current_cents − rolling_avg_cents| 对异常值排序。金额变动最大的排在前面;金额大但百分比较小的变动,比百分比大但金额较小的变动更重要。
异常值规则
具体示例:
| 当前值 | 滚动 6 个月平均值 | 预算 | 结果 |
|---|---|---|---|
| $1,200 groceries | $850 | $900 | 中等 — 为滚动平均值的 1.41 倍,占预算的 133% |
| $3,400 travel | $300 | $400 | 高 — 为滚动平均值的 11.3 倍,但符合实质性门槛 |
| $42 hobbies | $20 | $30 | 未标记(低于 $50 的实质性门槛) |
| $850 home maintenance | $120 | $150 | 高 — 为滚动平均值的 7.1 倍,单一原因是前往 IKEA 购物 |
| $1,800 restaurants | $1,200 | — | 中等 — 为滚动平均值的 1.5 倍,未设置预算 |
| $3,200 utilities(8 月) | $2,100 | $2,400 | 中等 — 热浪,达到滚动平均值的 1.5 倍,占预算的 133%;同比增长 +5%,因此属于季节性因素,而非生活方式变化 |
输出约定
{
"period": { "start": "2026-04-01", "end": "2026-04-30" },
"totals": {
"spend_cents": 624800,
"spend_cents_vs_rolling": 78400,
"spend_cents_vs_budget": -25200,
"categories_above_floor": 18,
"outliers_count": 3
},
"categories": [
{
"category": "food",
"subcategory": "groceries",
"current_cents": 102000,
"rolling_avg_cents": 85000,
"yoy_cents": 92000,
"budget_cents": 90000,
"vs_rolling_pct": 20.0,
"vs_budget_pct": 113.3,
"vs_yoy_pct": 10.9,
"severity": "low",
"outlier": false
},
{
"category": "travel",
"subcategory": null,
"current_cents": 340000,
"rolling_avg_cents": 30000,
"yoy_cents": 18000,
"budget_cents": 40000,
"vs_rolling_pct": 1033.3,
"vs_budget_pct": 850.0,
"vs_yoy_pct": 1788.9,
"severity": "high",
"outlier": true,
"reasons": ["above_rolling_multiple_2x", "above_budget_threshold"],
"drivers": [
{ "tx_id": "tx_20260408_002", "amount_cents": -312000,
"merchant": "Delta Air Lines", "single_driver": true,
"share_of_outlier_pct": 91.8 }
]
}
],
"rankings": {
"biggest_growers": ["travel", "home_maintenance", "restaurants"],
"biggest_shrinkers": ["entertainment", "transportation.gas"]
}
}
护栏
- 优先考虑实质性。 不要标记 $20 的 hobbies 超支。用户的注意力是最稀缺的资源。
- 不要重复计算子类别和父类别。 选择一个层级——标题摘要用顶级类别,深入分析用子类别。由 spending-analyst agent 决定展示哪一种。
- 年度大额类别(
auto_insurance、property_tax、home_insurance)在缴费月份通常会触发 10 倍以上的异常值。如果峰值符合recurring.json中商家的年度周期,则跳过标记。使用 spending-analyst agent 的季节性日历子信号。 - 负向异常值不一定都是坏事。 某个类别降至零,可能意味着漏缴账单(公用事业自动扣款失效)。两个方向都要标记,但采用不同的表述。
- 不要在此技能中判断原因(“她升职加薪了”/“孩子开始参加夏令营”)。呈现数据即可;由分析师 Agent 提供说明。