开发一个 QA 智能审计 skill
在推行过程体系的项目里,"质量保证(PQA)"不是一个会议纪要或一句口号,而是一套可被检查的过程活动清单。典型场景是这样的:
- 公司有一份《QA检查单模版》,里面按"项目生命周期过程"列出了 100+ 个检查项,每一项要么是"文件存在性"(比如"项目目录必须存在《需求规格说明书》"),要么是"文档内容"(比如"需求规格说明书每个需求应有唯一编号")。
- 手头有十几个项目的交付物目录,二级、三级文件夹嵌套,文档命名五花八门(XX项目_技术方案_v2.docx、技术方案终版.docx……)。
- 审计要干两件事:先确认文件在不在,再确认内容达不达标,最后汇总成一份能交给高层看的不符合项报告。
纯人工做这件事有三个致命问题:
|
痛点 |
说明 |
|
易漏 |
一份 153 项的检查单,人脑逐文件对照,漏 10 项是常态 |
|
低效 |
60 个文件 × 153 项,纯机械比对,一天未必干得完 |
|
不可复现 |
换个项目、换个人,结论口径和格式都不一样 |
而这件事又高度结构化:检查项是有格式的、文档是能解析的、报告是能模板化的。这正是 Skill(可复用的智能工作流)该接手的活。
二、需求是什么:这个 Skill 的设计目标
动手前,我把需求收敛成几条硬约束:
|
维度 |
需求 |
|
审计对象 |
既审"文档内容质量",也审"文件是否存在"——后者是项目级审计的核心。 |
|
检查单来源 |
不能绑定固定模板:要支持单文件单 sheet、单文件多 sheet、多文件三种来源。 |
|
文档格式 |
覆盖 Word(.doc/.docx)、PDF、Excel(.xlsx/.xlsm/.xls)、纯文本/Markdown;旧格式(.doc/.xls)经 LibreOffice 无头转换后解析,检查单本身也支持 .xls。 |
|
防遗漏 |
批量审计时,必须强制"扫到的每一个文件都被审到",否则报告无效。 |
|
输出 |
一份带明细、统计、图表的 Excel,业务方拿到就能用。 |
|
可复用 |
触发词驱动,任意项目目录 + 任意检查单即可复跑,不写死路径。 |
关键决策: 不做一个"大模型直接读文件夹然后写报告"的黑盒,而是把流程拆成检查单解析 → 文档解析 → 扫描匹配 → 报告生成四个可独立运行、可调试的脚本。AI 负责"判断是否符合",脚本负责"解析与汇总"——能力边界清晰,结果可校验。
三、Skill 的作用:三种模式,九种组合
Skill 对外暴露三种审计模式,每种模式再叠加三种检查单来源(单文件单 sheet / 单文件多 sheet / 多文件),形成 9 种组合。最常派上用场的是模式 3。
- 模式 1 · 单文档审计:一份文档 vs 一份检查单,深度审查单份文档的内容质量。适合"这份方案写得到不到位"的定点审查。
- 模式 2 · 多文档审计:一个目录下多份文档 vs 检查单(可批量套用),批量审同类文档的内容质量。
- 模式 3 · 项目活动 + 文档联合审计(核心):把一个项目根目录(顶层子目录 = 独立项目)丢进去,检查单里既有"文件存在性"项又有"文档内容"项,先验证文件在不在,再审计内容达不达标。这正是本博客实战案例用的模式。
整个 Skill 是一个"JSON 中间表示"驱动的管线。检查单和文档都被解析成结构化 JSON,AI 在 JSON 层面做语义判断,最后由报告脚本汇成 Excel。各模块互不依赖、可单独调试。
管线流程:
STEP 1 parse_checklist.py → 检查单 Excel → 检查项 JSON(自动识别列、识别检查类型)
↓
STEP 2 scan_files.py → 目录扫描 + 活动模式匹配,生成"强制全覆盖"的 findings 模板
↓
STEP 3 parse_document.py → 逐文件解析为结构化 section / table JSON
↓
STEP 4 generate_report.py → findings JSON → 5 sheet Excel 报告(含覆盖度校验)
1)检查单解析:列名自动识别 + 检查类型分类
检查单模板千变万化,列名可能是"检查项内容/审计项/检查要点",判定标准可能是"判定标准/依据/要求"。解析器内置了关键词表,用"首匹配优先"策略把每一列映射到标准角色(id / check_item / criteria / category / severity / check_type),找不到还有兜底(检查项缺列就取第一个非空列,标准缺列取第二个)。
更关键的是检查类型分类——解析器会从"检查类型"列的取值里识别出三类:
|
检查类型 |
说明 |
|
文件存在性(高严重级) |
走目录扫描分支,默认高严重级 |
|
文档内容 |
走内容审计分支 |
|
文档完整性 |
结构与内容混合检查 |
没有"检查类型"列时,所有项默认归为"文档内容"——此时文件存在性要靠 AI 从检查项文案里手动识别。
2)文档解析:统一的中间表示
parse_document.py 对 docx / pdf / txt / md / xlsx 分别解析,但最终都收敛成同一套 JSON 结构:sections[](带标题层级与定位)、tables[]、以及拼接好的 full_text。这样 AI 不论面对什么格式,都在同一个"章节 + 全文"视角上做判断。Excel 每个 sheet 被当作一个 section;PDF/文本用标题的正则启发式(第X章、1.1、一、 等)切分章节。文本文件统一用 utf-8 → gb18030 → latin1 回退解码,并限制 20MB 防爆内存。
3)活动模式:文件存在性的"模糊匹配"算法
这是模式 3 的技术核心。检查项文案里写的是"项目目录中必须存在《技术方案.docx》",而真实文件叫 XX项目_技术方案_v2.docx。解析器做两步:
- 文件名抽取: 用正则从检查项 / 判定标准的"存在/包含/交付/提交"等关键词之后抽取出书名号或扩展名包裹的文件名(如 技术方案.docx)。
- 模糊匹配: 把待查文件名和目录下真实文件名都去掉标点/空格/连字符并转小写做归一化,再按"完全相等→包含匹配(长串优先,得分=长度×3)→被包含(得分=长度×2)"的顺序打分,超过阈值(≥4)即命中。支持递归扫描子目录。
# 归一化:去掉 . _ - — 空格
pattern_stem = re.sub(r'[._\-—\s]', '', Path(file_pattern).stem.lower())
# 完全相等 → score 100;包含 → len×3;被包含 → len×2
if pattern_stem in fname_stem:
score = len(pattern_stem) * 3
匹配不到的文件,自动归入 missing_files 并默认标记为高严重级。
4)防遗漏机制:覆盖度校验
批量审计最怕"审了一半忘了还有文件"。Skill 用了一个强制约束:scan_files.py --output-template 会先把目录里扫到的每一个文件都列进模板(findings 初始为空数组),AI 必须逐个填充(哪怕"无问题"也要留 [])。最后 generate_report.py 会反查:模板里 _coverage_stats.total_files 与报告实际覆盖文件数是否一致,不一致就报[警告]而非[通过]。这条机制从工程上保证了"没有偷偷漏审"。
5)报告生成:5 个 sheet + 双柱状图
generate_report.py 用 xlsxwriter 输出一份带条件格式的 Excel:
|
Sheet |
内容 |
|
审计概览 |
项目/文件/不符合项计数、覆盖度校验(通过/警告)、严重等级与检查类型分布 |
|
审计明细 |
每条不符合项的定位与描述,严重级红/黄/绿着色,带自动筛选 |
|
按项目统计 |
各项目缺失/内容问题、高/中/低分解 |
|
按分类统计 |
跨项目按检查类别合并降序,含代表检查项 |
|
柱状图分析 |
按分类、按项目各一张柱状图 |
6)旧格式支持:无头转换 + 多重回退
现实中大量交付物仍是老格式:.xlsm(带宏的 Excel)、.xls(Excel 97–2003)、.doc(Word 97–2003)。Skill 没有把它们拒之门外,而是用一条"主路径转换 + 多层回退"的链路接入既有解析管线:
- .xlsm:openpyxl 原生直读(宏不参与解析,表格与数据照常提取)。
- .xls:优先用 LibreOffice 无头转换为 .xlsx 再走现有解析;若环境无 LibreOffice,回退 xlrd 直读。
- .doc:优先 LibreOffice 无头转换为 .docx;失败再回退 antiword 提取文本;在 macOS 上还可再回退系统自带 textutil 兜底。
- 检查单本身:也支持 .xls(同样经 LibreOffice 转换后解析)。
这样,无论项目里是崭新的 .docx 还是十年前的 .doc,都不再需要从审计流程里"手工剔除",内容质量一并纳入审查。
以最常用的模式 3(项目活动+文档联合审计)为例,标准四步:
① 解析检查单为 JSON
python3 scripts/parse_checklist.py \
"01.质量保证/质量保证计划-检查单模版V2.00.xlsx" \
--sheet "质量计划" -o /tmp/checklist.json
# 不确定 sheet 名时,先列出来:
python3 scripts/parse_checklist.py <检查单.xlsx> --list-sheets
② 活动模式扫描,生成"强制全覆盖"模板
python3 scripts/scan_files.py <项目根目录> \
--mode activity --checklist /tmp/checklist.json \
--output-template -o /tmp/scan_template.json
模板里已包含:所有文件清单、预填充的"文件存在性"缺失项、以及 _coverage_stats.total_files(你必须覆盖的文件总数)。
③ AI 逐文件审计,填写 findings
# 对每个文件:
python3 scripts/parse_document.py <文件路径> -o /tmp/doc.json
# 读取 doc.json,对照 checklist 的"文档内容"项做判断,
# 把不符合项填入该文件 findings 数组(无问题留 [])
删掉元数据键(_template_note / _coverage_rule / _coverage_stats)后保存为 /tmp/findings.json。
④ 生成报告
python3 scripts/generate_report.py -i /tmp/findings.json -o 审计报告.xlsx
打开后确认"覆盖度校验"一行显示 [通过] 全部 N 个文件已覆盖 即可交付。
调用入口: 日常使用无需记命令——在对话里说"用 qa-check 对 XX 目录做 QA 审计,检查单用 YY.xlsx 的 ZZ sheet",Skill 会自动按这条管线跑完并产出 Excel。
六、结果案例:P04 & P08 实战
真实触发的一句话需求:“用 qa-check,以《质量保证计划-检查单模版》的'质量计划'sheet 为检查单,对 Downloads 下的 P04 与 P08 做 QA 审计。”
我把两个项目目录作为根目录传入,检查单 153 个过程活动(√ 为 PQA 常规检查项)作为标准。最终覆盖度校验全部通过。
|
指标 |
数值 |
|
检查项(过程活动) |
153 |
|
被审计文件(27 + 33) |
60 |
|
不符合项 |
53 |
|
覆盖度校验通过 |
100% |
两项目共性问题
- 全部 13 份阶段质量报告正文保留模板占位文字(【简述该项目的项目信息…】),高层经理签字栏均为空。
- 均缺失:配置管理计划、配置状态报告、决策分析报告、产品集成计划、项目章程、项目预算、用户/安装/运维三类手册。
- 周报严重不连续(P04 仅 4 份、P08 仅 3 份,项目周期都在半年以上)。
P04(27 文件,16 项缺失)
- �� 整个需求开发目录缺失(无 SRS、无调研记录、无需求跟踪矩阵)
- �� 无项目计划/需求/设计评审报告
- �� 无代码走查记录表(仅 spotbugs 静态检查)
- �� 设计说明书缺失、无验收报告
P08(33 文件,13 项缺失)
- �� 测试用例评审报告两份重复,且其中一份日期早于项目立项,真实性存疑
- �� 项目计划评审时间写成 2012 年(硬伤)
- �� 设计说明书缺失(仅评审报告与 .rp 原型)
- �� 无试运行/验收阶段材料,风险跟踪表缺失
“审计不是挑刺,而是把‘过程资产到底齐不齐、文档到底达不达标’这件事,用一份可复现的报告讲清楚。”
报告最终含 5 个 sheet:审计概览、审计明细(53 条含章节级定位)、按项目统计、按分类统计、柱状图分析。业务方拿到即用。
该skill已经开源发布在skillhub上:SkillHub-专为中国用户优化的Skills社区
更多推荐



所有评论(0)