У цій публікації наші друзі з Cactus Compute показують, як Needle 2, модель виклику функцій 14 МБ, перетворює англійську мову на локальні операції на Raspberry Pi 5, використовуючи лише ЦП.
Введіть «увімкнути світлодіод», і через 78 мілісекунд світлодіод на нашому Raspberry Pi 5 увімкнеться. Це Needle 2, який працює лише на процесорі – без спеціального AI HAT.

Почнемо з того, що таке Needle немає. Це не чат-бот. Натомість команда Cactus Compute навчила його виконувати лише одне завдання: надійні, структуровані операції на пристрої.
«Голка 2 чудова»
– Ебен Аптон, генеральний директор Raspberry Pi
Налаштування просте — ви оголошуєте функції Python, потім Needle вибирає, яку з них, і заповнює аргументи. Ми використовуємо його для написання місцевих записок, запитів vcgencmdобмінюватися даними за допомогою світлодіодів і багато іншого на одному ЦП Raspberry Pi 5.
python3 -m venv needle-env
source needle-env/bin/activate
python -m pip install cactus-needle
Після першого завантаження Needle працює локально без хмарного API або підключення до мережі. Цей перший приклад не потребує додаткового обладнання.
import needle
from pathlib import Path
import subprocess
notes_path = Path("needle-notes.txt")
в Needle Клас прийняв завдання оро с @needle.tool. Декоратор використовує назву, рядок документа та анотації типу кожної функції для створення власної схеми. в save_note нижче в примітці для Needle це сказано text має бути рядком.
@needle.tool
def save_note(text: str):
"""Append a note to a local text file."""
with notes_path.open("a", encoding="utf-8") as notes:
notes.write(text + "\n")
return {"text": text, "path": str(notes_path)}
@needle.tool
def get_temperature():
"""Return the current CPU temperature of this Raspberry Pi in Celsius."""
out = subprocess.check_output(["vcgencmd", "measure_temp"], text=True)
return {"temperature_c": float(out.split("=")[1].split("'")[0])}
agent = needle.Needle(tools=[save_note, get_temperature])
response = agent.run("Save a note that says the cooler is working.")
Всередині run()Модель спочатку створює такий вибір інструментів (урізаний для ясності):
{
"type": "call",
"function_calls": [
{
"name": "save_note",
"arguments": { "text": "the cooler is working" }
}
]
}
run() виконує функцію та містить її значення, що повертається response["results"]:
[
{
"text": "the cooler is working",
"path": "needle-notes.txt"
}
]
У цей період перв complete() всередині run() вибрав функцію та згенерував її аргументи за 107 мс.
Ми також можемо запитати:
agent.reset()
response = agent.run("How hot is this Raspberry Pi?")
Дзвіночки голки:
{
"type": "call",
"function_calls": [
{"name": "get_temperature", "arguments": {}}
]
}
run() виконує vcgencmd і читання результатів включає:
{ "temperature_c": 49.9 }
Ми також оголосили set_led(on), blink_led(times)і take_photo() через rpicam-still перевірити вибір інструментів. Голка вибирає інструмент; Звичайний код Python вирішує, що станеться далі. Ви також можете прикрасити будь-яку функцію Python чіткою назвою, анотаціями та описом @needle.tool.
Голка нарочито вузька. Запитайте “яка столиця Франції?” і повертається { "function_calls": [] } за 92 мс, оскільки жоден із наданих нами інструментів не може відповісти на це запитання. Для моделі дії відхилення непов’язаного запиту є правильною відповіддю.
Оригінальний сеанс Needle становить близько 28 МБ. У цій демонстрації Python повний процес досяг піку з 43 МБ до 46,4 МБ, включаючи інтерпретатор. Ось деякі інші запуски:
| Питання | Телефонуйте | Попередня зарядка (струм/с) | Декодувати (поточний/и) | Витрачений час (мс) |
| Увімкніть світлодіод. | set_led |
488 | 296 | 78 |
| Наскільки гарячий цей Raspberry Pi? | get_temperature |
487 | 303 | 149 |
| Блимніть світлодіодом двічі. | blink_led |
475 | 314 | 83 |
| Зробіть фото. | take_photo |
461 | 248 | 76 |
| Збережіть примітку про те, що він працює холодніше. | save_note |
475 | 305 | 107 |
| Яка столиця Франції? | (жоден) | 470 | 297 | 92 |
Ці приклади було запущено на Raspberry Pi 5, 8 ГБ, ОС Raspberry Pi, лише ЦП, cactus-needle 2.0.7. Наповнення і декодування є лічильниками сеансів Needle. Будь-яка затримка в Витрачений час колонка настінного годинника для одного complete() перед виконанням вибраної функції Python.
Якщо ви вже пишете функції GPIO Zero, ви можете прикрасити їх і перенести. Це також стосується іншої програмної логіки. Голку також можна налаштувати локально на ноутбуці для певного набору інструментів.
Ви можете знайти ваги та код на huggingface.co/Cactus-Compute/needle2, github.com/cactus-compute/needle. Обидва випущені під Apache 2.0.