nigo81/nigo-skills

audit-report-checker

检查审计报告(财务报表 + 附注),发现勾稽错误、加总错误、文本格式问题。用于"检查审计报告/勾稽验证/报表核对/报告核查/数字核对/加总核对/报表平衡/审计报告复核/报告校对"。即使用户只说"帮我检查这份审计报告""看看这个报告有没有错""核对下报表数字"也应触发。支持分体式(报告+附注分文件)与合体式(单文件)报告,支持 Word/PDF/扫描件/图片报表,覆盖 50-150 页合体大报告,输出 7 sheet Excel + Markdown 复核报告。算术 100% 走代码计算,AI 负责语义定位与结构判断。

First seen Jul 14, 2026

Installation

$ npx skills add nigo81/nigo-skills --skill audit-report-checker

Summary

检查审计报告(财务报表 + 附注),发现勾稽错误、加总错误、文本格式问题。用于"检查审计报告/勾稽验证/报表核对/报告核查/数字核对/加总核对/报表平衡/审计报告复核/报告校对"。即使用户只说"帮我检查这份审计报告""看看这个报告有没有错""核对下报表数字"也应触发。支持分体式(报告+附注分文件)与合体式(单文件)报告…

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from nigo81/nigo-skills · top by installs.

npx skills add nigo81/nigo-skills

Browse all from nigo81/nigo-skills

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 123
License MIT
Default branch main
Open issues 1
Status Active

Skill metadata

Parsed from SKILL.md frontmatter.

Version1.0.0
LicenseMIT
More metadata
author
nigo
version
1.0.0

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 32,576 B
  • docs SUMMARY.md 663 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 10 installs

SKILL.md

审计报告核查

作者:nigo(公众号:逆行的狗)
版本:1.0.0

检查审计报告(财务报表 + 附注),发现勾稽错误、加总错误、文本格式问题。Claude 是主控——负责语义理解(定位报表、理解附注章节、判断列含义、标注表格结构),代码负责确定性算术(求和、核对、reconcile)。两者分工,消除旧工具"硬拆分 + 关键词匹配"导致的系统性误报。

最重要的一条原则:算术绝不手算

LLM 直接做数值加减会算错,且无法复现——审计核查中算错等于致命。所有数值计算,哪怕只是三个数相加,都调用 scripts/calculator.py。AI 只决定"传哪些数""哪个等于哪个",代码算出结果。

正确做法:

# 从报表/附注提取出数字后,调 calculator 验算
python3 scripts/calculator.py check "113,157,711.68" "113,157,711.68"   # 核对相等
python3 scripts/calculator.py sum "1,234.56 5,678.90 100.00"            # 求和
python3 scripts/calculator.py reconcile "100" "50" "30" "120"           # 期初+增-减=期末

错误做法:

# 心算"流动资产合计 = 货币资金 + 应收账款 + ..."  ← 会算错,且别人无法核验

calculator 支持千分位逗号、括号负数、横线(=0)、全角字符、万元单位,容差默认 0.01,用 round(diff, 6) 避免浮点边界误判。这是上一版已验证有效的原则,保留。


工作流

Step 0 — 选检查深度(scope)

开始前用 question 工具问用户两件事:检查深度(单选)+ 检查类型(多选,可空则按深度档执行)。

三档深度

档位 覆盖范围 耗时 适用
快速检查 四表间勾稽 + 格式(公司名/页码/页眉) 几分钟 初筛、只关心报表平衡
标准检查(默认) 快速 + 表内横加竖加 + 高频表注勾稽 + 文本(错别字/病句) 十几分钟 日常复核,覆盖常见错误
深度检查 标准 + 附注所有变动表 reconcile + 跨科目勾稽 + AI 结构标注全表 半小时以上,token 消耗大 重大报告、终稿复核

用户不选就默认标准。选深度检查时先提示 token 消耗较大让用户确认(128 页报告深度检查可能消耗很多)。

检查类型多选:勾稽 / 横加竖加 / 表注 / 文本 / 格式。用户可自由组合覆盖深度档(多选全部 ≈ 深度检查)。

