Шаблоны
Шаблоны позволяют использовать динамический контент в директивах воркфлоу, условиях и других полях. Используйте шаблонные переменные для доступа к контексту выполнения, результатам шагов и параметрам воркфлоу.
Базовый синтаксис
Заголовок раздела «Базовый синтаксис»Шаблонные переменные используют двойные фигурные скобки:
{{variableName}}Переменные разрешаются во время выполнения из контекста выполнения.
Именование переменных
Заголовок раздела «Именование переменных»Имена переменных и ID узлов поддерживают:
- camelCase:
{{projectName}},{{userInput}} - snake_case:
{{project_name}},{{user_input}} - kebab-case:
{{my-project}},{{user-input}}
Kebab-case поддерживается в первом сегменте ссылок на переменные:
{{my-variable}} - Простая переменная{{setup-workspace.path}} - ID узла с доступом к полю{{#each my-items}}...{{/each}} - Итерация по массивуПоследующие сегменты пути используют стандартные идентификаторы:
{{my-node.field_name}} - Kebab ID узла, snake_case поле{{setup-workspace.result.data}} - Вложенный доступ к путиДоступные переменные
Заголовок раздела «Доступные переменные»Контекст выполнения
Заголовок раздела «Контекст выполнения»{{executionId}} - ID текущего выполнения{{workflowId}} - Выполняемый воркфлоу{{currentNodeId}} - ID текущего узлаГлобальные переменные
Заголовок раздела «Глобальные переменные»Глобальные переменные объявляются один раз в variableRegistry воркфлоу и используются по короткому имени:
{{projectName}} - Объявленная глобальная переменная{{count}} - Объявленная глобальная (числовая)Ссылка по короткому имени разрешается только из variableRegistry. Имя, не объявленное как глобальное (и не являющееся системной переменной), ни к чему не разрешается и не проходит валидацию.
Выводы узлов
Заголовок раздела «Выводы узлов»Локальные выводы узла используются как node-id.name:
{{analyze-step.summary}} - Вывод 'summary' узла 'analyze-step'{{review.issues_count}} - Вывод 'issues_count' узла 'review'Объявление переменных
Заголовок раздела «Объявление переменных»Объявляйте глобальные переменные в variableRegistry воркфлоу. Каждая запись — это JSON Schema property: type и description обязательны, а любой JSON Schema ключ (enum, items, properties, pattern, minLength, minimum, default, …) может быть добавлен для ограничения значения.
{ "variableRegistry": { "projectName": { "type": "string", "description": "Название проекта" }, "count": { "type": "number", "description": "Счётчик элементов", "default": 0 }, "approved": { "type": "string", "description": "Гейт подтверждения", "enum": ["yes", "no"] }, "tags": { "type": "array", "description": "Выбранные теги", "items": { "type": "string" } } }}Вся запись переносится в схему, против которой валидируется записывающий узел, поэтому объявленное ограничение enforced на ответе агента. Строковая глобальная переменная с enum (узел записывает её через inputSchema.globalInputs) обязана вернуть одно из перечисленных значений — используйте это для гейт-переменных, читаемых condition-узлами (например, approved == "yes"), чтобы ответ свободным текстом не проскочил мимо гейта. Типизированный массив с items enforces тип элементов каждого значения (например, tags должен быть массивом строк). Не ставьте enum на числовой счётчик, который узлы инкрементируют: это запиннит значение и отвергнет растущий счёт.
Узел записывает глобальную переменную только перечислив её имя в inputSchema.globalInputs; каждый остальной возвращаемый ключ — локальный вывод узла, описанный в inputSchema.properties:
{ "inputSchema": { "type": "object", "globalInputs": ["projectName"], "properties": { "summary": { "type": "string", "description": "Итог шага (локальный для узла)" } } }}Движок маршрутизирует ответ агента по этому объявлению: projectName становится глобальной {{projectName}}; summary доступна только как {{node-id.summary}}.
Условные шаблоны
Заголовок раздела «Условные шаблоны»Используйте условные блоки для включения или исключения контента на основе значений контекста:
{{#if variable}}Контент если истина{{else}}Контент если ложь{{/if}}{{#if variable}}Контент если истина{{/if}}Ложные значения: null, undefined, false, 0, "", "нет", "no"
Примеры
Заголовок раздела «Примеры»{{#if has_file_access}}Сохранить в ./output.md{{else}}Вернуть результат в ответе{{/if}}{{#if approved}}Продолжаем деплой{{else}}Ожидаем подтверждения{{/if}}Условные шаблоны обрабатываются в полях directive и completionCondition узлов agent-directive.
Переменная, которую проверяет блочный хелпер ({{#if VAR}}, {{#unless VAR}}, {{#each VAR}}, {{#eq VAR ...}}, {{#neq VAR ...}}), валидируется так же, как ссылка по bare-имени: она должна быть объявленным глобалом в variableRegistry, выводом node-id.name или системной переменной. Необъявленное имя не проходит валидацию.
Шаблоны Unless
Заголовок раздела «Шаблоны Unless»Используйте {{#unless}} для обратного условия - контент показывается когда значение ложное:
{{#unless isLoggedIn}}Пожалуйста, войдите{{/unless}}{{#unless hasError}}Успех!{{else}}Произошла ошибка{{/unless}}Шаблоны сравнения на равенство
Заголовок раздела «Шаблоны сравнения на равенство»Используйте {{#eq}} для сравнения переменной со строковым значением:
{{#eq variable 'value'}}Контент если равно{{/eq}}{{#eq variable 'value'}}Контент если равно{{else}}Контент если не равно{{/eq}}Пример:
{{#eq upload_target 'staging'}}Деплой на staging сервер{{/eq}}{{#eq upload_target 'production'}}Деплой на production сервер{{/eq}}Шаблоны сравнения на неравенство
Заголовок раздела «Шаблоны сравнения на неравенство»Используйте {{#neq}} для показа контента когда переменная НЕ равна значению:
{{#neq variable 'value'}}Контент если не равно{{/neq}}{{#neq variable 'value'}}Контент если не равно{{else}}Контент если равно{{/neq}}Пример:
{{#neq test_info 'skip'}}Запусти тесты: {{test_command}}{{/neq}}Доступ к массивам
Заголовок раздела «Доступ к массивам»Доступ к элементам массива через квадратные скобки:
{{items[0].name}} - Поле name первого элемента{{users[1].email}} - Поле email второго элемента{{data[2].nested.value}} - Вложенный путь после доступа к массивуДинамические индексы массивов
Заголовок раздела «Динамические индексы массивов»Используйте переменные в качестве индексов для динамического доступа:
{{items[idx].field}} - Доступ через переменную idx{{steps[current_step].action}} - Часто используется для навигации по шагам{{matrix[row][col].value}} - Цепочка динамических индексов{{data[outer].items[inner].name}} - Смешанные литералы и переменныеПоведение:
- Переменная должна разрешаться в неотрицательное целое число
- Строковые переменные типа
"2"парсятся как числа - Невалидные индексы (отрицательные, дробные, нечисловые, null, объекты) возвращают плейсхолдер undefined
- Выход за границы массива возвращает плейсхолдер undefined
Практический пример: Навигация по шагам
Заголовок раздела «Практический пример: Навигация по шагам»{ "directive": "Выполни шаг {{current_step}} из {{total_steps}}:\n\nДействие: {{steps[current_step].action}}\nОжидаемый результат: {{steps[current_step].expected_result}}", "completionCondition": "Шаг выполнен с доказательствами"}С контекстом:
{ "current_step": 0, "total_steps": 3, "steps": [ { "action": "Инициализировать проект", "expected_result": "Папка проекта создана" }, { "action": "Установить зависимости", "expected_result": "node_modules заполнен" }, { "action": "Запустить тесты", "expected_result": "Все тесты проходят" } ]}Результат:
Выполни шаг 0 из 3:
Действие: Инициализировать проектОжидаемый результат: Папка проекта созданаШаблоны итерации
Заголовок раздела «Шаблоны итерации»Используйте {{#each}} для итерации по массивам:
{{#each items}}{{this}}, {{/each}}{{#each users}}{{name}} ({{age}})\n{{/each}}{{#each steps}}{{@index}}: {{action}}{{/each}}Внутри {{#each}}:
{{this}}- текущий элемент (сериализуется для объектов){{this.fieldName}}- доступ к полю текущего объекта{{this.nested.path}}- доступ к вложенным полям{{@index}}- текущий индекс (начиная с 0){{fieldName}}- сокращение для{{this.fieldName}}
Поддержка условий внутри циклов:
{{#each tasks}}{{#if done}}[x]{{else}}[ ]{{/if}} {{name}}\n{{/each}}Примеры
Заголовок раздела «Примеры»Динамическая директива
Заголовок раздела «Динамическая директива»{ "directive": "Реализуй фичу {{featureName}} в проекте {{projectName}}", "completionCondition": "Фича {{featureName}} реализована и протестирована"}Условное ветвление
Заголовок раздела «Условное ветвление»Ветвление через узел condition, читающий значение через contextPath:
{ "id": "check-tests", "type": "condition", "condition": { "operator": "eq", "left": { "contextPath": "testsPassed" }, "right": true }, "connections": { "true": "deploy", "false": "fix-and-retry" }}Цикл со счетчиком
Заголовок раздела «Цикл со счетчиком»Цикл через узел expression для инкремента счётчика и узел condition для проверки лимита:
{ "id": "increment", "type": "expression", "expressions": ["iterationCount = iterationCount + 1"], "connections": { "default": "check-limit" }}{ "id": "check-limit", "type": "condition", "condition": { "operator": "lt", "left": { "contextPath": "iterationCount" }, "right": 5 }, "connections": { "true": "improve", "false": "done" }}Шаблон в описании Input Schema
Заголовок раздела «Шаблон в описании Input Schema»Помогите агентам понять ожидаемый формат:
{ "inputSchema": { "type": "object", "properties": { "implementation": { "type": "string", "description": "Код для {{featureName}} на {{language}}" } } }}Экранирование
Заголовок раздела «Экранирование»Для вывода литеральных фигурных скобок используйте двойное экранирование:
\\{{notAVariable}} - Выводит: {{notAVariable}}Лучшие практики
Заголовок раздела «Лучшие практики»- Описательные имена — Используйте понятные имена переменных
- Значения по умолчанию — Предоставляйте fallback для опциональных переменных
- Согласованность типов — Сохраняйте согласованность типов переменных при использовании
- Документация — Документируйте пользовательские переменные в описании воркфлоу
Отладка
Заголовок раздела «Отладка»Проверьте значения переменных в контексте выполнения:
Агент: Какие текущие переменные контекста?[вызывает get_execution_context]