transaction-categorizer について
Transaction Categorizer は、取引の元の説明と符号付き金額から金融取引を分類する、家計管理向けのスキルです。ルールを適用してから残りを LLM で分類し、元の説明を保持しつつ、確信度の高い反復パターンからルールを提案します。
主な機能
- 01照合用に説明を正規化
- 02優先順位付きの加盟店ルールを適用
- 03指定された分類体系内で分類
- 04定期取引の候補を検出
- 05確信度を評価し不確実性を提示
- 06反復一致からルールを提案
活用シーン
- 01口座取引の一括分類
- 02定期支出の候補を特定
- 03確信度の低い分類を確認
- 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(任意)— 分かっている場合、分類の判別に役立ちます(例:証券口座への入金は、salaryよりdividendsである可能性が高くなります)。
ワークフロー
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)を削除します。 - 連続する複数の空白を 1 つにまとめます。
- 説明内の日付の数字を削除します。
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がユーザーの 2 つの口座間の内部振替に見える場合は、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 — 新しいルールを提案
分類後、同じ description_normalized の部分文字列が入力セット内の 3 件以上の取引に一致する、高信頼度(confidence ≥ 0.85)の LLM 分類結果を調べます。それぞれについて新しいルールを提案し、出力の rules.proposed[] に追加します。帳簿管理エージェントがこれらを確認してから、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"のようなルールは氏名を露出します。このような提案は、氏名を伏せるか、スキップしてください。