为什么要分档:审计师多数时候只需快速验证勾稽,无差别深度检查既慢又费 token。scope 让用户知情选择,按需触发。

附注-only 自动调整:若识别到文档只有附注、无四表(如盛屯/博达新材的纯附注 Word),自动跳过报表间/表注勾稽,聚焦附注内勾稽 + 横加竖加 + 文本格式,并告知用户调整了范围。详见后文"附注-only"。

DeepSeek 模型选择(启用 AI 时执行):标准/深度检查默认启用 DeepSeek 加速(文本错别字、附注表结构标注、warning 二次复核)。涉及 AI 时,问完深度+类型后先选模型,避免 reasoning 模型拖垮批处理:

  1. 检查 key 有效性:python3 scripts/ai_worker.py --test-check-key(读 ~/.deepseek/config.json;无 key 则全程走 --no-ai 纯代码)
  2. 查可用模型:python3 scripts/ai_worker.py --test-list-models(DeepSeek 503 服务繁忙时可能查不到,可跳过用默认)
  3. question 让用户选模型,默认推荐 flash 类模型(非 reasoning,单请求延迟低,适合大批量并发;reasoning 类如 v4-flash 单请求 25s+ 会拖垮批处理)。用户无偏好直接用 flash。
  4. 选定后 run_check 加 --model <选定> 传入,或写入 ~/.deepseek/config.json 的 model 字段持久化。

降级原则:DeepSeek API 服务繁忙(503)/限流属外部问题。多次失败时降级 --no-ai(纯代码 L1+scan+词库),文本/标注/warning 复核由 Claude 终审兜底(Step 5 本就要求 Claude 复核,不完全依赖 API)。

Step 1 — 解析文档

python3 scripts/parse_report.py "<文件或目录>" -o <输出目录>

脚本四路自动分流,按文档类型和内容特征选最佳提取路径:

  • PDF 文本型(首页文本 > 50 字)→ pdfplumber,数字 100% 精确
  • PDF 扫描型 → mineru 云端 API(extract --model vlm),数字需人工复核
  • Word 文本表格为主 → python-docx,精确
  • Word 图片报表(inline_shapes 偏多)→ mineru 云端 API

Word/PDF 双路(重要):实际场景大部分是 Word 报告。parse 对同 basename 的 .docx/.pdf 优先 .docx(去重,Word 表格精确无断字);无 Word 才用 PDF。两路分开处理:

  • Word 路(.docx):python-docx 提取 table 对象→markdown(实测金星90/博达87表全成功)+ 段落文本;章节定位(附注五-N 科目,Word 无固定页码);table 自动归属 chapter(Heading1 大章节 + Heading2/短文本明细)。伪表格(非 table 对象的制表位排版,少数)AI 兜底。
  • PDF 路(.pdf):pdfplumber + 页码定位(page=N,超链接可点击)。

定位差异:Word 用章节("附注五-3 应收账款"),PDF 用页码("第N页")。result 的 chapter(Word)/ page(PDF)字段区分,export 自动适配。

输出两个文件:

  • report.md:全文 markdown,每段用 <!-- SOURCE file="..." page=N method=... --> 标注来源页码和提取路径
  • extracted_tables.json:原始二维表格(headers + rows),不做列映射、不做报表分类、不做续表合并

解析层只输出原始数据,报表定位、附注识别、列含义判断全部由 Claude 在后续步骤用语义完成。这是消除旧工具"拆分匹配错误"的核心——parse 层不越界做本该人做的事。提取策略原理见 references/extraction.md

mineru 是云端 API,数据会上传 mineru.net。审计报告含敏感财务数据,首次走 mineru 路径前要告知用户并获得知情同意。详见 references/mineru_usage.md

Step 2 — 理解文档结构(语义,不靠关键词)

