LeRobot documentation

编写文档字符串

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

编写文档字符串

LeRobot 的 API 参考文档直接由 src/lerobot/ 中的 docstring 生成。docstring 并非注释,而是该对象的正式文档,以下格式是渲染器和 CI 检查所解析的格式。

此页面即为约定。如果您要在 src/lerobot/ 中添加或编辑任何公开内容,请遵循此约定。

未记录的公开方法就是不可见的方法。 [[autodoc]] 会静默跳过没有文档字符串的成员——没有警告,没有错误,它只是不会出现在渲染后的页面上。覆盖率和 API 参考的完整性是同一个问题。

一个示例中的格式

Google 章节标题,Hugging Face 类型格式。两者兼备,而非二选一。

def send_action(self, action: RobotAction, rate_hz: float = 30.0) -> RobotAction:
    """Command the robot to move to a target joint configuration.

    Values are clipped by the configured maximum relative target before reaching the motors, so the
    returned action may differ from the requested one.

    Args:
        action (`dict[str, float]`):
            Target values keyed by motor name, e.g. `{"shoulder_pan.pos": 0.0}`. Keys must match the
            robot's action features.
        rate_hz (`float`, *optional*, defaults to `30.0`):
            Control loop frequency.

    Returns:
        `dict[str, float]`: The action actually written to the motors after safety clipping.

    Raises:
        DeviceNotConnectedError: If the robot has not been connected.

    Example:
        ```python
        >>> from lerobot.robots.so_follower import SO101Follower, SO101FollowerConfig
        >>> robot = SO101Follower(SO101FollowerConfig(port="/dev/ttyACM0"))  # doctest: +SKIP
        >>> robot.connect()  # doctest: +SKIP
        >>> robot.send_action({"shoulder_pan.pos": 0.0})  # doctest: +SKIP
        ```
    """

本页示例中省略了交叉引用——有关其语法以及为何无法在代码块中显示的原因,请参阅交叉引用。

规则

章节

Args: · Returns: · Raises: · Yields: · Example: · Note:

按此顺序。不要使用其他章节标题。首先是一行摘要,然后是可选的自由格式描述,最后是各个章节。

Args: 行会被机器解析

name (`type`, *optional*, defaults to `X`):
    Description, indented on its own line.

The *optional*, defaults to clause is checked against the real signature default by make check-docstrings. It is not decorative — if you write a default that has drifted from the code, CI fails. Omit the clause entirely for required parameters:

    Args:
        port (`str`):
            Serial port the arm is connected to, e.g. `/dev/ttyACM0`.
        max_relative_target (`float | dict[str, float]`, *optional*):
            Caps the magnitude of the relative positional target vector. `None` disables clipping.
        use_degrees (`bool`, *optional*, defaults to `True`):
            Keep `True` for backward compatibility with existing policies and datasets.

类型应使用反引号。当默认值为 None 或无需重复说明时,请使用 *optional*,而不使用 defaults to。

返回:类型优先

缩进一行的格式,先输入类型,然后输入冒号,最后输入描述:

    Returns:
        `dict[str, float]`: The action actually written to the motors after safety clipping.

Yields: 形状相同。

**属性**:, 永不 属性:

doc-builder 会将单独的 Attributes: 解析为 Parameters: 的同义词,因此您的属性会被渲染为构造函数参数。这种处理是静默的且错误的。只要属性与构造函数参数不同,请使用带有 -- 分隔符的粗体形式:

class Robot(abc.ABC):
    """The base abstract class for all LeRobot-compatible robots.

    **Attributes**:
        - **config_class** (`type[RobotConfig]`) -- The expected configuration class for this robot.
        - **name** (`str`) -- The unique robot name used to identify this robot type.
    """

注意 --,而不是 :。

交叉引用

使用 doc-builder 的括号语法:用方括号括起来的反引号路径。不支持 Sphinx 角色(:pymeth:、:pyattr:),它们会在页面上以纯文本形式显示。

想要写入
主包中的类[Robot]
方法,显示完整路径[Robot.connect]
方法,显示裸名称[~Robot.connect]
嵌套路径[~robots.Robot.connect]
另一个 HF 库中的对象[~accelerate.Accelerator]

~ 仅从 链接文本 中去除路径;链接仍会解析为完整路径。

doc-builder 会在页面的所有位置解析此语法——包括围栏代码块内部。这就是为什么本页上的 docstring 示例使用普通文本而非交叉引用:包含交叉引用的代码块会渲染出解析后的链接,而不是你需要输入的语法。在你自己的 docstring 中,请随意使用交叉引用;此限制仅影响关于该语法的文档 about。

提示

使用 GitHub 风格的引用块:

> [!TIP]
> Call this once at startup — it takes about two seconds.

> [!WARNING]
> Torque is disabled on disconnect. The arm will drop if it is holding a load.

<Tip> 组件在 doc-builder 中属于遗留组件;请勿再添加新的此类组件。

示例必须使用围栏

