На этой странице
API для агентов
В DataSuite 2 есть JavaScript API — window.DataSuite. Через него ИИ-агент или скрипт автоматизации браузера делает то, что пользователь делает мышью: загружает таблицу, выбирает анализ и его параметры, запускает расчёт и читает карточки результатов, а для того, чего не считает ни один анализ, вводит код R в консоль страницы. API управляет той самой страницей, которую видит пользователь. Карточки попадают в тот же раздел вывода, считаются при тех же настройках и остаются на странице, где пользователь может их прочитать, экспортировать или сохранить. Вся статистика считается в браузере посетителя, на том же движке R (скомпилированном в WebAssembly), что и при нажатии кнопок приложения. Серверного адреса для запросов нет, данные не покидают компьютер, а сам API существует только на странице, где открыто приложение.
Первым агент вызывает DataSuite.help(). Вызов возвращает короткое руководство в формате Markdown, составленное под текущее состояние страницы (загружен ли набор данных, как через меню дойти до выбора файла на языке интерфейса пользователя), со ссылками на документацию.
Быстрый старт
- Откройте DataSuite 2 в браузере, которым управляет агент, и прочитайте
await DataSuite.help(). - Загрузите данные, лучше руками пользователя (см. как загрузить данные), и проверьте их вызовом
await DataSuite.describeData(). - Найдите нужный анализ через
await DataSuite.listAnalyses(), а что он принимает, узнайте черезawait DataSuite.describeAnalysis(name). - Запустите его:
await DataSuite.run(name, { variables, config })возвращает карточки в формате Markdown. - Раздел вывода можно перечитать в любой момент вызовом
await DataSuite.results().
await DataSuite.describeData(); // например: score (continuous), group (categorical: A, B)
await DataSuite.describeAnalysis("comparison");
const reply = await DataSuite.run("comparison", {
variables: ["score", "group"],
config: { specificTest: "welchTTest" },
});
reply.cards.map((card) => card.markdown);
Вызовы
Каждый вызов возвращает промис, и все они доступны сразу после загрузки страницы: собственный код API скачивается при первом обращении.
| Вызов | Возвращает | Меняет страницу |
|---|---|---|
help() |
руководство для агента в формате Markdown | нет |
describeData() |
набор данных: имя, число строк и наблюдений в работе, фильтры наблюдений, выбранные переменные, а по каждой переменной тип, имя в R (rName), n, число пропусков и уровни категориальной |
нет |
loadData(source) |
новый набор данных в описании describeData() с первыми и последними строками после разбора |
загружает данные |
listAnalyses() |
все анализы: name, пункт меню, описание в одну строку и адрес руководства |
нет |
describeAnalysis(name) |
роли, которые могут играть столбцы, и все параметры анализа | открывает его раздел |
run(name, options) |
карточки запуска в формате Markdown вместе со ссылками на источники и предупреждениями | выводит карточки |
status() |
свободна страница или занята, и ход расчёта | нет |
results(range) |
раздел вывода: карточки всех запусков в порядке на странице | нет |
cancel() |
остановлен ли запуск или код в консоли, начатые через API | останавливает запуск |
console(code, options) |
что напечатал R, его ошибки и предупреждения, построенные кодом карточки и по запросу значение | выполняет код в консоли R пользователя |
getSettings() |
все настройки приложения по ключам | нет |
setSettings(values) |
значения, которые вызов заменил | сохраняет настройки |
Как загрузить данные
Способов три, в порядке предпочтения.
Файл открывает пользователь
Свои данные пользователю лучше открыть самому: Меню → Загрузка и просмотр данных → Выбрать файл, а затем окно импорта, если оно откроется. help() даёт агенту эту просьбу на языке интерфейса пользователя, чтобы агент её передал. Файл не проходит через агента, а на вопросы импорта (какой лист, сколько строк заголовка) пользователь отвечает сам, глядя на свой файл. После этого describeData() показывает, что именно загружено.
Файл задаёт автоматизация браузера
Если автоматизация агента умеет заполнять поле выбора файла, агент передаёт файл в input#fileInput, скрытое поле за кнопкой Выбрать файл, и импорт идёт точно так же, как при выборе файла пользователем. Когда импорту нужен ответ (какой лист книги, сколько строк заголовка, какая кодировка текста), открывается окно импорта и ждёт нажатия кнопки Импорт.
loadData для небольших таблиц и общедоступных файлов
loadData — крайнее средство: таблица, которую набирает агент, стоит по токену на значение, и любое значение может незаметно исказиться. Источник задаётся одним из двух аргументов:
text— сама таблица в формате csv (по умолчанию), tsv, txt или json, не длиннее 100 тысяч символовurl— общедоступный файл по http или https размером до 25 МБ в любом формате, который импортирует приложение (csv, tsv, txt, json, xlsx, xls, ods, sav, zsav, por, dta, sas7bdat, xpt). Формат определяется по пути,formatимеет перед ним приоритет, а если путь формата не называет, его задаётname
Кроме источника вызов принимает name (имя набора данных), format, sheet (лист книги по имени или по индексу, считая с 0), headerRows (от 0 до 10) и encoding (для скачанного csv-, tsv- или txt-файла не в UTF-8). Расширение в name, которое импортирует приложение (например, survey.tsv), задаёт формат. Если оно противоречит format (а без него — расширению в url), вызов отклоняется, а любое другое расширение остаётся частью имени. Таблица проходит тот же импорт, что и у пользователя, с теми же парсерами, определением типов и окном импорта. Если окно задаёт вопрос, на который эти аргументы не отвечают, вызов отклоняется с перечнем вариантов. Файл по url страница скачивает сама, поэтому сервер должен разрешать другим сайтам читать файл (CORS): так устроены raw-файлы GitHub и большинство порталов открытых данных. Файл проекта DataSuite отклоняется, потому что открытие проекта заменяет весь сеанс. Такой файл пользователь открывает кнопкой Выбрать файл.
Ответ содержит то же, что возвращает describeData(), а также первые и последние пять строк после разбора (чтобы сверить их с задуманной таблицей), отчёт окна импорта (importNote) и уведомления, которые приложение показало во время импорта (appSaid).
Описание и запуск анализа
listAnalyses() возвращает список, ничего не загружая. Кроме статистических анализов в нём есть калькуляторы планировщика анализа, которым набор данных не нужен, и три записи преобразования данных: первая добавляет к набору данных правило преобразования (созданный им столбец доступен всем следующим запускам), вторая выводит список правил, третья удаляет правило.
describeAnalysis(name) открывает раздел анализа и возвращает, помимо его строки из listAnalyses():
variables— что представляет собой плоский списокvariablesв запуске и как его столбцы распределяются по ролямroles— роли, которые может играть столбец (зависимая переменная, группирующая переменная, предикторы). Для каждой роли указаны её ключ в конфигурации, принимает ли она несколько столбцов, чем она становится, если конфигурация её не задаёт (берётся изvariables, получает значение по умолчанию или обязательна), и к каким запускам она относитсяcolumns— пути в конфигурации, которые принимают отображаемое имя столбца (*в пути означает любой ключ или индекс). Путь, оканчивающийся на<key>, — это объект с ключами-столбцами, которые тоже записываются отображаемыми именамиoptions— все параметры:type,domainили границы числа (либоshape, словесное описание формы значения),off(значение там, где параметр не действует),value(текущее значение в разделе), действует ли параметр (applies) при текущей конфигурации раздела иlabel, подпись его элемента управления. У списка записей естьelementс параметрами одной записи, даже пока список пуст. Ключ с точкой в конфигурации записывается вложенным объектомreadsData— false для записи, которой нужна только её конфигурация (например, у калькуляторов планировщика)
run(name, options) запускает анализ так же, как кнопка запуска в его разделе: под индикатором выполнения, который блокирует страницу и останавливает расчёт кнопкой Отмена, а карточки добавляются в раздел вывода. Одновременно выполняется только один запуск. Параметры запуска:
variables— столбцы для анализа по отображаемым именам. Без них анализ идёт по текущему выбору, а список, отличный от него, заменяет выбор, который видит пользовательconfig— параметры и роли в том виде, в каком их перечисляетdescribeAnalysis, столбцы по отображаемым именам. Пропущенный параметр сохраняет значение, выставленное в разделеraw— при true в ответ добавляется сам объект результата, столбцы в нём названы отображаемыми именами, а список длиннее 100 значений заменён указанием его длины
В ответе есть cards (у каждой карточки index, её место в разделе вывода, а также title и markdown), citations (источники, на которые сослался запуск, разложенные, как в блоке ссылок, по methods, software и background), warnings (то, что пользователь увидел бы в уведомлениях), а у пакетного запуска с неудавшимися частями ещё и failures. Если содержимое ячейки таблицы на странице занимает несколько строк (например, статистика, а под ней p и размер эффекта), в Markdown эти строки соединены через ·.
Объём ответа
Ответ вмещает до 20 тысяч символов карточек. Если карточки длиннее, первая приходит целиком, а остальные только с названием и размером, и поле more называет точный вызов results({ from, count }), который их прочитает.
results({ from, count }) возвращает раздел вывода в порядке на странице: карточки всех запусков, включая запуски пользователя, и перед каждой карточку настройки с конфигурацией, при которой она рассчитана. Объём ограничен так же: записи приходят целиком, пока помещаются (первая карточка всегда), остальные с названием и размером, а more называет следующий вызов. from — индекс карточки (по умолчанию 0), count — сколько карточек прочитать (по умолчанию до конца), а total в ответе — число карточек в разделе вывода.
Медленный первый запуск
При первом запуске анализа в браузер устанавливаются его пакеты R, на это может уйти минута и больше, зато следующие запуски начинаются сразу. Если вызов прервался по тайм-ауту на стороне агента, расчёт продолжается. status() отвечает busy и сообщает анализ, сколько секунд он идёт, текст и прогресс индикатора выполнения, а также cards, число карточек в разделе вывода. Запомните это число до запуска, дождитесь от status() ответа idle, и results({ from: count }) вернёт всё, что построил запуск.
cancel() останавливает запуск, начатый через API (анализ или код в консоли), так же, как кнопка Отмена на индикаторе, и ждёт его завершения до десяти секунд. Ответ stopped: false означает, что запуск не успел остановиться: скомпилированный код R, который не проверяет прерывания, работает до конца. Запуск, начатый пользователем, может отменить только сам пользователь.
Консоль R
console(code, { value }) нужен для того, чего не считает ни один анализ. Вызов вводит код в консоль R страницы и выполняет его как код самого пользователя: в его сессии R и глобальном окружении, под индикатором выполнения, а код остаётся в консоли и её истории, где пользователь может его прочитать. Поэтому черновые вычисления лучше заключать в local({ ... }), а не оставлять рядом с объектами пользователя. Код — это команды R (несколько строк уходят одной отправкой, как при вставке) или слэш-команда. /data записывает наблюдения в работе во фрейм данных df, столбцы которого названы по rName переменных из describeData() (df$v_3_), а /output <expression> выводит карточку результата. Код с незакрытой скобкой или строкой не отправляется вовсе. Если консоль ещё выполняет строку, введённую пользователем, вызов отклоняется.
В ответе есть printed — текст консоли, где переменные названы отображаемыми именами (последние 20 тысяч символов, а если вывод длиннее, truncated сообщает его полную длину), отдельно errors и warnings с именами, под которыми переменные известны R, и карточки, построенные кодом, в том же виде, в каком их возвращает run. При value: true добавляется значение последнего выражения в виде данных (вектор, список или фрейм данных). Если вернуть его так нельзя (подогнанная модель, значение сверх объёма ответа, код с ошибкой), вместо него приходит valueError с указанием, что вернуть взамен (coef(fit), а не fit). Ошибка кода, который обратился к df до /data или назвал переменную отображаемым именем там, где R знает её rName, приходит с подсказкой в hint.
Настройки
getSettings() возвращает все настройки, которые сохраняет окно Настройки, по их ключам. setSettings({ key: value }) применяет их так же, как кнопка Сохранить в этом окне: при смене метода обработки пропусков данные готовятся заново, а все карточки результатов перерисовываются. Настройки сохраняются в этом браузере, переживают перезагрузку страницы и действуют в следующих сеансах пользователя, поэтому агенту стоит менять настройку, только если этого хочет пользователь. Отдельных настроек для одного запуска нет. Неверный ключ или значение, которое окно не приняло бы, отклоняет весь вызов: перечисляются все ошибки, и ничего не меняется. Ответ содержит значения, которые вызов заменил, чтобы их можно было вернуть.
Отказы
Ничто из переданного агентом не отбрасывается без предупреждения. Неизвестный анализ, аргумент, параметр, настройка или переменная, как и значение вне допустимой области, отклоняются ошибкой (Error), которая называет ближайшее совпадение и допустимые значения: unknown analysis "comparsion" – did you mean "comparison"?. Параметр, который при конфигурации запуска не действует, называется в warnings. Если конфигурация не задаёт роль, обязательную для анализа (например, время и событие в анализе времени до события), вызов отклоняется с её названием, и никакой другой столбец на её место не подставляется. Настройка, записанная в config, тоже отклоняется, а ошибка отсылает к setSettings.
Страница общая с пользователем, поэтому вызовы, которые её меняют (loadData, describeAnalysis, run, console и setSettings), отклоняются, пока идёт запуск, начатый агентом или пользователем. setSettings отклоняется и тогда, когда открыто окно настроек, потому что его сохранение отменило бы изменение.
WebMCP
В браузере с поддержкой WebMCP страница регистрирует эти вызовы ещё и как инструменты: агент, подключённый к браузеру, вызывает их, не выполняя JavaScript на странице. Это get_help, load_data, describe_data, list_analyses, describe_analysis, run_analysis, get_status, get_results, cancel_run, r_console, get_settings и set_settings. Каждый принимает те же аргументы и возвращает тот же ответ, что и вызов, по которому он назван. Отказ приходит как { error }, а не как ошибка вызова, потому что причину ошибки инструмента браузер скрывает.
По умолчанию WebMCP выключен, а включает его пользователь в разделе Настройки › ИИ-агенты. Пока он выключен, каждый инструмент отвечает { error } с объяснением. Это касается и set_settings, так что агент может выключить WebMCP, но не включить. Кнопка WebMCP на верхней панели показывает состояние (пока WebMCP включён, она закрашена зелёным, а если браузер его не поддерживает, приглушена) и открывает окно, где пользователю объяснено, что может подключённый агент. Агенту, который выполняет JavaScript на странице, как это делают средства автоматизации браузера, всё это не нужно: он вызывает window.DataSuite напрямую.