report.md,理解整体结构:

  • 编制单位、会计期间
  • 报告类型:合并报告(含合并 + 母公司共 8 张表)还是单体(4 张)?通过看是否有"母公司"字样和报表数量判断,不靠硬编码关键词字典
  • 四张报表的位置(合并资产负债表/利润表/现金流量表/所有者权益变动表,及母公司版本)及其页码范围
  • 合并报告同名报表会重复:合并报告里"资产负债表""所有者权益变动表"等标题通常出现两次——第一次是合并口径、第二次是母公司口径,表头往往都不带"合并"/"母公司"前缀,靠出现顺序(先合并后母公司)和编制单位行区分。两套都要提取,漏掉母公司 4 张表会让母公司层面的勾稽完全缺失。判断方法:同名报表在 report.md 中出现 ≥2 次 → 合并报告,按顺序分别归为合并/母公司。
  • 附注章节结构——每章讲哪个科目(如"附注三、货币资金"讲货币资金)
  • 是否附注-only(无四表)→ 走附注-only 分支
  • 图片报表页检测(重要):读 report.md 时留意是否有连续多页文本为空白。审计报告中四表(资产负债表等)常被做成图片嵌入 PDF,pdfplumber 对这些页提取为空白(实测盛屯 page 7-16 共10页空白=四表全是图片)。若 parse_report 的 report.md 已标注 <!-- WARNING: ... 为图片/扫描页 -->,直接据此处理;否则自己扫描各页文本量。发现四表区域空白时:

1. 对该页范围用 mineru 云端 OCR 重新提取:mineru-open-api extract "<报告.pdf>" --pages 7-16 -o <目录> --model vlm --language ch(需先 mineru-open-api auth 配 token,见 references/mineru_usage.md,含数据上传云端隐私提示) 2. OCR 结果(md)合并回 statements 提取 3. mineru 不可用时,在报告中明确标注"四表为图片,pdfplumber 未能提取,本次未执行报表间勾稽,建议人工复核或配 mineru token 重跑"——不要假装做了

识别同义科目变体靠语义理解,不做映射表:股东权益 = 所有者权益、股本 = 实收资本、股东权益变动表 = 所有者权益变动表。为什么用语义而不是关键词字典:每遇到一个新报告格式就要加规则,关键词爆炸不可持续;Claude 一次调用就能理解,且能处理变体。

生成 notemap.json(表注勾稽的定位基石,Step 2 必做):理解附注结构时,一次性生成「科目→附注明细表」精确映射 notemap.json(写入 parse 输出目录)。这是三层分工架构的定位层——Claude 语义定位(准、只做一次、低 token),取数/算术交给代码(DeepSeek locate + calculator)。

为什么定位必须 Claude 做:旧工具靠正则匹配标题 + 页码邻近定位,在①标题格式多样 ②同页多科目 ③续表跨页 上系统性失败(详见 旧报告检查工具_定位研究.md 的 4 大根因)。Claude 一次语义理解就能准确定位到表级别。

格式({科目: {...}}):

{"货币资金": {"table_ids": [220], "pages": [16], "field": "期末余额", "formula": "期末余额", "note": "报表数=附注期末余额"},
 "应收账款": {"table_ids": [221,222], "pages": [18,19], "field": "账面价值", "formula": "账面余额-坏账准备=账面价值", "note": "报表数=附注账面价值"}}
  • table_ids:该科目附注明细涉及的表 id(附注文件范围,绝不混入资产负债表/利润表等报表表,否则表注勾稽会"自己比自己")
  • field:报表数等于附注哪个字段(直接取,如"账面价值"/"期末余额")
  • formula:取数口径公式(field 取不到时按此运算,如"账面余额-坏账准备")
  • 定位方法(表 name 常为空,靠多重交叉):科目章节 page 区间 + 该区间内表 page + headers 内容 + 章节实际文字
  • 最低覆盖:标准检查至少 8 科目(货币资金/应收账款/应收票据/预付款项/存货/固定资产/营业收入/应付账款),深度检查覆盖全部报表列示科目。subjectsindex.json(scan 生成的科目→候选表粗索引)可作为定位参考/校验,但精确定位以 Claude 生成的 notemap 为准

