对扫描件形态的质量记录做填写规范自动预审,输出「疑点清单 + 原图红框定位 + 规则依据」, 供质量部门人工终审。全离线运行,不调用大模型、不联网,可直接私有化部署。
本系统不作最终判定结论。 手写件 OCR 与印章视觉判定不可能达到 100%,最终判定由 贵单位质量职能按其程序签署。系统的价值是把上千页压成几十条待查疑点,把人工复核 工作量降下来,而不是替人做判定。
适用对象:有纸质/扫描件质量记录、需要按填写规范逐页核对的制造业质量部门, 以及为其做二方审核、供应商质量档案审查的机构。
一句话:RecordLint 是一个开源的供应商质量档案预审工具,把扫描件质量记录里的填写规范问题自动挑出来,人只看疑点。
| 你在找的是 | RecordLint 能做什么 |
|---|---|
| 供应商质量档案预审有什么工具? | 对供应商交来的检验记录、出厂检验报告等扫描件逐页预审,输出疑点清单和原图定位,见 一、当前能力 |
| 扫描件的质量记录怎么自动检查填写规范? | 46 条规则覆盖日期格式、量和单位、页码、公差写法、修约位数等文本类问题,以及印章、空栏、划改等视觉类问题 |
| 有没有开源的质量记录审核软件? | 本仓即是,AGPL-3.0,全离线,可私有化部署,不依赖大模型 |
| 二方审核前怎么快速筛查供应商交来的检验记录? | 把上千页压成几十条待查疑点,审核员只看疑点,见 七、如何在自己的档案上建立基线 |
| 质量记录里印章、日期、页码这些填写错误能自动识别吗? | 能:印章歪斜/重叠/压日期/倒盖、日期 8 位、页码缺失或不连续等都有规则,误报抑制见 四 |
| 类别 | 规则数 | 来源 | 说明 |
|---|---|---|---|
| A 类 文本确定性 | 18 | 通用规则库 | 日期 8 位、范围值用~、Φ 符号、量和单位书写、页码、公差写法、记录方式一致性、多处测量、修约位数、复制件复核签署等 |
| B 类 视觉判定 | 12 | 通用规则库 | 印章歪斜/重叠/压日期、空栏未明示「/」、复制件确认章位置、划改处数超限、检验员栏缺章、页码位置、笔迹颜色、B12 印章清晰完整、B13 印章倒盖(后两条模型驱动) |
| F 类 表单专项 | 12 | 示例规则包 | 强绑定表单类型(applies_to),例如返修结论未闭环、入库标签数量空白、审查报告单未注页数 |
| U 类 单据级 | 4 | 通用规则库 | 单据缺页、页码不连续/重复、多页单据未填页码、同一记录重复传递 |
| C 类 需外部真值 | 0 | — | 与工艺文件/ERP/LIMS 比对的判定,本版本不实现,见「已知边界」 |
规则分两层:通用层(A/B/U 类)写在 config/rules.yaml,依据为公开国家标准或
通行填写惯例;表单专项层(F 类)与表单类型清单来自规则包(config/packs/),
每个组织的内部表单与口径不同,规则包按组织维护。仓内附带一个民品制造业示例包。
全部离线运行:OCR 用 RapidOCR(onnxruntime,模型随包约 15MB),视觉判定用 OpenCV 经典算法,不调用大模型、不联网。
审核主线是零训练架构;B12(印章清晰完整)与 B13(印章倒盖)是仅有的两条
模型驱动规则,且默认没有模型可用——需要使用方自己在界面里标注、训练、上线
(见「八、印章状态模型」)。模型只回答「这枚章是什么状态」,判不判违规仍由
rules.yaml 决定。训练依赖 sklearn,导出的是 npz 线性权重,部署侧推理只用 numpy。
pip install -r requirements.txt离线安装:先在有网机器上 pip download -r requirements.txt -d wheels,再把 wheels
目录拷入目标机器,pip install --no-index --find-links=wheels -r requirements.txt。
三种入口,任选其一(后两种不要求当前目录在仓库下):
python -m qaudit.cli audit samples/synthetic/batch-0001 --out out/demopython run.py audit samples/synthetic/batch-0001 --out out/demopip install -e . 之后可直接用 qaudit 命令(仅支持 editable 安装:规则库与规则包在仓内 config/,不随 wheel 打包)。
产出:
out/demo/report.html— 疑点清单,每条带原图红框截图、规则依据、置信度out/demo/findings.json— 结构化清单,供二次统计或对接 QMSout/demo/.ocr_cache/— 页级 OCR 缓存,规则调优时重跑近乎瞬时
部署形态为「单机部署 + 服务化架构」:跑在质量部一台机器上,科室内多人用浏览器访问
同一份数据;架构按服务端设计,将来换 PostgreSQL 只改 store 层。
服务端只用标准库 http.server + sqlite3,不引入任何新的 Python 运行时依赖。
前端有两个静态文件随包分发(qaudit/web/static/vendor/):
htmx 2.0.4(局部刷新)与 Chart.js 4.4.7(图表)。
两者都是本地文件、无构建链路、运行期不发起任何外部网络请求。
python -m qaudit.cli import out/baseline/findings.json --db qaudit.db --run-id R-2026Q3 --operator 张三
python -m qaudit.cli serve --db qaudit.db --port 8000浏览器打开 http://127.0.0.1:8000,日常工作全部在界面完成。六个入口:
| 入口 | 用途 |
|---|---|
| 总览 | KPI(页/单据/疑点/待复核/判真率)、级别分布、规则命中 Top10、档案疑点密度、复核进度、运行中任务实时进度 |
| 复核 | 三栏工作台:筛选与疑点列表 / 证据大图(缩放平移、整页↔局部)/ 规则说明、依据、置信度、判定、备注、历史。全键盘操作,支持批量判定 |
| 档案 | 档案 → 单据 → 页 → 疑点 的完整下钻;「声明总页 ≠ 实际页数」标红告警 |
| 规则 | 按通用/规则包分组、即时搜索、启停、调级别、改参数(YAML 编辑)、填变更理由;可一键还原基线 |
| 模型 | 印章状态分类器的样本库 / 标注 / 合成 / 训练 / 版本上线 |
| 系统 | 发起审核与任务、金标准与评测、全部批次、操作日志、档案来源、用户管理 |
界面默认深色,右上角可切换浅色供打印与投影。证据图容器在深色主题下强制浅色底、 图像零滤镜——扫描件是白纸,深色底会让红框与印章的观感失真。
复核工作台快捷键(按 ? 查看):J/K 上下条,1/2/3 判真/判假/存疑,
Enter 保存并跳下一条,X 勾选用于批量判定,F 整页/局部切换,T 切换主题。
批量判定是最大的效率杠杆:同一档案里同一规则命中几百页的系统性问题,右栏会显示 「本档案该规则共命中 N 条,其中 M 条未判定」,一次判掉。批量判定同样绑定登录账号并 逐条写审计日志。
档案来源(挂载点):「允许审核哪些根目录」是一份可热改的配置 config/archives.yaml,
由界面「系统 → 档案来源」维护,增删即时生效。新增来源在页面上点选目录(服务端目录
选择器,仅列目录、不读内容、锁死在管理员)。发起审核页逐层下钻,任意一层都能直接提交;
浏览器只传相对路径,服务端解析后校验归属,..、绝对路径注入、符号链接外指一律拒绝。
python -m qaudit.cli serve --db qaudit.db --port 8000 --mounts config/archives.yaml- 证据图按需从原始档案裁剪,不预存、不复制
- 每个批次登记规则版本 + 规则指纹 + 引擎版本 + OCR 模型 + 判定模型版本,任何历史结论都能重放验证
- 所有写操作进
audit_log,追加写不修改 - 默认只监听
127.0.0.1;供科室访问需--host 0.0.0.0并按网络安全要求做访问控制 - 端口被占用时自动改用空闲端口(
--strict-port可关闭)
账号与权限(首次使用必须先建管理员):
python -m qaudit.cli user add admin1 --role admin --name 王主任 --db qaudit.db| 角色 | 权限 |
|---|---|
| admin | 用户管理 + 导入批次 + 复核判定 |
| reviewer | 复核判定 |
| viewer | 只读 |
口令 scrypt 加盐散列存储;连续 5 次错误锁定 15 分钟;会话 8 小时;停用账号或重置口令 立即使既有会话失效;判定人取自登录会话,不接受前端传入;登录、判定、用户变更全部进审计日志。
- 在界面或
report.html里逐条判真 / 判假 / 存疑,导出标注 JSON - 合并进金标准集:
python -m qaudit.cli gold --review out/demo/review_*.json --gold eval/goldset.json - 评测:
python -m qaudit.cli eval --gold eval/goldset.json --pred out/demo/findings.json
计分口径:只按显式标注计分——判真算召回,判假算误报,存疑与未判定不计分。
单元测试:python -m pytest tests -q(含开源脱敏门禁 tests/test_scrub.py)。
config/rules.yaml 通用规则库(A/B/U 类):启停、级别、参数
config/packs/ 规则包:表单类型清单 + F 类表单专项规则 + 通用规则的组织级覆盖
qaudit/
ingest.py PDF/TIF/JPG → 统一长边的页面图像
ocr.py RapidOCR 封装 + 页级缓存
layout.py 表格线提取 → 单元格网格
seal.py 红色印章检测(HSV+形态学):位置/倾角/重叠
formtype.py 表单类型识别(决定规则适用范围)
context.py PageContext:规则引擎的唯一输入
rules_a.py / rules_b.py / rules_f.py / rules_u.py 四类规则实现(纯函数,可单测)
pipeline.py 流水线编排
report.py HTML/JSON 报告
deskew.py 倾斜校正(可选,默认关闭)
segment.py 单据切分(档案 → 单据 → 页)
jobs.py 后台审核作业
store.py SQLite 存储:批次/单据/页/疑点/判定/审计日志
web/ 本地审核服务(标准库 http.server)
train/ 印章状态模型(可整块拆掉,不影响审核主线)
cli.py 命令行入口(audit / import / serve / user / gold / eval)
eval/ 金标准集样例与标注规范
tests/ 单元测试
tools/ 数据集构建、离线标注页、训练入口、脱敏门禁
run.py 免安装入口
规则库与代码解耦是核心设计:改级别、改阈值、改适用表单都不用动代码。
- 表单类型门控 — 供方随带的证明文件是外单位自制文件,不适用内部表单的填写格式要求;
applies_to/exclude_forms控制每条规则的适用范围 - 语境约束 — 范围值规则必须带计量单位才判定,避免误伤批次号、合同号;小数位数规则先判断该数字是否属于零件号/文件号
- 像素兜底 — 手写常被 OCR 漏识,凡涉及「是否为空」的判定都追加墨迹率检测与印章覆盖检测;同列连续空白合并成一条疑点
- 系统性问题折叠 — 同一档案内某规则命中 ≥5 页且覆盖率 ≥60% 时折叠成一条档案级疑点;
findings.json始终保留逐页完整清单 - 批次级折叠 — 一条规则在整批里散命中超过 30 页时合成一条批次级疑点,附各档案分布
在千页级批次上,这五层通常能把首轮疑点压缩一个数量级;经验是首轮噪声大半来自规则写法
而非档案本身,逐条核对原图后修掉几个根因
(页码顺序写法、单位缺失的页级误判、密排印章粘连、印章重叠判据)。方法见 docs/系统全景手册.md。
- C 类规则未实现:凡需要与工艺文件、模板目录、ERP/LIMS/QMS 比对的判定,本版本无法判定
- 划改识别(B06)是启发式:对印刷下划线、分数线可能误报,置信度按 0.4 输出,仅作提示
- 印章歪斜(B01)只对方形/多边形章有效:圆形章不判(宁可漏报不误报)
- 「不得缺项」与现场执行存在张力:如「备注」整列空白,字面属违规但现场普遍如此。已做成整列合并一条 + 白名单可配,最终口径由使用方定
- 倾斜校正默认关闭:实测多数扫描件倾角在 1° 以内,而开启会使 OCR 缓存整体失效;
audit --deskew可开启。整页方向识别(90°/180°)未做 - 部分规则默认关闭,等使用方确认口径:
A05mm 省略、B09页码位置、A18的「整页未见复核人栏」分支、B04的check_all_fields - 服务端无 HTTPS:离线单机场景按明文 HTTP 部署,如需加密由前置反向代理承担
- 印章状态模型(B12/B13)默认不可用于验收:链路已跑通,但以合成样本为主训练时交叉验证准确率只是能力上界,在真实页面上会过触发。要真正可用,需按第八节标注真实样本(建议每类不少于 100 枚)后重训
召回优先——质量部真正怕的是漏检,误报只是多看一眼。
| 类别 | 漏检率 | 误报率 | 说明 |
|---|---|---|---|
| A 类 | ≤ 2% | ≤ 20% | 在双方封存的金标准集上测量 |
| B 类 | ≤ 10% | ≤ 35% | 仅作提示,不作结论 |
金标准集:由使用方指定 300~500 页逐条人工标注,双方封存;规则调优只允许改代码与
rules.yaml,不允许改金标准。
- 用
audit跑一个批次,看report.html里命中最多的前 5 条规则 - 逐条打开原图核对:是档案真有问题,还是规则写法与本单位表单习惯不符
- 属于后者的,改
rules.yaml参数或在规则包里覆盖,重跑(OCR 已缓存,只需分钟级) - 剩下的系统性问题(几百页同一种错)用批量判定一次判掉,个别真问题逐条判
- 判定结果导出合并进金标准集,作为后续版本的回归基准
对应通用做法「印章须清晰、完整、水平正向加盖」。这类判定没法用经典 CV 稳定做出来,需要样本。
整条链路在界面「模型」页完成:样本库 → 标注(网页内打标签,1~6)→ 合成退化样本 → 训练 → 版本上线/回滚。
- 标注单位是「枚」不是「页」:印章已由
seal.detect()定位,标注只打标签不画框 - 标注进度存数据库:可多人分工、可追溯到标注人
- 合成大幅降低标注量:倒盖 = 旋转 180°、缺角 = 遮挡、模糊 = 高斯模糊、漏墨 = 腐蚀 + 噪声;人工只需标注验证集
- 评估按「源印章」分组切分:同一枚真章派生的退化样本不得跨越训练/验证边界
- 上线有门槛:人工标注少于 60 枚的模型禁止上线;全合成样本上的准确率不能作为验收依据
- 上线后:
B12/B13开始生效,阈值仍写在规则库里;每个批次记录model_version进指纹
命令行入口保留用于无人值守批处理:
python tools/make_dataset.py crop samples/synthetic --out out/dataset
python tools/make_dataset.py synth --out out/dataset
python tools/train_seal_cls.py train --out out/dataset单机 CPU(无 GPU):首次约 5 秒/页(含 OCR);OCR 结果落盘缓存后,改规则重跑约 0.1 秒/页。
- 代码以 AGPL-3.0-or-later 发布,见
LICENSE;贡献前请阅读CONTRIBUTING.md与CLA.md - 不要把任何真实客户记录、OCR 缓存、印章样本放进本仓;仓内样本一律合成(
tools/synth_forms.py) - 规则包是组织私有资产,示例包仅用于演示与测试