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. ツールカタログが保存される場所です。
  2. アノテーションパイプラインがツールコールアトムを生成する方法
  3. 独自のツールを追加する方法

ツールが宣言される場所

2層。

カタログ(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"]
        }
      }
    }
  ]
}

データセットメタデータアクセサ経由で読み取ります:

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/ 以下に配置され、ツールごとに1ファイルとなります。ランタイムのディスパッチャーと正規の 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ツール呼び出しの両方を含む1つのアシスタントターンです。推論時、ランタイムは生成されたテキストを構造化されたtool_callsにパースし、対応する実装にディスパッチします。

独自のツールを追加する方法

注: 以下のステップ2と3は、カタログレイヤーとして今日提供されているものではないランタイムレイヤー(src/lerobot/tools/、Toolプロトコル、TOOL_REGISTRY、get_tools(meta))を説明しています。これらのモジュールはまだツリーに存在しません。ステップ1のみで、meta.toolsを介してチャットテンプレートにツールを表示させることができ、モデルが呼び出しを生成することを学習できます。推論時に呼び出しを実行するには、ランタイムレイヤーが必要です。

3つのステップ。具体的な例として、ポリシーが通常の制御ループの外で追加の観測をキャプチャするために呼び出すことができる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"]
        }
      }
    }
  ]
}

スキーマはOpenAIの関数呼び出し規約に完全に準拠しているため、チャットテンプレートはそれをネイティブでレンダリングできます。

ステップ 2 — call の実装

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"

ツールごとに1つのファイルにすることで、依存関係が分離されます。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内の各スキーマを検索し、対応する登録済みクラスをインスタンス化して、ディスパッチャがルーティングできる名前 → インスタンスの辞書を返します。

実装を書かずにツールを使用したい場合(例: トレーニング時のチャットテンプレート整形のみ)は、ステップ1だけで十分です。モデルは呼び出しを生成することを学習します。ステップ2と3は、推論時に実際に呼び出しを実行する場合にのみ必要です。

Update on GitHub