mcpField
T
transaction-categorizer

transaction-categorizer

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

关于 transaction-categorizer

Transaction Categorizer 根据原始描述和带正负号的金额分类财务交易,适用于家庭财务流程。它先应用匹配规则,再由 LLM 处理剩余交易;保留原始描述,并可根据高置信度的重复模式提出新规则。

主要功能

  1. 01规范化描述以供匹配
  2. 02按优先级应用商户规则
  3. 03依据给定分类体系归类
  4. 04标记可能的定期交易
  5. 05评估置信度并标记不确定项
  6. 06根据重复匹配提出规则

适用场景

  1. 01批量分类账户交易
  2. 02识别可能的定期支出
  3. 03检查低置信度分类
  4. 04根据重复商户模式扩展规则

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/lyndonkl/claude --skill transaction-categorizer

安装后在 Claude Code 中输入/transaction-categorizer确认已加载。

详细介绍

交易分类器

目录

概览

一笔交易只有一个 description_raw 字符串和一个带符号的 amount_cents。此技能会将其转换为规范的 merchant、category + subcategory、一个 is_recurring 布尔候选值,以及一个置信度。它会先应用规则(成本低且确定),仅在处理剩余交易时才回退到 LLM 推断。

它还会生成学习到的规则——当高置信度分类符合清晰的商户模式时,会为规则表提出一条新规则,以便今后相同的交易可以免费匹配。

输入约定

调用方提供:

  • transactions — {id, description_raw, amount_cents, account_id, date, account_type} 数组。
  • taxonomy — categories.json 中的分类体系区块(顶层类别 → 子类别列表)。
  • rules — 现有规则数组(参见规则格式)。
  • account_type_hints(可选)— 如果已知,可帮助消除歧义(例如,经纪账户中的存款更可能是 dividends,而不是 salary)。

工作流

Categorization Progress:
- [ ] Step 1: Normalize description_raw
- [ ] Step 2: Apply rules in priority order
- [ ] Step 3: Classify residual via LLM with taxonomy guard
- [ ] Step 4: Detect recurring candidates
- [ ] Step 5: Score confidence
- [ ] Step 6: Propose new rules from high-confidence matches
步骤 1 — 规范化

