以下の内容はhttps://www.m3tech.blog/entry/agentic-edaより取得しました。


Agentic Coding時代のデータ分析環境: marimo + gokartで高速かつ再現性あるEDAを実現しよう

こんにちは、AI・機械学習チームのMLエンジニア、髙橋です。

この記事はAI・機械学習チームブログリレー 5日目の記事です。 4日目は北川さんによる自作OSS pavise解説記事でした!

www.m3tech.blog

特に本編と関係ない夕方前の桜と空

はじめに

AIエージェントがコーディング作業の主役となった昨今、データ分析でも可能な限りコーディングの部分はエージェントに任せたいと考え、実践している方は多いと思います。

一発デモ的にデータ分析のJupyter Notebookを作成させると、短時間に一見整った分析ノートブックが出力されます。

しかし、実際に仕事でClaude CodeにJupyter Notebookを編集させながら分析していると、なにかと物足りなさ、取り回しの悪さを感じることがあります。

Jupyter Notebookをエージェントに編集させる際の難しさ

データ分析という仕事の性質上、「Planモードで実装内容を決めたら残りは自律的にエージェントに最後まで実装してもらう」というよりは、1つ結果を見てそこから次の分析内容を決めて実装・実行し、その結果を見て・・・、という繰り返しのプロセスが必要になります。

こうした繰り返しやり取りが生じるエージェントコーディングにおいては、Jupyter Notebookにはいくつか相性が悪い所があります。

エージェントにとって読解・編集しにくい

Jupyter Notebookの実体はJSONで、コーディングとは直接無関係なメタ情報や出力情報が含まれており、セッションが長くなるにつれて品質が低下していく傾向にあります。*1

実際に数ヶ月前までJupyter NotebookをClaude Codeに編集させていましたが、「セルを末尾に追加してほしいのに最上段に追加してしまう」「pythonのセルなのに、markdownセルとして書き込んでしまう」といった初歩的なミスが目立ち、通常のPythonファイルで実装しているときとは勝手がだいぶ違いました。

セルの実行順序依存

次に、Jupyter Notebookでは同じ変数名が登場した場合には、実行順序によってその結果が変わってしまいます。

プロンプトの指示が甘くdf = ...が複数回出て意図せず上書きしてしまう事故は、特にEDAの際には起きてしまうものなので、可能であれば仕組みで防ぎたいところです。

marimo + gokartによるアプローチ

この記事ではエージェントコーディングに適したデータ分析環境としてmarimoとgokartの利用を提案します。marimoの活用についてはいくつか他にも紹介記事がありますが、marimoとgokartを組み合わせることで更にノートブックが扱いやすく取り回しがよくなります。

marimo

marimo はポストJupyter Notebookとして開発されているPythonノートブックで、次の特徴があります。

  • リアクティブ実行: セル間の依存関係を自動で解析し、変更が波及するセルだけを再実行することができる。
  • Pure Python: .py ファイルとして保存されるため、エージェントが編集しやすい形式で、また出力がファイルに含まれないためコンテキストを余分に浪費しにくいです。
  • 再現性: セルの実行順序に依存しない。変数の再定義も禁止されており、常に一貫した結果が得られる。

gokart

gokart はエムスリーがOSSで開発しているPython の機械学習パイプラインツールです。 今回のブログリレー初日に北川さんがgokartの型システムの改良について書いています。

www.m3tech.blog

gokartにはいくつかの優れた性質・機能がありますが、今回の記事で重要な考え方は次の3つになります。

  1. 実行したい処理をgokart taskとして定義する。
  2. taskに対しては必要となる入力、パラメータを明示的に定義する。
  3. gokart.build(task)によってタスクが実行され、このときパラメータに基づく自動キャッシュ機能が働く。

キャッシュが効くことによって、一度marimo notebookのセッションが途切れてしまっても、明示的に結果を保存しなくとも高速に再現することができます。 また、行いたい処理をあらかじめタスクとして切り出しておくことによって、エージェントにとってもこのタスクを使いまわせば良い、とコードの意図を把握しやすくなります。

実際にmarimo + gokartで分析してみる

今回は課題として、BigQuery上に整備されているHacker Newsデータセットをmarimo+gokartを活用して分析してみます。

実際に作成したmarimo notebookは次のレポジトリに置いているので、必要な方は参考にしていただけますと幸いです。

github.com

ステップ0: 実行環境を整備する

まずはmarimo notebookが実行できる環境を整備します。

