Перейти до вмісту

Вбудовані інструменти агента

Це прив’язані до сервера інструменти, які вбудоване середовище виконання агента реєструє безпосередньо — мовний сервер, структурний пошук, налагоджувач, ядра, запитання й керування воркерами — на противагу інструментам MCP, які воно під’єднує, та загальним інструментам для файлів, пошуку й оболонки із середовища виконання harness. Їх немає в реєстрі MCP: зовнішній клієнт MCP їх не побачить, бо кожен із них прив’язаний до живого ресурсу на боці сервера — процесу мовного сервера, налагоджувального адаптера, інтерпретатора — що належить одному запуску.

Кожен інструмент тут реєструється лише тоді, коли його опорний ресурс підключено для запуску — наглядач мовного сервера чи налагодження, парсер tree-sitter, фабрика ядер, порт запитань, перелік vibe-воркерів. Виявлення мовного сервера чи налагоджувального адаптера для цього чекаута — це окрема, пізніша перевірка (status / adapters): ці інструменти залишаються на поверхні, щоб агент міг спитати, чому ніщо не придатне, а не здогадуватися.

Кожен інструмент оголошує рівень, і рівень вирішує, які поверхні його бачать — а не лише те, чи він запитує дозвіл. Режим плану та субагенти лише для читання обмежені рівнем read, тож інструмент рівня write або exec взагалі відсутній у їхній схемі.

Рівень Значення Інструменти тут
read Без побічних ефектів lsp, ast_grep, ask_user, п’ять vibe_*
write Змінює файли lsp_rename, ast_edit, resolve
exec Запускає процес або керує ним debug, eval

Реєструється, коли запуск має наглядача мовного сервера та робочий каталог. Чи сервер справді може відповісти, визначається під час виклику як перетин: кореневий маркер має існувати і бінарник сервера має резолвитися. Кожна з умов окремо означає, що жоден сервер не запуститься — status це підтверджує — а не тихий здогад.

Позиції адресуються line плюс підрядком symbol, ніколи не стовпцем. Модель, яку просять указати стовпець, здогадується, а хибний здогад резолвиться в інший символ у тому ж рядку — відповідь, що виглядає правильною, але стосується чогось іншого. Пропуск symbol у навігаційній дії — це помилка, а не здогад про перший стовпець.

Дія Аргументи Повертає
diagnostics file (або "*") Помилки та попередження; "*" замість цього запускає перевірку проєкту
definition file, line, symbol Де оголошено символ
type_definition file, line, symbol Де оголошено його тип
implementation file, line, symbol Конкретні реалізації
references file, line, symbol Кожне використання, не більше 50
hover file, line, symbol Сигнатура й коментар документації
symbols query або file Пошук у робочому просторі за query (не більше 100); символи документа за file (не більше 200)
code_actions file, line, symbol Швидкі виправлення, які пропонує сервер
status — Які сервери працюють і для яких коренів
reload — Перезапускає сервер для цього кореня

Виграш не в інструменті. write, edit і apply_patch обгорнуто: після запису файл синхронізується та зберігається через мовний сервер, і до результату інструмента долучаються лише нові діагностичні повідомлення. Агент дізнається, що зламав збірку, тієї ж миті, коли її зламав, і йому не треба пам’ятати, щоб спитати.

Уже повідомлену діагностику пригнічує журнал на кожен запуск, заведений за рівнем серйозності, кодом і повідомленням — позицію навмисно виключено, тож діагностика, яка лише з’їхала на чотири рядки вниз, не позначається знову як нова.

lsp_rename — перейменування в межах проєкту

Розділ із назвою «lsp_rename — перейменування в межах проєкту»

Окремий інструмент рівня write рівно з однієї причини: рівень визначає видимість. Якби перейменування вбудували в lsp, це або дало б досліднику лише для читання змогу переписувати репозиторій, або поставило б кожен hover за запитом на схвалення.

Аргумент Значення
file Де розташований символ
line Рядок з індексацією від 1
symbol Підрядок, що ідентифікує його в цьому рядку
new_name Як його назвати

Знаходить код за формою, а не за текстом. $NAME зіставляє будь-який вузол, $$$NAME — послідовність сусідніх вузлів, а $_ — це шаблонний символ, який нічого не зв’язує.

Властивість, яка робить його механізмом зіставлення, а не regex із зайвими кроками: метазмінна, повторена в одному шаблоні, має захопити той самий текст.

ast_grep(pattern: "if ($X != null) $X.dispose()", language: "dart")

зіставляє захисну умову, яка звільняє саме те, що перевірила, і не зіставляє ту, яка звільняє щось інше.

Аргумент Значення
pattern Фрагмент коду з метазмінними
path Файл або каталог для пошуку; типово — весь робочий простір
language Ідентифікатор граматики з постачання (dart, python, rust, c, …). Виводиться, коли path називає файл
max_results Типово 50

ast_edit — структурний перезапис із підготовкою

Розділ із назвою «ast_edit — структурний перезапис із підготовкою»

Те саме зіставлення, плюс шаблон rewrite із підставленими назад метазмінними. Нічого не записується. Зміну підготовлено, і результат називає edit_id.

ast_edit(pattern: "dispose($X)", rewrite: "$X.dispose()", language: "dart")
→ (proposed) 12 replacements in 4 files … call resolve with edit_id "edit_1"
Аргумент Значення
pattern Що зіставляти
rewrite Що поставити натомість, із підставленими $NAME
path Обсяг; типово — весь робочий простір
language Ідентифікатор мови

resolve — зафіксувати або відкинути підготовлену зміну

