Files
claw/docs/superpowers/specs/2026-04-16-multi-scene-kind-generator-design.md
木炎 af8f261b79 docs: add multi-scene-kind generator design spec
Design for extending sg_scene_generate to support multiple scene kinds
(report_collection, monitoring) with manual type selection in Web UI,
relaxing the requirement for meta tags in third-party scene directories.

🤖 Generated with [Qoder][https://qoder.com]
2026-04-16 23:22:08 +08:00

11 KiB
Raw Blame History

Multi-Scene-Kind Generator Design

Status: Draft Date: 2026-04-16 Author: Qoder

Problem Statement

sg_scene_generate 当前只支持 report_collection 类型的场景,强制要求场景目录的 index.html 包含 sgclaw-scene-kindsgclaw-tool-kind meta 标签。

现实情况

  • 400+ 第三方场景目录没有 meta 标签
  • 场景类型不单一:既有报表收集类(查询数据导出 Excel也有监测类(定时检查状态、监控告警)
  • 不可能要求所有第三方场景添加 meta 标签

结果:当前 sg_scene_generate 对真实场景目录完全无法使用。

Goal

扩展 sg_scene_generate 支持多种场景类型,让用户在 Web UI 上手动选择场景类型,而不是依赖场景目录中的 meta 标签。

Non-Goals

  • 不实现 LLM 自动识别场景类型(后续增强)
  • 不实现运行时自动推断场景类型
  • 不修改 registry.rs 的运行时校验逻辑V1 仍只支持已注册的类型)
  • 不实现完整的监测类参数解析器(生成简化模板,用户手动编辑)

Architecture

┌─────────────────────────────────────────────────────────────┐
│                    Web UI (HTML)                            │
│  ┌─────────────┐  ┌──────────────┐  ┌──────────────────┐   │
│  │ 场景路径输入 │  │ 场景类型下拉框│  │ 分析/生成按钮    │   │
│  └─────────────┘  └──────────────┘  └──────────────────┘   │
└─────────────────────────────────────────────────────────────┘
                           │
                           ▼
┌─────────────────────────────────────────────────────────────┐
│                 Node.js Server                              │
│  /analyze  →  LLM 提取 scene-id, scene-name                │
│  /generate →  调用 cargo run传递 --scene-kind 参数        │
└─────────────────────────────────────────────────────────────┘
                           │
                           ▼
┌─────────────────────────────────────────────────────────────┐
│              sg_scene_generate (Rust CLI)                   │
│  --scene-kind report_collection | monitoring               │
│                                                             │
│  analyzer.rs  →  放宽 meta 校验,接受用户指定类型           │
│  generator.rs →  根据类型选择不同模板                       │
└─────────────────────────────────────────────────────────────┘

Implementation Details

1. analyzer.rs — 放宽校验逻辑

当前行为

  • 强制要求 sgclaw-scene-kind meta 标签 = report_collection
  • 强制要求 sgclaw-tool-kind meta 标签 = browser_script
  • 缺失则报错退出

新行为

  • meta 标签可选
  • 如果缺失,使用用户通过 --scene-kind 参数指定的类型
  • 如果用户未指定,默认为 report_collection
  • sgclaw-tool-kind 默认为 browser_scriptV1 只支持这一种)

枚举扩展

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SceneKind {
    ReportCollection,
    Monitoring,
}

impl SceneKind {
    pub fn from_str(s: &str) -> Option<Self> {
        match s {
            "report_collection" => Some(Self::ReportCollection),
            "monitoring" => Some(Self::Monitoring),
            _ => None,
        }
    }
}

函数签名变更

// 改动前
pub fn analyze_scene_source(source_dir: &Path) -> Result<SceneSourceAnalysis, AnalyzeSceneError>;

// 改动后
pub fn analyze_scene_source(
    source_dir: &Path,
    scene_kind_hint: Option<SceneKind>,
) -> Result<SceneSourceAnalysis, AnalyzeSceneError>;

2. generator.rs — 多模板支持

函数签名变更

// 改动前
fn scene_toml(request: &GenerateSceneRequest, tool_name: &str, expected_domain: &str, target_url: &str) -> String;

// 改动后
fn scene_toml(request: &GenerateSceneRequest, analysis: &SceneSourceAnalysis, tool_name: &str) -> String;

模板路由

fn scene_toml(request: &GenerateSceneRequest, analysis: &SceneSourceAnalysis, tool_name: &str) -> String {
    match analysis.scene_kind {
        SceneKind::ReportCollection => scene_toml_report_collection(request, analysis, tool_name),
        SceneKind::Monitoring => scene_toml_monitoring(request, analysis, tool_name),
    }
}

3. sg_scene_generate.rs — 新增 CLI 参数

新增参数

--scene-kind <report_collection|monitoring>
    场景类型,默认 report_collection
    - report_collection: 报表收集类(查询数据导出报表)
    - monitoring: 监测类(定时检查状态、监控告警)

用法示例

# 报表类(默认)
cargo run --bin sg_scene_generate -- \
  --source-dir "D:/desk/场景/营销报表" \
  --scene-id marketing-report \
  --scene-name "营销报表" \
  --output-root "./out" \
  --lessons "docs/superpowers/references/tq-lineloss-lessons-learned.toml"

