Microsoft Researchは2026年7月8日、AIエージェントによるグラフ作成を支援する中間言語「Flint」を発表した。Flintは、AIエージェントが扱いやすく、人間も確認・編集しやすい短いチャート仕様を、Vega-Lite、Apache ECharts、Chart.js向けの詳細な設定へ変換する。列の役割や値の種類に応じて、目盛り、数値や日付の表示形式、レイアウトなどを補い、グラフを作りやすくする。
Microsoft Researchの記事では、Flintを「visualization language」または「visualization intermediate language」と呼んでいる。本稿では、チャートの種類や使うデータ列、その列が日付や価格、割合などの何を表すかを記述し、各描画ライブラリ向けの設定へ変換するための記述形式として説明する。
「短い設定」と「見栄え」の差を埋める
チャート描画ライブラリとしては、Vega-Lite 、Apache ECharts 、Chart.js といったものがある。これらはスケール、軸、余白、ラベル、配色などを細かく指定できる一方、既定値に任せた短い設定では見た目や読みやすさが不十分になりやすい。品質を上げようとすると、設定は長くなり、壊れやすくなってしまう。Flintは、この差を埋めるものとして発表された。
こうした難しさは、LLMやAIエージェントがチャート作成を担う場面でさらに目立ちやすい。エージェントに細かな設定を直接書かせると、ライブラリ固有の細部で誤りが起きたり、人間が後から読み、直し、再利用したりしにくくなる可能性がある。Flintは既存のチャート描画ライブラリを置き換えるものではなく、その手前でチャートの意図を受け渡す中間レイヤーとして機能する。
LLMベースのチャート生成でFlintが使いやすいのは、モデルに細かなチャート設定を丸ごと書かせず、まずデータの意味を推定させる設計にある。たとえば列名や値の並びから「この列は日付」「 この列は価格」「 この列は割合」と判断できれば、その判断をFlintの短い仕様に書き込める。その後はFlintのコンパイラが、軸の形式、スケール、配色、レイアウトなどを描画ライブラリ向けの具体的な設定に落とし込む。
発表で示された評価では、Flintと、モデルに複雑なVega-Lite仕様を直接生成させるDirectVLを比較した。Tidy Tuesdaysのテストデータを使ったLLMによる自己評価パイプラインでは、FlintのLLM-judgeスコアが、GPT-5.1で16.27対15.91、GPT-5-miniで16.16対15.60、GPT-4.1で15.91対15.34となり、いずれもDirectVLを上回ったとしている。また、FlintはMicrosoft ResearchのAI支援データ分析・グラフ作成プロジェクト「Data Formulator」でも使われている。
データ仕様とチャート仕様を分ける
Flintでは、まず人間やAIエージェントが、データ本体、データの意味、チャートの指定をまとめた入力を用意する。JavaScript/TypeScriptから使う場合、この入力はオブジェクトとして扱い、必要に応じてJSONファイルとして保存することもできる。入力をFlintのコンパイラに渡すと、Vega-Lite、Apache ECharts、Chart.jsといった描画ライブラリ向けの設定に変換される。アプリやスクリプトは、その変換後の設定を各ライブラリに渡してグラフを描画する流れになる。
入力は、グラフを直接描いた画像ファイルではなく、グラフ化するデータと「どう描きたいか」をまとめた仕様にあたる。中身は主にdata、semantic_types 、chart_spec で構成される。dataにはグラフ化する値を入れる。semantic_types では、列が日付、価格、割合、国、順位などの何を表しているかを、Rank、Temperature、Price、Countryなど70種類以上のセマンティック型で記述する。chart_spec では、チャートの種類と、x軸、y軸、色、サイズ、ファセット(小分け表示)などに、どのフィールドを使うかを指定する。
つまり、chart_spec が指定するのは「何をどこへ割り当てるか」で、コンパイラが担うのは「その指定を読みやすく表示するための細部」にあたる。軸の目盛り数、日付や数値の表示形式、余白の大きさ、ラベルの角度、凡例の位置、具体的な配色などを逐一書き込まなくても、Flintのコンパイラがdataとsemantic_types から列の性質を読み取り、各描画ライブラリ向けの詳細設定へ変換する。
ただし、具体的な指定が一切できないわけではない。chart_spec には基準サイズを示すbaseSizeや上限サイズを示すcanvasSize、テンプレート固有のchartPropertiesも含められる。さらに、optionsでレイアウト調整に関わる挙動を指定でき、生成後の各ライブラリ向け設定を直接編集することもできる。
同じ入力から複数の描画先向けの設定を生成できる点も特徴の一つとなっている。発表時点の描画先はVega-Lite、Apache ECharts、Chart.jsで、これらの描画先をまたいで30種類以上のチャート型に対応する。今後は描画先をさらに追加する予定としている。対応状況の詳細はプロジェクトサイト で確認できる。
プロジェクトサイトでは、Vega-Lite、ECharts、Chart.jsのギャラリーを切り替えながら、複数のチャート例を確認できる。下のキャプチャはVega-Lite向けギャラリーを表示したもの。
インストールとMCPサーバー
公開リポジトリには、npmパッケージflint-chartの元になるJavaScript/TypeScriptライブラリと、MCPサーバーとしてFlintを使うためのflint-chart-mcpのソースコードが含まれる。flint-chartは、Flintの入力から各チャート描画ライブラリ向けの設定や仕様を生成するためのライブラリで、npmからインストールできる。
npm install flint-chart
インストール後は、JavaScript/TypeScriptのスクリプトやアプリからflint-chartを読み込んで使う。データ本体、セマンティック型、チャート仕様をまとめた入力をassembleVegaLite()、assembleECharts()、assembleChartjs()に渡し、それぞれVega-Lite向けの仕様、EChartsのoption、Chart.jsのconfigを生成する。
MCPサーバーは、FlintをMCP対応のAIクライアントやコーディング環境からツールとして呼び出し、エージェントにチャートの作成、検証、レンダリングまで任せたい場合に必要になる。flint-chart-mcpは、ツール呼び出しの中で直接渡したデータのほか、指定したローカルのJSON、CSV、TSVのデータファイルを読み込める。
MCPサーバーを起動する場合は、次のように実行する。なお、ローカルのスクリプトからflint-chartを直接呼び出すだけなら、MCPサーバーは必要ない。
npx -y flint-chart-mcp
FlintはMITライセンスで公開されている。リポジトリにはTypeScript実装、MCPサーバー実装、デモサイト、ドキュメント、サンプル仕様、テストデータなどが含まれ、Microsoft ResearchがIDEAS Lab(中国人民大学)と共同で開発していると説明されている。Python版は現時点ではソースのみのプレビューで、研究論文は今後公開予定としている。
コラム: GPT-5.5でChart.js向け設定から棒グラフを作成
今回の記事用にGPT-5.5を利用して、Flintの入力からChart.js向けの設定を生成し、その設定をもとに作図してみた。
作図にあたって、まずflint-chartとchart.js をインストールした。
npm install flint-chart chart.js
次に、作図の元になるデータとFlintの入力を用意するため、generate-flint-chart.mjs を作成した。Chart.js向けの設定だけをJSONで手書きするなら、このNode.jsスクリプトは不要になる。ただし今回は、Flintの入力を実際にflint-chartへ渡し、Chart.js向けの設定が生成される流れを示すため、flint-chartのAPIを呼び出す小さなスクリプトをGPT-5.5で作成した。このファイルでは、サンプルデータ、セマンティック型、チャート仕様をまとめ、assembleChartjs()でChart.js向けの設定を生成する。あわせて、確認用のSVGも書き出す。
import { writeFileSync } from 'node:fs' ;
import { assembleChartjs } from 'flint-chart' ;
const input = {
data : { values : [
{ month : '2026-01' , users : 120 },
{ month : '2026-02' , users : 180 },
{ month : '2026-03' , users : 150 }
] },
semantic_types : { month : 'YearMonth' , users : 'Count' },
chart_spec : {
chartType : 'Bar Chart' ,
encodings : {
x : { field : 'month' },
y : { field : 'users' }
},
baseSize : { width : 720 , height : 420 }
}
};
const chartjsConfig = assembleChartjs (input);
writeFileSync ('flint_chartjs_config.json' , JSON .stringify (chartjsConfig, null , 2 ));
function buildSvg (config ) {
return '<svg>...</svg>' ;
}
const svgText = buildSvg (chartjsConfig);
writeFileSync ('flint_chartjs_bar.svg' , svgText);
このJavaScriptファイルは、node generate-flint-chart.mjs で実行した。この時点で、Chart.js向けの設定ファイルflint_chartjs_config.json と、確認用のflint_chartjs_bar.svg を書き出している。
この段階でSVGだけを使うなら、同じスクリプト内で生成した設定からSVGを書き出せるため、JSONファイルとして保存する必要はない。ただし今回は、Flintが生成したChart.js向け設定を確認し、PNG作成スクリプトでも再利用するため、flint_chartjs_config.json として保存した。構造は、棒グラフの種類、ラベル、データセット、軸設定などを含む。
{
"type" : "bar" ,
"data" : {
"labels" : [ "2026-01" , "2026-02" , "2026-03" ] ,
"datasets" : [
{
"label" : "users" ,
"data" : [ 120 , 180 , 150 ]
}
]
} ,
"options" : {
"scales" : {
"x" : { "title" : { "text" : "month" } } ,
"y" : { "beginAtZero" : true , "title" : { "text" : "users" } }
}
}
}
その後、記事に掲載するPNG画像を作るため、render-flint-chart-png.py を作成した。PNGの作成にはPythonを使い、画像を生成・加工するためのPythonライブラリであるPillowも利用した。Pillowを未導入の場合は、pip install pillowでインストールする。
こちらのPythonファイルもFlintの出力ではなく、GPT-5.5が記事用の描画スクリプトとして作成した。flint_chartjs_config.json からラベルと値を読み取り、Pillowで棒、軸、目盛り、ラベルを描いてflint_chartjs_bar.png として保存する。
from pathlib import Path
import json
from PIL import Image, ImageDraw
config = json.loads(Path('flint_chartjs_config.json' ).read_text(encoding='utf-8' ))
labels = config['data' ]['labels' ]
values = config['data' ]['datasets' ][0 ]['data' ]
img = Image.new('RGB' , (800 , 480 ), 'white' )
draw = ImageDraw.Draw(img)
img.save('flint_chartjs_bar.png' )
PNGの作成は、python render-flint-chart-png.py で実行した。