Skip to content
cccskills
FreePublished on GitHub

pipeline-testing

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.

The English summary is being prepared. Showing the original description.

See how to install

Files included (4)

  • SKILL.md12.1 KB
  • evals/evals.json1.1 KB
  • maahub_meta.json578 B
  • README.md316 B

SKILL.md (original)

Review the instructions the agent will receive before you install.

Pipeline Testing Skill

概述

测试 MaaFramework Pipeline JSON 中的 node,验证识别和操作是否正常工作。

历史审查后的测试边界

  • 资源加载检查是 smoke test,不是端到端证明:python tools/ci/check_resource.py assets/resource/base 能证明资源包可加载,但不能证明 CustomAction/CustomRecognition 名称存在、参数路径正确、run_task() 分支判断正确。
  • Custom 映射必须单独查:所有 action: Custom / action.type = Custom 的 custom_action 都要能映射到 @AgentServer.custom_action(...);所有 recognition.type = Custom 的 custom_recognition 都要能映射到 @AgentServer.custom_recognition(...)。
  • CustomRecognition 也要测:M9A 证明复杂 OCR/list/image 逻辑经常放在 CustomRecognition,不要只测 CustomAction。
  • 高风险链路要复测稳定态:购买、消耗、战斗开始、继续挑战、结算确认等动作后,先识别稳定页面或完成态,再继续危险动作。
  • 关闭节点不能继续调用:当 option 把可执行节点的 enable/enabled 设为 false 时,Python 必须先短路,不能再调用该节点的 run_recognition()/run_task();同时验证关闭可选分支后,同级战斗/调查分支仍会继续识别。

Custom 映射快速检查

rg -n '"Custom"|custom_action|custom_recognition' assets/resource -g '*.json'
rg -n '@AgentServer\.custom_action|@AgentServer\.custom_recognition' agent -g '*.py'

人工对照时按名字精确匹配。资源检查通过但这里缺注册,运行时仍会失败。

核心流程

# 1. 连接设备
find_adb_device_list()
controller_id = connect_adb_device(device_name="xxx")
# 或
controller_id = connect_window(window_name="xxx")

# 2. 加载 pipeline
load_pipeline(pipeline_path="<pipeline_json>")
RESOURCE_PATH = "<resource_base_path>"

# 3. 逐个测试
for node_name in pipeline_nodes:
    result = run_pipeline(
        controller_id=controller_id,
        pipeline_path=pipeline_path,
        entry=node_name,
        resource_path=RESOURCE_PATH
    )
    # succeeded + all_results 有内容 = 识别成功
    # 详见下方"结果判断"小节

结果判断

statusall_results含义
succeeded有内容✅ 识别成功
succeeded空❌ 识别失败
failed—❌ 节点未触发 / 识别超时

返回结构:

{
  "status": "succeeded",
  "nodes": [{
    "name": "node_name",
    "recognition": {
      "all_results": [{"box": [x, y, w, h], "score": 0.99, "text": "..."}]
    }
  }]
}

run_task() 结果判断 ⚠️

MCP 的 run_pipeline 单节点结果和 Python CustomAction 里的 context.run_task() 结果不是同一个使用场景。context.run_task() 的 result.nodes 可能包含:

  • 真正命中并执行完成的节点
  • next 列表里被尝试过但失败的节点
  • 调试面板显示红叉的节点

因此不要写:

# ❌ 错:有 nodes 不代表目标节点命中
result = context.run_task("AutoSky_CloneDied")
if result and result.nodes:
    handle_clone_loss()

应该检查节点是否真的完成或识别命中:

def task_result_has_hit(result, names: set[str]) -> bool:
    if not result or not result.nodes:
        return False
    for node in result.nodes:
        if getattr(node, "name", None) not in names:
            continue
        if getattr(node, "completed", False):
            return True
        recognition = getattr(node, "recognition", None)
        if recognition and getattr(recognition, "hit", False):
            return True
    return False

实战信号:调试面板里目标节点是红叉,但日志却进入了成功分支,基本就是把"节点出现过"误当成"节点命中"。

对于会回到稳定页面的流程,建议先检测稳定状态:

if task_result_has_hit(result, {"AutoSky_CheckExplorationInfo"}):
    return "done"

再跑危险兜底动作(取消结算、购买确认、继续挑战等),避免页面已经回稳后误触发。

跨测试导航 ⚠️

Click 节点会让页面跳转,破坏后续测试初始状态。必须用 BackButton_500ms 返回:

# 测试节点
run_pipeline(..., entry="NodeA", ...)

# 必须返回!不要 click_key(4) 模拟 ESC(可能进错页面)
run_pipeline(..., entry="BackButton_500ms", ...)

# 测下一个
run_pipeline(..., entry="NodeB", ...)

BackButton_500ms 在 main_ui.json 里,DirectHit 识别返回箭头,定位精确可靠。

ROI Sweep 测试方法

OCR 失败时不要换 TemplateMatch!先用 sweep 找 sweet spot。

操作流程:

  1. 生成测试 pipeline — 同一节点,多个 expand 变体
  2. 关键:expected 必须匹配当前资源实际显示文本;在 MaaGumballs 中文资源里是 ["角色"],不是英文 key ["Role"]
  3. run_pipeline 逐个跑,记录 score
  4. 选 score ≥ 0.99 且 ROI 不重叠相邻元素的 expand
  5. 用 generate_node.py --expand X --overwrite 正式写入

实战矩阵(5 节点实测):

节点e0e20e50最佳
角色✅✅ 0.9997✅e20
编队✅✅ 0.998✅e20
城堡✅❌—e3(仅 0-15)
佣兵团❌✅✅e20
前往群岛✅✅✅e20

观察:

  • OCR 引擎非确定性:同一 ROI 不同次测试结果可能不同
  • timeout: 2000 期间 OCR 会重试多次,所以单次失败不一定是真失败
  • 特殊节点(如"城堡")需小 ROI,因为大 ROI 包含邻近 UI 元素会干扰 OCR

资源保护 ⚠️

测试时绝对不要点击这些按钮(消耗资源):

  • 升级建筑、神殿升级
  • 供奉、祭拜先祖
  • 购买物品、商城购买
  • 确认战斗开始
  • 任何有资源消耗的确认按钮

误入后处理:尝试 BackButton_500ms 或 ESC → 切换 tab 刷新。

常见问题

现象排查
节点超时失败截屏看实际界面 → 调整 expected 文本或 roi
OCR 拆分多字(如"角色"→"电"+"色")缩小 ROI 避开干扰
误识别相邻文字缩小 ROI 限制范围
点击位置不准实际点击取 box 中心点:x + w/2, y + h/2
可滚动 UI 单视图测不全一个截图里只能看到 5-6 个元素,需要 swipe 多次分别测;详见下方
Click + BackButton 跳错页面Click 子页后按 BackButton 可能回到大地图/外层 UI,不是预期父页面;需主动 navigate 回来
部分可见元素识别边界处只露 25px 也能 OCR 找到(score 偏低 0.8x),用大 ROI 覆盖即可

可滚动 UI 多视图测试

单次截图只能测当前可见的 5-6 个元素。要测全列表(如城堡 10 个建筑)必须多次 swipe:

1. 进入目标页(如城堡顶部)
2. run_pipeline 测当前可见的 N 个节点
3. 每个 click 后 BackButton 返回
4. swipe 滚动一屏
5. 再 run_pipeline 测新可见的节点
6. 重复直到列表测完

典型案例:城堡建筑(10 节点)

  • 顶部:城堡管理/市场/铁匠铺/炼金工坊/训练所
  • 中段:城堡主厅/神殿/家族
  • 底部:藏馆/庄园

关键:所有节点共用同一大 ROI [x, top_y, w, full_h],不要给每个节点算不同 ROI(滚动后位置变了,原 ROI 失效)。

卡住时截图查看

症状:节点超时、OCR 找不到、行为异常、识别 score 突然下降

解决:调 screencap(controller_id) 看实际屏幕状态:

  • 当前在哪个页面?(是否已跳到其他页面)
  • 目标文字是否被遮挡/弹窗挡住?
  • 屏幕是否在加载/转圈?
  • 滚动位置对吗?

配合 ocr() 看识别结果交叉验证。不要盲调 ROI/expected,先看实际屏幕。

跨测试导航 ⚠️(Click 节点路径风险)

Click 节点会让页面跳转,破坏后续测试初始状态。必须用 BackButton_500ms 返回:

# 测试节点
run_pipeline(..., entry="NodeA", ...)

# 必须返回!不要 click_key(4) 模拟 ESC(可能进错页面)
run_pipeline(..., entry="BackButton_500ms", ...)

注意:BackButton 不一定回到你期望的父页面!

  • 例:城堡管理 → BackButton → 实际回到 大地图(不是城堡)
  • 例:训练所 → BackButton → 回到城堡(正常)

