LeRobot documentation
Ferramentas
Ferramentas
LeRobot suporta chamadas de ferramentas em políticas — mensagens de assistente podem emitir invocações estruturadas como say(text="OK, starting now") que o runtime despacha para uma implementação real (TTS, controlador, logger, …).
Esta página aborda:
- Onde o catálogo de ferramentas fica.
- Como o pipeline de anotação produz átomos de chamada de ferramenta.
- Como adicionar sua própria ferramenta.
Onde as ferramentas são declaradas
Duas camadas.
O catálogo — uma lista de esquemas de funções no estilo OpenAI — está em meta/info.json["tools"] em cada conjunto de dados. Exemplo:
{
"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"]
}
}
}
]
}Leia-o por meio do acessor de metadados do conjunto de dados:
from lerobot.datasets.dataset_metadata import LeRobotDatasetMetadata
meta = LeRobotDatasetMetadata(repo_id="pepijn/super_poulain_final_annotations")
tools = meta.tools # list[dict] — OpenAI tool schemasSe o info.json do conjunto de dados não declarar nenhuma ferramenta, meta.tools retorna DEFAULT_TOOLS de lerobot.datasets.language — atualmente uma lista com uma única entrada contendo o esquema canônico say. Assim, conjuntos de dados sem anotações e consumidores de modelos de chat continuam funcionando sem nenhuma configuração:
prompt_str = tokenizer.apply_chat_template(
sample["messages"],
tools=meta.tools, # works either way
add_generation_prompt=False,
tokenize=False,
)As implementações — Python executável — ficarão em src/lerobot/tools/, um arquivo por ferramenta. O despachador de runtime e a implementação canônica de say (que encapsula o pocket-tts da Kyutai) não fazem parte da camada de catálogo descrita aqui; hoje, esta camada fornece apenas o armazenamento do esquema e a constante de fallback DEFAULT_TOOLS.
Invocações de ferramentas por linha
O catálogo acima descreve o que pode ser chamado. A chamada real — o nome da função mais os valores dos argumentos — é armazenada por linha, nos átomos de assistente em language_events:
{
"role": "assistant",
"content": null,
"style": null,
"timestamp": 12.4,
"camera": null,
"tool_calls": [
{ "type": "function",
"function": { "name": "say", "arguments": { "text": "On it." } } }
]
}As receitas inserem esses dados nas mensagens renderizadas por meio de 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,
}O alvo de treinamento do modelo é um turno do assistente que carrega tanto o texto do plano quanto a chamada da ferramenta say. Na inferência, o tempo de execução analisa o texto gerado de volta em tool_calls estruturados e despacha para a implementação correspondente.
Como adicionar sua própria ferramenta
Observação: As etapas 2 e 3 abaixo descrevem a camada de tempo de execução (
src/lerobot/tools/, o protocoloTool,TOOL_REGISTRY,get_tools(meta)), que não faz parte da camada de catálogo distribuída hoje — esses módulos ainda não existem na árvore. A etapa 1, por si só, é suficiente para tornar a ferramenta visível para o modelo de chat viameta.tools, permitindo que o modelo aprenda a gerar a chamada; a execução da chamada na inferência requer a camada de tempo de execução.
Três etapas. Exemplo concreto: uma ferramenta record_observation que a política pode chamar para capturar uma observação extra fora do loop de controle regular.
Etapa 1 — declare o esquema
Adicione uma entrada em meta/info.json["tools"] editando o arquivo
diretamente no disco antes de executar o pipeline de anotação (ela será
preservada).
{
"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"]
}
}
}
]
}O esquema segue exatamente a convenção de chamada de função da OpenAI, de modo que o modelo de chat pode renderizá-lo nativamente.
Etapa 2 — implemente a chamada
Crie 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"Um arquivo por ferramenta mantém as dependências isoladas — record_observation pode puxar pillow, enquanto say puxa pocket-tts. Usuários que instalam apenas as ferramentas de que precisam evitam dependências transitivas pesadas.
Etapa 3 — registre-o
Adicione em src/lerobot/tools/registry.py:
from .record_observation import RecordObservationTool
TOOL_REGISTRY["record_observation"] = RecordObservationToolÉ isso. Em tempo de execução, get_tools(meta) consulta cada schema em meta.tools, instancia a classe registrada correspondente e retorna um dicionário nome → instância para o dispatcher rotear.
Se você deseja usar uma ferramenta sem escrever uma implementação (por exemplo, apenas para o formatação do chat-template no momento do treinamento), a etapa 1 é suficiente — o modelo ainda aprende a gerar a chamada. As etapas 2 e 3 são necessárias apenas para realmente executá-la na inferência.
Update on GitHub