Antigravity で Python コードを書き始めてから、「ちょっとしたデータ探索は Jupyter でやりたいのに、いつもエージェントに全部任せてしまって気づけばノートブックを開かなくなった」という感覚はないでしょうか。私自身、個人開発で分析まわりを触る時期になってしばらく同じ状態になり、「Antigravity に寄せすぎると手の感覚が鈍る/Jupyter に寄せすぎると構造化が進まない」という振り子のような迷いを経験しました。
ここではその振り子を止めるために日々試している3つのワークフローを共有します。単に「Jupyter を Antigravity で開く方法」ではなく、エージェントと対話的探索をどう分担させるかという観点でまとめています。今日からそのまま取り入れられる運用ルールとコード例を中心にしました。
ワークフロー1 — ノートブックから .py に「育てる」
データ分析を始めるとき、私は最初の30分〜1時間を必ず Jupyter だけで進めます。Antigravity のエージェントを呼ばず、手でセルを書いて、df.head() を何度も叩きます。ここを飛ばしてエージェントに投げると、「なんとなく動くけどデータの癖をつかめていないコード」が生まれやすいためです。
探索が落ち着いた段階で、ノートブックをモジュール化する工程にエージェントを引き込みます。具体的な手順は次のとおりです。
# notebooks/eda_sales_2026q1.ipynb から抽出したいセル
# Cell 3: 月次集計ロジック
import pandas as pd
def summarize_monthly(df: pd.DataFrame, value_col: str = "amount") -> pd.DataFrame:
"""月次の売上・取引数・平均客単価を返す。
Antigravityで抽出後、`src/analytics/sales.py` に移植する想定。
"""
monthly = (
df.assign(month=df["date"].dt.to_period("M"))
.groupby("month")
.agg(total=(value_col, "sum"), count=(value_col, "count"))
)
monthly["avg_ticket"] = monthly["total"] / monthly["count"]
return monthly.reset_index()
# 期待出力: month / total / count / avg_ticket の4列を持つ DataFrame
summarize_monthly(df).head()このセルを選択したまま、Antigravity のエージェントに次のように頼みます。
「このセルを
src/analytics/sales.pyに移して、型ヒントと pytest のテストを1つ書いてください。ノートブック側にはfrom analytics.sales import summarize_monthlyだけを残してください」
コツは、ノートブックの該当セルを選択した状態でエージェントに依頼することです。Antigravity はアクティブな選択範囲を文脈として優先的に渡すため、「どのセルの話か」を自然言語で長々と説明する必要がなくなります。私はこのやり方で、10個前後のセルを抱えた探索ノートブックを半日で整理された .py モジュールに移し替えています。
育てる過程で注意したいのは、ノートブックの残骸をそのまま残さないことです。移植が済んだセルにはマジックコメント # moved-to: analytics.sales.summarize_monthly を残し、翌朝見返して該当セルを削除するルールにしておくと、探索ノートブックがいつまでも膨らみ続けるのを防げます。
ワークフロー2 — エージェントにセル単位で書いてもらう
2つ目は逆方向です。ノートブック上で「このセルだけ」エージェントに書き換えてもらう運用です。全セルを丸ごと任せると探索の痕跡が消えてしまいますが、セル単位なら「この分析の肝になる部分だけ AI の助けを借りる」ことができます。
実装のコツは、セルの先頭にコメントで意図を書き、そのコメントをエージェントへのプロンプトとして使うことです。
# TODO(agent): 直近12ヶ月の売上に対して、STL分解で季節性成分を取り出し、
# season / trend / resid の3列を持つ DataFrame を返す
# statsmodels.tsa.seasonal を使う
# period=12 を仮定してよい
# resid の標準偏差も計算して print する
import pandas as pd
from statsmodels.tsa.seasonal import STL
def decompose(series: pd.Series) -> pd.DataFrame:
stl = STL(series, period=12, robust=True).fit()
result = pd.DataFrame({
"season": stl.seasonal,
"trend": stl.trend,
"resid": stl.resid,
})
print(f"resid std: {result['resid'].std():.3f}")
return result
# 期待出力: resid std の値が1行print され、3列のDataFrameが表示される
decomposed = decompose(df.set_index("date")["amount"])
decomposed.tail()このスタイルの良いところは、後からノートブックを読み返したときにどこを AI に書いてもらったかが一目でわかる点です。# TODO(agent): を grep すれば AI が生成した箇所だけ抽出できるので、検証やコードレビューのときに役立ちます。
ひとつだけ気をつけたいのが、ノートブックのマジックコマンド(%timeit や %load_ext)はエージェントが見落としやすいという点です。パフォーマンス計測のセルを書き換えてもらうときは、「%%time を残したまま」と明示的に依頼するほうが安全です。私はこれで何度か計測ラインを消されて、原因がわからずしばらく悩みました。
ワークフロー3 — 実行結果をエージェントの文脈に渡す
3つ目は、ノートブックで計算した結果をエージェントの判断材料として使うパターンです。これはデータ分析ワークフローで最も差がつく部分だと感じています。
たとえば、ある特徴量の相関行列を出力したあと、次のようにエージェントに渡すと意思決定が早くなります。
# セルで相関を可視化してから、結果を短いテキストに落とす
corr = df[["age", "income", "score", "ltv"]].corr().round(2)
print(corr)
# 期待出力例:
# age income score ltv
# age 1.00 0.12 0.08 0.31
# income 0.12 1.00 0.45 0.67
# score 0.08 0.45 1.00 0.58
# ltv 0.31 0.67 0.58 1.00この出力をそのままコピーしてエージェントに渡し、「ltv を目的変数にした線形回帰モデルを書いてほしい。相関行列はこれです」と頼むと、エージェントは income と score を特徴量に選ぶような提案をしてくれます。相関行列をスクリーンショットではなくテキストで渡すことが重要で、エージェントは表形式のテキストをそのまま解釈できます。
逆に、グラフ画像をそのままエージェントに期待しないのが私のルールです。Antigravity はマルチモーダルな入力にも対応してきていますが、統計的な判断が必要な場面では画像より数値テーブルのほうが確実にミスが減ります。describe()・value_counts()・corr() の出力を文字で渡す習慣をつけておくと、モデル選定の速度が目に見えて上がります。
データ分析に特化した AGENTS.md の書き方
上記3つのワークフローを安定させるために、私はプロジェクトルートに分析向けの AGENTS.md を置いています。これは Antigravity が起動時に読み込むエージェント向けの指示書で、データ分析プロジェクトでは次のような項目を書くと事故が減ります。
# Data Analysis Project — Agent Guidelines
## Notebook Policy
- `notebooks/` 配下のノートブックは「探索用」です。最終ロジックは必ず `src/analytics/` 以下の Python モジュールに移してください
- 既存ノートブックのセルを書き換えるときは、`# TODO(agent):` コメントがあるセルのみが対象です
- マジックコマンド (`%%time`, `%matplotlib inline` など) は勝手に削除しないでください
## Data Handling
- 実データ (`data/raw/`) には書き込み禁止です。加工結果は `data/interim/` に置いてください
- 個人情報が含まれるカラム (`email`, `phone`, `address`) は集計前にハッシュ化してください
- DataFrame を返す関数には必ず docstring と想定カラムの説明を書いてください
## Testing
- `src/analytics/` 配下の関数には pytest を追加してください
- テストデータは `tests/fixtures/` に最小限のサンプル CSV を配置してください
- `pandas.testing.assert_frame_equal` を使って型と値の両方を検証してくださいこの AGENTS.md は Claude Code など他のエージェントにも読ませられる共通ファイルです。Antigravity 単体の設定ファイルに依存しないので、チームでエージェントツールが混在していても同じルールで運用できます。エージェント向けガイドラインの考え方については AGENTS.md を使いこなすための実践ガイド に詳しくまとめています。
実運用で感じているトレードオフ
3つのワークフローを使い分けるときに、正直に言うと悩むポイントがあります。「どこまで Jupyter の対話性を残すか」と「どこから構造化されたモジュールに移すか」の線引きは、プロジェクトごとに答えが違います。
経験則として、同じセルを3回以上コピペしている自分に気づいた瞬間が、モジュール化のサインです。データ分析は「書き捨て」と「再利用」が同居するので、どちらにも偏らないバランス感覚が必要です。Antigravity のエージェントは、この判断を下す良い相談相手になります。「このセルを関数化すべきか、ノートブックにとどめるべきか、意見をくれ」と聞くだけでも、第三者の視点で整理してくれます。
関連して、エディタ側のカスタム設定については Antigravity エディタの高度なカスタマイズガイド で詳しくまとめているので、ノートブック運用と合わせて読むとワークフロー全体が整います。
ノートブックと .py モジュールの役割分担について、実務に沿った具体例で学べる一冊です。
明日から試せる一歩
今使っている分析ノートブックを1つだけ開いて、3回以上コピペしている関数があるかどうかを確認してみてください。もし見つかったら、そのセルを選択して Antigravity のエージェントに「これを src/analytics/ 以下の新しいファイルに移して、最小のテストを1つ書いてほしい」と頼むだけで、ワークフロー1の第一歩が踏み出せます。
小さな一関数の移植から始めると、Jupyter とエージェントの役割分担が手触りとして分かってきます。振り子のような迷いは、実際に手を動かして何度かこの往復を繰り返すうちに、自然と止まっていきます。