示例位于一个包含 >>> 的围栏式 ```python 代码块中。正是这个围栏使其渲染为代码块,也是 doctest 预处理器正则表达式所查找的内容:

    Example:
        ```python
        >>> from lerobot.robots.so_follower import SO101FollowerConfig
        >>> cfg = SO101FollowerConfig(port="/dev/ttyACM0")
        >>> cfg.use_degrees
        True
        ```

未加围栏的 >>> 仍会被收集——doctest 会在 docstring 的任何位置查找提示符。你失去的是渲染效果,因此它在页面上会显示为一整段文字。每个示例都需要围栏。

每个示例要么在 CI 中执行,要么带有 # doctest: +SKIP。任何涉及硬件、GPU 或从 Hub 下载内容的示例都会添加 +SKIP:

    Example:
        ```python
        >>> robot.connect()  # doctest: +SKIP
        >>> policy = ACTPolicy.from_pretrained("lerobot/act_aloha_sim_transfer_cube_human")  # doctest: +SKIP
        ```

将包含可运行示例的文件添加到 utils/documentation_tests.txt 中。

将示例放在模块的三个到五个真正的入口点上。在琐碎的访问器上放置示例只会带来噪音。

你会经常遇到的三种模式

配置数据类

配置字段在历史上是通过每个字段上方的 # 注释来记录的。doc-builder 无法识别行内注释——这样的类在渲染时会列出所有字段,但没有任何描述。请将它们移到类文档字符串中的 Args: 块中:

@dataclass
class SOFollowerConfig:
    """Configuration for SO-family follower arms.

    Args:
        port (`str`):
            Serial port the arm is connected to, e.g. `/dev/ttyACM0`.
        max_relative_target (`float | dict[str, float]`, *optional*):
            Caps the magnitude of the relative positional target vector. A scalar applies to all motors;
            a dict maps motor name to a per-motor cap. `None` disables clipping.
        use_degrees (`bool`, *optional*, defaults to `True`):
            Keep `True` for backward compatibility with existing policies and datasets.
    """

    port: str
    max_relative_target: float | dict[str, float] | None = None
    use_degrees: bool = True

doc-builder 不会从基类继承 docstring。LeRobot 中注册的配置类通常是薄弱的多重继承垫片:

@RobotConfig.register_subclass("so101_follower")
@dataclass
class SOFollowerRobotConfig(RobotConfig, SOFollowerConfig):
    pass

该类会渲染所有字段——包括继承的字段——且完全不带任何描述,无论基类的文档写得多么完善。Args: 块必须位于 [[autodoc]] 所指定的具体类中,并且必须涵盖继承的字段。

基类,然后是具体的子类

抽象基类承载了规范契约。子类只需记录偏离之处——端口语义、校准特性、电机布局、支持的功能键。切勿将基类契约复制到每个子类中。

Robot、Teleoperator、Camera、MotorsBusBase、ProcessorStep 和 PreTrainedPolicy 都遵循此结构。

模块级别名

多个公开名称是别名,而非独立的类:

SO100FollowerConfig = SOFollowerRobotConfig
SO101FollowerConfig = SOFollowerRobotConfig

[[autodoc]] 会解析别名并渲染规范类名,因此 ## SO101FollowerConfig 标题下的正文将显示 class lerobot.robots.so_follower.SOFollowerRobotConfig。只需为规范类编写一次文档,并在页面正文中提及别名,而不是为每个别名单独创建 autodoc 块。

不应记录的内容

  • 私有成员。 以 _ 开头的任何内容都不属于公共 API。
  • 以文字形式重述的类型注解。 port (str): A string. 没有提供任何信息。请说明它的用途。
  • 来自上游的内置代码。 src/lerobot/policies/molmoact2/molmoact2_hf_model/ 是从 transformers 内置的,并且已经带有上游风格的文档字符串。请保持原样——重新调整其格式只会导致下次同步时产生冲突。它已被排除在 API 参考和文档字符串检查之外。

此规则如何强制执行

检查它能捕获的内容
make check-docstringsArgs: 条目与签名不匹配;文档中记录的默认值与实际值不一致
make doctest不再运行的示例
make check-doctest-listutils/documentation_tests.txt 中的过期或未排序条目
ruff(D 规则)Google 规范风格的违规
interrogateDocstring 覆盖率低于当前阈值
doc-builder指向不存在内容的 [[autodoc]] 路径——这会导致文档构建失败

在提交 PR 之前,请一起运行它们:

make check-docstrings && make doctest && pre-commit run --all-files

然后渲染页面并实际查看它:

doc-builder build lerobot docs/source/ --build_dir /tmp/doc-build

检查清单

  • 您修改过的每个公共成员都有文档字符串。
  • 每个 Args: 条目都与签名匹配,包括 *optional*, defaults to 子句。
  • Returns: 采用类型优先,缩进一行。
  • 不要使用裸的 Attributes: — 请使用 **Attributes**: 并配合 -- 分隔符。
  • 没有 Sphinx 角色 — 交叉引用使用 [~module.Class.method]。
  • 示例位于 ```python 围栏代码块中,并且要么在 CI 中运行,要么带有 # doctest: +SKIP。
  • Config 数据类字段位于具体类的 Args: 块中,而不是 # 注释。
  • 已目视检查渲染后的页面。
Update on GitHub