ksp_env_bench Benchmark 数据集构建流程
ksp_env_bench 通过四阶段流水线自动构建 benchmark 数据集,每个阶段各司其职、层层递进。
整体架构
┌─────────────────────────────────────────────────────────────────┐
│ BenchGeneratePipeline │
├─────────────────────────────────────────────────────────────────┤
│ [1] InitialEngineGenerator → 随机生成机器人初始状态 │
│ ↓ │
│ [2] TrajectoryGenerator → 基于工具图采样工具调用轨迹 │
│ ↓ │
│ [3] IntendedTasksGenerator → 从轨迹反推用户意图任务 │
│ ↓ │
│ [4] DialogGenerator → 生成用户/助手对话 │
│ ↓ │
│ [输出] JSONL 格式 benchmark 样本 │
└─────────────────────────────────────────────────────────────────┘
阶段一:初始状态生成(InitialEngineGenerator)
核心文件: generator/initial_engine_generator.py
随机生成符合 KUKA KSP 系统规范的机器人初始状态,包含以下维度:
|
维度 |
生成内容 |
生成策略 |
|---|---|---|
|
Controller |
user_group、op_mode、spoc_status |
加权随机 + 业务约束(如 Operator 不能在 Ext 模式) |
|
Robot |
A1-A6 关节角度、move_mode、step_size、jog_override |
分段采样:经典位姿、边界值、随机值 |
|
Tool/Base |
工具坐标、基座坐标、激活索引 |
四种策略:empty/continue/jump/full |
|
System |
语言(中文/英文)、系统时间 |
随机选择 |
|
Notification |
日志、警告、错误消息 |
从消息池按比例采样 |
关键特点:
-
不依赖 LLM,纯规则随机生成
-
通过
KSPEnvEngine验证,确保符合规范 -
使用 MD5 hash 生成唯一
instance_id
阶段二:工具调用轨迹生成(TrajectoryGenerator)
核心文件: generator/trajectory_generator.py
基于工具图配置(configs/tool_graph_config.yaml)采样生成工具调用序列:
# 流程概览
for step_index in 1..num_step:
1. 根据当前节点获取可用边(工具依赖关系)
2. 加权随机选择下一个工具
3. 根据 JSON Schema 采样工具参数
4. 通过 MCP Executor 执行工具调用
5. 记录执行结果(成功/失败)
6. 更新当前节点,继续循环
关键机制:
-
工具图驱动: 通过
__START__→ 工具 → 工具 的边权重控制采样 -
Schema 参数采样: 根据工具的 JSON Schema 自动生成合法参数
-
去重保护: 避免近期重复调用相同工具+参数
-
在线执行: 通过 MCP 服务实时执行,获取真实观测结果
阶段三:意图任务生成(IntendedTasksGenerator)
核心文件: generator/tasks_generator.py
从工具调用轨迹反推用户原始意图,生成标准化任务集合:
双轨策略:
-
LLM 生成(优先): 让 LLM 分析轨迹,抽象出用户可自然提出的任务
-
规则生成 + LLM 质检(回退): 基于工具配置的
task_role(goal/support/query)规则提取,再由 LLM 审核质量
任务分类:
-
goal: 核心目标任务(如点动机器人、设置工具坐标) -
support: 辅助步骤(如模式切换、权限校验),并入目标任务 -
query: 查询类任务(如获取变量值、检查安全驱动器)
阶段四:对话生成(DialogGenerator)
核心文件: generator/dialog_generator.py
基于意图任务和工具轨迹,生成用户-助手对话样本:
对话场景分类(11种):
|
类别 |
用户行为 |
助手行为 |
示例 |
|---|---|---|---|
|
atom |
clear |
execute |
明确指令:"将A1轴正向移动30度" |
|
atom |
noisy |
execute |
口语化:"帮我把A2转一下" |
|
ambiguous |
slot_ambiguous |
clarify |
缺参数:"移动一下" |
|
ambiguous |
intent_ambiguous |
clarify |
意图不清:"处理一下报警" |
|
ambiguous |
inapplicable |
reject |
非法请求:"删除系统文件" |
|
multi-turn |
continuation |
execute |
承接上文:"继续移动" |
|
multi-turn |
transition |
execute |
切换任务:"现在设置工具坐标" |
|
composite |
chain |
execute |
多步连续:"先切换模式,再点动A1" |
|
composite |
parallel |
execute |
并列任务:"设置语言和主题" |
|
composite |
condition |
execute |
条件任务:"如果安全驱动器正常,就移动" |
最终样本结构
每条 benchmark 样本包含:
{
"instance_id": "inst_abc123", # 实例ID
"initial_engine": {...}, # 初始引擎状态
"trajectory": [...], # 工具调用轨迹
"trajectory_pass": True, # 轨迹是否执行成功
"intended_tasks": [...], # 意图任务列表
"quality_pass": True, # 质量是否通过
"category": "atom", # 对话类别
"sub_category": "clear-execute", # 子类别
"history": [...], # 历史对话(多轮)
"input_message": {...}, # 用户输入
"output_messages": [...], # 助手回复(含工具调用)
"current_engine": {...}, # 当前引擎状态
"final_engine": {...}, # 最终引擎状态
}
数据筛选与输出
Pipeline 层面的筛选:
-
quality_pass=True: 质检通过的样本 →pass_output_path -
quality_pass=False: 质检失败的样本 →fail_output_path
并行生成:
-
通过
asyncio.Semaphore控制并发数 -
自动处理实例释放和异常恢复
设计理念
ksp_env_bench 的核心设计理念是**"先有执行轨迹,后有自然语言"**:
-
从状态出发: 随机生成真实的机器人初始状态
-
模拟操作: 通过工具图采样真实的工具调用序列
-
反推意图: 从执行轨迹逆向推导用户任务
-
生成对话: 基于任务生成多样化的自然语言交互
这种方式确保了 benchmark 数据的真实性(工具调用可真实执行)和覆盖度(通过工具图配置控制分布),同时通过 LLM 引入了自然语言多样性(不同表达方式、歧义场景、多轮对话)。
本文来自博客园,作者:limingqi,转载请注明原文链接:https://www.cnblogs.com/limingqi/p/21171379
浙公网安备 33010602011771号