name: html-structure-validate description: 验证HTML5结构和基础语法。阻塞式质量门 - 如果验证失败则停止流水线。确保确定性输出质量。
HTML结构验证技能
目的
此技能是一个阻塞式质量门,确保生成的HTML满足最低结构要求。这是对概率性AI生成输出的首次确定性验证。
技能检查:
- HTML5合规性 - 正确的DOCTYPE、标签
- 标签闭合 - 所有标签正确闭合
- 必需元素 - Meta标签、样式表链接
- 格式良好性 - 有效结构
如果验证失败,流水线停止并触发钩子通知用户。
这强制执行原则:Python验证,确保确定性质量。
操作步骤
-
加载要验证的HTML文件
- 读取AI技能生成的
04_page_XX.html - 验证文件存在且可读
- 确认文件是文本(非二进制)
- 读取AI技能生成的
-
运行验证检查
- 检查HTML5结构合规性
- 验证标签闭合
- 验证头部部分
- 检查必需CSS链接
- 验证页面容器结构
-
生成验证报告
- 记录所有执行的检查
- 列出发现的任何错误
- 记录警告(非阻塞)
- 记录信息性发现
-
保存验证报告为JSON
- 保存到:
output/chapter_XX/page_artifacts/page_YY/06_validation_structure.json - 包含时间戳
- 包含所有检查结果
- 保存到:
-
以适当代码退出
- 如果有效返回0(继续流水线)
- 如果无效返回1(停止流水线,触发钩子)
输入参数
html_file: <str> - 04_page_XX.html的路径
output_dir: <str> - 验证报告目录
strict_mode: <bool> - 如果为true,警告也视为失败(默认:false)
page_number: <int> - 页码(用于报告)
chapter: <int> - 章节号(用于报告)
验证检查
检查1:DOCTYPE声明
要求:文件必须以正确的DOCTYPE开头
<!DOCTYPE html>
检查:
- [ ] 文件包含
<!DOCTYPE html>(不区分大小写) - [ ] DOCTYPE出现在任何标签之前
- [ ] DOCTYPE在第一行或靠近开头
错误如果:缺少或不正确的DOCTYPE
检查2:HTML标签
要求:正确的<html>开始和结束标签
<html lang="en">
...
</html>
检查:
- [ ]
<html>标签存在 - [ ]
</html>结束标签存在 - [ ] 标签正确配对
- [ ] 没有未闭合的
<html>标签
错误如果:缺少任一标签或配对不正确
检查3:头部部分
要求:完整的<head>部分包含元数据
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>...</title>
<link rel="stylesheet" href="../../styles/main.css">
</head>
检查:
- [ ]
<head>和</head>标签存在 - [ ]
<meta charset="UTF-8">存在 - [ ]
<meta name="viewport">存在(如果缺少则警告) - [ ]
<title>标签包含内容存在 - [ ] CSS
<link>标签包含href属性存在
错误如果:缺少字符集、标题或CSS链接 警告如果:缺少视口meta标签
检查4:主体部分
要求:正确的<body>标签包含内容
<body>
<div class="page-container">
<main class="page-content">
...
</main>
</div>
</body>
检查:
- [ ]
<body>和</body>标签存在 - [ ]
<div class="page-container">存在 - [ ]
<main class="page-content">存在于容器内 - [ ] 主体包含实质性内容(> 100字节)
错误如果:缺少标签或必需的容器div
检查5:标签闭合验证
要求:所有标签必须正确闭合
检查:
- 未匹配的开始标签(例如,
<p>没有</p>) - 不正确的嵌套(例如,
<p><h2>text</h2></p>) - 正确使用自闭合标签(例如,
<br/>、<img/>) - 正确格式化的注释块(
<!-- -->)
验证方法:
- 将HTML解析为树结构
- 验证所有节点正确匹配
- 检查嵌套不违反HTML5规则
错误如果:任何未匹配或不正确嵌套的标签
检查6:标题标签(h1-h6)
要求:有效的标题层次结构
<h1>章节标题</h1>
<h2>部分标题</h2>
<h3>子部分</h3>
检查:
- [ ] 所有标题标签正确闭合
- [ ] 第一个标题应该是h1(如果不是则警告)
- [ ] 标题级别没有大幅跳跃(h1 → h4可疑)
- [ ] 所有标题都有文本内容(非空)
错误如果:标题标签不正确闭合 警告如果:可疑的层次结构
检查7:内容结构
要求:页面容器中有意义的内容
检查:
- [ ]
<main class="page-content">包含元素 - [ ] 内容包含标题或段落
- [ ] 没有完全空的内容区域
- [ ] 存在文本节点或元素(> 100个单词总数)
错误如果:没有内容或空结构
检查8:列表完整性
要求:所有列表正确结构化
检查每个<ul>或<ol>:
- [ ] 列表开始和结束标签匹配
- [ ] 列表包含
<li>元素 - [ ] 所有
<li>标签正确闭合 - [ ]
<li>计数匹配开始/结束对 - [ ] 没有嵌套的
<ul>或<ol>不正确闭合
错误如果:空列表或未匹配的<li>标签
检查9:图像和链接标签
要求:自闭合标签正确格式化
检查:
- [ ] 所有
<img>标签有src和alt属性 - [ ] 所有
<a>标签有有效的href属性 - [ ] 图像路径没有明显错误(没有损坏的语法)
- [ ] 自闭合标签使用正确的语法
警告如果:图像缺少alt文本或链接缺少href
检查10:表格标签(如果存在)
要求:正确的表格结构
检查:
- [ ]
<table>、<tr>、<td>、<th>标签正确嵌套 - [ ] 所有行有一致的列计数
- [ ] 表格标题和主体正确结构化
错误如果:格式错误的表格结构
验证报告格式
输出:06_validation_structure.json
{
"page": 16,
"book_page": 17,
"chapter": 2,
"validation_type": "structure",
"validation_timestamp": "2025-11-08T14:34:00Z",
"overall_status": "PASS",
"error_count": 0,
"warning_count": 1,
"checks_performed": [
{
"check_name": "DOCTYPE声明",
"status": "PASS",
"details": "找到有效的HTML5 DOCTYPE"
},
{
"check_name": "HTML标签",
"status": "PASS",
"details": "正确的<html>开始和结束标签"
},
{
"check_name": "头部部分",
"status": "PASS",
"details": "所有必需的meta标签和标题存在"
},
{
"check_name": "主体部分",
"status": "PASS",
"details": "主体和内容结构有效"
},
{
"check_name": "标签闭合",
"status": "PASS",
"details": "所有标签正确匹配和闭合"
},
{
"check_name": "标题层次结构",
"status": "PASS",
"details": "找到4个标题,正确的h1-h4层次结构"
},
{
"check_name": "内容结构",
"status": "PASS",
"details": "主要内容区域包含3个段落中的245个单词"
},
{
"check_name": "列表完整性",
"status": "PASS",
"details": "1个列表包含3个项目,所有都正确形成"
},
{
"check_name": "图像标签",
"status": "PASS",
"details": "此页面上没有图像"
},
{
"check_name": "表格标签",
"status": "PASS",
"details": "此页面上没有表格"
}
],
"errors": [],
"warnings": [
{
"check": "标题层次结构",
"message": "第一个标题是h2,通常页面开头应该是h1",
"severity": "LOW"
}
],
"summary": {
"total_checks": 10,
"passed": 9,
"failed": 0,
"warnings": 1,
"html_valid": true,
"tags_matched": true,
"content_substantial": true
}
}
验证规则
通过标准
- DOCTYPE存在且有效
- 所有必需标签(
html、head、body、main、div.page-container)存在 - 所有标签正确闭合和匹配
- 标题标签包含内容
- CSS样式表链接存在
- 内容结构有效
- 没有结构错误
失败标准(阻塞流水线)
- 缺少DOCTYPE
- 缺少必需标签
- 未匹配或不正确嵌套的标签
- 缺少标题或CSS链接
- 空内容
- 格式错误的列表或表格
警告(记录但不阻塞)
- 缺少视口meta标签
- 第一个标题不是h1
- 标题大幅跳跃(h1 → h4)
- 图像缺少alt文本
- 链接缺少href
实现:使用Python脚本
此验证由现有的validate_html.py工具执行,在结构验证模式下运行:
cd Calypso/tools
# 验证单个页面HTML
python3 validate_html.py \
../output/chapter_02/page_artifacts/page_16/04_page_16.html \
--output-json ../output/chapter_02/page_artifacts/page_16/06_validation_structure.json \
--strict-structure
# 退出代码:
# 0 = 有效(继续到下一个技能)
# 1 = 无效(停止流水线)
钩子集成
当验证失败时:
# 触发钩子:.claude/hooks/validate-structure.sh
# 接收:
# - 页码
# - HTML文件路径
# - 验证报告路径
# - 错误详情
# 钩子行为:
# - 记录失败详情
# - 保存错误报告
# - 通知用户
# - 停止流水线(不进一步处理)
错误恢复
如果验证失败:
- 用户查看验证报告
- 用户识别AI生成HTML中的问题
- 选项:
- 手动修复HTML并重新验证
- 使用改进的提示重新运行AI生成
- 审查源提取数据中的错误
- 谨慎继续(专家覆盖)
质量指标
验证提供指标:
- 检查通过的百分比
- 错误严重级别
- 内容大小(单词计数、元素计数)
- 结构复杂性
这些指标输入到最终质量报告中。
成功标准
✓ 验证成功完成 ✓ 所有结构检查通过(0错误) ✓ 验证报告以JSON格式保存 ✓ 返回退出代码0(如果无效则返回1) ✓ 如果验证失败,有清晰的错误消息
通过后的下一步
如果验证通过:
- 章节的所有页面通过此门处理
- 技能4(合并页面)合并单个页面HTML
- 质量门2(语义验证)检查语义结构
- 继续通过验证流水线
失败后的下一步
如果验证失败:
- 流水线停止
- 触发钩子
validate-structure.sh - 用户收到带有详情的错误报告
- 用户必须修复问题并重试
设计说明
- 这是第一个确定性质量门
- 使用经过验证的
validate_html.py工具 - 在语义分析之前捕获结构问题
- 提供清晰、可操作的错误消息
- 对于确保流水线可靠性至关重要
测试
测试结构验证:
# 使用已知良好的HTML测试
python3 validate_html.py ../output/chapter_01/chapter_01.html
# 应该显示:✓ 有效
# 使用无效HTML测试(如果需要)
python3 validate_html.py broken_html.html
# 应该显示:✗ 无效,带有具体错误