生成 manifest.json(四表提取的结构契约,Step 2 必做):理解四表在文件里的位置/列布局后,写成 manifest.json(写入 parse 输出目录)。这是三层分工架构的结构契约层——Claude 语义识别结构(准、只做一次),抽数交给 apply_manifest 纯机械执行(零猜测、新格式改 JSON 不改代码)。

自动生成优先runcheck --auto-manifest --auto-note-map 时 DeepSeek 并发自动生成 manifest.json 和 notemap.json(看 sheet 表头/附注表内容判断列布局/科目归属),代码做结构性校验 + 回原文核对降错。自动生成失败或校验大量不过→回退 Claude 手写(有模板库)。

为什么用 manifest 不靠代码猜:天邑列布局(B/E/F) vs Macko(A/C/D) 不同、Macko 母公司 BS 主表/续表列布局不同、续表项目名带空格("负 债 合 计")、非标准名("股东权益合计")——每遇到一个新格式,代码猜列/猜 sheet/硬编码 ALIAS 都会崩。manifest 把这些差异声明在 JSON 里,apply_manifest 按声明抽数。

格式(详见 references/manifest_template.md,含 4 份报告的 manifest 样例):

{
  "report_format": "merged_docx | split_xlsx | split_docx | split_pdf",
  "company": "...", "period": "...",
  "files": {"文件名": {"role": "statements|notes|opinion|cover", "loader": "xlsx|docx|pdf|doc"}},
  "statements_map": {
    "合并资产负债表": {
      "source": "文件名", "loader": "xlsx|docx|pdf",
      "sheets": ["sheet名"], "source_table": "表名(docx/pdf按此在extracted_tables定位)",
      "kind": "linear | matrix",
      "item_col": 0, "current_col": 2, "prior_col": 3,
      "field_aliases": {"股东权益合计": "所有者权益合计"},
      "merge_into": null
    }
  }
}
  • files.role+loader:分体式文件角色(报表/附注/正文/封面)+ 读取器(xlsx=openpyxl / docx,pdf=读extracted_tables / doc=textutil转)
  • itemcol/currentcol/prior_col:列布局(看 dump 确定,不猜)
  • sheets+mergeinto:BS 续表/分段合并(同表不同列布局时分两段,mergeinto 合并)
  • sourcetable:docx/pdf 时按表名/内容在 extractedtables 定位四表(表 name 常为空,靠内容匹配"资产总计"+"流动资产合计"=BS)
  • field_aliases:项目名标准化("股东权益合计"→"所有者权益合计")
  • kind: linear|matrix:权益变动表矩阵结构(sheetsmain/sheetsprior + value_col)

生成方法:Claude 看每个报表文件的 dump(xlsx 的 sheet 名+表头+前3行 / docx 的 extractedtables 四表名+列)后手写 manifest(3-5 分钟)。Macko/天邑/巨东/清研的 manifest 已在各自 parseoutput 目录,可作为模板。

Step 3 — 提取 statements.json(apply_manifest 机械执行)

用 Step 2 的 manifest.json,调 apply_manifest 纯机械抽数:

python3 scripts/apply_manifest.py <parse输出目录>/manifest.json -o statements.json

applymanifest 读 manifest 的 statementsmap,按声明的 source+loader(xlsx 读 sheet / docx,pdf 读 extractedtables 按 sourcetable 定位)+ itemcol/currentcol/priorcol 抽数,套 fieldaliases 标准化项目名,处理 merge_into 分段合并,产出 statements.json。零猜测、零改代码——所有格式差异已在 manifest 声明。

产物格式(与 calculator_rules 匹配):

{
  "合并资产负债表": {"流动资产合计": {"current": "113,157,711.68", "prior": "..."}, "资产总计": {"current": "...", "prior": "..."}},
  "合并利润表": {...},
  "合并现金流量表": {...},
  "合并所有者权益变动表": {...},
  "母公司资产负债表": {...}, ...
}

字段名必须精确calculator_rules 按字段名匹配(如 "期末现金及现金等价物余额"),字段名不一致会导致 L1 检查报"缺少必要项目"。提取前先查必需字段清单:

python3 scripts/calculator_rules.py

