mcpField
C
category-trend-analyzer

category-trend-analyzer

github.com/lyndonkl数据与数据库18736 次安装9 周前更新
代码仓库

关于 category-trend-analyzer

用于预算分析的技能,可比较当前期间、近 6 个月均值、预算及去年同期的分类支出。它筛出达到重要性门槛的异常,并列出相关交易,供支出分析使用。

主要功能

  1. 01当前、滚动、预算及同比比较
  2. 02按重要性门槛识别异常
  3. 03列出异常对应的主要交易
  4. 04按金额影响排列异常
  5. 05季节性及年度账单规则

适用场景

  1. 01检查每月分类支出的变化
  2. 02查找异常支出的相关交易
  3. 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_pctcurrent / 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 提供说明。

评论

支持 Markdown