本文へ移動
cccskills
無料GitHub で公開

pipeline-generate

Generate MaaFramework Pipeline nodes and recognition snippets from screenshots or observed UI state. Use for OCR node generation, ROI sweep, choosing TemplateMatch/OCR/ColorMatch/CustomRecognition, preserving target-file schema style, and designing `next`/`[JumpBack]` links before merging generated nodes into pipeline JSON.

インストール方法を見る

含まれるファイル(5)

  • SKILL.md14.8 KB
  • generate_node.py9.0 KB
  • generate_sweep.py5.1 KB
  • maahub_meta.json549 B
  • README.md937 B

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

pipeline-generate

概念

Pipeline 由 Node 组成。本 skill 针对OCR 文本识别节点,按 Pipeline 协议生成节点 JSON 并合并到目标 pipeline 文件。

核心流程:连接设备 → ocr() 拿 box → 扩大 ROI → 合并节点

自带脚本(与本 SKILL.md 同目录):

脚本用途
generate_node.py单节点生成(默认 expand=20)
generate_sweep.py多 expand 变体扫描,找最佳 ROI

MCP 工具绑定

依赖 maa-mcp MCP 服务。

工具说明
find_adb_device_list / connect_adb_device连接设备
ocr截图 + OCR 一步完成(内部已调 screencap,外部不要再调)
load_pipeline / save_pipeline读/写 pipeline JSON
check_and_download_ocr首次需下载 OCR 模型
run_pipeline测试 pipeline 节点

输入参数

参数必填默认说明
target_text✅—要识别的目标中文文字
node_name✅—节点名(PascalCase)
pipeline_file✅—目标 pipeline 路径(相对 assets/resource/base/pipeline/xxx.json 或绝对路径)
action_type❌ClickClick / DoNothing / LongPress / Swipe / ClickKey / InputText
expand_offset❌20ROI 扩边像素(推荐先用 sweep 找最佳)
post_delay❌500
timeout❌2000
overwrite❌False节点名冲突时是否覆盖

3 步工作流(伪代码)

# === Step 1: 连接设备 ===
from maa_mcp.adb import find_adb_device_list, connect_adb_device
controller_id = connect_adb_device(find_adb_device_list()[0])

# === Step 2: OCR 拿 box + 算 ROI ===
from maa_mcp.vision import ocr
from maa_mcp.download import check_and_download_ocr

ocr_results = ocr(controller_id)
if isinstance(ocr_results, str) and "OCR 模型文件不存在" in ocr_results:
    check_and_download_ocr()
    ocr_results = ocr(controller_id)

matched = [r for r in ocr_results if target_text in (r.text if hasattr(r, "text") else r["text"])]
best = max(matched, key=lambda r: r.score if hasattr(r, "score") else r["score"])
box = best.box if hasattr(best, "box") else best["box"]

# 扩大 ROI(720p 硬编码 + 4 边裁剪)
SCREEN_W, SCREEN_H = 720, 1280
x, y, w, h = box
E = expand_offset
roi = [
    max(0, x - E),
    max(0, y - E),
    min(SCREEN_W - max(0, x - E), w + 2 * E),
    min(SCREEN_H - max(0, y - E), h + 2 * E),
]

# === Step 3: 合并到目标 pipeline ===
from maa_mcp.pipeline_tools import load_pipeline, save_pipeline
from pathlib import Path

PROJECT_ROOT = Path(__file__).resolve().parents[3]
pipeline_path = Path(pipeline_file)
if not pipeline_path.is_absolute():
    pipeline_path = PROJECT_ROOT / "assets" / "resource" / "base" / "pipeline" / pipeline_file

existing = load_pipeline(str(pipeline_path)) or {}
if node_name in existing and not overwrite:
    raise RuntimeError(f"节点 '{node_name}' 已存在")
existing[node_name] = {
    "recognition": "OCR",
    "expected": [target_text],
    "roi": roi,
    "action": action_type,
    "post_delay": post_delay,
    "timeout": timeout,
}
save_pipeline(
    pipeline_json=json.dumps(existing, ensure_ascii=False, indent=4),
    output_path=str(pipeline_path),
    overwrite=True,
)

ROI 扩大示意

原始 box:     ┌────┐
              │ 文字│
              └────┘
扩大后 roi:   ┌──────────┐
              │  ┌────┐  │
              │  │文字│  │
              │  └────┘  │
              └──────────┘

使用流程

脚本位于 .claude/skills/pipeline-generate/,所有命令从项目根目录 f:\workspace\MAAGC 运行。

步骤 1: Sweep 找最佳 expand