测试前先确认 BackButton 路径,或者用 ocr() 检查当前页面状态再继续。

⚠️ MCP start_agent=true 失败时的 Fallback 方案

症状:run_pipeline(..., start_agent=true) 报

Agent 启动失败: Agent 启动失败 (identifier=12345): connect() 返回 False

根因(常见):

  1. MaaFramework 的 agent 子进程(socket 进程)未在预期时间窗口内完成 MaaAgentServerStartUp
  2. Socket 路径冲突 / 权限问题
  3. MaaFramework 内部 MaaAgentServerNotImpl(这个错误明确说"用 MaaFramework,不要用 MaaAgentServer")

Fallback 1:单节点测试(推荐):

用 start_agent=false + 指定 entry 测单个节点(只测 OCR/Template 识别,跳过 CustomAction 链):

# 不开 agent,直接测某个节点
result = run_pipeline(
    controller_id=cid,
    pipeline_path="f:/workspace/MaaGumballs/assets/resource/base/pipeline/sky.json",
    entry="AutoSky_BagConfig",   # 任意节点名
    resource_path="f:/workspace/MaaGumballs/assets/resource/base",
    start_agent=False,          # ← 关键:false
)

适用场景:测 OCR / TemplateMatch / ColorMatch 等识别节点的 ROI 和 expected 文本是否正确。

Fallback 2:手动启动 agent 后 MCP 通过 socket 连接:

如果单节点测试不够(需测完整任务链),手动跑 agent 进程,然后用 connect_adb_device / connect_window 让 MCP 复用。

# 步骤 1:手动启动 agent
import subprocess
agent_proc = subprocess.Popen(
    ["python", "agent/main.py", "test_socket"],
    cwd=".",
)

# 步骤 2:让 MCP 连接(需要 MCP 内部 socket ID 匹配)
# 实际中,MCP 启动 agent 会自动起 socket,如果手动起需要 MCP 端配对
# 通常这一步是 MCP 内部行为,我们无法直接控制

Fallback 3:放弃 MCP,直接用 MaaFramework Python API:

import sys
sys.path.insert(0, "f:/workspace/MaaGumballs")
from maa.agent.agent_server import AgentServer
from maa.toolkit import Toolkit
from maa.resource import Resource
from maa.controller import AdbController
from maa.tasker import Tasker

Toolkit.init_option("./")
res = Resource(); res.post_bundle("./assets/resource/base").wait()
ctrl = AdbController(adb_path="adb", address="127.0.0.1:16384"); ctrl.post_connection().wait()
tasker = Tasker(); tasker.bind(res, ctrl)

import action.sky
autosky = action.sky.AutoSky()
result = autosky.run(tasker.context, type('X', (), {'custom_action_param': '{}'})())

何时用哪种:

  • Fallback 1(单节点):调试 ROI / expected / TemplateMatch,快速迭代 → 首选
  • Fallback 3(直接 API):测完整 task 链,真实环境验证 → MCP 不可用时用
  • Fallback 2(手动起 agent):通常不需要,MCP 会自动处理

测试模板

## <文件名> 测试记录

日期: 2026-06-05
设备: xxx
controller_id: xxx

### Node 列表
- [ ] node_name_1
- [ ] node_name_2

### 测试进度
| Node | 结果 | 备注 |
|------|------|------|
| xxx  | ✅   | score=0.999 |
| xxx  | ❌   | 原因xxx |

Reference(详见 pipeline-guide)

  • ROI / box / target 概念
  • 识别类型:DirectHit / OCR / TemplateMatch / FeatureMatch / ColorMatch / And / Or
  • 动作类型:Click / LongPress / Swipe / Scroll / InputText / ClickKey
  • 节点生命周期:pre_wait_freezes → pre_delay → action → post_wait_freezes → post_delay → 截图识别 next

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

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.

The English summary is being prepared. Showing the original description.

KhazixW2/MaaGumballs70Updated Oct 15, 2026

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

The English summary is being prepared. Showing the original description.

KhazixW2/MaaGumballs70Updated Oct 15, 2026

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

The English summary is being prepared. Showing the original description.

KhazixW2/MaaGumballs70Updated Oct 15, 2026

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.

The English summary is being prepared. Showing the original description.

KhazixW2/MaaGumballs70Updated Oct 15, 2026

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.

The English summary is being prepared. Showing the original description.

KhazixW2/MaaGumballs70Updated Oct 15, 2026

See all skills by KhazixW2

Report a problem with this skill