Обзор
Приложения могут определять возможности ИИ, которые находятся внутри рабочего пространства — повторно используемые инструкции для навыков и агенты с настраиваемыми системными подсказками.defineSkill
Определяйте навыки ИИ-агентов
defineSkill
Определяйте навыки ИИ-агентов
Навыки определяют многократно используемые инструкции и возможности, которые агенты ИИ могут использовать в вашем рабочем пространстве. Используйте Основные моменты:
defineSkill() для определения навыков со встроенной валидацией:src/skills/example-skill.ts
name— уникальная строка-идентификатор навыка (рекомендуется kebab-case).label— читаемое человеком отображаемое имя, показываемое в UI.contentсодержит инструкции навыка — это текст, который использует агент ИИ.icon(необязательно) задаёт значок, отображаемый в UI.description(необязательно) предоставляет дополнительный контекст о назначении навыка.
defineAgent
Определяйте ИИ-агентов с пользовательскими промптами
defineAgent
Определяйте ИИ-агентов с пользовательскими промптами
Агенты — это ИИ-помощники, работающие в вашем рабочем пространстве. Используйте Основные моменты:Примечания к схеме:
defineAgent() для создания агентов с пользовательским системным промптом:src/agents/example-agent.ts
name— уникальная строка-идентификатор агента (рекомендуется kebab-case).label— отображаемое имя, показываемое в UI.prompt— это системный промпт, определяющий поведение агента.description(необязательно) предоставляет контекст о том, что делает агент.icon(необязательно) задаёт значок, отображаемый в UI.modelId(необязательно) переопределяет модель ИИ по умолчанию, используемую агентом.responseFormat(необязательно) задаёт формат вывода агента. По умолчанию для свободного текста используется{ type: 'text' }. Используйте{ type: 'json', schema }, чтобы принудительно получать структурированный JSON-вывод. ВызовrunAgent()или ИИ-шаг рабочего процесса может запросить другой формат, который имеет приоритет.roleUniversalIdentifier(необязательно) связывает агента с ролью, определённой вашим приложением. Эта роль не должна предоставлять больше прав, чем роль приложения, иначе сборка завершится с ошибкой; см. Роли агентов.modelConfiguration(необязательный параметр) включает встроенные инструменты модели, как на странице настроек агента:{ webSearch: { enabled: true }, twitterSearch: { enabled: true } }. Каждый инструмент работает только с моделями, которые его поддерживают. Не указывайте его, чтобы они оставались отключенными.isSystem(необязательный параметр, по умолчаниюfalse) скрывает агента из списков агентов, как агентов, которых Twenty создает для шагов ИИ в рабочих процессах. Он изменяет только отображаемое: агентов приложения можно изменять только через приложение, независимо от значения этого флага.
responseFormat значение { type: 'json' } и укажите schema:src/agents/structured-agent.ts
- Схема — это плоский объект:
typeкаждого свойства должен быть примитивом (string,numberилиboolean). Вложенные объекты и массивы не поддерживаются. description(необязательно) для каждого свойства подсказывает модели, что туда нужно поместить.required(необязательно) перечисляет свойства, которые модель всегда должна возвращать.additionalProperties: false(необязательно) запрещает любые свойства, не объявленные вproperties.
defineMcpServer
Предоставьте внешний MCP-сервер ИИ рабочего пространства (бета-версия)
defineMcpServer
Предоставьте внешний MCP-сервер ИИ рабочего пространства (бета-версия)
Используйте Основные моменты:
defineMcpServer() для развертывания удалённого MCP-сервера (Streamable HTTP) вместе с вашим приложением, чтобы ИИ рабочего пространства мог использовать его инструменты без синхронизации этих данных с Twenty:src/mcp-servers/github.ts
nameимеет формат snake_case (строчные буквы, цифры и символы подчёркивания, начинается с буквы, не более 32 символов) и уникален в рабочем пространстве. Он добавляется в начало имён инструментов сервера.urlдолжен быть URL-адресом HTTP или HTTPS.connectionProvider(необязательно) ссылается на поставщика подключения, объявленного тем же приложением. Запросы отправляют токен доступа этого подключения в качестве токена Bearer. Не указывайте его для общедоступного сервера.- URL-адрес нельзя изменить в более поздней версии, пока подключён поставщик подключения, поэтому токены никогда не отправляются на другой хост.
- Рабочие пространства могут деактивировать сервер; более поздняя версия приложения сохранит этот выбор.
- Требуется
"engines": { "twenty": ">=2.53.0" }.
runAgent
Запуск агента из логической функции
runAgent
Запуск агента из логической функции
runAgent() позволяет логической функции запустить одного из агентов вашего приложения (с его навыками и инструментами). Идентифицируйте агента по universalIdentifier, который вы передали в defineAgent(), и передайте в качестве input то, над чем он должен работать:src/logic-functions/run-enricher.ts
input— это строка или список из 1–100 сообщений ({ role: 'user' | 'assistant', content: string }). Сообщениеuserтакже может содержать вложения файлов (см. ниже). Чтобы поддерживать диалог, передавайтеthread, а не воспроизводите предыдущие ходы самостоятельно.- По умолчанию вызов ожидает агента, который может самостоятельно читать и обновлять записи
с помощью собственных инструментов —
runAgent()возвращает результат после завершения запуска. ПередайтеwaitForCompletion: false, чтобы вызов вернул результат сразу после запуска:statusбудет иметь значениеRUNNING, аresult: null; ответ поступит в беседуthreadId. Запуск, длящийся более 15 минут, также завершается со значениемRUNNING. - Агент также может приостановить работу, пока не изменится запись или не пройдет некоторое время.
Затем
runAgent()завершается со значениямиsuccess: true,status: 'SUSPENDED'иresult: null; позже агент самостоятельно продолжает работу, а его ответ появляется в беседеthreadId. Вызовthread, агент которого все еще ожидает, завершается ошибкой, пока агент не завершит работу. - Каждый вызов сохраняется вместе с его входными данными и статусом, а также с его ответом и использованием
после завершения, поэтому он отображается в запусках агента. Без
threadвызов получает собственный разговор:threadIdзадаёт его, и последующий вызов его никогда не видит. - Приложение может запускать только собственных агентов.
- Роль по умолчанию приложения должна предоставлять флаг разрешения
AI— добавьтеSystemPermissionFlag.AIвpermissionFlagUniversalIdentifiers(или установитеcanAccessAllTools: true). Без этогоrunAgent()завершится с ошибкой прав доступа. - Установите достаточно большое значение
timeoutSecondsдля логической функции — выполнение агента может занимать несколько секунд. statusимеет значениеCOMPLETEDи не равный nullresult, когда запуск завершается без ожидания;SUSPENDEDсо значениемsuccess: trueиresult: null, пока он ожидает;RUNNINGсо значениемsuccess: trueиresult: null, когда вызов не ожидал запуска;FAILEDсо значениемsuccess: falseиerror, содержащим причину (например, когда в рабочем пространстве во время запуска закончились кредиты ИИ).
src/roles/default-role.ts
Отправка файлов вместе с сообщением
Сообщениеuser может содержать attachments, поэтому агент видит снимок экрана или
PDF, а не только его имя. Каждая запись ссылается на файл, который ваше приложение уже
загрузило в папку agent-chat:src/logic-functions/describe-screenshot.ts
UPLOAD_FILE в роли приложения по умолчанию
наряду с AI. filename является необязательным и служит только для обозначения файла для модели.- Вложения могут содержать только сообщения
user. Их нельзя представить в ходе assistant, поэтомуrunAgent()отклоняет их, а не удаляет. - Не более 10 вложений на сообщение.
fileIdдолжен указывать на полностью загруженный файл в том же рабочем пространстве, в папкеagent-chat. В противном случае вызов завершается ошибкой вместо того, чтобы незаметно ответить без файла.
Запрос структурированного результата
ПередайтеresponseFormat, чтобы задать формат только для этого вызова. Он имеет приоритет над
собственным responseFormat агента, поэтому один агент может обслуживать вызывающих, которым нужны
разные результаты. Он использует ту же схему, что и defineAgent():src/logic-functions/score-lead.ts
Продолжение диалога
Передайтеthread, и Twenty сохранит диалог: при каждом вызове отправляется только
новый ввод, а агент видит предыдущие ходы, включая то, что
вернули его инструменты. Используйте в качестве ключа любой стабильный идентификатор со своей стороны, например Slack-
канал и временную метку цепочки сообщений:src/logic-functions/reply-in-thread.ts
- Ключи ограничены вашим приложением и агентом, поэтому два приложения никогда не используют
один диалог. Передавать
threadмогут только токены доступа приложения. inputможет содержать только сообщенияuser: в диалоге уже есть ответы агента.additionalInstructionsпередаются модели только для этого вызова и не сохраняются, что подходит для указаний для каждого запроса, например правил форматирования или крайнего срока. Они также работают безthread.- Каждый запуск сохраняется как ход с указанием его статуса, включая неудачные. Его использование сохраняется при возврате агента, даже если у него закончились кредиты. Неудачный запуск не является частью разговора, поэтому следующий вызов его не видит.
- Вызовы в одной и той же цепочке выполняются по одному: второй вызов ожидает завершения первого, поэтому каждый из них видит предшествующие ему ходы.
- Когда ходы выполняются от имени разных участников (см. ниже), каждый из них видит только текст ходов остальных, но никогда не видит результаты их инструментов, поскольку они были получены с разрешениями другого пользователя.
Запуск от имени участника рабочего пространства
ПередавайтеrunAsWorkspaceMemberId, когда запуск инициирован человеком — например, чат-ботом, отвечающим на сообщение, — чтобы агент действовал как этот участник, а не как приложение:src/logic-functions/answer-question.ts
- Токен без привязанного пользователя может указать любого участника. Логическая функция выполняется с таким токеном; то же относится к токенам, выпущенным через
client_credentialsили на основе API‑ключа. - Токен, выданный от имени пользователя (как у фронтенд‑компонента), может указывать только на участника самого этого пользователя.
sendInboxMessage
Начните или продолжите беседу в чатах участников
sendInboxMessage
Начните или продолжите беседу в чатах участников
sendInboxMessage() отправляет сообщение из вашего приложения в чаты одного или нескольких
участников рабочего пространства. Это может завершиться вызовом инструмента, на который участник отвечает из чата,
после чего разговор продолжается с ассистентом Twenty. См.
Входящие, чтобы узнать о его параметрах, вспомогательных функциях упоминаний
и о том, как выполнять публикации из фронтенд-компонента.