本指南综合了使用强大、开源、纯文本记账工具 Beancount 进行纯文本记账的最佳实践。它涵盖了基础理念、从基础到进阶的语法、复杂资产的实际案例,以及长期账本管理策略。
第一部分:"为什么" —— 智能簿记的基础
在深入了解“怎么做”之前,理解“为什么”至关重要。有效的记账是个人财务管理的基石,也是通往财务清晰与自由的必经之路。
超越支出追踪:通往财务清晰之路
简单的支出追踪应用只会告诉你钱花到哪里去了。而一套强大的记账系统不仅能告诉你这些,还能提供更多:它提供你财务健康状况的完整图景,包括你的净资产、现金流以及投资表现。首要目标是可观测性——获得对财务生活清晰、数据驱动的理解,这使你能够做出明智决策、评估风险,并朝着退休等长期目标努力。
为什么要复式记账?平衡系统的力量
与单式记账(简单的支出清单)不同,复式记账法将每笔交易记录为至少两个账户之间的价值流动。其核心原则是基本会计恒等式:
这套系统确保你的账本始终保持平衡,大幅减少错误。它通过生成资产负债表(你拥有什么、欠什么)和利润表(你赚了多少、花了多少)等关键报表,提供完整的财务图景。
第二部分:Beancount 入门
Beancount 是一个强大的、基于 Python 的纯文本记账工具。
在 Beancount.io 上首次体验 Fava
Beancount.io 提供了一个强大的环境,将 Beancount 引擎与移动应用(iOS、Android)和网页应用——Fava(一个出色的基于网页的账本可视化界面)结合在一起。无需安装。当你使用该平台时,你直接在一个文本编辑器中操作你的账本文件(例如 main.bean),并实时看到 Fava 生成的报表更新。
Fava 将你写的纯文本转化为交互式图表、财务报表和可筛选的交易列表,让你清晰地查看财务报告。
或从终端开始使用bea
如果你更愿意在 shell 中工作,bea 就是 Beancount.io 的命令行工具。无需账户:用 brew install bex-co/tap/bea 或 uv tool install beancount-io 安装,它就可以在同一个纯文本文件上创建、校验、查询和生成报表。CLI 快速入门能让你在几分钟内得到第一本账本,而用 bea 度过第一个月会端到端地完成一整个月。
五种核心账户类型
Beancount 使用五种顶层账户类型,它们构成了你账本的结构:
| 账户类型 | 描述 | 典型余额 |
|---|---|---|
Assets | 你拥有的东西(现金、银行账户、投资、房产)。 | 正数 |
Liabilities | 你欠的东西(信用卡债务、贷款、房贷)。 | 负数 |
Income | 钱的来源(工资、奖金、利息)。 | 负数 |
Expenses | 钱的去向(餐饮、房租、旅行、税费)。 | 正数 |
Equity | 你的净资产;用于初始余额。 | 负数 |
Beancount 等式
Beancount 强制执行它自己版本的会计恒等式,即整个账本中所有分录之和等于零:
这就是为什么按照惯例,Income、Liabilities 和 Equity 账户持有负值——它们是增加你 Assets 和 Expenses 的资金_来源_。
第三部分:Beancount 的语言 —— 核心语法
Beancount 中的所有条目都是以日期开头的指令。
定义账户(open)和商品
在你使用一个账户之前,必须用 open 指令声明它。你还可以选择性地指定它将持有的货币或“商品”。
; YYYY-MM-DD open Account:Name [Commodity1, Commodity2, ...]
2020-01-01 open Assets:Bank:US:Chase:Checking USD
2020-01-01 open Liabilities:CreditCard:US:Discover USD
2020-01-01 open Expenses:Food:Groceries
2020-01-01 open Income:Salary:Google商品可以是现实世界的货币(例如 USD、JPY),也可以是你定义的任何自定义单位,比如航空里程(MILES_UA)或股票代码(HOOL)。
记录你的第一笔交易(*)
交易是最常见的条目。它们以日期、标志(* 表示完整交易,! 表示未完成交易)、可选的收款方和描述开头。紧随其后的每一行(缩进两个空格)都是对一个账户的“分录”。
; YYYY-MM-DD * "Payee" "Description"
; Account1 Amount Commodity
; Account2 -Amount Commodity
2024-07-28 * "Trader Joe's" "Weekly groceries"
Expenses:Food:Groceries 125.50 USD
Liabilities:CreditCard:US:Discover -125.50 USD为方便起见,如果一笔交易只有两条分录,你可以省略第二行的金额,Beancount 会自动计算。
2024-07-28 * "Trader Joe's" "Weekly groceries"
Expenses:Food:Groceries 125.50 USD
Liabilities:CreditCard:US:Discover交易级平衡: 更重要的是对于日常使用而言,每一笔单独的交易也必须平衡——单笔交易内所有分录之和必须等于零。如果一笔交易不平衡,Beancount 会显示这样的错误:

处理多货币交易(@ 和 @@)
Beancount 擅长多币种记账。
- 用
@指定每单位换算价格。 - 用
@@指定换算的总成本。
; Buying a flight in EUR with a USD card
2024-08-01 * "Lufthansa" "Flight to Berlin"
Expenses:Travel:Flights 500.00 EUR @@ 545.00 USD ; 500 EUR cost me 545 USD in total
Liabilities:CreditCard:US:Discover -545.00 USD第四部分:确保准确性 —— 对账的艺术
维护准确账本的关键实践是定期对账。这涉及将你 Beancount 账本中的余额与金融机构提供的官方对账单进行比对。
使用余额断言(balance)自动化检查
balance 指令是你进行自动化检查的主要工具。你断言在某个给定日期,某个账户有特定余额。如果 Beancount 计算出的余额与你的断言不符,它会报错。这对于快速定位错误极为宝贵。
注意: 余额断言检查的是指定日期_开始时_(该日任何交易之前)的账户状态。
; From your monthly credit card statement
2024-08-01 balance Liabilities:CreditCard:US:Discover -1432.78 USD关联支持文件(document)
你可以链接到银行对账单或收据等外部文件,形成可审计的轨迹。Fava 让这些链接可点击。
2024-08-01 document Liabilities:CreditCard:US:Discover "statements/discover-2024-07.pdf"纠正错误和初始化余额
当你开始记账或发现无法追溯的差异时,你需要做一个调整。标准做法是使用一个特殊的 Equity 账户。
; Initializing a cash account when starting your ledger
2020-01-01 * "Initial Balance" "Setting up cash account"
Assets:Cash:Wallet 200.00 USD
Equity:Opening-Balances -200.00 USDEquity:Opening-Balances 账户持有从未知或外部来源进入你账本的金额。
对于确切差异并不重要的快速修复,pad 指令可以自动调整账户余额以符合后续的 balance 断言,将差额记入权益账户。请谨慎使用,因为它可能掩盖更大的问题。显式调整通常更安全。
第五部分:高级和现实交易模式
追踪债务:管理应收和应付
复式记账非常适合追踪别人欠你的钱(Assets:Receivables)或你欠别人的钱(Liabilities:Payable)。
示例: 你为一顿 90 美元的聚餐买单,你的朋友 Bob 欠你他那 45 美元的份额。
-
记录初始支出和应收款:
2024-08-05 * "Dinner Place" "Dinner with Bob" Expenses:Food:Restaurant 45.00 USD ; Your share Assets:Receivables:Bob 45.00 USD ; Bob owes you Assets:Bank:US:Chase:Checking -90.00 USD -
当 Bob 还你钱时:
2024-08-06 * "Bob" "Paid me back for dinner" Assets:Bank:US:Chase:Checking 45.00 USD Assets:Receivables:Bob -45.00 USD
Assets:Receivables:Bob 账户现在为零,你的账本完美平衡。
资产与费用:购车与折旧
像汽车这样的大额购买不是简单的支出;它是购置一项会随时间贬值(折旧)的资产。
-
将购买记录为资产:
2023-01-15 * "Toyota Dealer" "Purchase of a new car" Assets:Car:ToyotaCamry 30000.00 USD Assets:Bank:US:Chase:Checking -30000.00 USD -
记录年度折旧: 假设你估计这辆车每年贬值 3,000 美元。在年末,你将此记录为支出。
2023-12-31 * "Depreciation" "Annual car value depreciation" Expenses:Depreciation:Car 3000.00 USD Assets:Car:ToyotaCamry -3000.00 USD
在这笔分录之后,你的 Assets:Car:ToyotaCamry 账户正确地反映了汽车的新价值(27,000 美元),并且你已将该年的使用成本恰当地作为支出入账。
第六部分:深入探讨 —— 建模复杂的现实世界资产
案例研究 1:房地产会计
房子往往是你最大的资产和负债。以下是如何为它建模。
-
创建账户和自定义商品:
2022-01-01 commodity HOUSE_123MAIN name: "Property at 123 Main St" 2022-01-01 open Assets:Property:Home:123Main HOUSE_123MAIN 2022-01-01 open Liabilities:Mortgage:HomeLoan USD 2022-01-01 open Expenses:Home:Interest 2022-01-01 open Expenses:Home:PropertyTax -
记录购买: 假设你以 10 万美元首付和 40 万美元贷款买下一套 50 万美元的房子。
2022-03-15 * "Settlement Company" "Purchase of 123 Main St" Assets:Property:Home:123Main 1 HOUSE_123MAIN {500000.00 USD} Assets:Bank:DownPayment -100000.00 USD Liabilities:Mortgage:HomeLoan -400000.00 USD -
记录每月房贷还款: 你的每月还款由本金(减少负债)和利息(一项支出)组成。
2022-04-01 * "Mortgage Bank" "Monthly Mortgage Payment" Liabilities:Mortgage:HomeLoan 800.00 USD ; Principal Expenses:Home:Interest 1200.00 USD ; Interest Assets:Bank:US:Chase:Checking -2000.00 USD -
追踪增值(未实现收益): 房子的市值会变化。为了在不影响你官方净资产的情况下追踪它(因为在你卖出之前收益并未实现),你可以使用一个带有“虚拟”货币的价格指令。
对于受支持的市场资产和货币对,实时价格可以在托管账本中维护估值报价。单项房产仍然需要你自己的估价和有日期的价格,如下例所示。
; The purchase price is the real cost basis 2022-03-15 price HOUSE_123MAIN 500000.00 USD ; An updated market estimate is an unrealized gain 2024-01-01 price HOUSE_123MAIN 550000.00 USD.UNREALIZED
这让你可以在 Fava 的图表中看到估计价值,而不会不当抬高你的资产负债表。
探索一个带房贷追踪、折旧和房产出售的实时房地产示例账本:
案例研究 2:跟踪限制性股票单位(RSUs)
RSU 是一种常见的股权薪酬形式。为它们记账涉及追踪初始授予、归属事件和代扣税。
-
初始设置: 为已归属(
HOOL)和未归属(HOOL.UNVEST)股票创建商品,以及后面分录涉及的每一个账户。预先声明所有这些账户,正是让下面两笔交易能够独立加载的原因。2021-01-01 commodity HOOL 2021-01-01 commodity HOOL.UNVEST 2021-01-01 open Assets:Brokerage:Etrade:HOOL HOOL 2021-01-01 open Assets:Grant:Unvested HOOL.UNVEST 2021-01-01 open Income:Grant:Awards HOOL.UNVEST 2021-01-01 open Expenses:Grant:Vested HOOL.UNVEST 2021-01-01 open Income:Salary:Hooli:RSU USD 2021-01-01 open Expenses:Taxes:Federal USD 2021-01-01 open Expenses:Taxes:State USD -
记录初始授予: 这笔交易展示了总授予量进入一个未归属资产账户。此时尚无应税事项,因此整个条目以追踪商品
HOOL.UNVEST计价。2021-02-01 * "Hooli" "Initial RSU Grant" Assets:Grant:Unvested 1000 HOOL.UNVEST Income:Grant:Awards -1000 HOOL.UNVEST -
记录一次归属事件: 这是关键交易。当股票归属时,你确认收入,雇主代扣股票以缴税,你保留其余部分。假设 100 股以 150.00 美元归属,那么:
- 总薪酬:100 × 150.00 美元 = 15,000.00 美元
- 为缴税代扣的股票:40 × 150.00 美元 = 6,000.00 美元(联邦 4,800.00 美元 + 州 1,200.00 美元)
- 你保留的股票:60 × 150.00 美元 = 9,000.00 美元的成本基础
- 到手现金:0.00 美元——全部代扣都以股票支付
这些金额就是该分录的内容,并且它们对得上:6,000.00 美元的税加上 9,000.00 美元的留存股票,正好等于 15,000.00 美元的收入。
2022-02-01 * "Hooli" "RSU Vesting Event" ; Ordinary income: 100 shares * $150.00 Income:Salary:Hooli:RSU -15000.00 USD ; Tax withheld, funded by 40 of the 100 shares (40 * $150.00 = $6,000.00) Expenses:Taxes:Federal 4800.00 USD Expenses:Taxes:State 1200.00 USD ; The 60 shares you keep, at their $150.00 vesting-day basis Assets:Brokerage:Etrade:HOOL 60 HOOL {150.00 USD} ; Retire the 100 unvested units the grant was tracking Assets:Grant:Unvested -100 HOOL.UNVEST Expenses:Grant:Vested 100 HOOL.UNVEST
这笔单一、平衡的交易为整个事件建模:未归属授予减少,收入被确认,税被代扣,60 股净归属股票以正确的成本基础出现在你的券商账户中,供未来计算资本利得时使用。
有两个细节值得抄进你自己的账本。第一,按账户逐笔写出代扣,而不是让一个包罗万象的平衡账户吸收它——如果联邦和州的分录之和不等于被代扣股票的价值,这笔交易将不平衡,Beancount 会告诉你。第二,不要在分录之间留空行:空行会终止交易,Beancount 会对随后的分录报语法错误。
如果你雇主在公开市场上卖出代扣的股票,而不是以归属价收回它们,那么这次卖出是另一笔单独的交易——Assets:Brokerage:Etrade:HOOL 的减少对应现金——卖出价与 150.00 美元基础之间的任何差额都是一笔小的资本利得或损失。把它排除在归属分录之外。
第七部分:账本项目管理
随着你的账本增长,组织变得至关重要。
使用版本控制(Git)保护你的数据
由于你的账本是文本文件,它非常适合用 Git 进行版本控制。这为你提供了所有变更的完整历史,保护你免受意外删除或错误的影响。警告: 你的财务数据高度敏感。请使用 GitHub/GitLab 等服务上的私有仓库,或自行托管。
使用标签(#)和链接(^)组织
Beancount 提供了除账户之外对交易进行分组的两种方式:
- 标签(
#): 用于事件或项目。例如,你可以筛选与某次特定旅行相关的所有交易。2024-07-20 * "Hotel" "Vienna" #trip-europe-2024 - 链接(
^): 用于连接发生在不同时间的、财务上相关的交易,比如一次现金取款和相关的银行手续费。
结构化文件的可扩展策略(include)
单一庞大的文件难以管理。使用 include 指令将账本拆分为多个文件。
main.bean:
; Main ledger file
; Global options
option "title" "My Personal Ledger"
option "operating_currency" "USD"
; Include account declarations and other files
include "accounts.bean"
include "years/2023.bean"
include "years/2024.bean"
include "events/trip-europe-2024.bean"一个稳健的组织策略,按优先级排序:
- 按事件: 为一次重大的、自成一体的事件创建一个单独文件(例如
trip-europe-2024.bean)。 - 按类别/收款方: 对于高度规律、重复性的交易,如水电费或工资,将它们归入自己的文件(例如
recurring-rent.bean)。 - 按账户: 对于与特定账户紧密耦合的交易(利息、手续费、信用卡还款),可以考虑按账户单独建文件。
- 按日期: 对于所有其他一般交易,简单按年(
2024.bean)或按月(2024/07.bean)拆分就很有效。
第八部分:结论
Beancount 的学习曲线很陡峭,但它以对你财务数据无与伦比的掌控力、灵活性和控制力回报你的付出。通过接纳复式记账的原则以及 Beancount 提供的实用工具,你可以从简单的支出追踪迈向一套完整、准确、有洞察力的个人财务管理系统。你的账本将成为一项永久、私密且极其宝贵的资产,帮助你理解过去、规划未来。
Beancount.io 入门
Beancount.io 是一个现代化的基于云的财务管理平台,它将你基于文本的交易记录转化为全面的财务报表,包括利润表、资产负债表和试算平衡表。通过将纯文本文件的可靠性与强大的可视化工具相结合,Beancount.io 帮助你在对财务生活保持精确控制的同时,获得对投资表现的宝贵洞察。
用 Beancount.io 开启你的财务之旅——查看当前方案和定价了解各档位包含的内容。


