LeRobot documentation

도구

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

도구

LeRobot는 정책에서 도구 호출을 지원합니다. 어시스턴트 메시지는 say(text="OK, starting now")와 같은 구조화된 호출을 출력할 수 있으며, 런타임은 이를 실제 구현(TTS, 컨트롤러, 로거 등)으로 전달합니다.

이 페이지에서 다루는 내용:

  1. tool catalog이 저장되는 위치입니다.
  2. How the annotation pipeline produces tool-call atoms.
  3. 자신의 도구를 추가하는 방법

도구가 선언되는 위치

두 개의 레이어.

카탈로그 — OpenAI 스타일의 함수 스키마 목록 — 은 각 데이터셋의 meta/info.json["tools"]에 있습니다. 예시:

{
  "features": { "...": "..." },
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "say",
        "description": "Speak a short utterance to the user via the TTS executor.",
        "parameters": {
          "type": "object",
          "properties": {
            "text": {
              "type": "string",
              "description": "The verbatim text to speak."
            }
          },
          "required": ["text"]
        }
      }
    }
  ]
}

dataset 메타데이터 접근자를 통해 읽으세요:

from lerobot.datasets.dataset_metadata import LeRobotDatasetMetadata

meta = LeRobotDatasetMetadata(repo_id="pepijn/super_poulain_final_annotations")
tools = meta.tools     # list[dict] — OpenAI tool schemas

데이터셋의 info.json에 도구가 선언되어 있지 않으면, meta.tools은 lerobot.datasets.language의 DEFAULT_TOOLS를 반환합니다. 현재 이는 정형화된 say 스키마를 가진 단일 항목 목록입니다. 따라서 주석이 없는 데이터셋과 채팅 템플릿 사용자는 어떤 설정 없이도 계속 작동합니다:

prompt_str = tokenizer.apply_chat_template(
    sample["messages"],
    tools=meta.tools,                 # works either way
    add_generation_prompt=False,
    tokenize=False,
)

구현 — 실행 가능한 Python — 은 src/lerobot/tools/ 아래에 위치하며, 도구별로 하나의 파일로 구성됩니다. 런타임 디스패처와 정형화된 say 구현(Kyutai의 pocket-tts를 래핑)은 여기 설명하는 카탈로그 레이어의 일부가 아닙니다. 현재 이 레이어는 스키마 저장소와 DEFAULT_TOOLS 폴백 상수만 제공합니다.

행별 도구 호출

위 카탈로그는 호출할 수 있는 것을 설명합니다. 실제 호출 — 함수 이름과 인자 값 — 은 language_events의 어시스턴트 원자에서 행별로 저장됩니다:

{
  "role": "assistant",
  "content": null,
  "style": null,
  "timestamp": 12.4,
  "camera": null,
  "tool_calls": [
    { "type": "function",
      "function": { "name": "say", "arguments": { "text": "On it." } } }
  ]
}

Recipes는 tool_calls_from을 통해 렌더링된 메시지에 이를 삽입합니다:

user_interjection_response:
  bindings:
    speech: "emitted_at(t, role=assistant, tool_name=say)"
  messages:
    - { role: user, content: "${task}", stream: high_level }
    - {
        role: assistant,
        content: "${current_plan}",
        stream: high_level,
        target: true,
        tool_calls_from: speech,
      }

모델의 학습 대상은 계획 텍스트와 그리고 say 도구 호출을 모두 포함하는 하나의 어시스턴트 턴입니다. 추론 시 런타임은 생성된 텍스트를 구조화된 tool_calls로 다시 파싱하여 해당 구현으로 분기합니다.

자체 도구 추가 방법

참고: 아래 단계 2와 3은 런타임 레이어(src/lerobot/tools/, Tool 프로토콜, TOOL_REGISTRY, get_tools(meta))를 설명하며, 이는 현재 제공되는 카탈로그 레이어의 일부가 아닙니다. 해당 모듈은 아직 트리에 존재하지 않습니다. 단계 1만으로도 meta.tools를 통해 채팅 템플릿에서 도구를 볼 수 있게 되어 모델이 호출을 생성하도록 학습할 수 있습니다. 추론 시 호출을 실행하려면 런타임 레이어가 필요합니다.

세 단계입니다. 구체적인 예시: 정책이 호출하여 정규 제어 루프 외부에서 추가 관측을 캡처할 수 있는 record_observation 도구입니다.

1단계 — 스키마 선언

meta/info.json["tools"] 아래에 항목을 추가하려면, 어노테이션 파이프라인을 실행하기 전에 디스크에서 파일을 직접 편집하세요(이 항목은 유지됩니다).

{
  "tools": [
    { "type": "function", "function": { "name": "say", "...": "..." } },
    {
      "type": "function",
      "function": {
        "name": "record_observation",
        "description": "Capture a high-resolution still image for the user.",
        "parameters": {
          "type": "object",
          "properties": {
            "label": {
              "type": "string",
              "description": "Short label for the saved image."
            }
          },
          "required": ["label"]
        }
      }
    }
  ]
}

schema는 OpenAI의 function-calling 규약을 정확히 따르므로, chat template가 이를 네이티브로 렌더링할 수 있습니다.

2단계 — 호출 구현

src/lerobot/tools/record_observation.py를 생성합니다:

from .base import Tool
from typing import Any

RECORD_OBSERVATION_SCHEMA: dict[str, Any] = { "...": "..." }   # mirrors the JSON above


class RecordObservationTool:
    name = "record_observation"
    schema = RECORD_OBSERVATION_SCHEMA

    def __init__(self, schema: dict | None = None, output_dir: str = "."):
        self.output_dir = output_dir

    def call(self, arguments: dict) -> str:
        label = arguments["label"]
        # ... save the latest camera frame to <output_dir>/<label>.png ...
        return f"saved {label}.png"

도구별로 파일을 분리하면 의존성이 격리됩니다. record_observation은 pillow를 가져올 수 있고, say는 pocket-tts를 가져옵니다. 필요한 도구만 설치하는 사용자는 무거운 전이 의존성을 피할 수 있습니다.

3단계 — 등록

src/lerobot/tools/registry.py에 추가:

from .record_observation import RecordObservationTool

TOOL_REGISTRY["record_observation"] = RecordObservationTool

그것으로 끝입니다. 런타임에 get_tools(meta)는 meta.tools에서 각 스키마를 조회하고, 일치하는 등록된 클래스를 인스턴스화한 후, 디스패처가 라우팅할 수 있는 이름 → 인스턴스 딕셔너리를 반환합니다.

구현을 작성하지 않고 도구를 사용하려는 경우(예: 학습 시 chat-template 포맷팅만 수행하는 경우) 1단계만으로도 충분합니다. 모델은 여전히 호출을 생성하도록 학습됩니다. 2단계와 3단계는 추론 시 실제로 호출을 실행해야 할 때만 필요합니다.

Update on GitHub