LeRobot documentation
الأدوات
الأدوات
يدعم LeRobot استدعاءات الأدوات في السياسات — حيث يمكن لرسائل المساعد إصدار استدعاءات منظمة مثل say(text="OK, starting now") يقوم وقت التشغيل بتوجيهها إلى تنفيذ فعلي (TTS، متحكم، مسجّل، …).
يتناول هذا الصفحة:
- المكان الذي توجد فيه كتالوج الأدوات.
- كيف ينتج خط أنابيب التوسيم ذرّات استدعاء الأدوات.
- كيفية إضافة أداة خاصة بك.
المكان الذي تُعلن فيه الأدوات
طبقتان.
الفهرس — وهو قائمة بمخططات الدوال على طراز 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 يعيد DEFAULT_TOOLS من lerobot.datasets.language — وهو حالياً قائمة من عنصر واحد تحتوي على مخطط say القياسي. وبالتالي، تستمر مجموعات البيانات غير المعلَّمة ومستهلكو قوالب المحادثة في العمل دون أي إعداد:
prompt_str = tokenizer.apply_chat_template(
sample["messages"],
tools=meta.tools, # works either way
add_generation_prompt=False,
tokenize=False,
)التنفيذات — بلغة بايثون القابلة للتشغيل — ستُوضع تحت src/lerobot/tools/، بملف واحد لكل أداة. أما مُوجِّه وقت التشغيل والتنفيذ القياسي لـsay (الذي يغلّف pocket-tts من Kyutai) فليس جزءًا من طبقة الكتالوج الموصوفة هنا؛ فاليوم لا تُشحن هذه الطبقة سوى تخزين المخطط وثابت الاحتياط 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." } } }
]
}تدمج الوصفات هذه في الرسائل المُصيَّرة عبر 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"]
}
}
}
]
}يتبع المخطط بدقةً اتفاقية استدعاء الدوال الخاصة بـ OpenAI، لذا يمكن لقالب المحادثة عرضه بشكل أصلي.
الخطوة 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، ويُنشئ الكلاس المسجّل المطابق، ويعيد قاموسًا من الأسماء إلى الكائنات (name → instance) يمكن لموزّع الطلبات توجيه الاستدعاءات إليه.
إذا كنت ترغب في استخدام أداة دون كتابة تنفيذ (على سبيل المثال، لتنسيق قالب المحادثة أثناء التدريب فقط)، فإن الخطوة 1 وحدها كافية — لا يزال النموذج يتعلم توليد الاستدعاء. لا تُحتاج الخطوات 2 و3 إلا لتنفيذ تنفيذ فعلي له أثناء الاستدلال.
Update on GitHub