Skip to main content
Навыки и агенты сейчас проходят альфа-тестирование. Функция работает, но продолжает развиваться.
Приложения могут определять возможности ИИ, которые находятся внутри рабочего пространства — повторно используемые инструкции для навыков и агенты с настраиваемыми системными подсказками.
Навыки определяют многократно используемые инструкции и возможности, которые агенты ИИ могут использовать в вашем рабочем пространстве. Используйте defineSkill() для определения навыков со встроенной валидацией:
src/skills/example-skill.ts
Основные моменты:
  • name — уникальная строка-идентификатор навыка (рекомендуется kebab-case).
  • label — читаемое человеком отображаемое имя, показываемое в UI.
  • content содержит инструкции навыка — это текст, который использует агент ИИ.
  • icon (необязательно) задаёт значок, отображаемый в UI.
  • description (необязательно) предоставляет дополнительный контекст о назначении навыка.
Агенты — это ИИ-помощники, работающие в вашем рабочем пространстве. Используйте defineAgent() для создания агентов с пользовательским системным промптом:
src/agents/example-agent.ts
Основные моменты:
  • name — уникальная строка-идентификатор агента (рекомендуется kebab-case).
  • label — отображаемое имя, показываемое в UI.
  • prompt — это системный промпт, определяющий поведение агента.
  • description (необязательно) предоставляет контекст о том, что делает агент.
  • icon (необязательно) задаёт значок, отображаемый в UI.
  • modelId (необязательно) переопределяет модель ИИ по умолчанию, используемую агентом.
  • responseFormat (необязательно) определяет форму вывода агента. По умолчанию для свободного текста используется { type: 'text' }. Используйте { type: 'json', schema }, чтобы принудительно получать структурированный JSON-вывод.
По умолчанию агент возвращает свободный текст. Чтобы получить структурированный вывод, установите для responseFormat значение { type: 'json' } и укажите schema:
src/agents/structured-agent.ts
Примечания к схеме:
  • Схема — это плоский объект: type каждого свойства должен быть примитивом (string, number или boolean). Вложенные объекты и массивы не поддерживаются.
  • description (необязательно) для каждого свойства подсказывает модели, что туда нужно поместить.
  • required (необязательно) перечисляет свойства, которые модель всегда должна возвращать.
  • additionalProperties: false (необязательно) запрещает любые свойства, не объявленные в properties.
runAgent() позволяет логической функции запустить одного из агентов вашего приложения (с его навыками и инструментами). Идентифицируйте агента по universalIdentifier, который вы передали в defineAgent(). Передайте либо строку prompt, либо историю диалога messages — но не оба варианта одновременно:
src/logic-functions/run-enricher.ts
Для многошаговых ботов (Slack, Discord, Teams, …) передавайте историю треда как messages вместо одного prompt:
src/logic-functions/reply-in-thread.ts
Основные моменты:
  • Укажите ровно один из prompt (строка) или messages (от 1 до 100 элементов вида { role: 'user' | 'assistant', content: string }).
  • Агент выполняется синхронно и может самостоятельно читать и обновлять записи с помощью собственных инструментов — runAgent() возвращает результат после завершения выполнения.
  • Приложение может запускать только собственных агентов.
  • Роль по умолчанию приложения должна предоставлять флаг разрешения AI — добавьте SystemPermissionFlag.AI в permissionFlagUniversalIdentifiers (или установите canAccessAllTools: true). Без этого runAgent() завершится с ошибкой прав доступа.
  • Установите достаточно большое значение timeoutSeconds для логической функции — выполнение агента может занимать несколько секунд.
  • success имеет значение true, а result — не null, когда запуск завершается; при ошибке success равно false, result равно null, а в error содержится причина (например, если в рабочем пространстве закончились AI-кредиты во время запуска).
src/roles/default-role.ts
Избегайте циклов: если вы вызываете runAgent() из триггера события базы данных *.updated, и агент обновляет ту же запись, ограничьте триггер, указав в updatedFields поле, которое агент никогда не изменяет (например, исходный URL), или добавьте проверку, что хотя бы одно целевое поле всё ещё пусто, прежде чем вызывать runAgent().

Запуск от имени участника рабочего пространства

Передавайте runAsWorkspaceMemberId, когда запуск инициирован человеком — например, чат-ботом, отвечающим на сообщение, — чтобы агент действовал как этот участник, а не как приложение:
src/logic-functions/answer-question.ts
Затем запуск выполняется с собственной ролью участника: он может делать всё, что может делать этот участник, и не больше; созданные им записи приписываются этому участнику, и к ним применяются его разрешения на уровне строк. Роль агента в этом не участвует — это роль по умолчанию приложения для запусков, за которыми никто не стоит. Опускайте это поле для автономных запусков (плановые задания, триггеры событий базы данных): в таких случаях сохраняется собственная роль агента. Действующее приложение остаётся привязанным к контексту запуска для отслеживания происхождения, не сужая при этом полномочий участника.Ваше приложение отвечает за сопоставление человека, который инициировал запуск, с участником рабочего пространства. Чтобы указать участника, требуется токен доступа приложения; то, кого можно указать с помощью токена, зависит от того, привязан ли к нему пользователь:
  • Токен без привязанного пользователя может указать любого участника. Логическая функция выполняется с таким токеном; то же относится к токенам, выпущенным через client_credentials или на основе API‑ключа.
  • Токен, выданный от имени пользователя (как у фронтенд‑компонента), может указывать только на участника самого этого пользователя.
Все остальное — обычная пользовательская сессия, API‑ключ без токена приложения — вообще не может указывать участника.
runAgent() генерирует исключение, если не удаётся определить участника рабочего пространства — неизвестного или удалённого участника, либо участника без роли. При этом никогда не используется роль самого агента, так как это предоставило бы больше прав доступа, чем запросил вызывающий код.