といってもClaude Codeに今回の分析対象と使うツール(uv, marimo, gokart, google-cloud-bigqueryなど)を指定してpyproject.tomluv.lockを用意させるだけです。

ステップ1: SQLクエリを実行し結果を取得するgokart taskを定義する

今回のBigQueryDownloadTaskではパラメータを実行するSQLクエリとし、出力はそのクエリ実行結果のpandas dataframeとします。

実装は次の通りです。

class BigQueryDownloadTask(gokart.TaskOnKart[pd.DataFrame]):
    sql: str = luigi.Parameter(description='SQL query to execute')

    def run(self):
        client = bigquery.Client()
        query_job = client.query(self.sql)
        df = query_job.to_dataframe()
        self.dump(df)

入力パラメータは実行したいsqlのクエリ、出力はその実行結果のgokart taskになります。

実行したいクエリが同じであれば、自動的に以前の実行結果のキャッシュが呼ばれ、初回の実行であれば実際にクエリが実行されます。

今回はBigQueryからのデータ取得を例にしましたが、ここはローカルのDBからのデータ取得でもよいですし、時間を要するモデル学習をタスクとして定義してもよいです。

ステップ2: marimo notebookを書かせ始める

分析の準備が整ったのでここからmarimo notebookを書き始めます。

BigQueryDownloadTaskを利用して、Hacker Newsのデータセットを取得します。 別のセルで取得したいSQLgenerated_sqlの条件は指定し整形しています。

BigQueryDownloadTaskの呼び出しセル

@app.cell
def _(BigQueryDownloadTask, generated_sql, gokart, mo):
    task = BigQueryDownloadTask(sql=generated_sql)
    df = gokart.build(task, return_value=True)
    mo.md(f'**{len(df):,} 行を取得しました**')
    return (df,)

実際に実行したSQLクエリ

SELECT
  FORMAT_TIMESTAMP('%Y-%m', timestamp) AS month,
  keyword,
  COUNT(*) AS story_count,
  AVG(score) AS avg_score,
  AVG(descendants) AS avg_comments
FROM `bigquery-public-data.hacker_news.full`,
UNNEST(['chatgpt', 'gemini', 'claude', 'llama', 'copilot']) AS keyword
WHERE type = 'story'
  AND timestamp >= '2022-11-01'
  AND timestamp <= '2026-03-31'
  AND LOWER(title) LIKE CONCAT('%', keyword, '%')
GROUP BY month, keyword
ORDER BY month, keyword

今回はchatGPTやGeminiといった主要なLLMがニュースタイトルに含まれている記事が何件登場したか時系列でみてみる所から始めてみました。

綺麗に図を作る部分についてはClaude Codeに任せてうまくやってくれるので、そこは「よしなに」と依頼しています。

主要なLLMモデルがニュースタイトルに含まれた数の月次推移

ステップ3以降: 壁打ちを繰り返す

ここからは気になった点の分析と出力コードの微修正を繰り返していきます。

このとき、marimo notebookのセッションが途切れてしまっても、同じSQLであればgokartが管理しているキャッシュを返してくれます。

今回はClaude Codeに関連したターム、MCPやskillsなどが含まれる記事数をみてみました。

Claude Codeに関連するワードがニュースタイトルに含まれた数の月次推移

2025年前半はMCPがとにかく話題でしたが10月頃本格リリースされたskillsが圧倒的な1位、MCPも勢いを取り戻しつつある。最近のトレンドはskillsなどを配布できるPluginも注目を集めていることが分かります。

まとめ

今回はmarimo + gokartを活用したデータ分析環境を紹介しました。

marimoとgokartを組み合わせることで、取り回しのよいnotebookを用いたデータ分析ができます。

実装はエージェントに任せつつ行いたい分析のディレクション・プロンプティングに集中できて非常に開発体験が良いので、ぜひ一度試していただければ幸いです!

過去記事もどうぞ

以前Claude CodeやLLMについて書いた記事もあるのでぜひ読んでみてください!

www.m3tech.blog

www.m3tech.blog

We are hiring!

エムスリーではAgentic Codingやデータ分析に関心を持つエンジニアを大募集しています!興味のある方はぜひカジュアル面談にお越しください!

エンジニア採用ページはこちら

jobs.m3.com

カジュアル面談もお気軽にどうぞ

jobs.m3.com

インターンも常時募集しています

open.talentio.com

*1:数ヶ月前のOpus 4.5での体験をもとに書いており、最新のモデルでは改善している可能性があります。




以上の内容はhttps://www.m3tech.blog/entry/agentic-edaより取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14