From beancounter-cli
Beancount 个人财务管理 - 账单导入、BQL 查询分析、预算管理、投资建议。当用户提到账单、记账、beancount、财务、收支、预算、报表时使用。
npx claudepluginhub vincentor/claude-code-pluginsThis skill is limited to using the following tools:
使用 beancounter CLI 和 beancount 工具链管理个人财务。
Guides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Guides building MCP servers enabling LLMs to interact with external services via tools. Covers best practices, TypeScript/Node (MCP SDK), Python (FastMCP).
Generates original PNG/PDF visual art via design philosophy manifestos for posters, graphics, and static designs on user request.
Share bugs, ideas, or general feedback.
使用 beancounter CLI 和 beancount 工具链管理个人财务。
cd ${CLAUDE_PLUGIN_ROOT}/src && uv run <command>
!cat ~/.beancounter/config.yaml 2>/dev/null || echo "未配置。请创建 ~/.beancounter/config.yaml,参考下方初始化说明。"
首次使用前,创建 ~/.beancounter/config.yaml:
# 账本主文件路径(用于 bean-query 查询和 validation)
main_ledger: "/path/to/your/beancount/main.bean"
# 账单导入输出根目录
billings_root: "/path/to/your/beancount/billings"
# 分类规则文件目录(含 payment_mapping.yaml, expense_rules.yaml)
rules_dir: "/path/to/your/.beancounter"
# 默认导入参数
import_defaults:
auto_filename: true
update_index: true
default_category: "default"
同目录下还需要两个规则文件:
~/.beancounter/payment_mapping.yaml — 支付方式 → 账户映射~/.beancounter/expense_rules.yaml — 消费分类规则cd ${CLAUDE_PLUGIN_ROOT}/src && uv run beancounter import <source> <file> [options]
支持的账单源:
| source | 格式 | 说明 |
|---|---|---|
wechat | CSV/XLSX | 微信支付账单 |
alipay | CSV | 支付宝账单 |
cmb | 招商银行信用卡对账单 | |
cmb_debit | 招商银行借记卡交易流水 | |
ccb_debit | 建设银行借记卡交易明细 |
常用选项:
| 选项 | 说明 |
|---|---|
--config, -c <dir> | 规则配置目录(含 payment_mapping.yaml 等) |
--billings-root <dir> | 账单输出根目录 |
--category <name> | 账单分类(default, investment, trip 等) |
--auto-filename | 自动生成文件名(source-year.month.bean) |
--update-index | 自动更新 00.bean index 文件 |
--year <int> | 指定年份(覆盖自动检测) |
--dedupe-with <file> | 用已有 .bean 文件去重 |
-v | 详细日志 |
标准导入命令模板:
cd ${CLAUDE_PLUGIN_ROOT}/src && uv run beancounter import <source> <file> \
--config <rules_dir> \
--billings-root <billings_root> \
--auto-filename \
--update-index \
--category default
其中 <rules_dir> 和 <billings_root> 从 ~/.beancounter/config.yaml 中读取。
导入完成后,建议立即执行以下查询,汇总导入结果给用户:
# 查看导入期间的支出分布
cd ${CLAUDE_PLUGIN_ROOT}/src && uv run bean-query <main_ledger> \
"SELECT root(account, 3) as category, sum(position) as total
WHERE account ~ 'Expenses' AND date >= <start> AND date <= <end>
GROUP BY category ORDER BY sum(position) DESC"
# 查看收入汇总
cd ${CLAUDE_PLUGIN_ROOT}/src && uv run bean-query <main_ledger> \
"SELECT account, sum(position) as total
WHERE account ~ 'Income' AND date >= <start> AND date <= <end>
GROUP BY account"
beancounter 使用两个 YAML 规则文件来自动分类账单交易。这些文件位于 ~/.beancounter/ 目录下(即 config.yaml 中 rules_dir 指向的目录)。
将账单中的支付方式(如银行卡号、钱包名称)映射到 beancount 账户。
文件结构:
payment_accounts:
- pattern: "招商银行.*信用卡\\(1284\\).*"
account: "Liabilities:Cards:CMBC:Master1284"
type: "LIABILITY"
- pattern: "^零钱$"
account: "Assets:MBP:WeChat:Wallet"
type: "ASSET"
字段说明:
| 字段 | 说明 |
|---|---|
pattern | 正则表达式,匹配账单中的支付方式字段 |
account | 对应的 beancount 账户全名 |
type | 账户类型:LIABILITY(信用卡等负债)或 ASSET(储蓄卡、钱包等资产) |
匹配逻辑: 按列表顺序,从上到下第一个匹配的规则生效。未匹配时,交易的支付账户会标记为未知(Assets:Unknown)。
根据商户名、商品描述等信息,将交易分类到具体的支出/资产账户。
文件结构:
classification_rules:
- name: "咖啡饮品"
merchant_pattern: ".*(luckin coffee|瑞幸咖啡|喜茶|霸王茶姬).*"
product_pattern: ".*"
expense_account: "Expenses:Life:Fruits-Snacks:Drinks"
priority: 90
- name: "电商-宠物食品"
merchant_pattern: ".*(京东|淘宝|天猫).*"
product_pattern: ".*(猫粮|狗粮|猫砂).*"
expense_account: "Expenses:Pets:Food"
priority: 95
字段说明:
| 字段 | 说明 |
|---|---|
name | 规则名称(描述性,便于维护) |
merchant_pattern | 正则表达式,匹配商户名/交易对手 |
product_pattern | 正则表达式,匹配商品描述/备注 |
payment_channel_pattern | (可选)匹配支付渠道,如 ^transfer$ 用于识别转账 |
counterparty_last4_pattern | (可选)匹配对方账号后四位,用于内部转账识别 |
expense_account | 分类到的 beancount 账户 |
priority | 优先级(0-1000),数值越高越优先匹配 |
优先级体系:
| 优先级范围 | 用途 | 示例 |
|---|---|---|
| 1000 | 内部转账(最高优先级) | 自己的银行卡之间互转 |
| 95-100 | 精确匹配 | ETC 通行费、加油站、特定保险 |
| 85-95 | 商户/品类匹配 | 咖啡店、打车、电商细分 |
| 40-50 | 平台兜底 | 京东/淘宝未匹配商品时的默认分类 |
| 0 | 全局兜底 | Expenses:Other(所有未匹配交易) |
匹配逻辑: 所有规则按 priority 降序排列,同时满足 merchant_pattern 和 product_pattern(以及可选的 payment_channel_pattern、counterparty_last4_pattern)的第一条规则生效。
当导入账单后发现分类不准确时,AI 应主动帮助改进规则。
识别未分类/错分类的方法:
# 查看被分到 Expenses:Other 的交易(说明没有匹配到合适规则)
cd ${CLAUDE_PLUGIN_ROOT}/src && uv run bean-query <main_ledger> \
"SELECT date, narration, payee, position WHERE account = 'Expenses:Other' ORDER BY date DESC LIMIT 20"
# 查看标记为 Assets:Unknown 的交易(说明支付方式未识别)
cd ${CLAUDE_PLUGIN_ROOT}/src && uv run bean-query <main_ledger> \
"SELECT date, narration, payee, position WHERE account ~ 'Unknown' ORDER BY date DESC LIMIT 20"
改进流程:
Expenses:Other 和 Assets:Unknown 的交易cat ~/.beancounter/expense_rules.yaml 或 cat ~/.beancounter/payment_mapping.yamlbean-query 验证:
cd ${CLAUDE_PLUGIN_ROOT}/src && uv run bean-query <main_ledger> \
"SELECT DISTINCT account WHERE account ~ 'Expenses' ORDER BY account"
编辑规则的注意事项:
\( \) 需要 YAML 双转义:写成 \\( \\)product_pattern 区分# 非交互式查询(推荐)
cd ${CLAUDE_PLUGIN_ROOT}/src && uv run bean-query <main_ledger> "<BQL语句>"
# 交互式 REPL
cd ${CLAUDE_PLUGIN_ROOT}/src && uv run bean-query <main_ledger>
其中 <main_ledger> 从 ~/.beancounter/config.yaml 的 main_ledger 字段获取。
SELECT <列...>
FROM <事务过滤>
WHERE <记账行过滤>
GROUP BY <分组>
ORDER BY <排序> [ASC|DESC]
LIMIT <数量>
事务级别:
date — 日期year, month, day — 日期分量flag — 标记(*, !)payee — 付款方narration — 描述tags — 标签集links — 链接集记账行级别:
account — 账户名position — 金额(含成本基础)units(position) — 纯金额cost(position) — 成本基础balance — 运行余额| 操作符 | 说明 | 示例 |
|---|---|---|
=, != | 等于/不等于 | account = "Assets:Cash" |
<, >, >=, <= | 比较 | date >= 2024-01-01 |
~ | 正则匹配 | account ~ "Expenses:Food" |
AND, OR, NOT | 逻辑 | year = 2024 AND month = 1 |
| 函数 | 说明 |
|---|---|
SUM(position) | 求和 |
COUNT(*) | 计数 |
MIN(date), MAX(date) | 最小/最大 |
FIRST(date), LAST(date) | 首个/末个 |
| 函数 | 说明 | 示例 |
|---|---|---|
YEAR(date) | 提取年份 | YEAR(date) = 2024 |
MONTH(date) | 提取月份 | MONTH(date) = 6 |
ROOT(n, account) | 账户前 N 层 | ROOT(2, account) → Expenses:Food |
PARENT(account) | 父账户 | |
LEAF(account) | 叶节点 | |
COST(position) | 成本基础 | |
UNITS(position) | 金额单位 |
-- 余额表
BALANCES
-- 指定日期的余额
BALANCES FROM CLOSE ON 2024-12-31
-- 账户日记
JOURNAL "Assets:Cash"
-- 输出原始 beancount 格式
PRINT FROM year = 2024
月度支出汇总:
SELECT month, root(account, 3) as category, sum(position) as total
WHERE account ~ "Expenses" AND year = 2024
GROUP BY month, category
ORDER BY month, total DESC
收入 vs 支出对比:
SELECT root(account, 1) as type, sum(position) as total
WHERE account ~ "^(Income|Expenses)" AND year = 2024
GROUP BY type
资产负债总览:
SELECT account, sum(position) as balance
WHERE account ~ "^(Assets|Liabilities)"
GROUP BY account
ORDER BY balance DESC
消费类别排行(当月):
SELECT root(account, 3) as category, sum(position) as total, count(*) as txns
WHERE account ~ "Expenses" AND year = 2024 AND month = 12
GROUP BY category
ORDER BY total DESC
某类消费月度趋势:
SELECT year, month, sum(position) as total
WHERE account ~ "Expenses:Food"
GROUP BY year, month
ORDER BY year, month
按商户/描述搜索:
SELECT date, narration, account, position
WHERE narration ~ "美团" AND year = 2024
ORDER BY date DESC
特定账户流水:
SELECT date, narration, position, balance
WHERE account = "Assets:Cards:CMBC:5367"
ORDER BY date DESC
LIMIT 20
年度收支净值:
SELECT year, sum(position) as net
WHERE account ~ "^(Income|Expenses)"
GROUP BY year
ORDER BY year
资产变动趋势(按月):
SELECT month, sum(position) as net_change
WHERE account ~ "^Assets" AND year = 2024
GROUP BY month
ORDER BY month
投资账户余额:
SELECT account, sum(position) as balance
WHERE account ~ "Assets:Investment|Assets:Fund|Assets:Stock"
GROUP BY account
ORDER BY balance DESC
# 验证账本语法
cd ${CLAUDE_PLUGIN_ROOT}/src && uv run bean-check <main_ledger>
# 格式化 .bean 文件
cd ${CLAUDE_PLUGIN_ROOT}/src && uv run bean-format <file.bean>
内置 stock_analyzer.py 提供美股实时数据分析(基于 yfinance):
# 完整分析(输出 JSON)
cd ${CLAUDE_PLUGIN_ROOT}/src && uv run python stock_analyzer.py AAPL
# 含同业对比
cd ${CLAUDE_PLUGIN_ROOT}/src && uv run python stock_analyzer.py AAPL --peers MSFT,GOOG,AMZN
# 快速查价
cd ${CLAUDE_PLUGIN_ROOT}/src && uv run python stock_analyzer.py AAPL --quick
输出包含:实时价格、估值指标、技术指标(MA/RSI/MACD/布林带等)、期权数据、同业对比。 AI 应基于 JSON 原始数据进行分析和评分,生成投资分析报告。
当用户请求时:
| 用户意图 | 操作 |
|---|---|
| "导入微信账单" | beancounter import wechat <file> --config ... --billings-root ... --auto-filename --update-index |
| "导入支付宝/招行/建行账单" | 同上,替换 source 为 alipay/cmb/cmb_debit/ccb_debit |
| "这个月花了多少" | bean-query: 本月 Expenses 汇总 |
| "收支情况" | bean-query: Income + Expenses 对比 |
| "账户余额" | bean-query: BALANCES 或 Assets+Liabilities 汇总 |
| "餐饮消费趋势" | bean-query: Expenses:Food 按月 GROUP BY |
| "家庭资产总览" | bean-query: Assets + Liabilities 分账户汇总 |
| "预算还剩多少" | bean-query 当月支出 + 对比预算目标 |
| "分析某只股票" | stock_analyzer.py 获取数据 + AI 分析 |
| "投资建议" | bean-query 投资持仓 + stock_analyzer + WebSearch 市场新闻 |
| "生成月度报告" | 多轮 bean-query 汇总 + AI 撰写报告 |
| "有些交易分类不对"/"改进分类规则" | 查询 Expenses:Other + 读取规则文件 + 添加/修改规则 |
| "这个支付方式没识别" | 查询 Assets:Unknown + 读取 payment_mapping.yaml + 添加映射 |
| "盘点"/"资产盘点"/"对账" | 引导用户逐账户核实余额,生成盘点/调整交易 |
资产盘点是核实实际账户余额并记录到 beancount 账本的过程。分为初始化盘点(首次建账)和调整盘点(定期核对差异)两种模式。
根据用户来源选择交互方式:
判断标准: 对话上下文有 lark-cli 相关消息、用户提到"飞书/群里"、或可推断用户在使用飞书机器人。
cd /Users/vincent/.claude/plugins/cache/vincent-personal-plugins/lark-cli/0.1.0/src && \
uv run lark-cli message send "<消息内容>"
要点:每组发送后等待回复,使用 Markdown 格式,金额用千分位逗号。
余额输入:直接在对话中以 Markdown 表格展示账户,让用户用自然语言回复余额(余额是自由输入,不适合 AskUserQuestion)。
选择题:账户命名、处理方式等选择类问题,使用 AskUserQuestion 工具。
accounts/assets.bean),获取所有账户及元数据(corp、type、注释)<billings_root>/*/inventory/inventory-*.bean),获取上次余额展示格式:
请查看 **招商银行** App,告诉我以下账户的当前余额:
| 账户 | 说明 | 上次余额 |
|------|------|----------|
| `CMBC:5367` | 工资卡活期 | 122,339.33 CNY |
| `CMBC:5367:ZZB` | 朝朝宝 | 100,926.05 CNY |
| `CMBC:YKT3616` | 香港一卡通 | 167,840.18 HKD + 37,648.49 USD |
请直接给我每个账户的当前余额即可。
关键要点:
盘点时用户常反馈以下情况:
| 情况 | 处理方式 |
|---|---|
| 发现新账户 | 用 AskUserQuestion 提供 2-3 个符合现有命名风格的选项,记录后写入 assets.bean |
| 账户已销户 | 在 assets.bean 添加 close 指令,不纳入盘点 |
| 余额清零但保留 | 以 0.00 CNY 纳入盘点(用户可能后续存入) |
| 不参与盘点 | 跳过(如关联扣款账户、中间过渡账户) |
新账户命名示例:
用户:"我的一卡通还有个基金账户,余额是 104,542.85 HKD"
→ AskUserQuestion 提供选项:
1. Assets:Cards:CMBC:YKT3616:Fund(放在一卡通下,作为子账户)
2. Assets:Funds:CMBC:YKT3616(放在 Funds 分类下,按机构归类)
写入文件前必须展示完整汇总让用户确认:
**本次盘点汇总 (YYYY-MM-DD)**
| 账户 | 余额 |
|------|------|
| **招商银行** | |
| CMBC:5367 活期 | 86,201.88 CNY |
| CMBC:YKT3616:Fund 一卡通基金 (**新**) | 104,542.85 HKD |
| ... | |
**新增账户:** CMBC:YKT3616:Fund, Bank:WingLung:NXT 等
**销户账户:** WeChat:LingQianTong
**不纳入盘点:** ZZB/ZZY/ZZY2(已清零), Alipay:Payment(0)
确认无误的话我就开始更新文件了?
同时更新:
5a. assets.bean(如有变更):
open 指令(含 corp/type 元数据、币种约束)close 指令5b. 盘点文件 <billings_root>/<year>/inventory/inventory-<YYYYMMDD>.bean:
; 资产盘点 YYYY-MM-DD
YYYY-MM-DD * "账户余额盘点"
;银行卡
Assets:Cards:CMBC:5367 86201.88 CNY
Assets:Cards:CMBC:YKT3616 15440.38 HKD
Assets:Cards:CMBC:YKT3616 109.72 USD
; 南向通
Assets:Bank:WingLung:NXT 1752.51 HKD
; 移动支付账户
Assets:MBP:WeChat:Wallet 573.51 CNY
; 理财
Assets:Funds:TxLicai 247654.95 CNY
; 股票账户
Assets:Stocks:HKstock 78184.29 HKD
Assets:Stocks:USstock 1963.03 USD
; 现金
Assets:Cash 0.00 CNY
Equity:Opening-Balances
关键规则:
Equity:Opening-Balances 不写金额,beancount 自动计算平衡值调整模式(非初始化)的差异处理:
YYYY-MM-DD * "资产盘点-差异调整"
Assets:Cards:CMBC:5367 -2339.33 CNY ; 账本 122339.33 → 实际 120000.00
Expenses:Adjustment:Inventory 2339.33 CNY
Expenses:Adjustment:InventoryIncome:Adjustment:Inventorycd ${CLAUDE_PLUGIN_ROOT}/src && uv run bean-check <main_ledger>
盘点的核心价值环节:将用户实际余额与账本计算余额逐账户对比。
cd ${CLAUDE_PLUGIN_ROOT}/src && uv run bean-query <main_ledger> \
"SELECT account, sum(position) as balance WHERE account ~ '^Assets' GROUP BY account ORDER BY account"
生成差异报告:
| 账户 | 账本余额 | 实际余额 | 差异 | 说明 |
|------|---------|---------|------|------|
| CMBC:5367 | 86,201.88 | 86,201.88 | 0 | 一致 |
| CCB:3577 | 2,528.33 | 16,689.77 | +14,161.44 | 有未记录收入 |
差异含义:
理想状态: 完整记账体系下所有差异应为 0。差异数据可量化账单完整度,指导补录优先级。
初始化模式(--init)下账本余额全为 0,此步骤可跳过。
盘点完成后,主动为用户提供资产分析:
展示格式参考:
## 资产总额
| 币种 | 金额 | 折合人民币 |
|------|------|-----------|
| CNY | 450,998.43 | 450,998.43 |
| HKD | 418,792.62 | 369,961.40 |
| **合计** | | **836,259.75 CNY** |
## 按机构分布
| 机构 | 折合人民币 | 占比 |
|------|-----------|------|
| 腾讯理财通 | 247,654.95 | 29.6% |
| 招商银行 | 228,013.69 | 27.3% |
Expenses:Other 和 Assets:Unknown 的交易~/.beancounter/expense_rules.yaml 和 ~/.beancounter/payment_mapping.yamlaccounts/assets.bean 获取所有账户及元数据,查找上次盘点文件获取参考余额assets.bean(新增/销户)和盘点文件bean-check 语法验证$ARGUMENTS 包含用户的具体请求,解析后决定执行哪个操作。