EmbodiFlow文档
开始使用数据工作流与算法训练与部署开发者参考
  • 工作流与算法

工作流

  • 认识工作流
  • 搭建自己的工作流
  • 运行与日志

算法

  • 算法目录
  • 编写自定义算法

算法开发指南

  • 第一个算法
    • 标准化
    • 质检
    • 变换
    • 增强
    • 切分
    • 整理
    • 导出
  • 镜像算法
  • 在工作流中使用算法
  • 接口参考
  • SDK 参考
  • 命令行
  • MCP 工具
  • 问题排查

© 2026 EmbodiFlow

llms.txtOpenAPI JSON
  1. 工作流与算法
  2. 算法开发指南
  3. 接口参考

接口参考

算法能声明的一切:装饰器参数、特征、参数、语义类型、事实、资源、结束方式和版本。

在 Python 算法里,main.py 中的装饰器和 Params 数据类就是接口,文件里其余的部分只是具体工作。把两者分开,平台才能不运行你的代码,就在编辑器里显示端口、检查工作流的连接、建议版本号。

保存时,平台静态读取接口,并随版本冻结为 algorithm.yaml。运行时,SDK 会按装饰器重新构建接口,如果和冻结的不一致就拒绝启动(ALGORITHM_MANIFEST_DRIFT)。

装饰器参数和 param(...) 的默认值必须是字面量:字符串、数字、布尔值、列表、字典,以及 SDK 构造器 Feature、Check、Input 和 param。其他写法都会被 ALGORITHM_FILE_INVALID 拒绝,提示里会写出是哪一行。
测试阶段。自定义算法和工作流已经在产品里,可以直接试用,但还没有在真实数据上完成完整验收。可能会遇到不完善的地方,依赖结果之前请先核对。

装饰器参数

参数必填规则
name、title是name 由小写字母、数字和 - 组成,长 2 到 63,以字母开头,在算法的整个生命周期内不变。团队算法名称不能以 ef- 或 embodiflow- 开头。
description否显示在算法库中。
level否check 和 enrich:recording(默认)或 episode。
reads录制级 checkraw 或 recording(默认)。
inputs否额外的 features 输入:Input(requires=[…], optional=False)。名称由小写字母、数字和 _ 组成,最长 32,且不能是数据类型名、默认端口名或 run 的参数名。
featuresenrich至少一个 Feature(...)。
checkscheck;任何会写出质检结果的类别Check(id, title, description="")。
labelssegment任务片段携带的标签键:{键: 语义类型}。
requires否数据必须具备的事实,见下文。
params否一个数据类,每个字段都是 param(default, …)。
resources否见下文。
requirements否pip 依赖字符串,只用二进制 wheel,保存时锁定。
retries、cache否默认:暂时性错误重试一次,开启缓存。
services否仅内置算法:["vlm"]。
privacy否仅内置算法:"redacts" 或 "numbers_only"。

代码里不写 version。保存时,平台会根据接口的变化建议下一个版本。

数据类型

端口带有八种数据类型之一,只有类型相同的端口才能连接。

类型含义
raw一条录制上传的文件。
recording标准录制:LeRobot v3 目录树加 meta/embodiflow/recording.json。
features关于录制或其任务片段的新数值。
checks判断结果,每条带一个状态。
episodes带任务文字的时间段。
version一个数据集版本。
selection逐个任务片段的决定:保留、划分、任务。
artifact可下载的文件。

Feature

特征的声明方式是 Feature(name, type, per, dtype=…, shape=…, unit=…, frame=…, names=…, source=…, describe=…)。

字段含义
name短名称。平台会以团队专属的名称保存。
type下表中的语义类型。
perframe、recording、episode 或 file。
dtypefloat32(默认)、float64、int8、int16、int32、int64、uint8 或 uint16。
shape单个值的形状。数组类型有固定的默认形状。
unit、frame几何类型必填,按 file 保存的除外。
names各分量的名称,例如关节名。
sourcerecorded、imported、estimated、computed(默认)或 retargeted。
describe补充说明,例如重定向动作的 {"targetRig": "tron2av3"}。

参数

参数是工作流不改代码就能调整的设置。Params 的每个字段都是 param(default, minimum=…, maximum=…, enum=…, title=…, description=…, widget=…),类型来自注解:int、float、str、bool,或者字符串、整数、浮点数的列表。

列表字段用字面量列表作默认值,还可以使用 items_enum、min_items 和 max_items。控件 tags 接受自由字符串,multiselect 需要 items_enum。工作流在 with 里设置取值,平台会按这些限制检查。

语义类型

特征的语义类型告诉下一步这些数字是什么意思,编辑器正是靠它判断哪些输出可以连到要求 keypoints3d.hand21 之类类型的输入。注册表是封闭的,团队按原样使用这些类型。