# 监测类
cargo run --bin sg_scene_generate -- \
  --source-dir "D:/desk/场景/设备监测" \
  --scene-id device-monitor \
  --scene-name "设备监测" \
  --scene-kind monitoring \
  --output-root "./out" \
  --lessons "docs/superpowers/references/tq-lineloss-lessons-learned.toml"

4. 监测类模板设计

监测类场景差异较大,生成简化模板,用户后续手动编辑:

[scene]
id = "<scene-id>"
skill = "<scene-id>"
tool = "monitor_<scene-id>"
kind = "browser_script"
version = "0.1.0"
category = "monitoring"

[manifest]
schema_version = "1"

[bootstrap]
expected_domain = "<从 analyzer 提取或空>"
target_url = "<从 analyzer 提取或空>"
requires_target_page = true

[deterministic]
suffix = "。。。"
include_keywords = ["<scene-name>"]
exclude_keywords = []

# 参数部分留空,用户手动编辑
# [[params]]
# name = "xxx"
# resolver = "literal_passthrough"

[artifact]
type = "monitoring-status"
success_status = ["ok", "running"]
failure_status = ["error", "timeout"]

# 后处理留空,用户手动编辑

5. Web UI 改动

新增控件

<div class="form-group">
  <label>场景类型</label>
  <select id="sceneKind">
    <option value="report_collection" selected>报表收集类</option>
    <option value="monitoring">监测类</option>
  </select>
  <span class="hint">报表类:查询数据导出 Excel监测类定时检查状态</span>
</div>

JavaScript 改动

// generate() 函数增加 sceneKind 参数
const sceneKind = document.getElementById('sceneKind').value;
const response = await fetch('/generate', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    sourceDir,
    sceneId,
    sceneName,
    sceneKind,  // 新增
    outputRoot,
    lessons
  })
});

6. Node.js Server 改动

/generate 接口

async function handleGenerate(req, res) {
  const { sourceDir, sceneId, sceneName, sceneKind, outputRoot, lessons } = body;
  // ...
  const args = [
    "run", "--bin", "sg_scene_generate", "--",
    "--source-dir", normalize(sourceDir),
    "--scene-id", sceneId,
    "--scene-name", sceneName,
    "--scene-kind", sceneKind || "report_collection",  // 新增
    "--output-root", normalize(outputRoot),
    "--lessons", normalize(lessons),
  ];
  // ...
}

Compatibility Matrix

场景目录 meta 标签 用户选择 最终类型
有 meta report_collection 未选择 report_collection
有 meta report_collection report_collection report_collection
有 meta report_collection monitoring monitoring(用户优先)
无 meta 未选择 report_collection(默认)
无 meta monitoring monitoring

用户选择优先于 meta 标签:因为用户比静态 meta 标签更了解场景的实际用途。

File Changes Summary

文件 改动类型 改动量
src/generated_scene/analyzer.rs 修改 ~30 行
src/generated_scene/generator.rs 修改 ~50 行
src/bin/sg_scene_generate.rs 修改 ~20 行
frontend/scene-generator/sg_scene_generator.html 修改 ~15 行
frontend/scene-generator/server.js 修改 ~5 行
frontend/scene-generator/generator-runner.js 修改 ~5 行
tests/scene_generator_test.rs 修改 ~30 行
tests/fixtures/generated_scene/monitoring/index.html 新增 ~20 行

总计~175 行改动8 个文件。

Testing Strategy

单元测试

  1. analyzer_accepts_missing_meta_with_hint — 缺失 meta 标签时,使用 hint 参数
  2. analyzer_uses_meta_when_present — 有 meta 标签时,使用 meta 值
  3. generator_emits_report_collection_template — 报表类模板正确
  4. generator_emits_monitoring_template — 监测类模板正确

集成测试

  1. 无 meta 标签的场景目录 + --scene-kind report_collection → 生成成功
  2. 无 meta 标签的场景目录 + --scene-kind monitoring → 生成成功
  3. Web UI 选择监测类 → 生成的 scene.toml 包含 category = "monitoring"

手动验证

  1. 真实场景目录 D:\desk\智能体资料\场景\营销2.0零度户报表数据生成 → 选择报表类 → 生成成功
  2. 真实监测类场景 → 选择监测类 → 生成成功

Risks and Mitigations

风险 影响 缓解措施
监测类模板过于简化 用户需要大量手动编辑 文档说明 + 后续迭代优化
用户选错类型 生成错误模板 UI 上提供清晰说明
registry.rs 不支持 monitoring 生成的包无法注册 V1 只生成,运行时支持后续迭代

Open Questions

  1. 监测类场景的 artifact.type 应该是什么?当前设计为 monitoring-status,是否合适?
  2. 监测类是否需要新的 resolver 类型?
  3. 是否需要在前端 UI 显示更多类型说明?

References

  • docs/superpowers/plans/2026-04-15-generated-scene-skill-platform-plan.md — 原实现计划
  • src/generated_scene/analyzer.rs — 当前分析器
  • src/generated_scene/generator.rs — 当前生成器