构建一个仅用于匹配的 description_normalized — 绝不覆盖 description_raw。

  • 转为大写。
  • 去除开头的供应商代码(SQ *、TST*、PAYPAL *、CKCD、POS DEBIT、ACH DEBIT)。
  • 去除结尾的地理信息( PORTLAND OR、 800-555-1234 CA、 #1234)。
  • 将多个空格合并为一个。
  • 删除描述中的日期数字。

SQ *TRADER JOES #123 PORTLAND OR → TRADER JOES。

步骤 2 — 应用规则

对每笔交易,按优先级顺序遍历 rules。第一个 match 子串(不区分大小写)出现在 description_normalized 中的规则胜出。应用其 merchant、category、subcategory,以及(如果已设置)is_recurring。

如果有多条规则匹配,则最具体的规则(match 最长)胜出。

如果规则匹配,则设置 source: "rule" 和 confidence: 1.0。

步骤 3 — 分类剩余交易

对未匹配的交易,通过 LLM 进行分类:

  • 将输出限制在所提供的 taxonomy 范围内 — 绝不编造类别。
  • 选择 category.subcategory(例如,food.groceries)。
  • 提出一个规范的 merchant 名称。
  • 如果符号和 account_type 表明这是收入,则优先选择 income.* 分支。
  • 如果 account_type 为 brokerage 或 401k 且金额为正,则优先选择 income.dividends、income.interest_earned 或 savings_investment.*。
  • 如果 description_raw 看起来像用户两个账户之间的内部转账,则分类为 financial.transfers_internal。

根据线索强度设置 source: "llm" 和 confidence: 0.6–0.9。

步骤 4 — 检测定期交易候选项

符合以下条件时,将 is_recurring 候选值设为 true:

  • 过去 90 天内,同一账户中该商户出现 ≥ 3 次,金额相差在 ±10% 以内,且具有固定周期(每周、每两周、每月、每季度)。
  • 或者,匹配的规则明确将 is_recurring 设为 true。

这只是一个候选项 — 将其提升至 recurring.json 是定期扣费检测技能的工作。

步骤 5 — 置信度
来源默认置信度
规则匹配(子串长度 ≥ 8)1.00
规则匹配(子串长度 4–7)0.92
LLM 具有强分类信号(例如,“NETFLIX” → entertainment.streaming)0.85
LLM 信号较弱0.65
无法分类到 uncategorized 以上0.30

如果置信度 < 0.5,则将 category: "uncategorized.unknown" 标记为待审核。

步骤 6 — 提出新规则

分类后,扫描高置信度的 LLM 匹配项(confidence ≥ 0.85),其中相同的 description_normalized 子串覆盖输入集合中的 ≥ 3 笔交易。对每个匹配项提出一条新规则,并将其追加到输出中的 rules.proposed[]。记账 Agent 会在这些规则合并到 categories.json 之前进行确认。

分类体系

该技能遵循调用方提供的分类体系。家庭财务团队使用的默认分类体系如下:

housing → mortgage, rent, property_tax, hoa, home_insurance, home_maintenance,
          utilities_electric, utilities_gas, utilities_water, utilities_internet
food → groceries, restaurants, coffee, alcohol
transportation → gas, auto_insurance, auto_maintenance, public_transit, rideshare,
                 parking, tolls
health → medical_copay, prescriptions, dental, vision, mental_health, gym
personal → clothing, haircare, subscriptions_personal
kids → childcare, school, activities, kids_clothing
entertainment → streaming, events, hobbies, books
travel → flights, lodging, travel_food, travel_other
financial → fees, interest_paid, transfers_internal
income → salary, bonus, interest_earned, dividends, capital_gains, refund, other_income
savings_investment → 401k_contribution, ira_contribution, hsa_contribution,
                     brokerage_deposit, savings_deposit
uncategorized → unknown

切勿臆造类别。如果一笔交易不符合任何类别,请使用 uncategorized.unknown,并发出 taxonomy_gap 警告。

规则格式

{
  "match": "TRADER JOE",
  "merchant": "Trader Joe's",
  "category": "food",
  "subcategory": "groceries",
  "is_recurring": false,
  "priority": 100,
  "added_on": "2026-01-20",
  "source": "user_confirmed | learned"
}

priority 值越大,优先级越高。人工添加的规则默认优先级为 200;由该技能学习到的规则默认优先级为 100。

置信度与审计

每笔输出交易都包含:

  • category 和 subcategory — 必须属于分类体系。
  • merchant — 规范的显示名称。
  • confidence — [0.0, 1.0]。
  • source — rule | llm | uncategorized。
  • matched_rule_id(如果 source: rule)。

切勿覆盖 description_raw;始终保留该字段,以便重新分类。

输出约定

{
  "categorized": [
    {
      "id": "tx_20260115_001",
      "merchant": "Trader Joe's",
      "category": "food",
      "subcategory": "groceries",
      "is_recurring_candidate": false,
      "confidence": 1.0,
      "source": "rule",
      "matched_rule_id": "rule_trader_joes"
    }
  ],
  "rules_proposed": [
    {
      "match": "BLUE BOTTLE",
      "merchant": "Blue Bottle Coffee",
      "category": "food",
      "subcategory": "coffee",
      "evidence_count": 4,
      "evidence_tx_ids": ["tx_20260103_004", "tx_20260110_002", "tx_20260117_007", "tx_20260124_001"]
    }
  ],
  "warnings": [
    { "tx_id": "tx_20260118_009", "type": "taxonomy_gap", "description_raw": "ZELLE TO M COPPENS" }
  ],
  "summary": {
    "total": 142,
    "rule_matched": 118,
    "llm_classified": 22,
    "uncategorized": 2,
    "uncategorized_pct": 1.4
  }
}

防护措施

  • 逐字节保留 description_raw。 规范化仅用于匹配。
  • 切勿臆造类别。 只能使用提供的分类体系中的类别。
  • 考虑账户类型。 券商账户中的“存款”不是工资;储蓄账户中的“取款”很可能是转账,而非消费。
  • 内部转账在各账户间必须相互抵消。 如果一侧被归类为 financial.transfers_internal,另一账户中金额符号相反的对应交易也应归类为 transfers_internal;如不一致,请标记。
  • 未分类比例超过批次中新交易的 5% 时,属于质量信号;请在摘要中指出。
  • 拟议规则中不得包含个人身份信息(PII)。 诸如 match: "ZELLE TO JOHN SMITH" 的规则会暴露姓名;请对其脱敏或跳过此类提议。

评论

支持 Markdown