类型含义形状或取值
scalar一个数[1]
vector一组数[n]
label.bool是否标签bool
label.category声明集合中的一个字符串;describe.values
label.text自由文本字符串
spans任务片段或录制内的时间段{ startS, endS, label } 列表
embedding嵌入向量[n];describe.model
pose.se3位置加四元数[7]:x y z qx qy qz qw;unit、frame
keypoints3d.hand213D 手部 21 个关键点,MediaPipe 顺序[63];unit、frame
skeleton.hand2121 个手部关节,各带 6 自由度位姿,MediaPipe 顺序[147] = 21 x (x y z qx qy qz qw);unit、frame
skeleton.body2222 个身体关节,各带 6 自由度位姿,SMPL 顺序(骨盆在前)[154] = 22 x (x y z qx qy qz qw);unit、frame
keypoints2d2D 图像关键点[2k];frame 为相机
confidence每个样本 0 到 1 的置信度[n]
calibration.stereo校正后的双目外参{ R[9], T[3] }
calibration.cam_imu相机到 IMU 的变换和时间偏移{ R[9], T[3], dtS }
depth.video16 位深度视频文件
mask.video逐帧掩码视频文件
video.preview单路相机视频的轻量浏览器预览副本,帧不变文件,embodiflow-preview/v1
ros2.mcapROS 2 MCAP 文件(TF 树、图像、点云、标记)文件
action.joint关节空间动作[n];names
action.ee_pose末端执行器动作[7],带夹爪时为 [8]
json任意小型 JSON对象,最大 1 MiB;requires 只能用 name:<特征名> 匹配

事实与 requires

事实是平台对数据的了解,全部从数据本身推导,不由人填写。你的代码通过 ctx.facts 读取它们,requires 则用它们判断算法到底适不适用。

事实类型来源
kindrobot 或 human项目
format字符串:mcap、lerobot、video 或 x-<自有格式>上传
privacy_requiredbool录制档案
duration_s数字先看上传摘要,再看录制,最后看任务片段窗口
cameras整数先看上传摘要,再看录制
stereobool录制:带内参的双目对
imubool录制:IMU 列
actionbool录制:存在 action 特征
recorded_hand_posebool录制:录制得到的手部关键点
gripper_widthbool录制:夹爪宽度列
episodes整数数据集版本:任务片段数量

requires 把事实映射到 true、false、与取值相等的字符串,或 ">=2"、"<600" 这样的比较式。只要有一个条件不成立,步骤就以「不适用」结束:显示为灰色,不算失败。未知的事实永远不满足条件,所以步骤会是「不适用」,而不是靠猜测去运行。你的代码也可以在运行时用 ctx.not_applicable(code, message) 自行决定。

资源

键默认值含义
cpu4CPU 核数。
memory8Gi内存,例如 8Gi 或 16Gi。
disk10Gictx.tmp 使用的临时空间。
gpuNoneNone,或 {"count": 1, "memoryGb": 16}。
timeout30m时长,例如 20m,或 {"perInputMinute": …, "min": …, "max": …}。

每个步骤至少获得 4 个 CPU 核和 8Gi 内存,申请 GPU 时至少 8 GB 显存;写得更小也按这个下限运行。资源必须能放进一台机器,申请的 GPU 超过所有资源池时,会被 ALGORITHM_GPU_UNSATISFIABLE 拒绝。

申请 GPU 的算法会自动运行在 CUDA SDK 基础镜像上,已预装 PyTorch 和 CUDA 13,你不需要自己选基础镜像。它的试跑同样使用 GPU,等 GPU 有空余时才开始;没有 GPU 的部署会以 ALGORITHM_SAMPLE_RUN_GPU_UNSUPPORTED 拒绝。

GPU 试跑还没有在全新安装的部署上完整验证过。如果遇到异常,请把运行 ID 发给我们。

代码如何结束

代码以什么方式结束,就告诉了平台发生了什么,不同的方式会让步骤以不同的状态结束。镜像算法用退出码表达同样的结果。

Python退出码(镜像)含义步骤结束为
return0完成。成功
ctx.not_applicable(code, msg)85这份数据不归我处理。不适用
ctx.input_unusable(code, msg)87数据已损坏。失败;录制被隔离
raise TransientError(msg)88请重试:网络问题、GPU 忙。重试,然后失败
其他任何异常1程序错误。失败;回溯在日志里

code 由大写字母、数字和 _ 组成,长 3 到 64。步骤信息的格式是 <code>: <message>。

版本与引用

工作流用 embodiflow/<name>@<major> 或 team/<name>@<major> 引用算法,每次运行都使用该主版本下已保存的最高版本。这样,修复会在下一次运行时自动生效,而破坏性的改动要等你切换到新的主版本。

端口、level、requires、声明的特征、质检项或标签,或者参数的类型发生变化,都属于破坏性改动,需要升主版本;按次版本保存会被 ALGORITHM_INTERFACE_CHANGED 拒绝。已保存的版本永远不变。

run 如何被调用

run 每条录制调用一次;任务片段级每个任务片段调用一次;整理和导出则每个数据集版本调用一次。参数按名称绑定,需要哪个就写哪个,顺序随意。

参数得到
raw、recording、version主输入。
episode仅任务片段级:正在处理的任务片段。
额外输入的名称一个 Features 对象;输入可选且缺席时为 None。
out该类别的写入器。
ctx上下文:params、facts、recording_id、run_id、step_id、tmp、log、progress(done, total, message)、not_applicable 和 input_unusable。
statesetup(ctx) 的返回值。

用 setup(ctx) 只加载一次模型。目前平台每个任务调用它一次;以后的版本可能在一个任务里处理许多条目,仍然只调用一次 setup,你的代码不需要任何改动。正因为如此,run 不能在全局变量里保存随条目变化的状态。

下一步

  • SDK 参考
  • 镜像算法
上一页

在工作流中使用算法

下一页

SDK 参考