隐私说明:本文只讨论系统设计和验证方法。所有公司名称、交易对象、金额、期间和业务关系均未使用;示例为虚构数据,配图为重新绘制的结构图,不是实际账套截图。本文不构成会计或税务建议。
最初想解决的不是“做账更快”
这套系统最初只是一个本机运行的网页工具:录入交易、上传附件、生成草稿凭证,再输出科目余额表、利润表和资产负债表。
真正使用以后,我发现困难并不是把一笔收款变成借贷分录。更麻烦的是几个月以后,面对一张报表上的数字,还能不能回答下面这些问题:
- 它来自哪些凭证?
- 凭证依据的是哪张发票、合同或银行流水?
- 当时为什么按这种业务事实处理?
- 后来补到的新资料有没有改变原来的解释?
- 修正一笔历史数据时,有没有破坏已经申报过的期间?
于是系统目标从“自动记账”变成了“建立可以检查的证据链”。
一条记录必须能来回追溯
系统现在围绕一条固定链路组织:
原始资料 → 业务事实 → 会计分录 → 凭证 → 账簿 → 报表 → 检查结果
向前走,是把资料整理成报表;向后走,是从报表数字一路找到它的原始依据。
这改变了很多功能的优先级。附件不再只是凭证旁边的一个下载链接,而是需要保留原文件、原文件名、归档副本、资料类型、状态以及它与哪些凭证相关。重复文件不能因为“看起来多余”就删除;聊天截图在正式合同补齐后也不能消失,而应该标记为“历史沟通资料,正式原件已补”。
这不是为了把页面做得更复杂,而是为了不让后来的整洁覆盖当时真实发生过的过程。
AI 只能生成草稿,不能决定事实
系统支持用 AI 解析交易描述和附件,但生成结果默认只能进入草稿状态。草稿不影响报表,必须经过人工确认和过账,才进入正式账簿。
这是一个刻意保留的摩擦。如果 AI 看到“退款”“代付”“预收”之类的词就直接入账,它可能在分录形式上完全平衡,却把业务事实理解错了。
例如下面是一组纯虚构数据:
银行收到 10,000 元
它可能是销售收款、客户预付款、股东借款、往来款归还,也可能是错误转账。金额和摘要不足以决定会计含义。系统可以给出候选科目,却不能替人补齐不存在的事实。
因此这里的自动化边界是:减少录入和检索成本,不取消事实确认。
我给系统设了几条不能被“优化”掉的约束
为了避免系统越自动化越不可控,底层保留了一些硬规则:
- 金额以“分”为整数保存,避免浮点误差。
- 不平衡凭证不能过账。
- 草稿凭证不进入报表。
- 银行流水需要能够找到对应凭证或明确解释。
- 已申报报表作为历史锚点,后续整理不能为了让当前数字好看而覆盖它。
- 删除和修改必须尊重资料、凭证与分录之间的外键关系。
- 关键调整前先创建完整还原点。
这些规则的共同目的不是“符合某个软件架构”,而是让一次局部修改不会悄悄改变另一段历史。
最难的一次清理:删除异常,但证明有效账簿没变
在多轮导入、修正和恢复后,数据库里曾积累两百余条历史异常记录,其中包括父凭证已经不存在的试算分录,以及仍指向旧交易的失效关联。
直接删除并不难,难的是证明没有误伤有效数据。我采用的顺序是:
- 先创建包含完整数据库的还原点;
- 把所有待处理异常导出成 JSON 和 CSV;
- 计算有效账簿的 SHA-256;
- 只删除已经证明失去父记录的异常项,并解除失效关联;
- 再次计算有效账簿 SHA-256;
- 核对银行余额、草稿数量、未挂接流水、外键检查和已申报期间差异。
清理前后有效账簿哈希一致,说明删除的是不会进入正式账簿的历史残留,而不是“看起来没用”的业务记录。
这件事让我认识到,数据清理最重要的产物不是更小的数据库,而是一套能够说明“删了什么、为什么能删、有效结果为什么没变”的证据。
“健康检查”不是看服务有没有启动
系统后来增加了一页只读健康检查,它不会修改数据库,而是集中回答几类问题:
- 有没有不平衡凭证;
- 当前期间还有多少草稿;
- 银行流水是否全部找到对应记录;
- 账簿和银行最后余额是否一致;
- 数据库外键是否存在异常;
- 资产、负债、权益和损益是否满足钩稽关系;
- 已申报快照与当前历史期间是否出现不应有的差异。
目前项目有 57 个页面或操作路由、21 个页面模板和 50 项自动化测试。规模不是目标,但测试覆盖了凭证平衡、过账与反过账、报表、流水拆分、资料关联、出库佐证、合同履约、健康检查和历史期间边界等关键行为。
为什么坚持本地运行
这类系统放到公网并不会天然更先进。它保存的不是普通笔记,而是合同、银行流水、发票、申报截图和业务解释。对一个低频、单人维护的系统来说,本机运行、明确备份和按需打开,比增加登录、服务器和公网攻击面更符合风险收益。
所以我没有把它做成在线 SaaS,也不打算自动提交税务系统。报表和检查结果仍然用于人工核对;真正的申报动作留在官方系统中完成。
这个项目值得公开的部分是什么
当然不是某家公司发生过哪些交易,也不是一套可以照搬的会计处理答案。
值得公开的是几条更通用的方法:
- 自动化系统首先要定义哪些决定不能交给 AI;
- 涉及历史数据时,修正当前结果不能破坏已经确认的过去;
- 删除数据之前,要先定义“不变的结果”并能够验证;
- 附件、业务解释和结构化数据必须互相链接,单独保存任何一边都不够;
- 真正可靠的工具,不只是给出答案,还要帮助人解释答案从哪里来。
这套系统仍然不是通用会计软件,也不适合在没有专业复核的情况下直接使用。但它是我投入精力最多的个人工具之一:不是因为页面最多,而是因为每增加一项功能,都必须同时考虑事实、历史、证据、回滚和验证。