报表原文项目名与清单不一致时,在 manifest 的 field_aliases 里声明映射(如"股东权益合计"→"所有者权益合计"、"负债和股东权益总计"→"负债和所有者权益总计"),不要改代码。

Step 4 — 代码侧检查(含 scan 代码验算)

python3 scripts/run_check.py <parse输出目录> \
  --statements <parse输出目录>/statements.json \
  --note-map <parse输出目录>/note_map.json \
  --scope <scope> --scan --use-ai -o <parse输出目录>/results.json

说明:

  • --statements--note-map 支持相对路径,脚本会优先相对于 <parse输出目录> 解析;如果找不到会给出明确报错。
  • 建议命令中写绝对路径或 <parse输出目录> 前缀,避免不同工作目录下的路径歧义。

可选参数(用于提速/跳过已跑过的慢步骤):

  • --max-workers N:DeepSeek 并发数(默认 60)
  • --skip-annotation:跳过 AI 结构标注(复用本地 annotations_cache.json
  • --skip-text-ai:跳过 AI 文本错别字/病句检查
  • --skip-ai-review:跳过 DeepSeek 对 warning/error 的预复核(默认执行,最终终审仍由 Claude Step5 完成)

脚本执行确定性检查(不依赖 LLM),--scan 必加——它让代码分担横加竖加的粗活,大幅减轻你在 Step 5 的负担:

--use-ai 说明(默认启用)

  • 默认 --use-ai:启用 DeepSeek 并发(4 场景:①文本错别字 ②附注表结构标注 ③表注勾稽+附注reconcile(按 Step2 的 notemap 定位→locate 取数→calculator 比较)④warning 预复核;均批量化 + 并发默认 60)。需 DeepSeek API key + 选定 flash 类模型(见 Step 0)。文本检查(错别字/病句)和表注勾稽取数只有 --use-ai 能自动执行,纯代码扫描覆盖不到。--note-map 不传时默认读 <inputdir>/note_map.json(Step2 生成)。
  • 可选 --no-ai:纯代码扫描(无文本 AI 检查),DeepSeek 服务繁忙/无 key 时降级用。此时文本检查只走内置词库,结构标注/warning 复核由 Claude 在 Step 5 手动完成。

- 代码自动降级点:runcheck.py 在 AI 结构标注(runcheck.py:2368-2400)、表注勾稽(runcheck.py:2533-2562)、文本错别字(runcheck.py:2473-2510)、warning 二次复核(run_check.py:2640-2670)四个场景均捕获 API/取数异常,失败时跳过该场景并在 results.json 中生成降级提示,不会中断主流程。

  • 模型选择--model <name> 传入;不传则用 ~/.deepseek/config.json 的 model 字段。优先 flash 类(非 reasoning),详见 Step 0。

执行的检查(按 scope):

  • L1 报表间勾稽:调 calculator_rules.py 四函数,验资产=负债+权益等恒等式
  • 页码连续性公司名一致性金额单位错别字词库粗筛
  • scan 代码验算--scan):

- 竖加验算:含"合计/小计"行的附注表,代码 sum 明细=合计(排除所有合计/小计/总计行和"其中:"子项)。金星 301 张表能代码验算 64 张,通过的直接记 info(你不用再做这些表) - 横加验算:列名匹配已知模式(账面余额-坏账准备=账面价值、期初+增加-减少=期末、原价-折旧-减值=价值) - 通过记 info(减负),不平记 warning(可能特殊表结构,需你在 Step 5 用 AI 结构标注复核,区分真错 vs 特殊结构) - 额外输出 candidates.json(代码无法判断的变动表/复杂横加表清单,留给你在 Step 5 做 AI 结构标注)和 subjectsindex.json(41 科目→附注候选表粗索引,供你在 Step 2 生成 notemap.json 时参考/校验,精确定位以 Claude 生成的 note_map 为准)

输出 results.json,每条结果含:checktype / rulename / severity / passed / description / expected / actual / difference / sourcelocation / targetlocation / evidence / page / context / source_file

