用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/publieople/hermes-config-kit --skill notion-bill命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
基于 SOC 职业分类
| name | notion-bill |
| description | Notion 记账系统 — 创建/查询账单、管理收支记录 |
| category | productivity |
基于拉琪奥 Agent 迁移的 Notion 账本系统,管理「收支记录」数据库。
| 配置 | 值 |
|---|---|
| 账本 database_id | 12366ad7-c9c4-8141-8f05-e335b3d0cb5b |
| 账本 data_source_id | 12366ad7-c9c4-81d6-9cbc-000bcd11a4d0 |
| 人脉 database_id | 1f766ad7-c9c4-8007-a335-d4f650b7217f |
| 人脉 data_source_id | 1f766ad7-c9c4-809b-b8aa-000b9c738b61 |
| API Key 路径 | ~/.config/notion/api_key |
| Notion-Version | 2025-09-03 |
创建账单前必须查询数据库元数据,验证所有 select/multi_select 值已存在,绝对不允许直接创建新选项。
验证方式:用 data_source_id 查询数据库元数据 GET /v1/data_sources/{data_source_id}
所有账单创建/删除操作,必须先展示计划,用户确认(Y/N)后再执行。
审核清单:项目、金额、日期、大项、小项、渠道、平台、标签、相关人员
所有金额都用正数,无论收入还是支出。 方向由「大项」区分(收入 vs 饮食/日常购物等),不由正负号区分。
标题字段不要包含 emoji。 Emoji 通过 icon 属性单独设置。
"上海燕矽食品",icon = "🥡""🥡 上海燕矽食品" — emoji 重复,icon 已经设了饮食、日用杂货、休闲娱乐、日常购物、固定消费、生活服务、金融投资、收入、贷款、借款、退款、他人消费、信息遗失、仅记录、资金流转出、资金流转入
外卖、外出就餐、食材、日用品、房租、电费、电话费、电子产品、数字产品、内容消费、工资、兼职、打工、投资分红、转账、代单、交通、退款、利息、零食、饮料、服装、速食、生活费、资金流转、游戏、水费、学费、卡券包、医社保、户外活动、红包、酒店、租赁、流量、他人消费、借款、仅记录、打印、文创周边、信息遗失、服务费、班费、报销、报名费、投资理财、邮寄、贷款、理发、食堂、其他 等
微信零钱、微信零钱通、支付宝(余额交易统一用这个,没有单独的「支付宝余额」渠道)、京东白条、美团月付、平安银行储蓄卡、中国银行储蓄卡、中国银行信用卡、中国银行社保卡、邮储银行储蓄卡、工商银行信用卡-银联/VISA、京东小金库、余额宝(余额宝内交易)、其他
| 场景 | 大项 | 小项 | 示例 |
|---|---|---|---|
| 你帮舍友付(你支出) | 饮食 | 代单 | 你下单付两份,舍友之后转账给你 |
| 舍友还你钱(你收入) | 收入 | 代单 | 舍友把AA份额转给你 |
| 食堂带饭(你支出,帮舍友带一份) | 饮食 | 代单 | 支付宝付给食堂摊主(如马海涛),20自己的+17舍友的;自己的记为食堂,舍友的记为代单。银行账单显示为"支付宝-马海涛",不要被收款人姓名误导 |
有退款的消费必须创建两条关联记录:
银行账单上会出现三条记录:一笔消费、一笔退款、再一笔消费。 必须创建三条关联记录:
净效果:两笔支出 + 一笔退款 = 一笔净支出 ✅
用户无特殊说明时:
触发条件:银行账单显示白条/美团月付扣款时。
错误模式:直接在库中新建一条「白条还款 ¥金额」,导致库里出现两条同月同金额的重复记录。
正确做法:
POST /v1/data_sources/{id}/query 查:平台=京东 + 小项=还款 + 状态=未结算 + 交易渠道=空 的同月记录金额 → 银行实际值、交易日期 → 银行扣款日、交易渠道 → 扣款卡、状态 → 已结算、父项 → 补全涉及商品搜索模板:
{"filter":{"and":[
{"property":"平台","select":{"equals":"京东"}},
{"property":"小项","select":{"equals":"还款"}},
{"property":"状态","status":{"equals":"未结算"}}
]}}
错误模式:用户告知几个名字后,我只查了"阮承远"+"冯忠耀"(因为我"记得"这俩在库),其他人漏了关联。
正确做法:用户每给一个名字 → 立即用 POST /v1/search 在人脉库(database_id=1f766ad7-c9c4-8007-a335-d4f650b7217f)查。人脉库是源头不是记忆。
昵称≠真实姓名("拿琛橡"="阮承远"、"马老师"="马涵君"、"裘隅闿"="谢雨婷"、"郑钩杰"="郑钧杰")。同时尝试昵称+真实姓名。
触发场景:群收款/转账/红包等含人名的记录。
项目名是查询/检索的字符串,用真实姓名保证按"姓名"搜索能命中。
触发场景:银行卡账单显示"扣 ¥X、退款 ¥X、再付 ¥X"三连。
必问用户:
经典案例:买移动空调 ¥420 → 原本想走闲鱼,但线下交易后支付宝扣 ¥420 → 卖家孙明良支付宝退款 ¥420 → 再付 ¥420 走中行储蓄卡。
症状:写完 /tmp/batch5.py 跑完后,下一轮说"can't open file"。
正确做法:
/home/po/.hermes/scripts/ 或 ~/workspace/.hermes/cache/ 不是 /tmp/POST /v1/search — 查询记录和人脉(推荐,比 /data_sources/{id}/query 稳定)POST /v1/pages — 创建账单页PATCH /v1/pages/{id} — 更新账单GET /v1/data_sources/{data_source_id} — 获取数据库元数据(验证选项用)不要在 write_file 或 terminal -c 中直接写 Path.home().joinpath(...) 长路径。 工具可能在序列化时截断为 Path.h...。
正确做法:用 terminal 的 heredoc 写脚本文件再执行:
cat > /tmp/script.py << 'SCRIPTEOF'
import ...
apikey = Path.home().joinpath('.config/notion/api_key').read_text().strip()
...
SCRIPTEOF
python3 /tmp/script.py
或者用 os.path.expanduser 避免长链式调用:
import os
apikey = Path(os.path.expanduser("~/.config/notion/api_key")).read_text().strip()
Python 的 float 序列化与 Notion API 返回的金额可能有精度差异:
Notion API 返回: 60.9 (float from JSON)
Python f-string: 60.90 (float → "60.9")
当通过 POST /v1/search 按标题+金额+日期查找页面时,不要直接用精确字符串匹配金额。正确做法:
# ❌ 会漏匹配
key = f"{title}|{amount}|{date_str}" # 60.9 vs 60.90
# ✅ 用容差比较
if title == t_title and abs(amount - t_amount) < 0.01 and date_str == t_date:
# match!
更稳健的方案:用 data_sources/{id}/query 拉取整页列表,按金额+日期+标题三元组模糊匹配。
import urllib.request, json
from pathlib import Path
key = Path.home().joinpath(".config/notion/api_key").read_text().strip()
headers = {
"Authorization": f"Bearer {key}",
"Notion-Version": "2025-09-03",
"Content-Type": "application/json"
}
# 创建账单
body = {
"parent": {"database_id": "12366ad7-c9c4-8141-8f05-e335b3d0cb5b"},
"properties": {
"项目": {"title": [{"text": {"content": "外卖"}}]},
"金额": {"number": 19.07},
"交易日期": {"date": {"start": "2026-04-30"}},
"交易渠道": {"select": {"name": "微信零钱"}},
"大项": {"select": {"name": "饮食"}},
"小项": {"select": {"name": "外卖"}},
"标签": {"multi_select": [{"name": "外卖"}, {"name": "晚餐"}]},
"状态": {"status": {"name": "已结算"}}
},
"icon": {: , : }
}
search_body = {"query": "姓名"}
# POST /v1/search → 筛选人脉数据库的页面
# 用页面 ID 关联
"相关人员": {"relation": [{"id": "联系人页面ID"}]}
当代单/关联记录用到的人不在人脉库时,必须先创建联系人再创建账单:
POST /v1/search + 人脉 database_id 搜索姓名POST /v1/pages 到人脉库创建(只需「姓名」字段)"相关人员": {"relation": [{"id": "xxx"}]}白条分期涉及三层数据结构,不要混淆:
| 层级 | 说明 | 大项 | 小项 | 金额 | 示例 |
|---|---|---|---|---|---|
| 购买记录 | 在京东白条上买的商品本身 | 日常购物 | 电子产品/服装等 | 商品全价 | OPPO Find X8 4399元 |
| 分期记录 | 每期还款的独立记录 | 日常购物 | 还款 | 每期金额 (183.27) | OPPO第19/24期 |
| 月度账单 | 当月实际扣款的汇总记录 | 日常购物 | 还款 | 各分期之和 (309.60) | 5月账单 |
月度账单 (309.60)
├── 父项 → 购买记录 (OPPO, 正装) ← 指向商品
│
分期记录 (183.27, 第19期)
└── 父项 → 购买记录 (OPPO) ← 指向商品
分期记录 (126.33, 第2期)
└── 父项 → 购买记录 (正装) ← 指向商品
数据库中已有按到期日自动创建的 未结算 分期记录(平台=京东,无渠道,节点为未结算)。当银行账单显示白条扣款时:
❌ 不要新建一条分期记录
✅ 找到已有的那条,PATCH 更新:
- 交易日期 → 改为实际扣款日(银行截图上的日期)
- 交易渠道 → 扣款卡(如中国银行储蓄卡)
- 状态 → 已结算
京东白条还款在银行账单中可能显示为:
网银在线-肯特瑞小额贷... → 白条还款不要被商户名误导,直接记作:
每月会用扣款卡一次性扣款(金额=所有到期分期之和),需要建一条月度账单记录:
项目:白条还款
金额:各分期之和(如 126.33 + 183.27 = 309.60)
渠道:扣款卡(如中国银行储蓄卡)
大项:日常购物
小项:还款
标签:还款
平台:京东
状态:已结算
父项 → 所有涉及的商品购买记录(如 OPPO、正装)
如果京东白条账单显示有分期(如正装第2期 126.33),但数据库中查不到对应记录,需要手动创建:
项目:白条还款
金额:分期金额(如 126.33)
渠道:扣款卡
大项:日常购物
小项:还款
标签:还款
平台:京东
状态:(如果已还=已结算,如果未还=未结算)
父项 → 对应商品购买记录
当前月还完后,剩余的未还分期需要提前建好(设为 未结算,无渠道),有规律可循:
# 搜索所有 白条分期(小项=还款 且 平台=京东)
search 项目 含 "白条还款" OR 平台 = "京东"
# 区分:
# - 渠道为空 + 未结算 = 未来的分期(不要手动设为已结算)
# - 渠道有值 + 已结算 = 已还的分期
# - 平台=京东 + 小项≠还款 = 商品购买记录(用作父项)
用户发送任意渠道的账单截图时(微信零钱、银行储蓄卡/信用卡、支付宝等),按以下流程处理:
使用视觉工具提取所有交易记录,注意识别:
⚠️ 视觉工具选择(铁律):
mmx vision describe <image_path> — 不要调用 vision_analyze,它走 MiniMax M2.7(纯文本模型),永远返回 "I don't see any image"~/.npm-global/bin/mmx。mmx quota 可查 VLM 额度(coding-plan-vlm 配额)mmx vision describe 直接支持 WebPPIL.Image.open() 转 JPEG 再 base64关键步骤:先查询数据库中近期的所有记录(POST /v1/search 拉取最近 100 条),与截图内容做交叉比对:
在分类前,先搜索数据库中使用同一交易渠道的历史记录:
按本 skill 的分类规则对每笔新交易分类:
当用户要求修改已有记录时(如改日期、改渠道、改状态):
POST /v1/search 找到该记录的 page IDPATCH /v1/pages/{id} 更新对应字段常见更新场景:白条还款修改
银行端显示名对照:
展示完整计划给用户确认:
用 Notion API 批量创建新页面。
当有退款或代单需要关联父项时,必须分两阶段创建:
阶段 1:创建所有原始消费记录(父项)
POST /v1/pages 逐一创建,每条间隔 ≥0.3 秒(API 限速)page.idparent_ids = {} # index → {title, amount, date, id}
for i, bill in enumerate(parent_bills):
result = notion_post("pages", body)
parent_ids[i] = {"title": bill["title"], "id": result["id"]}
time.sleep(0.3)
阶段 2:创建关联记录(子项),设置 relation
"父项": {"relation": [{"id": parent_id}]}父项 都指向对应的实际消费记录(不是反过来)"父项": {"relation": [{"id": "父项的pageID"}]}
创建完成后如果需要回头查找页面 ID(例如脚本中断后补跑),首选模式:
POST /v1/data_sources/{DATA_SOURCE_ID}/query 拉取最近记录(title, round(amount, 2), date) 三元组匹配abs(amount - target) < 0.01 比较查询确认写入成功
⚠️ 关键区分:同一家店(如雪芳餐饮、象郡餐饮),叫外卖 vs 堂食,小项和标签完全不同:
| 消费方式 | 项目名 | 大项 | 小项 | 标签 | 图标 | 说明 |
|---|---|---|---|---|---|---|
| 外卖(点餐平台送到) | 「外卖」或商户简称 | 饮食 | 外卖 | 外卖+餐食 | 🥡 | 默认值——不确定走这个 |
| 堂食/到店吃 | 商户全名 | 饮食 | 外出就餐 | 外食+餐食 | 🍜 | 仅当用户明确说去店里吃 |
| 食堂 | 「外食」(用户偏好,不用商户名) | 饮食 | 食堂 | 餐时(午餐/晚餐) | 🍚 | |
| 零食(自贩机/小卖部) | 「零食」 | 饮食 | 零食 | 零食+餐食 | 🍿 | |
| 饮料(自贩机/超市) | 「饮料」 | 饮食 | 饮料 | 饮料+餐食(或饮料+夜宵) | 🥤 | 注意:自贩机非代单时用饮料/零食 |
| 奶茶/饮品店(悸动烧仙草等) | 商户简称 | 饮食 | 饮料 | 饮料+餐时 | 🥤 | 即时饮品消费,非外卖 |
| 淘宝/平台买饮料(整箱/多瓶) | 「淘宝·盐汽水」 | 饮食 | 饮料 | 饮料 | 🥤 | 平台=淘宝,不标餐时标签 |
| 微信商户类型 | 默认小项 | 标签 | 示例 |
|---|---|---|---|
| 餐饮店/餐厅(外卖订单) | 外卖 | 外卖+餐食 | 雪芳餐饮、象郡餐饮、牛哥酸菜鱼、正新鸡排 |
| 餐饮店/餐厅(堂食) | 外出就餐 | 外食+餐食 | 上海市食堂三楼**(食堂)** |
| 快递/电商平台(外卖) | 外卖 | 外卖+餐食 | 京东(外卖) |
| 全国连锁快餐(微信支付) | 外卖 | 外卖+餐食 | 塔斯汀、正新鸡排 |
| 自动售货机(零食) | 零食 | 零食+餐食 | 农夫山泉自贩机 |
| 自动售货机(饮料) | 饮料 | 饮料+餐食 | 农夫山泉自贩机(饮料) |
| 自动售货机(泡面/非饮料即食) | 零食 | 零食+餐食 | 农夫山泉(安吉)智能生活(泡面) |
| 食堂/学校餐厅 | 食堂 | 餐食 | 上海市食堂三楼 |
| 食堂(支付宝付给个人) | 饮食/食堂 | 餐食 | 支付宝-马海涛(食堂摊位收款人) |
| 电费代扣(学校代收) | 固定消费/电费 | 电费 | 上海中侨职业技术大学-代收扣款 |
| 电费代单还款(舍友分摊) | 收入/代单 | 代单 | zzh/王怡然/sjh各转75,父项指向电费记录 |
| AI/API 服务 | 日常购物/数字产品 | 数字产品 | 杭州深度求索 |
| 阿里云/云服务 | 日用杂货或日常购物/数字产品 | API, 数字产品 | 阿里云百炼、阿里云计算 |
| 移动话费/手机充值 | 固定消费/电话费 | 移动话费 | 中移电子商务(电话费)中国银行储蓄卡 |
| 蜜雪冰城/悸动烧仙草等奶茶店 | 饮食/饮料 | 饮料 | 蜜雪冰城、悸动烧仙草。标签=饮料(+餐时如果知道时间) |
| 基金定投(银行端"支付宝-蚂蚁(杭州)") | 金融投资/基金 | 基金 | 支付宝-蚂蚁(杭州)扣款。项目名=「支付宝·基金定投」,渠道=扣款卡。智能定投金额随涨跌幅浮动(如 ¥274→¥299→¥599),不要用之前金额当固定值比对 |
| 学校补贴工资("上海中侨职业技术大学"收入) |
| 线索 | 判定 |
|---|---|
| 商户名是正新鸡排/塔斯汀/京东等外卖平台 | ✅ 外卖 |
| 用户没说"去吃了"、"堂食" | ✅ 默认=外卖 |
| 商户名带具体楼层(中侨一楼) | ✅ 默认=外卖(中侨一楼商户除非用户明确说是堂食,否则默认外卖) |
| 用户说"去吃的"、"到店"、"堂食" | ✅ 外出就餐 |
参见 references/alipay-yuebao-flow.md。
核心原则:双账户视角,每一跳都记,不跳过任何环节。
跨账户资金流转(如银行充值微信)的对端关联模式参见 references/cross-account-flow-pairing.md。
| 渠道 | 用途 |
|---|---|
| 支付宝 | 支付宝余额变动(回收款到账、转入余额宝、余额宝转回、提现) |
| 余额宝 | 余额宝内交易(转入、转出、收益) |
| ⚠️ 不存在「支付宝余额」渠道,余额交易统一用「支付宝」 |
支付宝侧:
回收宝 +1382 → ①OPPO回收(收入/其他, 支付宝)
→ ②转入余额宝(资金流转出, 支付宝) ← 子→①
→ 钱在余额宝里...
→ ⑦余额宝转回余额(资金流转入, 支付宝) ← 子→①
→ ⑥提现到社保卡(资金流转入, 中国银行社保卡) ← 子→⑦
余额宝侧(独立记录):
③自动转入余额宝(资金流转入, 余额宝)
④余额宝收益(收入/利息, 余额宝)
⑤余额宝转出(资金流转出, 余额宝)
| 收入/工资 |
| 工资 |
| 学校打款,项目名=「学校补贴工资」,渠道=入账卡 |
| 食堂(支付宝/校园卡) | 饮食/食堂 | 午餐或晚餐 | 支付宝-孙利纳 中国银行储蓄卡 |
| 公交卡扣款(银行端"支付宝-宁德市公共"/"支付宝-上海公共交通") | 固定消费/交通 | 交通 | 项目名=「公共交通卡」,渠道=扣款卡。金额常见 ¥1/¥2/¥3/¥4/¥5 |