关于 pdf-statement-parser
用于从银行、券商、退休账户、HSA 和房贷 PDF 对账单中提取结构化数据的提示词驱动技能。它识别文档类型,按字段标签提取明细,并输出含置信度的严格 JSON。
主要功能
- 01识别对账单类型
- 02提取账户与期间信息
- 03抽取交易或持仓明细
- 04金额转为整数分
- 05日期标准化为 ISO 8601
- 06逐字段置信度评分
适用场景
- 01将银行对账单整理为 JSON
- 02提取券商账户持仓记录
- 03解析房贷对账单或税表
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ lyndonkl/ claude --skill pdf-statement-parser安装后在 Claude Code 中输入/pdf-statement-parser确认已加载。
详细介绍
PDF 对账单解析器
目录
概览
银行、券商、退休账户、HSA 和抵押贷款对账单以各种版式的 PDF 形式提供。本技能介绍由提示词驱动的提取方法:识别文档类型,根据标签(而非位置)查找规范字段,提取每一行交易或持仓,并生成严格的 JSON 记录。所有金额均转换为整数分,所有日期均转换为 ISO 8601(YYYY-MM-DD)。
可直接配合 Claude 的 PDF 阅读功能使用:Read PDF,然后根据可见内容运行本技能的工作流。无需外部库。
输入契约
调用方提供:
pdf_path— 单个对账单 PDF 的绝对路径。expected_type(可选)— 以下类型之一:checking_statement | savings_statement | credit_card_statement | brokerage_statement | 401k_statement | hsa_statement | mortgage_statement | tax_form | insurance_doc | unknown。如果未提供,本技能会检测类型。known_accounts(可选)— 用于匹配的{id, institution, mask, type}数组。
工作流
- [ ] Step 1: Read the PDF (first pass: pages 1-2 for header)
- [ ] Step 2: Detect document type from header keywords
- [ ] Step 3: Extract account identity (institution + mask + type)
- [ ] Step 4: Extract statement period (start/end dates)
- [ ] Step 5: Extract balance markers (opening / closing / available)
- [ ] Step 6: Extract line items (transactions, holdings, or events)
- [ ] Step 7: Normalize to integer cents and ISO dates
- [ ] Step 8: Score confidence on each field; emit JSON
步骤 1 — 读取 PDF
使用 Read 工具读取 PDF 路径。对于超过 10 页的 PDF,分段读取:第 1–5 页(页眉和首批交易),然后按需读取后续页码范围。记录总页数。
步骤 2 — 检测文档类型
按以下权威性顺序查找页眉信号:
| 信号 | 文档类型 |
|---|---|
| “Statement of Account” + “Available Balance” + 支票账户样式的交易 | checking_statement |
| “Savings Statement” / “Money Market Statement” | savings_statement |
| “Credit Card Statement” + “Payment Due” + “Minimum Payment” | credit_card_statement |
| “Account Summary” + “Holdings” + 股票代码 | brokerage_statement |
| “401(k) Statement” / “Retirement Plan” + “Vested Balance” | 401k_statement |
| “Health Savings Account” / “HSA” + “Contribution Limit” | hsa_statement |
| “Mortgage Statement” + “Principal” + “Escrow” | mortgage_statement |
| “W-2” / “1099” / “1098” / “5498” 表格编号 | tax_form |
| 保单声明页、保费、免赔额 | insurance_doc |
如果两个信号的权威性相同,优先选择文档标题或页眉中的信号。
步骤 3 — 提取账户身份信息
- 机构:页面顶部的徽标文字,或“由……发行” / “对账单来自”标签。
- 掩码:末尾 4 位数字 — 查找
****1234、xxxx1234、Account ending in 1234,或该机构使用的脱敏格式。始终存储为****1234。 - 账户类型:根据上文第 2 节和可见标签(“Checking”、“Visa Signature”、“Roth IRA”)确定。
- 所有者姓名:账户持有人的全名(用于与下游
household.json成员匹配)。
根据 (institution, mask) 与 known_accounts 匹配。如果没有匹配项,将 account_match 标记为 "new",并提出类似 acc_<type>_<incrementing> 的 account_id。
步骤 4 — 提取对账单周期
查找以下标签:“Statement Period”、“Cycle Date”、“Closing Date”、“Period Beginning … Period Ending”。输出:
period_start— 覆盖的第一天(ISO)。period_end— 覆盖的最后一天,也是对账单的结算日(ISO)。
如果只有结算日期,将 period_end = closing_date,并将 period_start = null,同时将该周期的 confidence: 0.6。
步骤 5 — 提取余额标记
对于现金/信贷账户:opening_balance_cents、closing_balance_cents、available_balance_cents(如果存在)。对于信用卡,还要提取 statement_balance_cents、minimum_payment_cents、payment_due_date。
对于经纪账户/401k/HSA:total_value_cents、cash_cents、invested_cents。跳过期初/期末交易余额——这些是持仓报表。
对于抵押贷款:current_principal_cents、monthly_pi_cents、monthly_escrow_cents、next_payment_due、extra_principal_ytd_cents。
步骤 6 — 提取明细项
三种模式:
现金/信贷交易。 对交易表中的每一行,提取:date、post_date(如果是单独的列)、description_raw、amount。符号约定:流出为负,流入为正。如果账单使用两个列(“Withdrawals”和“Deposits”),请相应设置符号。按原样保留打印出来的 description_raw——簿记员之后会规范化商户名称。
经纪账户/401k/HSA 持仓。 对每一行持仓,提取:symbol、description、shares(小数)、price(每股价格)、value、cost_basis(如果显示)、asset_class(根据基金说明映射:见下方操作指南)。
抵押贷款活动。 最近付款表:每笔记录包含 date、total_paid_cents、principal_cents、interest_cents、escrow_cents、extra_principal_cents。
税务表格。 按操作指南提取特定表格的字段(W-2 方框、1099-DIV 普通/合格股息、已支付的 1098 抵押贷款利息、5498-SA HSA 缴款)。
步骤 7 — 规范化
- 金额:
$1,247.50→124750美分。负向流出:-$87.42→-8742。 - 日期:
01/15/26→2026-01-15。两位数年份默认按当前世纪处理,除非上下文另有说明。 - 去除说明文字两端的空白;保留大小写。
步骤 8 — 置信度评分
为每个字段指定 [0.0, 1.0] 范围内的置信度:
1.0— 直接从带标签的字段中提取。0.85–0.95— 根据位置上下文提取(推断列标题,数值清晰)。0.6–0.8— 根据周围文本推断或部分通过 OCR 识别。< 0.6— 标记为需人工审核。
整体记录的 confidence = min(必填字段的各项置信度)。
文档类型操作指南
checking_statement / savings_statement
必填:institution、mask、period_start、period_end、opening_balance_cents、closing_balance_cents、transactions[]。核对:opening + Σ(transactions.amount) = closing,误差在 ±$1 以内。
credit_card_statement
必填:institution、mask、period_start、period_end、opening_balance_cents、closing_balance_cents、statement_balance_cents、minimum_payment_cents、payment_due_date、transactions[]。注意:从持卡人角度看,信用卡流出是消费(会使卡片余额增加);但对于统一家庭账本,应将消费视为负数(资金流出家庭),将信用卡还款视为正数(或作为内部转账)。请记录所采用的符号约定。
brokerage_statement
必填:institution、mask、account_type、period_end、total_value_cents、holdings[]。可选:cash_cents、transactions[](买入/卖出/股息)。资产类别映射:
| 基金提示 | asset_class |
|---|---|
| "S&P 500", "Total Stock Market", "Large Cap Blend", VOO/VTI/SPY | us_equity |
| "International", "Developed Markets", "Emerging Markets", VXUS/IXUS | intl_equity |
| "Total Bond", "Aggregate Bond", "Treasury", BND/AGG | us_bond |
| "Money Market", "Cash Reserve", SPAXX | cash |
| "REIT", "Real Estate" | reit |
| "Target Date 20XX" | target_date(记录年份) |
如果无法映射,将 asset_class 设为 null,置信度设为 0.5。
401k_statement
必填:institution、owner、period_end、total_balance_cents、ytd_contribution_cents(如果显示)、employer_match_ytd_cents(如果显示)、holdings[]。注意是否有归属情况列——如果显示,单独记录 vested_cents。
hsa_statement
必填:institution、period_end、cash_cents、invested_cents、total_cents、ytd_contribution_cents、ytd_distribution_cents(如有显示)。如果打印了保障类型,请记录:self_only 或 family。
mortgage_statement
必填:institution、mask、period_end、current_principal_cents、monthly_pi_cents、monthly_escrow_cents、next_payment_due、recent_payments[]。如果打印了利率 APR,请记录。
tax_form
必填:form_type(W-2、1099-DIV、1099-INT、1099-B、1098、5498-SA、1095)、tax_year、issuer、recipient、key_boxes(因表格类型而异)。将解读工作交给税务合规 Agent——此技能只负责提取表格框中的信息。
输出约定
输出单个 JSON 对象:
{
"document_type": "checking_statement",
"source_path": "inbox/2026-01-15-batch/checking-jan.pdf",
"institution": "Bank Name",
"account": {
"mask": "****1234",
"type": "checking",
"owners": ["Jane Doe", "John Doe"],
"match": "acc_chk_001",
"match_confidence": 0.95
},
"period": {
"start": "2025-12-15",
"end": "2026-01-14"
},
"balances": {
"opening_cents": 1124300,
"closing_cents": 1247500,
"available_cents": 1247500
},
"transactions": [
{
"date": "2025-12-16",
"post_date": "2025-12-17",
"description_raw": "TRADER JOE'S #123 PORTLAND OR",
"amount_cents": -8742,
"confidence": 0.97
}
],
"reconciliation": {
"expected_closing_cents": 1247500,
"computed_closing_cents": 1247500,
"diff_cents": 0,
"ok": true
},
"extracted_at": "2026-01-20T14:00:00Z",
"overall_confidence": 0.94,
"warnings": []
}
对于 brokerage/401k/HSA,按 playbook 将 transactions 替换为 holdings 和余额字段。
置信度评分
出现以下情况时,降低整体置信度并添加一条 warnings[]:
- 对账差异 > $1 →
warning: "reconcile_failed: diff $X.XX",且overall_confidence: max(0.5, current * 0.7)。 - 缺少任何必填字段 →
warning: "missing_required: <field>",且overall_confidence ≤ 0.5。 - 页面 OCR 质量差(字符难以辨认)→
warning: "low_ocr_quality_page_<n>",并应用每个字段的置信度惩罚。 - 超过 20% 的持仓资产类别未知 →
warning: "unknown_asset_class_high"。
防护规则
- 绝不编造值。 如果 PDF 中看不到某个字段,将其设为
null并添加警告。不得插值。 - 绝不在此处规范化商户名称。 这是簿记员的工作;逐字节保留
description_raw。 - 绝不在此处对交易进行分类。 分类由下游的
transaction-categorizer负责。 - 对现金/信用卡账单,声明
ok: true前始终进行对账。 - 货币: 除非账单另有说明,否则假定为 USD。如果不是 USD,请记录货币代码;不要自动换算。
- 仅记录账户掩码。 绝不提取或存储完整账号。
示例
对于一份 4 页的 Chase 活期账户账单,账期为 2025-12-15 至 2026-01-14,期初余额为 $11,243.00,三笔存款合计 $4,832.00,二十七笔支出合计 $3,600.00,期末余额为 $12,475.00,解析器输出:
document_type: "checking_statement"institution: "Chase"account.mask: "****1234"、account.type: "checking"period.start: "2025-12-15"、period.end: "2026-01-14"balances.opening_cents: 1124300、balances.closing_cents: 1247500transactions: [...]— 共 30 条记录,每条包含description_raw、amount_cents(带正负号),且各字段置信度 ≥ 0.92reconciliation.ok: true、diff_cents: 0overall_confidence: 0.95、warnings: []