| name | bank-flow-reconciliation |
| description | 银行流水合并与核对工具。支持多银行多格式流水文件的智能合并(标准化为统一12列格式), 以及银行流水与序时账(总账)的自动化双向核对(9层递进匹配引擎)。 当用户提到"银行流水核对""流水核对""银行流水合并""合并流水""流水匹配""银行存款核对" "对账""核对银行流水""bank reconciliation""流水对账""多账号流水合并""银行流水审计" "核对银行存款""序时账核对"时触发。 即使用户只说"帮我核对下银行流水"或"把这几个银行的流水合到一起"也应触发。 审计场景中涉及银行存款测试、资金核对时优先使用此 skill。 |
| slug | nigo-bank-flow-reconciliation |
| displayName | 银行流水合并核对 |
| version | 1.0.0 |
| summary | 银行流水合并与核对工具,9层递进匹配引擎,支持多银行多格式流水合并与序时账自动双向核对,输出审计底稿。 |
| license | MIT |
作者:nigo(涂佳兵) | 微信公众号:逆行的狗
审计实务 + 数字化工具,分享审计效率提升的实战经验。
银行流水合并与核对
概述
三个脚本,按工作流顺序:
- 预检查 (
scripts/bankflow_precheck.py):读取文件,输出列名、样本行、金额统计、科目分布。只探查不判断。
- 流水合并 (
scripts/bankflow_merge.py):多银行多格式流水 → 统一12列标准化Excel
- 流水核对 (
scripts/bankflow_reconcile.py):银行流水 vs 序时账,9层递进匹配,输出核对底稿
AI 的工作:运行脚本 → 看输出 → 填配置 → 运行脚本 → 问用户要不要 AI 复核。匹配逻辑全在代码里,AI 不需要理解引擎内部。
数据准备
核对需要两份数据:序时账(总账/明细账)和银行流水。
序时账必需字段
| 要素 | 说明 |
|---|
| 银行存款科目行 | 科目代码通常以 1002 开头。无科目代码列时可用科目名称"银行存款"代替 |
| 日期列 | 记账日期或凭证日期 |
| 借方/贷方金额列 | 两列分开,不能只有一列带正负号的金额 |
| 凭证号列 | 识别同一笔凭证的多行分录 |
| 摘要列 | L2 匹配层的关键信息源 |
| 客商信息 | ⭐ 决定性因素。有客商→匹配率 90%+,无客商→30-50% |
⭐ 客商信息(两种来源,二选一)
| 来源 | 配置 | 场景 |
|---|
| ①客商辅助核算列 | 客商辅助项列名: "客户,供应商" | 用友/金蝶标准账套,客商在对方科目行的辅助核算项中(拆分模式) |
| ②交易对手列 | 交易对手列名: "往来单位名称" | 银行存款行上有独立的"往来单位"/"交易对手"列(直接模式,匹配率更高) |
直接模式实证 92.6%,拆分模式 78.5%。优先直接模式,银行存款行无客商值时才用拆分模式。
银行流水必需字段
| 要素 | 说明 |
|---|
| 交易日期 | 每笔交易日期 |
| 金额(借/贷 或 收/支) | 两列分开 |
| 对方户名 | 强烈建议,与序时账客商交叉匹配 |
| 摘要 | L2 匹配线索 |
文件格式 .xlsx/.xls/.csv 均可,表头不在第一行或尾部有汇总行都能处理。
工作流程
第1步:判断任务类型
- 仅合并:多个银行流水 → 一个标准化Excel
- 仅核对:已有标准化流水 → 与序时账核对
- 合并+核对:先合并再核对
用户说"核对"但提供了多个银行的流水文件 → 通常需要先合并。
第2步:运行预检查
python SKILL_DIR/scripts/bankflow_precheck.py \
--gl "序时账.xlsx" \
--bank "银行流水.xls" \
--bank-subject "1002"
输出:文件格式、列名、前3行样本、金额统计、候选客商列诊断表(列名+非空率+样本值)、银行科目分布、主体列分布。AI 看这些信息做第3步的判断。
常用参数:--gl-subject-col(科目代码列名)、--bank-subject-name(按名称过滤)、--bank-header-row(跳过前置行)。全表见 references/配置参数详解.md。
第3步:做判断
看预检查输出,做 4 个决策:
决策1:列映射
根据列名和样本值确定配置中各字段对应哪列。看实际列名,不凭猜测——"科目编号"/"科目代码"/"科目编码"在不同软件中叫法不同。
陷阱提醒:
- 无科目代码列:用科目名称列代替,配
科目代码列名: "科目名称", 银行科目代码: "银行存款"
- 科目代码混在编码列(如"1002/8111001012600894851"):直接用该列,配
银行科目代码: "1002",引擎 startswith 天然处理
- 假客商陷阱:
交易对手列 100% 非空但样本值是银行账户名(如"中国农业银行墨江县支行007316")→ 不是真客商。看样本值判断,不被非空率迷惑。真客商可能在对方科目行的复合字段中
决策2:客商信息够不够?
看预检查的诊断表:候选客商列在银行存款行上有值 → 直接模式(交易对手列名)。只在对方科目行有值 → 拆分模式(客商辅助项列名)。
⓾ 客商缺失确认(STOP)
如果所有候选列在两边都无值,或样本值是银行账户名等非客商信息——停下来用 question 工具问用户。
为什么停:匹配率会从 90%+ 暴跌到 30-50%,落差太大。用户需要知情同意——他可能更愿意先整理客商数据,而不是接受一个大半匹配不上的底稿。
- [A] 继续:仅用金额+日期匹配,接受低匹配率
- [B] 补充字段:我指定正确的对手列
- [C] 取消:先完善数据
决策3:多账户覆盖了吗?
看预检查输出的账号分布。
单账户或两边账户一致 → 直接继续。
⓾ 多账户不完全覆盖确认(STOP)
序时账有 5 个银行账户但流水只有 2 个——静默继续会让另外 3 个账户全部无法匹配,用户以为全核对过了实际只核了一部分。审计场景中这个认知差异是风险。
- [A] 仅核对匹配的账户:过滤序时账只保留有流水的
- [B] 全部核对:不设账户列名,整体核对(匹配率偏低)
- [C] 补充流水:我补缺失的银行流水文件
多账户标识不一致:序时账用"招商银行",流水用账号"3960xxx"→ 分组键不匹配 → 0%。此时不设账户列名(选[B]),整体核对。
公司列必须对称:序时账有公司列但流水没有 → 0%。不要配 公司列名,改用 主体过滤。
性能:>5000 行时强烈建议设账户列名分组(16s vs 129s)。
决策4:范围对齐了吗?(低匹配率首要原因)
看预检查的银行科目分布和主体分布。序时账范围明显大于流水时,大量记录无法匹配。
| 类型 | 典型场景 | 解决方案 | 实证 |
|---|
| 科目代码范围 | 序时账含32个银行科目,流水只有1个 | 精确限定 银行科目代码: "100201" | 16% → 99% |
| 主体范围 | 序时账含11个主体,流水只有1个 | 主体过滤: "主体,西安德诺" | 4% → 93% |
| 日期范围 | 序时账全年,流水半年 | 日期范围: "2025-01-01,2025-06-30" | 偏低→正常 |
⓾ 范围限定确认(STOP)
配 主体过滤/日期范围 或收窄 银行科目代码 前——被过滤的记录完全不参与核对,用户可能误以为全部核对过了。审计底稿遗漏记录而不披露是重大风险。
- [A] 确认限定:接受范围对齐后的高匹配率
- [B] 保留全部:不限定,整体核对(匹配率偏低但不遗漏)
选 [A] 后才配置过滤参数。汇报结果时披露实际使用的过滤条件。
第4步:写配置
根据判断结果写 reconcile_config.json。
完整参数表和 JSON 示例见 references/配置参数详解.md(gl_config + bank_config 全字段、客商模式选择、从合并结果衔接核对的固定映射)。
第5步:运行核对
python SKILL_DIR/scripts/bankflow_reconcile.py \
reconcile_config.json \
--output "输入文件所在目录/核对底稿.xlsx"
不传 --output 默认保存到 CWD,文件名 银行流水核对底稿_YYYYMMDD_HHMMSS.xlsx。建议显式传 --output。
第6步:AI 复核(可选)
STOP — 运行完第5步后先停下来。不要自动加 --ai-review 重跑。
为什么停下来问:AI 复核逐条读未匹配记录(可能上百条),耗时 1-2 分钟和可观 token。但匹配率 90%+ 时,剩余十几条交给会计人工看反而更高效(他们有业务上下文)。自动复核 = 在用户不需要时浪费时间和钱。这是实际使用中最常被跳过的 gate——看到匹配率就想继续跑,但复核是可选的,选择权在用户。
读引擎输出的匹配率,用 question 工具问:
当前匹配率:金额 99.2% / 条数 98.4%,未匹配 112 条。
- [A] 进行 AI 复核:逐条审查未匹配记录,可匹配的写入底稿(预计 1-2 分钟)
- [B] 不复核:直接出底稿,剩余交人工(推荐:匹配率已高)
- [C] 先修范围/数据:匹配率偏低时回到决策4
选 [A] 才进入 AI 复核(详见 references/AI复核流程.md)。未匹配 > 500 条时引擎自动跳过——说明范围没对齐,该修范围而不是硬复核。
匹配率预期
| 场景 | 预期金额匹配率 |
|---|
| 范围对齐 + 有客商 | 90%~99%(正常) |
| 范围对齐 + 无客商 + 有摘要 | 70%~90% |
| 无客商 + 无摘要 | 30%~50% |
| 范围不对齐 | <50%(先修范围) |
金额匹配率 ≥ 90% 就算好结果,不需要分析原因。 条数匹配率通常低于金额匹配率——序时账把多笔小额费用报销汇总成一笔凭证是常态(如 50 笔银行流水对应 1 笔 GL),这会拉低条数匹配率但不影响核对结论。只要总额平衡(流水收支 ≈ 序时账借贷),底稿可以直接交付,未匹配记录交会计人工核视即可。不要主动长篇分析匹配率不高的原因——用户要的是底稿,不是分析报告。
依赖安装
pip install pandas openpyxl xlrd rapidfuzz
xlrd 仅在读 .xls 时需要。rapidfuzz 可选(回退到 difflib)。
参考文档
| 文档 | 何时查阅 |
|---|
references/配置参数详解.md | 写配置时——三个模块全部参数表和 JSON 示例 |
references/AI复核流程.md | 执行 AI 复核时——按月分批、subagent 提示词、三个判断层次 |