这篇能做出什么
做完这篇教程,你会得到三样东西:
1. 一张干净的月度流水表:把银行和信用卡导出的原始账单,统一成 date / amount / currency / merchant / direction / account 六列,去掉卡号、姓名等敏感信息。
2. 一份分类拆解报告:钱花在哪几个大类、每类的环比变化、Top 商户、固定订阅支出、异常单笔,全部由 Claude 按你给的分类字典生成,不确定的条目标记成“待确认”而不是瞎猜。
3. 一份可执行的预算清单:不是“少喝咖啡”这种空话,而是“把 A 订阅从月付改年付、每月省 X 元、下月账单里验证这一笔”这种能打勾的动作。
举个例子,输入是三个月共 400 多行流水,输出长这样:
```markdown
| 类目 | 本月 | 上月 | 环比 | 占比 |
|---|---|---|---|---|
| 餐饮外卖 | 2180 | 1720 | +26.7% | 21.3% |
| 交通通勤 | 640 | 655 | -2.3% | 6.3% |
| 订阅服务 | 288 | 288 | 0% | 2.8% |
| 待确认 | 156 | 90 | +73% | 1.5% |
```
先说清一件事:Claude 本身不是银行直连工具,它不会替你登录网银。数据进入 Claude 有三条路径——手动上传导出文件、通过第三方账单聚合服务导出、通过连接器(Connector / MCP)读取。哪条路适合你,取决于你对隐私和便利的取舍,具体支持范围以 Anthropic 官方文档当前版本为准。下面按“手动导出”这条最可控的路走一遍,最后再讲连接器方案的边界。
前置条件清单
- 一个 Claude 账号,能上传文件、能开 Project(不同套餐能力不同,以官方页面为准)
- 近 2~3 个月的银行流水、信用卡账单,导出成 CSV(多数网银支持导出 CSV 或 Excel)
- 本地装 Python 3(只用来做脱敏和格式统一,不装也能用表格软件手动做,只是慢)
- 一个本地文件夹,专门放这次的账单,用完可整个删掉
- 心理准备:只上传脱敏后的数据。完整卡号、身份证号、网银密码、短信验证码,一个都不要出现在对话里
第一步:决定数据怎么进 Claude
三条路径的差别很实在:
| 路径 | 便利度 | 授权范围 | 撤销方式 | 适合谁 |
|---|---|---|---|---|
| 手动导出 CSV 上传 | 每月手动一次 | 只给 Claude 你上传的那份文件 | 删除对话/项目文件即可 | 大多数人,尤其是第一次做 |
| 第三方聚合服务导出 | 一次授权,后续自动 | 该服务可读你的账户交易 | 在服务方后台断开 | 账户多、嫌手动麻烦 |
| 连接器 / MCP 读取 | 授权后可在对话里直接查 | 取决于连接器声明的 scope | 在 Claude 设置里断开 + 在数据源侧撤销 | 想长期做、能看懂权限页的人 |
第一次做体检,建议走第一条。原因很简单:你能清楚知道 Claude 到底看到了什么,删的时候也删得干净。
第二步:把账单脱敏成“够用就好”的数据
分析支出根本不需要你的卡号。写一个小脚本,把敏感字段砍掉,账号换成散列别名:
```python
sanitize.py
import csv, re, hashlib
RAW = "raw_transactions.csv" # 银行导出的原始文件
OUT = "clean_transactions.csv"
左:你银行文件里的列名;右:本教程统一列名。按实际表头改左边
COLUMN_MAP = {
"交易日期": "date",
"交易金额": "amount",
"币种": "currency",
"商户名称": "merchant",
"收支方向": "direction",
"卡号后四位": "account",
}
def alias(v: str) -> str:
return "acct_" + hashlib.sha256(v.encode()).hexdigest()[:6]
with open(RAW, newline="", encoding="utf-8-sig") as f, \
open(OUT, "w", newline="", encoding="utf-8") as g:
reader = csv.DictReader(f)
writer = csv.writer(g)
writer.writerow(["date", "amount", "currency", "merchant", "direction", "account"])
for row in reader:
merchant = row.get(COLUMN_MAP["商户名称"], "") or ""
商户名里常混订单号、手机号,把连续 4 位以上数字抹掉
merchant = re.sub(r"\d{4,}", "", merchant).strip()
writer.writerow([
row.get(COLUMN_MAP["交易日期"], "").strip(),
row.get(COLUMN_MAP["交易金额"], "").strip().replace(",", ""),
row.get(COLUMN_MAP["币种"], "CNY").strip() or "CNY",
merchant,
row.get(COLUMN_MAP["收支方向"], "").strip(),
alias(row.get(COLUMN_MAP["卡号后四位"], "unknown")),
])
print("done ->", OUT)
```
跑完打开 clean_transactions.csv 看一眼,确认没有姓名、完整卡号、备注里的转账留言。有就再加两行清洗规则。
第三步:统一格式,把“脏数据”挡在分析之前
Claude 分析得好不好,八成取决于这一步。三条硬规则:
1. 日期统一成 YYYY-MM-DD。03/04/2025 到底是 3 月 4 日还是 4 月 3 日,机器猜不出来,人也会看错。
2. 金额统一成带符号的数值。支出为负、收入为正,退款单独标正数并加 refund 标记。
3. 转账和还款要单独标出来。信用卡还款、自己账户间互转,如果当成支出算,你的总支出会凭空翻倍。
在 CSV 里加一列 type,取值只用这几个:
```csv
date,amount,currency,merchant,direction,account,type
2025-03-02,-38.50,CNY,某某咖啡,支出,acct_a1b2c3,expense
2025-03-05,-288.00,CNY,某某云服务,支出,acct_a1b2c3,subscription
2025-03-08,1200.00,CNY,工资,收入,acct_d4e5f6,income
2025-03-10,-1200.00,CNY,信用卡还款,支出,acct_a1b2c3,transfer
2025-03-12,38.50,CNY,某某咖啡,收入,acct_a1b2c3,refund
```
这一列不用全手填,先让规则跑一遍,剩下的交给 Claude。
第四步:规则先行分类,Claude 兜底
纯靠模型分类,好处是灵活,坏处是不稳定——同样的“某某便利店”,这个月归“餐饮”,下个月归“日用”。稳妥做法是:关键词规则覆盖大头,剩下的未知项批量交给 Claude。
```python
classify_rules.py
import csv, json
RULES = {
"餐饮": ["餐", "咖啡", "茶", "美团", "饿了么", "restaurant", "cafe", "bakery"],
"交通": ["地铁", "公交", "打车", "加油", "停车", "railway", "airline"],
"居住": ["房租", "物业", "水费", "电费", "燃气", "宽带"],
"购物": ["超市", "便利店", "商城", "mall", "market"],
"订阅": ["云服务", "会员", "subscription", "storage", "music"],
"医疗": ["药", "医院", "诊所", "体检"],
}
def rule_categorize(merchant: str) -> str:
m = merchant.lower()
for cat, kws in RULES.items():
if any(k.lower() in m for k in kws):
return cat
return "待确认"
unknown, rows = [], []
with open("clean_transactions.csv", newline="", encoding="utf-8") as f:
for row in csv.DictReader(f):
if row["type"] in ("transfer", "income"):
continue
cat = rule_categorize(row["merchant"])
row["category"] = cat
rows.append(row)
if cat == "待确认":
unknown.append({"merchant": row["merchant"], "amount": row["amount"]})
with open("unknown.json", "w", encoding="utf-8") as g:
json.dump(unknown, g, ensure_ascii=False, indent=2)
print(f"共 {len(rows)} 笔,待确认 {len(unknown)} 笔")
```
如果“待确认”比例超过 20%,说明关键词表太窄,回到 RULES 里补几个词再跑一遍,比让模型硬猜划算。
第五步:给 Claude 的分析指令怎么写
指令里必须出现四样东西:角色、分类字典、输出格式、防编造约束。直接抄这份模板:
```markdown
你是我的个人支出分析助手。我只提供已脱敏的流水,不含卡号与身份信息。
【任务】
1. 按下面这 12 个类目归类 merchant,不要新增类目:
餐饮 / 交通 / 居住 / 购物 / 订阅 / 医疗 / 教育 / 娱乐 /
人情往来 / 手续费 / 待确认 / 其他
2. 统计每个类目的小计、笔数、占比,以及相对上月的环比。
3. 列出金额 Top 10 商户,标注所属类目。
4. 找出所有疑似固定订阅(同一商户连续 2 个月以上、金额相近)。
5. 标出单笔超过 500 元的支出及其商户。
【约束】
- 只依据我给的表格,不要补充任何我没提供的数字。
- 归类没把握的,写进“待确认”,并在备注里说明你怀疑的两个类目。
- 输出用 Markdown 表格,金额保留两位小数。
- 如果表格被截断或行数对不上,先告诉我,不要继续算。
【数据】
(在此粘贴 clean_transactions.csv 内容,或直接上传文件)
```
几个实操要点:
- 先给字典,再给数据。顺序反了,模型容易自创类目。
- 行数多就分批。一次贴几百行容易截断,按“每批 150 行、每批结束报一次行数”来切。
- 要它复述总数。让 Claude 在报告开头写“共读取 N 笔、合计 X 元”,和你本地脚本的结果对一下,对不上就重发。
第六步:让 Claude 拆解“钱花在哪”
拿到第一版统计后,追问三轮,每轮只问一件事:
第一轮——结构
> 按占比排序,指出占比前 3 的类目,并说明这三类合计占了总支出的百分之多少。
第二轮——变化
> 对比两月数据,指出环比增幅超过 20% 且绝对金额超过 200 元的类目,逐条给出可能原因(只说可能,不要下结论)。
第三轮——异常
> 列出本月出现、上月没有的商户,以及金额为整数的支出(房租、会员费常是整数,异常整数往往值得看一眼)。
三轮下来,你会得到类似这样的结论:餐饮涨了 26%,主要来自新增的 5 家外卖商户;订阅类目 4 笔共 288 元,其中 2 笔是自动续费且你半年没用过。这才是“体检”该有的颗粒度。
第七步:生成可执行的预算清单
预算建议最容易变成废话。给指令时加两个硬约束:每条动作必须绑定一个具体商户或类目,必须写清验证方式。
```markdown
基于上面的分类结果,帮我做下月预算,遵守以下规则:
1. 用「固定支出 / 必要弹性支出 / 可选支出」三分法,不用 50/30/20。
2. 每类给出:本月实际、下月预算、差额、差额来自哪几笔具体支出。
3. 只给 3 条行动建议,每条必须包含:
- 动哪个商户或类目(写到名字)
- 预计每月省多少(用我数据里的真实金额推算)
- 下个月怎么验证(看哪一类、哪一笔)
4. 如果某类已经很低,明确写“不建议压缩”,不要凑数。
```
输出大概长这样:
```markdown
| 分类 | 本月实际 | 下月预算 | 差额 | 依据 |
|---|---|---|---|---|
| 固定支出 | 4200 | 4200 | 0 | 房租+宽带+话费 |
| 必要弹性 | 2600 | 2200 | -400 | 餐饮外卖 2180→1800 |
| 可选支出 | 1400 | 900 | -500 | 取消 2 个未使用订阅 |
行动 1:取消「某某云存储」「某某会员」两笔自动续费,合计 288 元/月 → 月省 288。
验证方式:下月账单中「订阅」类目应降至 0~50 元区间。
行动 2:餐饮外卖从每周 5 次降到 3 次 → 按本月客单价推算月省约 400。
验证方式:下月「餐饮」类目笔数应从 42 笔降到 26 笔左右。
行动 3:把某笔月付服务改年付(若确认会长期使用)→ 年省约两个月费用。
验证方式:改完后该商户一年只出现 1 笔。
```
第八步:固化成每月能复跑的流程
别每次重写指令。把上面几段提示词存成一个 prompt.md,连同 sanitize.py、classify_rules.py 放进同一个文件夹;如果用 Project 功能,把分类字典和分析指令存为项目说明,每月只换 CSV。
复跑流程压缩成四步:
```bash
python sanitize.py # 脱敏 + 统一列名
python classify_rules.py # 规则分类,产出 unknown.json
把 clean_transactions.csv 和 unknown.json 交给 Claude,用 prompt.md 里的指令
把结论追加到 report-YYYY-MM.md
```
第三个月开始,你就有连续基线了,环比才有意义。
授权范围、可撤销性与隐私边界
这部分值得单独说清,尤其是走连接器路线的人。
授权范围
- 只申请只读权限。任何要求“发起支付”“转账”“修改账户设置”的授权,一律不接。
- 授权页面上会列出 scope,仔细看有没有“读取全部账户”“读取历史交易”这类宽泛描述。能用单个账户就别授权全部。
- 连接器能读什么、能写什么,以该连接器的官方文档为准,不要凭印象判断。
可撤销性
- Claude 侧:在设置里的连接器 / 集成页面断开,断开后该连接器不能再读取。
- 数据源侧:第三方聚合服务的授权,要去它自己的后台撤销,光在 Claude 里断开不一定同步失效。
- 银行侧:部分银行 App 里有“第三方授权管理”,可以强制解除。
- 撤销后建议再检查一次:历史对话里已经上传的文件、已经生成的报告,仍然存在,需要单独删除。
隐私边界
- 不上传:完整卡号、身份证号、网银登录密码、短信验证码、安全问题的答案。
- 谨慎上传:带个人姓名和住址的账单 PDF。能导 CSV 就导 CSV,PDF 里信息量大得多。
- 上传前问自己一句:这份文件如果被完整看到,最坏情况是什么?如果答案让你不舒服,就先脱敏。
- 不同地区对金融数据聚合的监管要求不同,涉及自动化接入时,以官方页面和当地法规为准。
常见坑与排错
金额全变成正数,支出收入分不清
银行导出常把方向放在单独一列。检查 direction 是否被正确读取,必要时用 amount 的正负号重建。
信用卡还款被算成支出,总支出翻倍
典型双重计算。把还款和账户互转统一标成 type=transfer,统计时排除。
退款当月被当成收入,类目占比失真
退款单独标 type=refund,归到原类目做冲减,别混进收入。
日期 03/04/2025 被解析成 3 月 4 日,实际是 4 月 3 日
统一转 ISO 格式再分析。转换前先抽 10 行人工核对。
CSV 打开是乱码
Excel 导出的中文 CSV 常见编码问题。读取用 encoding="utf-8-sig",写出用 utf-8。
Claude 报的行数和本地对不上
文件被截断。分批发送,每批让它报“本批 N 行、小计 X 元”,累加核对。
模型给某个商户编了个类目
在指令里加一条:“归类依据必须是商户名中的关键词,并在备注列写出你匹配到的关键词。”写不出关键词的,就该进“待确认”。
类目分得太细,20 多个类每类都是几十块
控制在 12 个左右。类目是用来做决策的,不是用来做会计凭证的。
多币种混在一起加总
先按当月汇率折算成一种货币,并在报告里注明汇率来源和日期,以官方发布为准。
下一步建议
1. 先跑三个月,别只跑一个月。 单月数据的“异常”大多只是发放时间差异,三个月才能看出趋势。
2. 加一次订阅专项审计。 把所有 type=subscription 的行拉出来,逐条问“过去 90 天我用过吗”,这一步的省钱效率通常最高。
3. 把规则库当资产维护。 每次“待确认”里新出现的商户,补进 RULES,三个月后自动分类率能到 90% 以上。
4. 想自动化再上连接器。 手动流程跑顺了、清楚自己要哪几个指标之后,再考虑接入只读连接器,这时你才有能力判断授权页面上的 scope 是不是过分。
5. 每季度做一次“预算 vs 实际”复盘。 重点看连续两个月超支的类目——那不是意外,是预算定错了,该改的是预算数字本身。