Розділ із назвою «resolve — зафіксувати або відкинути підготовлену зміну»
Аргумент Значення
edit_id З результату (proposed)
action accept або discard

Кожен файл звіряють із вмістом, зафіксованим у момент підготовки, і будь-яка розбіжність відхиляє всю зміну. Частково застосований структурний перезапис лишає дерево, яке не компілюється ні за старою формою, ні за новою.


Реєструється, коли запуск має наглядача сесій налагодження, робочий каталог та ідентифікатор розмови. Чи адаптер справді може запуститися, визначається під час виклику за тим самим правилом перетину, що й для мовного сервера (кореневий маркер і бінарник). Рівень exec; не безпечний для паралелі (сесія — це стан між викликами, тож continue, який обганяє stack, прочитав би кадр, що вже зсунувся).

Одна сесія на розмову, з жорстким TTL (30 хвилин). Другий launch відхиляють, а не тихо замінюють ним перший.

Операція Аргументи Примітки
adapters — Які адаптери тут придатні й чому ні
status — Чи працює сесія і де вона зупинилася
breakpoints file, lines[] Порожній lines очищає файл. Можна ставити до запуску
launch program, args[] Запускає програму, зупинену на ваших точках зупину
attach port Під’єднується до вже запущеної програми, яку налагоджують
continue thread_id? Виконується до наступної зупинки
pause thread_id? Зупиняє її там, де вона є
step_over / step_in / step_out thread_id? Переміщує на один крок
threads — Ідентифікатори та назви потоків
stack thread_id? Кадри, не більше 30
scopes frame_id Області видимості кадру, кожна з reference
variables reference Дочірні елементи, не більше 50; значення — не більше 400 символів
evaluate expression, frame_id? Обчислюється у власній області видимості кадру
output — stdout/stderr програми, яку налагоджують, обмежено
terminate — Завершує сесію й убиває адаптер
Ідентифікатор Команда Кореневі маркери
dart dart debug_adapter pubspec.yaml
debugpy python3 -m debugpy.adapter pyproject.toml, setup.py, requirements.txt
lldb lldb-dap Cargo.toml, CMakeLists.txt
delve dlv dap go.mod

debugpy надає перевагу локальним для проєкту .venv/bin або venv/bin над $PATH: Python із $PATH — це інше середовище, і під’єднання не з того середовища падає так, що це читається як зламаний код.


Комірка Python або JavaScript, чиї змінні, імпорти та завантажені дані зберігаються між викликами. Рівень exec; не безпечний для паралелі.

Аргумент Значення
code Комірка
description Обов’язковий. 5–10 слів для мітки в транскрипті
language python (типово) або javascript
reset Відкинути інтерпретатор і спершу почати чисто
  • Останній вираз повертається так, як це робить блокнот.
  • display() працює, фрейм pandas відображається як таблиця, а фігура matplotlib повертається як зображення, яке показує транскрипт.
  • Ідіоми IPython, які люди набирають рефлекторно — %pip, %cd, !cmd, %%bash, %%timeit — переписуються у звичайний код. %pip ще й витісняє sys.modules, тож наступний import бачить те, що щойно встановили.

Виклик власних інструментів зсередини комірки

Розділ із назвою «Виклик власних інструментів зсередини комірки»
contents = tool("read", {"path": "lib/auth.dart"})

Міст знову входить у реєстр інструментів harness, тож обмеження, схвалення та кожна обгортка застосовуються точно так, як до виклику, виданого моделлю. Він іде власним каналом ядра, а не через loopback-сокет: жодного порту, жодного секрету, жодного правила вихідного трафіку.

Тайм-аут комірки — це бюджет бездіяльності (типово 5 хвилин), і він призупиняється, поки триває виклик через міст, тож комірку, яка розгалужується на субагентів, не вбивають посеред розгалуження.


Рівень read. Єдиний спосіб, яким запуск щось питає в оператора. Він показує в розмові пронумеровану картку й блокує, доки хтось не відповість, не пропустить або доки запитання не вичерпає тайм-аут. Ніколи не пишіть запитання як повідомлення в чаті — це завершує хід.

Аргумент Значення
question Що спитати
context Необов’язково: чому ви питаєте і що залежить від відповіді
options[] Варіанти, кожен {label, description?}
allow_free_text Чи приймається введена відповідь
multi_select Чи можна вибрати кілька варіантів

Пропуск — це успіх: продовжуйте на заявленому припущенні й не питайте знову. Тайм-аут — це помилка з тією самою інструкцією. Запити на дозвіл («чи можна мені це зробити?») — це окремий шлюз, і вони показуються як така сама картка в розмові.

Реєструється лише тоді, коли існують і порт запитань, і цільовий простір. Без під’єднаної людини виклик падає, а не блокується назавжди — та сама позиція відмови за замовчуванням, яку займає prompt обмеження, коли не під’єднано жодного того, хто схвалює.


Реєструється лише поки увімкнено режим vibe. Усі п’ять мають рівень read: шлюз належить інструментам воркера, де власне й відбувається редагування.

Інструмент Аргументи Примітки
vibe_spawn brief, label, tier? Повертає керування негайно; воркер працює далі
vibe_send worker_id, message Дописує до брифу й перезапускає
vibe_wait worker_id, timeout_seconds? Блокує, доки він не завершиться
vibe_kill worker_id Зупиняє його
vibe_list — Рівень, статус, витрачений час і останній результат

tier — це fast (механічна робота з чіткою специфікацією) або good (проєктування, судження чи перевірка того, що створив fast-воркер).