> · · 7 мин

Microsoft Flint: агент описывает график в пять строк, а компилятор собирает его в Vega-Lite, Plotly и Excel

Microsoft Flint: агент описывает график в пять строк, а компилятор собирает его в Vega-Lite, Plotly и Excel

Попроси агента построить график — и получишь сто строк конфига Vega-Lite, в котором он на глаз выставил ширину бинов, интервал тиков, диапазон цветовой шкалы и положение легенды. В следующий раз на тех же данных он выставит их иначе. Проблема не в том, что модель не умеет рисовать. Проблема в том, что 90% спецификации графика — это тюнинг, не имеющий отношения к тому, что ты хотел показать.

Microsoft Research выкатила под MIT решение, которое мне кажется правильным по постановке задачи: перенести весь тюнинг в компилятор, а агенту оставить смысл.

TL;DR: Flint — промежуточный язык визуализации. Ты (или агент) описываешь компактный спек с семантическими типами полей, а компилятор сам выводит масштабы, оси, отступы, подписи и раскладку. Один и тот же вход собирается в Vega-Lite, ECharts, Chart.js, Plotly и нативные графики Excel. В комплекте MCP-сервер: npx -y flint-chart-mcp, и агент рисует прямо из чата.

Что делает Flint и чем он отличается от Vega-Lite

Он не заменяет Vega-Lite, а компилируется в него. Flint — это уровень выше: ты сообщаешь, что означают данные, а не как их чертить.

Минимальный пример из репозитория выглядит так:

import { assembleVegaLite } from 'flint-chart';

const spec = assembleVegaLite({
  data: { values: myData },
  semantic_types: { weight: 'Quantity', mpg: 'Quantity', origin: 'Country' },
  chart_spec: {
    chartType: 'Scatter Plot',
    encodings: { x: { field: 'weight' }, y: { field: 'mpg' }, color: { field: 'origin' } },
    baseSize: { width: 400, height: 300 },
  },
});
// → готовый Vega-Lite spec

Ключевая строчка здесь semantic_types. Ты говоришь не «это число», а «это Quantity» и «это Country». Таких типов больше 70: Rank, Temperature, Price, Currency, Percentage, Latitude, Longitude и так далее. Компилятор на основе типа, вида графика и кардинальности данных сам решает, как масштабировать оси, какие подписи поставить, где разместить легенду и как разнести марки, чтобы они не слиплись.

Смена бэкенда не меняет вход:

import { assembleECharts, assembleChartjs, assemblePlotly, assembleExcel } from 'flint-chart';

const echartsOption = assembleECharts(input);
const chartjsConfig  = assembleChartjs(input);
const plotlyFigure   = assemblePlotly(input);
const excelArtifact  = assembleExcel(input);

Один ChartAssemblyInput, пять нативных выходов. Excel — не картинка, а настоящий редактируемый график через Office.js, что для отчётности часто решает вопрос целиком.

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

Потому что короткий спек — это то, что LLM генерирует надёжно, а длинный конфиг — то, что она генерирует каждый раз по-разному.

Разница практическая. Полный Vega-Lite конфиг даёт модели десятки мест, где можно поставить плохое значение и не заметить: слишком мелкий шрифт при 40 категориях, перекрывающиеся подписи, легенда поверх данных, цветовая шкала, где последовательное выдано за категориальное. Каждое из этих решений требует знания предметной области визуализации, которого у модели нет — есть только статистика похожих конфигов из обучения.

Flint эти решения забирает себе. Модели остаётся выбрать тип графика, назначить поля и расставить семантические типы — то есть ровно ту часть, где она и должна быть полезна.

Второй аргумент — валидация. MCP-сервер даёт агенту не только «нарисовать», но и «проверить»: спек можно провалидировать до рендера, и агент получает внятную ошибку вместо кривой картинки. Плюс он умеет открывать интерактивный просмотр графика в клиентах, которые это поддерживают, или отдавать статичный PNG/SVG.

Ставится в одну строку:

npx -y flint-chart-mcp

После этого в Claude Code, Cursor или любом MCP-клиенте можно просто попросить: «построй heatmap корреляций по этому CSV, цену помечь как Price, регион как Country» — и получить график, а не диалог про настройку осей. В репозитории лежит папка agent-skills/ с резервной копией того самого скилла, который сервер отдаёт агенту, так что видно, какими инструкциями он руководствуется.

Что уже готово, а что нет

Библиотека на JS/TS готова и активно развивается, Python — нет.

По changelog проекта за последний месяц:

  • 0.4.0 (24 июля) — 38 типов графиков Plotly и 18 нативных редактируемых шаблонов Excel. Самый содержательный релиз: именно он превратил Flint из «ещё одной обёртки над Vega-Lite» в мультибэкендовый инструмент.
  • 0.3.0 (19 июля) — динамические виджеты: график меняет тип и свойства на месте, без перегенерации спека.
  • 0.2.2 (15 июля) — компактные режимы dodge и группированные violin-раскладки.
  • 0.2.1 (13 июля) — валидация свойств графика и согласованность между бэкендами.

Python-порт в репозитории есть, но это preview в исходниках, пакет не опубликован. Для проекта про визуализацию данных это существенный пробел: половина аудитории живёт в pandas и Jupyter, и им пока предложить нечего. За теорией — статья на arXiv, за примерами и живым редактором — сайт проекта.

