11 KiB
Executable File
11 KiB
Executable File
任务:重写 IR Generation,实现高可靠性、可测试的中间表示提取
一、背景与目标
我们正在为吉利汽车车机测试团队验证 AI 自动生成测试用例的可行性。输入是产品需求文档(PRD),输出是 Robot Framework 测试脚本。
当前流程中,文档解析(doc_parser)已稳定,能将 Word 文档转为结构化 JSON,并将流程图图片转为精确的 logic_tree JSON。但直接基于这份 JSON 生成 IR(中间表示)时,LLM 经常丢失分支,稳定性差。
现在需要重新实现 IR 生成,采用“分阶段理解 + 程序化校验”架构,彻底解决分支丢失问题。
核心原则:LLM 负责“关联理解”和“受限翻译”,程序负责“确定性校验”和“完整性审计”。
二、已有资产与路径
-
输入文件:
C:\Users\peterz\.openclaw\workspace\skills\doc_parser_skill\output\车机娱乐系统禁止功能文档_脱敏 v0.9_v2_updated.json- 结构:包含
sections数组和image_analysis数组。 sections每个元素有source(章节标题)、blocks(para和table)、images(图片引用 ID 列表)。image_analysis中,流程图类型的图片包含logic_tree,是一个有根、有节点、有分支的树形结构,分支准确。
- 结构:包含
-
工作目录:
C:\Users\peterz\.openclaw\workspace\skills\ir_generation_new_skill- 请在此目录下创建 Python 脚本、Prompt 模板、测试等。
-
最终输出文件:放在
C:\Users\peterz\.openclaw\workspace\skills\doc_parser_skill\output\ir_final.json:最终的 IR JSON。ir_audit_report.md:完整性审计报告,供人工快速审查。
三、IR Schema 定义
最终 IR 是一组可测试的功能规则,每条规则包含触发条件、动作、来源锚点,足以让规则引擎自动生成覆盖正常/边界/异常的 Robot Framework 测试用例。
目标 Schema(示例):
{
"feature": "行车娱乐限制",
"feature_id": "DRL-001",
"rules": [
{
"rule_id": "DRL-001-SYS-FG-01",
"description": "开关开启,系统限制应用在前台,车速≥15km/h 且持续超过5秒且非P档时,应用被打断并退至后台,同时弹出特定 Toast",
"priority": "P0",
"sources": [
{"type": "table", "section": "3.1.1", "row": 2},
{"type": "logic_tree", "image_id": "rId16", "node_ids": ["n19","n21","n23","n25","n26"]}
],
"precondition": {
"switch": "开启",
"app_type": "系统限制",
"app_state": "前台"
},
"trigger": {
"operator": "AND",
"conditions": [
{"signal": "车速", "operator": ">=", "value": 15, "unit": "km/h"},
{"signal": "车速_持续时间", "operator": ">", "value": 5, "unit": "秒"},
{"signal": "档位", "operator": "!=", "value": "P"}
]
},
"actions": [
{"type": "system", "description": "打断应用前台进程"},
{"type": "system", "description": "将应用调入后台"},
{"type": "user_interaction", "description": "显示Toast", "content": "在行车状态下无法使用该应用"}
]
}
]
}
注:具体字段可根据实际文档内容灵活扩充,但必须包含 rule_id、description、sources、trigger、actions。
## 四、新实现流程(分三个阶段)
阶段一:宏观语义索引(Semantic Index)
目标:让 LLM 一次性阅读整个文档,生成一份语义索引,识别出所有功能单元(function unit)并建立概念映射,但不提取具体规则细节。
输入:完整的 xxx_parsed.json(所有 sections + image_analysis)。
LLM 调用:一次。
任务要求:
编写一个 Python 脚本 step1_semantic_index.py,其功能:
读取输入 JSON 文件。
构造 Prompt,要求 LLM 输出如下结构的 JSON:
json
{
"feature_name": "行车娱乐限制",
"concepts": [
{"name": "行车娱乐限制", "aliases": ["行车娱乐限制", "行车娱乐禁止"], "defined_in": ["3.1", "3.1.1"]},
{"name": "系统限制", "aliases": [], "defined_in": ["3.1", "3.1.1"]},
...
],
"function_units": [
{
"unit_id": "FU-001",
"name": "系统限制-前台-行车打断",
"description": "当开关开启、应用为系统限制类型且处于前台时,满足车速和档位条件后,系统打断应用并显示Toast",
"sources": [
{"section": "3.1.1", "type": "table", "row": 2, "text_snippet": "打断:车速≥15km/h...退至后台"},
{"image_id": "rId16", "logic_tree_nodes": ["n19","n21","n23","n25","n26"]},
{"image_id": "rId17", "logic_tree_nodes": ["n1","n2","n3"]}
]
},
...
]
}
Prompt 中必须强调:功能单元应覆盖文档描述的所有主要行为,特别是图片逻辑树中的决策路径。不允许遗漏分支。
调用 LLM(可以使用 anthropic.Anthropic 或内部 API),将结果保存为 semantic_index.json。
自检测试:编写 test_step1.py,读取 semantic_index.json 并验证:
所有 function_units 的 sources 中引用的 image_id 必须存在于原输入的 image_analysis 中。
每个 function_unit 至少引用一张图片或一段文字。
所有 logic_tree_nodes 引用的节点 ID 必须在对应 logic_tree 的节点 id 中存在。
无空的 unit_id 或 name。
迭代指引:如果测试失败,分析原因,调整 Prompt(增加更严格的结构化输出指令、Few-shot 示例)并重新运行,直到全部通过。
## 阶段二:逐功能单元 IR 提取
目标:对阶段一产出的每个功能单元,准备一个仅含相关上下文的数据包,让 LLM 据此填充详细的 IR 规则。
输入:semantic_index.json 和原始文档 JSON。
LLM 调用:每个功能单元一次,可并行。
任务要求:
编写 step2_ir_extraction.py:
加载 semantic_index.json 和原始文档 JSON。
为每个 function_unit 构造一个“精准上下文包”:
从原始文档中提取该单元引用的具体段落、表格行、以及完整的 logic_tree(如果引用了节点,则提取相关子树;简单起见可以提取整棵树)。
上下文包示例结构:
json
{
"unit_id": "FU-001",
"unit_name": "系统限制-前台-行车打断",
"texts": ["打断:车速≥15km/h且持续5秒后,将目标应用/功能退至后台或暂停对应功能..."],
"tables": [{"headers":["功能","功能详细说明"], "rows":[...]}],
"logic_trees": [
{"image_id": "rId16", "tree": {...}},
{"image_id": "rId17", "tree": {...}}
]
}
构造 Prompt,要求 LLM 输出一个或多个符合 IR Schema 的规则 JSON 对象(数组 rules)。
强制要求:
每条规则的 sources 必须包含引用的逻辑树节点 ID 列表和文本来源。
触发条件必须精确,包含运算符和数值(如 >=15),不可模糊。
动作必须明确区分系统行为和用户可见交互。
如果文档中存在矛盾(如图片和文字冲突),请优先采用图片逻辑树,并在 description 中注明差异。
提供 IR Schema 和 1-2 个 Few-shot 示例。
将所有功能单元产出的规则数组合并,保存为 ir_fragments.json,格式:[ { "unit_id": "FU-001", "rules": [...] }, ... ]
自检测试:编写 test_step2.py:
验证每个 ir_fragment 的 rules 非空。
验证每条规则的 sources 中有逻辑树节点引用。
验证 trigger.conditions 中的每个条件均有 signal、operator、value。
检查是否有重复的 rule_id(可暂时用 unit_id + 序号,但最终合并时会处理)。
迭代指引:如果某些片段规则为空或条件缺失,检查是否为上下文包裁剪太狠(丢失了关键文本),优化提取逻辑或调整 Prompt,再次运行。
阶段三:确定性合并与完整性校验
目标:用程序逻辑将多个片段的规则去重、合并,并基于逻辑树节点覆盖率生成审计报告,告知人工哪里可能遗漏。
LLM 调用:无(或用极简 LLM 做最终文案规范化)。
任务要求:
编写 step3_merge_and_audit.py:
加载 ir_fragments.json 和原始文档 JSON(含所有 logic_tree 节点)。
合并去重:
按 trigger 和 actions 的语义相似度进行规则合并。简化方案:如果两条规则的触发条件和动作完全相同(值比较),只保留一条,合并 sources。
合并后重新分配稳定的 rule_id(如 DRL-001-SYS-FG-01)。
完整性审计(生成 ir_audit_report.md):
逻辑树节点覆盖率:遍历所有 logic_tree 中的每个 decision 和 action 节点,检查是否有至少一条规则的 sources 引用了该节点。列出未被覆盖的节点及其所在的图片 ID。
表格枚举覆盖:识别所有表格中列出“应用类型”、“限制方式”的枚举值,检查这些值是否出现在规则的 precondition 或条件中。
全局开关覆盖:检查所有涉及开关状态的规则,是否完整覆盖了“开启”和“关闭”两种状态。
报告格式:Markdown 表格,列出检查项、状态(✅/⚠️/❌)、详情。
合并后的最终 IR 保存为 ir_final.json。
人类检查提示:审计报告最上方用醒目的文字说明:“请人工审查以下 ⚠️ 和 ❌ 项,确认是文档遗漏还是 IR 提取遗漏。如无需修改,则在对应项后标注‘已确认’。”
编写 test_step3.py,验证:
ir_final.json 中无重复 rule_id。
所有 rule_id 符合命名规范(DRL-001-...)。
ir_audit_report.md 文件存在且包含覆盖率统计。
迭代指引:如果审计报告显示大量节点未覆盖,需回溯检查阶段二的提取质量,可能是某些功能单元未被识别,或提取时丢失了节点引用。可补充遗漏的单元,重新提取片段后再次合并审计。
## 五、总体执行顺序与依赖
首先实现并运行 step1_semantic_index.py,通过测试。
接着运行 step2_ir_extraction.py,通过测试。
最后运行 step3_merge_and_audit.py,生成最终交付物。
所有脚本应可重复执行,且运行 python main.py(如有)可一键完成所有步骤。
六、开发与协作要求
所有 Python 代码需有清晰的注释,关键函数有 docstring。
Prompt 模板可以单独作为 .txt 或 .md 文件存放,便于调试。
测试脚本独立,并输出明确的通过/失败信息。
如果某个阶段需要人类帮助(例如需要确认某个功能划分是否合理),请在该阶段输出清晰的问题并暂停,等待人类回复后继续。
你将在工作目录 C:\Users\peterz\.openclaw\workspace\skills\ir_generation_new_skill 中完成所有工作。
现在开始执行。首先请通读输入文件(路径已给出),理解其结构,然后着手实现阶段一。