定位字段(审计师核对原文用,必填)

  • page:页码(纯数字,如 45)。从 report.md 的 <!-- SOURCE ... page=N --> 注释或附注章节位置获取。
  • context:原文摘录(约50字,被检查的那行原文片段),审计师在 Excel 里直接看到原文,不用翻 PDF。
  • sourcefile:由 runcheck 自动回填原始报告路径,你写语义检查结果时无需手动填。
  • rule_name:用有意义的科目名(如 货币资金年末竖加存货-原材料横加),不要带 id=N 前缀(id 是解析时的表格序号,对审计师无意义)。

Step 5 — 语义检查(必须执行,skill 的核心价值)

run_check.py 只是代码侧的确定性粗筛(L1 报表间恒等式 + 页码/单位/错别字词库)。以下四类语义检查是本 skill 区别于普通脚本的核心能力,必须执行,不可跳过——跳过等于只做了 20% 的工作。

Agent 终审输出习惯(D2.4)

  • Agent 在 Step 5 回原文核对时,不必把每一条思考过程都输出给用户。可在内部快速按表分组、批量判断、直接修正 results.json
  • 修正完成后直接执行 Step 6 导出,最后一次性告知用户报告保存路径和核心结论(几个错误、几个存疑、分别是什么)。仅在需要用户决策或确认存疑时才展开细节。

⚠️ Claude 终审强制(D2.1 核心,最重要)

  • 所有 error/warning 必须经 Claude 整体语义复核才能输出
  • 终审必须回原文核对,不能只看 results.json 的字段

- 横加竖加 warning:读 extractedtables.json 里该表的完整 headers+rows(用 sourcelocation 的表格ID定位),整体看这张表判断:①这列是不是百分比列(不该加金额)②这几行是不是"其中"子项(重复加)③是不是两期混算(明细和≈合计的整数倍)④明细是否真漏加/多加(真错)。禁止只看 expected/actual/ratio 数字猜——ratio 相同的可能是真错也可能是跨列,只有看表原文才能区分。 - 表注勾稽 warning:按 notemap 的 tableids 去 extractedtables 看那张表的实际内容,确认 tableid 指对了附注表(不是别的科目表/风险汇总表/坏账表)。subjectsindex 的粗匹配常指错表,notemap 必须回原文核对定位。取数差异时看附注表合计行 vs 报表值。 - 错别字 error:grep report.md + 解压 docx XML 全文搜索该词,确认原文确实存在(AI 会编造原文没有的词,如"先讲先出"幻觉)。不存在→删除(幻觉)。

  • 复核规则:

- 确认真错(回原文确认加总不平/勾稽对不上/错别字确实存在)→ 保留 error - 特殊结构(百分比列、子项重复、减项、不同口径、note_map 指错表)→ 降为存疑或删除 - 误报(AI幻觉、PDF空格断词、DeepSeek过度报告)→ 删除不显示

  • evidence 必须含"Agent复核:确认/存疑/删除 + 回原文核对依据",无标记视为未复核必须补做

表注勾稽(checktype="表注"):runcheck --use-ai 已自动执行(三层分工:Step2 的 note_map 定位 → DeepSeek locate 取数 → calculator 比较"报表数 vs 附注数")。你只需做 Claude 终审 + 兜底:

  1. 抽查 notemap 定位准确性:随机几个科目对照附注原文,确认 tableids 指对了附注明细表(不是报表行)
  2. 终审 results.json 里 check_type=表注 的 warning(报表数≠附注数 / 取数失败),区分:①真错(数值确实对不上)②口径差异(附注按账龄/类别拆分,口径不同属正常)③locate 取数失败(→手动补)。按"确认真错/存疑/删除"复核,evidence 加"Agent复核"标记
  3. --no-ai 或取数失败的科目降级为 Claude 手动:按 note_map 定位去附注原文提数,调 calculator check 比较(算术绝不手算,全走 calculator)
  • 最低工作量(硬性门槛):note_map 覆盖的科目每科目一条结果(标准≥8、深度全覆盖报表列示科目)。附注-only 无四表→跳过,记一条 info 说明原因