# 生成多个 expand 变体的测试 pipeline
python .claude/skills/pipeline-generate/generate_sweep.py "角色" "46,1248,50,30" 0,5,10,15,20,25,30

然后用 run_pipeline 逐个测试每个 Sweep_<text>_eN 节点,用 BackButton_500ms 返回大地图(详见 pipeline-testing)。记录成功的 expand 值(score ≥ 0.99 为佳)。

步骤 2: 正式生成节点

python .claude/skills/pipeline-generate/generate_node.py "角色" UI_RoleListPage main_ui.json --expand 20 --overwrite

关键经验

历史审查后的生成策略

  • 先判断节点类型,不要默认所有问题都是 OCR:稳定图标/按钮优先 TemplateMatch,颜色状态可用 ColorMatch,动态文本用 OCR,列表/复杂图像后处理用 CustomRecognition。
  • MaaGumballs 的历史文件多为平铺字段风格;M9A HEAD 多为 v5 object-form:action: { type, param }、recognition: { type, param }。生成时沿用目标文件的既有风格,不要在同一局部混用两套格式。
  • 生成链路时先画父级 next 状态机:稳定页面、成功态、弹窗 [JumpBack]、加载 [JumpBack]、危险确认分支分开建节点。
  • 对会消耗资源或改变账号状态的节点,默认生成 DoNothing 或单独验证节点;只有用户明确要执行时才生成直接点击确认。
  • 如果需要 Python,先决定是 CustomAction 还是 CustomRecognition:动作/控制流用 CustomAction;识别后处理和动态 box 返回用 CustomRecognition。
  1. ocr() 自动截图:MaaMCP 的 ocr() 工具会自行获取当前画面,调用前不要重复 screencap();如果换了 MCP provider,先读该工具的参数说明确认截图语义。

  2. ROI 不是越大越好:默认 expand=75 会失败(OCR 把"角色"拆成"电"+"色")。多数节点 sweet spot 是 expand=20-30。

  3. 特殊节点需要小 ROI:"城堡" expand≥20 全失败,只接受 0-15(上方有图标 M/3.9m/1077/👍 干扰)。

  4. expected 必须匹配当前资源实际显示文本:在 MaaGumballs 中文资源里 ["角色"] 正确、["Role"] 找不到;跨语言项目要按目标资源/locale 写实际 OCR 文本或项目约定的 i18n 形式。

  5. OCR 非确定性:同一 ROI 不同次结果可能不同,timeout: 2000 期间会重试。

  6. OCR 失败不要立刻换 TemplateMatch:先看截图、扫 ROI、检查 expected 与颜色干扰;如果目标本质是稳定图标/按钮,TemplateMatch 本来就是正确选择,不必死守 OCR。

  7. 可滚动 UI 用大 ROI + 父级 orchestrator(重要):

    • 不要在 Click 节点的 next 里放 [JumpBack]CastleSwipeDown/Up —— 找不到文字时会死循环滑动!
    • 正确模式参考 marry.json 里的 CastleHall 节点:父级 orchestrator 节点的 next 列表里放 [JumpBack]XXXEntry + [JumpBack]XXXSwipeDown + [JumpBack]XXXSwipeUp 等
    • 滚动容错 ROI 范围参考 CastleHallEntry: [60, 391, 609, 795]
  8. run_pipeline 必须有手动超时意识:超过 ~10 秒不返回要主动停止,可能 ROI/expected 配错或 OCR 引擎卡住。

  9. 改完 pipeline 文件后调 load_pipeline(path) 即可:不需要重启 server。run_pipeline 每次都按 pipeline_path 从磁盘读最新内容,reload 后立即生效。

  10. 可滚动 UI 用统一大 ROI:当多个目标在同一个可滚动列表(如城堡建筑列表)时,所有节点共用同一 ROI [x, top_y, w, full_h],覆盖整个滚动区域。避免每个节点各自 ROI 滚动后失效。前提:每个节点的 expected 文字是唯一的(OCR 按 expected 匹配不会冲突)。

  11. ROI 上边界 ≤ 元素最小 y:目标元素在 y=424 时,ROI y 起点必须 ≤ 424,否则切掉顶部导致 OCR 失败。例:原 ROI [100, 450, ...] 把"城堡管理"切掉 26px → 改为 [100, 400, ...] 通过。

  12. 卡住时截图查看:节点超时、OCR 找不到、行为异常时,调 screencap 看当前屏幕实际状态。可能界面已不在预期页、可能位置已被遮挡。

  13. 跨页面流程用 next 状态机而非 Python orchestration:当一个流程涉及多个页面跳转(如:大地图 → 活动入口 → 难度选择 → 队伍 → 战斗),用 MaaFramework 的 next + [JumpBack] 串节点。不要写 Python for/while 调 context.run_task() 模拟状态机。详见 .claude/skills/pipeline-option/SKILL.md 的「不要做 #10」和 .claude/skills/pipeline-guide/SKILL.md 的「跨页面状态机」。

  14. 跨文件节点引用在 run_pipeline 测试中会失败:MaaFramework 全局加载时所有 assets/resource/base/pipeline/*.json 合并到同一命名空间,[JumpBack]OtherFileNode 能解析。但 run_pipeline 只加载单文件,跨文件引用会报"加载 Pipeline 失败"。应对:

    • 单元测试每个节点用 run_pipeline(无跨文件依赖的子流程)是 OK 的
    • 含跨文件引用的状态机流程,集成测试必须用 MaaFramework GUI/CLI 触发
    • 调试时可考虑 MaaCli 命令行运行全 bundle

已验证最优 expand(5 节点实测)

节点expandscore备注
UI_RoleListPage200.9997中部偏左
UI_RoleFormationPage200.998角色右边
UI_CastlePage30.997⚠️ 仅 0-15
UI_TeamPage200.997城堡右边
ClickGoToArchipelago200.991中间大地图按钮

用 color_filter 减少 OCR 干扰(实战技巧)

场景:ROI 里同时有目标文字 + 周边装饰(如"0/31"绿色能量条 vs "0/23"绿色节点数),OCR 可能误识别装饰色块。

方案:先建一个 ColorMatch 节点(限定像素颜色范围),然后在其他 OCR 节点上加 color_filter 字段引用它。

"AutoSky_GreenCheck": {
    "recognition": "ColorMatch",
    "roi": [558, 802, 157, 45],
    "method": 4,
    "lower": [22, 123, 57],      // RGB 下界(暗绿)
    "upper": [55, 215, 102],     // RGB 上界(亮绿)
    "action": "DoNothing",
    "post_delay": 200,
    "timeout": 2000
},

"AutoSky_CheckEnergyZero": {
    "recognition": "OCR",
    "expected": ["0/\\d+"],
    "roi": [850, 1280, 220, 50],
    "color_filter": "AutoSky_GreenCheck",  // ← 只在绿色区域 OCR
    "action": "DoNothing"
}

取色技巧(用截图工具):

  • 目标区域:取目标装饰/边框色(非文字色,文字一般会变色)
  • RGB 范围要宽松一些(±20),覆盖光照变化
  • method=4 是 RGB(0=HSV)

实战案例:本项目(MaaGumballs)用这个方法区分"能量条 0/31"vs"节点数 0/23",两者都是绿色 OCR 文本,周围装饰色也不同。

已验证:可滚动 UI 统一 ROI(10 城堡建筑)

节点统一 ROIscore备注
CastleManage[100, 400, 520, 880]0.999顶部
Market同上0.999顶部
Blacksmith同上0.998顶部
AlchemyWorkshop同上0.999顶部
TrainingCenter同上1.000顶部
CastleMainHall同上0.876顶部只露 25px
Shrine同上0.999中段
Family同上0.999中段
Museum同上0.999底部
Manor同上0.999底部

关键设计:

  • 所有节点 ROI 完全相同([100, 400, 520, 880],覆盖 y=400-1280)
  • 不靠 expand 微调,靠 expected 文字差异让 OCR 区分
  • 不放 next 链(避免死循环)

跨页面状态机流程(用 next + [JumpBack])

当生成的活动流程需要跨多个页面跳转(如:大地图 → 活动入口 → 难度选择 → 队伍 → 战斗),用 MaaFramework 的 next + [JumpBack] 机制串接各页面节点,不要写 Python orchestration。

模式:状态机入口节点

{
    "MyActivity_Start": {
        "next": [
            "MyActivity_TeamReady",                      // 已在队伍配置页 → 点击"进入战斗"
            "[JumpBack]MyActivity_Difficulty_Select",     // 在难度选择页 → 选难度
            "[JumpBack]MyActivity_Enter"                 // 在大地图 → 找入口
        ],
        "timeout": 10000
    },

    "MyActivity_Enter": {
        "next": [
            "MyActivity_Enter_Click",                    // 找到图标 → 点击
            "[JumpBack]BigMap_Activity_Resident",         // 切"常驻"tab
            "[JumpBack]BigMap_Activity"                  // 打开活动页
        ],
        "timeout": 10000
    },

    "MyActivity_EnterBattle": {
        "recognition": "OCR",
        "expected": ["进入战斗"],
        "action": "Click",
        "next": [
            "MyActivity_FightStart",                       // 战斗开始
            "[JumpBack]MyActivity_TravelSelect_Boat",      // 乘船
            "[JumpBack]MyActivity_TravelSelect_Walk"       // 步行 fallback
        ]
    },

    "MyActivity_TravelSelect_Boat": {
        "recognition": "OCR",
        "expected": ["确定"],
        "roi": [490, 740, 100, 80],                     // 窄 ROI 限定乘船行
        "action": "Click"
    },

    "MyActivity_TravelSelect_Walk": {
        "recognition": "OCR",
        "expected": ["确定"],
        "roi": [490, 590, 100, 80],                     // 窄 ROI 限定步行行
        "action": "Click"
    }
}

关键设计要点

  1. [JumpBack] 是状态回退的关键:命中后执行完节点链,自动返回父节点的 next 继续。
  2. 窄 ROI 区分同名字段:用 y 范围 [490, 740, 100, 80] vs [490, 590, 100, 80] 区分两个"确定"按钮行(y 范围不重叠)。
  3. target_offset 偏移点击:识别难度文字后用 target_offset: [270, 0, 0, 0] 把点击位置右移到"确定"按钮上。
  4. 跨文件节点引用:MaaFramework 全局加载会合并所有 pipeline/*.json,所以 [JumpBack]BigMap_Activity(在 main_ui.json)能从 growth_trial.json 引用。但 run_pipeline 测试只加载单文件,集成测试需用 GUI/CLI。

与 Python orchestration 的本质区别

状态机(推荐)Python orchestration(次选)
流程推进由 MaaFramework 调度自己写 for/if 调度
每个节点 next 显式声明后继Python 函数串行 run_task
[JumpBack] 自动状态回退手动实现回退逻辑
跨页面异常有自然路径需手动 try/except

详见 .claude/skills/pipeline-option/SKILL.md 的「不要做 #10」和 .claude/skills/pipeline-guide/SKILL.md 的「跨页面状态机」典型模式。

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

生成 MaaFramework Pipeline 项目的可交互状态机图谱。当用户想"看 Pipeline 节点关系"、"画状态机图"、"画 Mermaid 图"、"看 node 间关系"、"找孤立节点 / orphan node"、"看 Python 怎么驱动 Pipeline"、"看 interface.json 入口"、"调试跨文件 next 引用"、"重构前理清架构" 时使用。**任何涉及 MaaFramework 节点关系可视化的需求都用这个 skill**,即便用户没明确说"画图"。

日本語の概要は準備中です。原文の説明を表示しています。

KhazixW2/MaaGumballs672026年10月2日 更新

Universal Pipeline JSON 编写指南。基于 MaaFramework Pipeline 协议,提供节点命名、识别算法、动作类型、流程控制、可复用节点等编码规范与模式参考。在编写、修改或审查 Pipeline JSON、设计节点流程、使用 TemplateMatch/OCR/Custom 识别或 Click/Swipe 动作时使用。

日本語の概要は準備中です。原文の説明を表示しています。

KhazixW2/MaaGumballs672026年10月2日 更新

Audit a MaaFramework/Maa-series project's Git history to learn how Pipeline JSON, interface options, Python AgentServer CustomAction code, and related data tables evolved. Use when asked to review a Maa project from initial commit through a target commit, map `action: Custom` pipeline nodes to `@AgentServer.custom_action(...)` implementations, find pipeline/custom/option patterns or breakages, and produce a report plus skill-improvement recommendations.

日本語の概要は準備中です。原文の説明を表示しています。

KhazixW2/MaaGumballs672026年10月2日 更新

Add runtime UI options (select/checkbox/switch/input) to MaaFramework option surfaces such as `assets/interface.json` or `assets/resource/tasks/**/*.json`. Use when adding a user-facing toggle, selector, checkbox, or input; wiring options to `pipeline_override`; aligning option paths with Python `context.get_node_data()` or CustomAction params; or reviewing option behavior across Pipeline JSON and Python.

日本語の概要は準備中です。原文の説明を表示しています。

KhazixW2/MaaGumballs672026年10月2日 更新

Test and validate MaaFramework Pipeline JSON, recognition nodes, action nodes, CustomAction/CustomRecognition wiring, resource loading, and end-to-end task behavior. Use when running `run_pipeline`, checking OCR/TemplateMatch/ColorMatch ROI, validating `context.run_task()` results, auditing `action: Custom` or `recognition: Custom` registrations, or choosing the right resource-check command.

日本語の概要は準備中です。原文の説明を表示しています。

KhazixW2/MaaGumballs672026年10月2日 更新

KhazixW2 のスキルをすべて見る

このスキルの問題を報告する