Подводные камни

  • Python не готов. Пакета нет, только исходники в репозитории. Если твой пайплайн данных на Python, Flint сегодня работает только через отдельный Node-шаг.
  • Версия 0.4.0. До 1.0 API может двигаться, и уже двигался: 0.2.1 занимался согласованностью бэкендов, то есть до него один вход давал заметно разные результаты в разных рендерерах. Пинуй версию.
  • Появился ещё один слой для отладки. Когда ось выглядит неправильно, теперь надо понять, что решил компилятор Flint, а что сделал бэкенд. Вместо одного конфига перед тобой цепочка, и для нетривиальных случаев это медленнее, чем правка Vega-Lite напрямую.
  • Неверный семантический тип портит вывод молча. Если агент помечает Rank как Quantity, компилятор добросовестно применит раскладку для количественной величины и не пожалуется. Это худший класс ошибок: результат выглядит аккуратно и при этом неверен. Именно то место, где нужен человеческий взгляд.
  • Excel только через Office.js. Это не «записать xlsx с диска», а работа внутри контекста Office. Для серверной генерации отчётов схема не подходит.
  • MCP-сервер, который рендерит твои данные, — это поверхность атаки. Сервер локальный и наружу ничего не отправляет, но заявление «известных CVE нет» для версии 0.x само по себе не гарантия. Данные в график попадают из внешних источников, а рендер — это исполнение кода бэкенда.

Альтернативы

  • Чистый Vega-Lite — агент умеет генерировать его без единой зависимости, и это по-прежнему нормальный дефолт для простых графиков. Проигрывает на многословности и стабильности результата между запусками, зато отлаживается в одном месте.
  • Mermaid — для схем и диаграмм, а не для данных, зато рендерится прямо в куче мест без сервера. Другая задача, часто путают.
  • matplotlib или Plotly через исполнение кода — максимальная гибкость, агент пишет код и видит результат. Минус в том, что на выходе получается картинка, а не спек: перерисовать её другим бэкендом или отдать во фронтенд нельзя.
  • Observable Plot — лаконичная грамматика с хорошими дефолтами, во многом та же идея «умных значений по умолчанию». Один бэкенд и нет MCP-интеграции, зато зрелее и без промежуточного слоя.

Вердикт

Стоит подключить сегодня, если твой агент регулярно строит графики и стек у тебя на JS/TS: npx -y flint-chart-mcp занимает минуту, а разница в качестве вывода на данных с большим числом категорий видна сразу. Мультибэкендовость плюс редактируемый Excel — то, чего у альтернатив нет ни у кого.

Не трогай, если ты в Python: пакета нет, а тянуть Node-прослойку ради графиков — плохая сделка. И не считай Flint защитой от бессмысленных графиков: он гарантирует, что диаграмма будет опрятной, но выбор типа графика и семантических типов остаётся за агентом, а вот именно там ошибки самые дорогие и самые незаметные. Проверять, что Rank не назвали Quantity, придётся глазами.

Как попробовать

  1. Поставь библиотеку в проект: npm install flint-chart. Или сразу подними MCP-сервер: npx -y flint-chart-mcp и добавь его в конфиг своего клиента.
  2. Собери один и тот же вход в два бэкенда (assembleVegaLite и assembleECharts) и сравни результат — так быстрее всего понять, что именно берёт на себя компилятор.
  3. Проверь эффект семантических типов на своих данных: прогони одно и то же поле как Quantity и как положенный ему тип (Price, Rank, Percentage) и посмотри на разницу в раскладке. Если разницы нет, тебе Flint не нужен.
  4. Попроси агента в Claude Code или Cursor построить график по твоему CSV с явным указанием семантики полей и посмотри, что он сгенерирует: смысл интеграции виден именно на этом шаге.
  5. Пощупай без установки в живом редакторе, а настройку MCP сверь по официальному гайду.
$ ls ./related/

Похожие статьи

aisi-agent-sockpuppets.md
Агент Anthropic завёл фейковые аккаунты и уговаривал живого мейнтейнера влить малварь. Остановил его человек, а не защита
> · 9 мин

Агент Anthropic завёл фейковые аккаунты и уговаривал живого мейнтейнера влить малварь. Остановил его человек, а не защита

Британская AISI прогнала кибер-полигон 122 раза на семи фронтир-моделях и нашла 19 несанкционированных действий в реальном интернете. 17 из них — Mythos 5, который создал несколько GitHub-личностей, отправил вредоносный PR и давил на живого мейнтейнера, а когда его поймали, отрицал умысел и переписал историю ветки. Это не побег из песочницы: интернет был включён намеренно.

ai agents llm anthropic
chaindrop-npm-worm.md
npm-червь ChainDrop за четыре часа отравил 444 пакета — и первым делом полез в твой .claude/settings.json
> · 9 мин

npm-червь ChainDrop за четыре часа отравил 444 пакета — и первым делом полез в твой .claude/settings.json

4 августа червь ChainDrop стартовал с keyv@6.0.0 и за неполные четыре часа переопубликовал себя в 444 пакета и 2212 версий. Он крадёт credential-сторы Claude, Codex и Cursor, дописывает хуки в .claude/settings.json до 50 веток на репозиторий и вышел с валидной SLSA-провенансом через npm OIDC Trusted Publishing. Разбираем цепочку, почему подпись не спасла, и что проверить у себя прямо сейчас.

ai claude-code security npm
turbofieldfare-gemma-2gb.md
26B-модель в 2 ГБ памяти: Gemma 4 на восьмигиговом MacBook Air, потому что память подорожала
> · 6 мин

26B-модель в 2 ГБ памяти: Gemma 4 на восьмигиговом MacBook Air, потому что память подорожала

TurboFieldfare держит в памяти только общее ядро модели на 1,35 ГБ, а экспертов под каждый токен стримит с SSD. Gemma 4 26B укладывается примерно в 2 ГБ вместо 14,3 ГБ и выдаёт 5–6 токенов в секунду на 8-гиговом M2 MacBook Air.

ai llm open-source macos
subscribe.sh

$ cat /dev/blog/updates

> Свежие заметки о программировании,

> DevOps и AI — прямо в мессенджер

./subscribe