横加竖加(check_type="横加"/"竖加"):Step 4 的 scan 已对含合计行的表做了代码验算,你在这里做 scan 做不了的部分:

按表分组复核(效率关键,禁止逐条):同一张表的多个竖加/横加 warning(如某账龄表4列各报1条=4条warning)合并成一次复核——读该表完整原文一次,批量判断该表所有 warning。用 source_location(表格ID)分组:

# 按表分组 warning,一张表一次复核
from collections import defaultdict
by_table = defaultdict(list)
for w in warnings: by_table[w.get("source_location")].append(w)
for table_loc, table_warns in by_table.items():
    # 读这张表的完整 headers+rows(一次),批量判断该表所有 warning

判断标准(必须给明确结论,禁止骑墙存疑)

  • 删除(确认误报):百分比列误参与竖加 / "其中"子项重复 / 两期混算(明细和≈合计整数倍)/ 跨列对比(数量级悬殊)/ note_map 指错表 / 合计行空值
  • 确认错误(真错):calculator 确认明细和≠合计,且排除了上述结构原因(同一张表同一列,明细确实漏加/多加)
  • 通过(确认无误):差异<0.5%且能判断是四舍五入(calculator 确认差几分钱)
  • 存疑(仅当回原文仍无法判断):附注口径与报表口径确实不同(如附注按账龄拆分、报表是净值),需审计师判断口径——这是唯一允许存疑的情况。看不懂表结构不是存疑理由,要继续读到懂或标删除。

为什么必须明确结论:审计师拿到报告要能直接行动(改/不改/人工核),"存疑"过多等于没核查。DeepSeek 会误报,但你回原文后应能判断,判断不了说明原文读得不够。

附注内变动表 reconcile(check_type="附注内"):调 calculator reconcile 验证期初 + 增加 − 减少 = 期末(固定资产、应付职工薪酬、应交税费等,见 rules.md C1)。凡识别为四列变动结构的表都做。

文本复核(check_type="文本"):通读 report.md,找错别字、病句、前后矛盾、数据口径不一致。这是 LLM 擅长而脚本词库只是粗筛的部分。

执行完以上四类才能进 Step 6。若某类确实无目标(如附注-only 文档无四表→无表注勾稽对象),在 results 里记一条 info 说明"未执行表注勾稽(原因:附注-only 无四表)",不要静默跳过——让用户知道哪些检查做了、哪些没做、为什么。

每条语义检查结果必须填定位信息(审计师要回原文核对):从 report.md 找到被检查内容的 <!-- SOURCE page=N --> 标记,填入 page;把被检查的那行原文摘录(约50字)填入 context。这样审计师在 Excel 里点页码能打开原报告、看原文摘录能直接核对,不用逐页翻 PDF。

把补充结果按统一格式追加到 results.json(字段同 Step 4)。

Step 6 — 输出报告

python3 scripts/export_report.py results.json -o <输出目录>

生成两个文件:

  • 7 sheet Excel:按审计师友好分类,通过项不进详细 sheet(只在摘要统计):

- 摘要:检查范围 / 通过 / 问题 / 存疑统计 + 按类别统计 + 严重程度说明 - 报表内勾稽:资产负债表平衡、利润表推导、现金流量表、权益变动表(L1恒等式 + 表内竖加) - 表注勾稽:报表数 vs 附注数(应收账款=账面余额-坏账准备等41科目) - 附注内勾稽:附注变动表 reconcile(期初+增加-减少=期末)、跨附注表关系 - 横加竖加:附注明细表的横向纵向加总(账面余额-坏账=账面价值、明细之和=合计) - 文本格式:错别字、页眉、页码、公司名、单位、编号 - 检查项:所有检查项列表(包括通过项)

  • Markdown 复核报告:按问题/存疑分章,给人读

Severity 二元化

  • 问题:确认错误需修改(Agent复核确认)
  • 存疑:可疑需人工核实(Agent复核存疑)
  • 通过:通过项不在详细 sheet 显示,仅在摘要统计

输出只读不改源报告(audit-only)。

Step 7 — 解读结果

