Некоторые роли повторяются из задачи в задачу: проверить изменения публичного API, пройтись по diff на предмет регрессий, осмотреть код без права его трогать. Встроенные профили субагентов универсальны, а такая роль - узкая и постоянная, и каждый раз описывать её заново в промпте расточительно и ненадёжно.
Наивный ход - держать формулировку роли в голове или в заметке и вклеивать её в общий промпт всякий раз, когда нужен такой проход. Пока это делаешь ты и по памяти, роль плывёт: сегодня попросил только читать, завтра забыл про это, и общий агент с полным набором инструментов начал править там, где ты ждал одного лишь осмотра.
Ломается это на дрейфе объёма. Универсальный агент, которому дали задачу ревьюера, всё равно вооружён записью и exec; стоит инструкции чуть ослабнуть - и он выходит за роль, потому что технически может. Роль, живущая только в словах промпта, не имеет границы: она держится на дисциплине формулировки, а не на механизме, и потому ненадёжна ровно там, где важна.
Профессиональный механизм - вынести роль в отдельный файл-профиль субагента. Project-профиль живёт в .devin/agents/<name>.md или .devin/agents/<name>/AGENT.md; поддерживается и кросс-инструментальный путь .agents/agents/. Во frontmatter - имя, описание и allowed-tools, в теле - собственно инструкции роли. Такой профиль лежит в репозитории, читается на ревью и переносится вместе с проектом.
Ключевая деталь здесь - allowed-tools. Это не пожелание в тексте, а граница исполнения: субагент с allowed-tools из read, grep и glob физически не может писать в файлы, как бы ни была сформулирована его задача. Роль перестаёт держаться на дисциплине промпта и начинает держаться на списке разрешённых инструментов - то есть на том же принципе, что и вся permission-модель Devin Local.
Как это выглядит на практике, показывает короткий профиль ревьюера контракта API. Frontmatter задаёт имя, человекочитаемое описание и три read-only инструмента; тело формулирует узкую задачу - осмотреть diff без изменения файлов, проверить status codes, схему запроса и ответа, обратную совместимость и негативные случаи, вернуть findings с указанием file:line и severity. Ничего сверх этого профиль сделать не даст.
Формат таких профилей на дату среза экспериментальный, и это диктует стиль. Держите определения маленькими и по одной ясной роли на файл; не закладывайте в них много логики, которая может не пережить смену формата, и сверяйтесь с changelog, прежде чем полагаться на конкретное поле. Маленький профиль легче и проверить, и починить, когда формат сдвинется.
Отдельная строка про nesting. Поле max-nesting позволяет субагенту порождать дочерних агентов, и на бумаге это заманчиво - роль, которая сама раздаёт подзадачи. На практике вложенность быстро увеличивает и расход, и сложность наблюдения: за деревом агентов труднее уследить, а счёт растёт с каждым уровнем. Не включайте nesting без явной необходимости; по умолчанию узкая роль должна быть плоской. Если подзадачи всё же нужны, честнее вынести их в отдельные именованные профили, чем прятать в глубину одного.
Оправдан custom subagent тогда, когда роль и вправду узкая и повторяется. Разовый проход не стоит файла - его проще описать в самом промпте. Но ревьюер, который нужен на каждом diff, или разведчик, который всегда только читает, окупают формализацию: один раз описанная роль перестаёт зависеть от того, вспомнили ли вы сегодня все её ограничения. Формализацию оправдывает повторяемость роли, а не её сложность.
Проверять профиль нужно не по тексту, а по поведению. Запустите его на заведомо известном diff и убедитесь, что он остался в пределах allowed-tools - не тронул файлы, вернул findings в обещанном виде с file:line и severity. После этого откройте Customizations и посмотрите, что реально загрузилось: профиль, лежащий в репозитории, и профиль, применённый в сессии, - не одно и то же, пока вы не увидели второе своими глазами. Полезно прогнать профиль и на diff, где нарушение заведомо есть, - и убедиться, что он его называет, а не молчит.
Типичные провалы узнаваемы. Первый - выдать ревьюеру инструменты записи "на всякий случай" и получить агента, который вместо отзыва начинает чинить, стирая границу роли. Второй - включить nesting без нужды и удивиться расходу и тому, что за деревом субагентов уже не уследить. Третий - положиться на экспериментальное поле как на стабильное и обнаружить после обновления, что профиль читается иначе. Признак всех трёх один: роль описали словами, но не заземлили её на allowed-tools и не сверили с тем, что загрузилось на самом деле.
---
name: api-contract-reviewer
description: Проверяет изменения публичного HTTP API
allowed-tools:
- read
- grep
- glob
---
Исследуй diff без изменения файлов.
Проверь status codes, request/response schema,
backward compatibility и negative cases.
Верни findings с file:line и severity.