向用户解释发现的问题,按严重程度说明,保持简洁

  • 错误(红):calculator 算出确定差异,如资产 ≠ 负债 + 权益。给出应为值、实际值、差异、页码定位、修复建议。
  • 异常(黄):AI + 代码双验证不一致,如报表数 vs 附注数对不上。提示人工复核。
  • 提示(蓝):AI 发现可疑但无法量化,如营业外收入为负。避免漏报但不制造噪音。

对标记"异常"的项做二次判断,排除规则误触(如附注口径不同导致的正常差异)后再呈现给用户。

输出习惯:完成 Step 5 终审和 Step 6 导出后,直接告诉用户报告保存路径(Excel + Markdown),并给出核心统计(问题数/存疑数/主要问题)。不必逐项展开,除非用户要求。


关键指引

细节在各 reference 文件,这里只给骨架和读取时机。

定位四表:看编制单位、会计期间、项目结构,语义识别合并 + 母公司 8 张或单体 4 张。识别变体(股东权益 = 所有者权益)。读 references/rules.md 了解科目覆盖范围。

附注语义索引:理解"附注三、货币资金"讲货币资金、"(三)应收账款"讲应收账款,不穷举正则匹配标题。按科目索引后按需取数,不全量加载。

列含义判断:看表头和内容判断期末/期初/附注编号/项目名列,不硬编码列数。3 列、4 列、8 列左右两栏都能处理。

AI 结构标注:读 references/structure_annotation.md,用里面的 prompt 模板标注行 type/op、列 type、横加关系,批量标注提效。标注失败降级为仅合计行验证。

附注-only:无四表 → 跳过报表间/表注勾稽,做附注内勾稽 + 横加竖加 + 文本格式。报告中明确标注"本文档为附注-only,未执行报表间/表注勾稽"。


算术纪律 + 大报告分批

50-150 页合体大报告(如盛屯 128 页)容易上下文爆炸。分批策略:

  1. 先读四表(通常在报告前部,页数少)→ 执行报表间/表内检查
  2. 按科目逐个去附注找明细(用语义索引定位,不全量加载附注)
  3. 分批处理避免上下文爆炸

算术纪律全程不变:任何数值加减都调 calculator,AI 只决定传哪些数。


跨平台依赖安装 + mineru 隐私

Python 依赖(mac/Windows 通用):

pip install pdfplumber python-docx openpyxl openai

mineru(仅扫描件/图片报表才需要):

npm install -g mineru-open-api
mineru-open-api auth   # 配置免费 token

脚本纯 Python 跨平台(pathlib、无平台特定命令),mac/Windows 双平台、中文路径、含空格路径均支持。

mineru 数据隐私:审计报告含敏感财务数据,上传云端前必须告知用户并获得知情同意。上市公司公开报告无隐私问题;未公开/保密报告建议优先用文本路径(pdfplumber/python-docx,数据不出本机)。详见 references/mineru_usage.md


references 索引

文件 何时读
references/rules.md 做表注勾稽时查 41 科目对照表;做变动表时查 reconcile 规则;用户问覆盖哪些科目时
references/structure_annotation.md 做横加竖加时用 prompt 模板标注附注表格;标注失败查降级策略;批量标注查提效建议
references/extraction.md 看到 report.md 中 mineru 来源标记时判断数字置信度;用户问为什么分四路/为什么文本优先时
references/mineru_usage.md 首次遇扫描件/图片报表需引导安装配置 mineru;mineru 调用失败排查;用户问数据安全时
references/user_rules.md 每次检查时加载用户自定义规则并执行;用户描述新需求时写入

用户自定义规则

references/user_rules.md。用户可在对话中描述特殊检查需求(如"我们事务所要求核对关联方披露完整性""金融行业客户重点查贷款五级分类"),你理解后整理成"自然语言描述 + 适用场景 + 期望结果"格式写入该文件的"## 我的规则"章节。规则跟着 skill 走(不绑定具体报告目录),所有报告共用。检查时一并执行这些规则。规则失效或需修改时,用户在对话里说即可,你更新文件。