TL;DR
- 複数のAIエージェントを使い分けて Polarsベースのデスクトップアプリを開発
- Python →Rustへの移行で 起動時間が20秒 →瞬時に劇的改善
- AIが得意な技術スタックを選ぶことが成功の鍵
はじめに
こんにちは!
私は インメモリカラムナーデータ処理技術、特に Apache Arrow や Polars に魅了され、個人的にアプリ開発に挑戦していいます。
この度、最新の技術に触れてみようと思い 最新の技術であるAIエージェントを活用し、ビッグデータ向け高速データ処理アプリ POLCA (POLars Cool Application) を開発しました。本記事では、AIエージェントによるコード生成から、アプリを完成に至るまでの、開発の裏側と試行錯誤の道のりをリアルにご紹介します。
POLCAとは?
Polarsライブラリを使った、ビッグデータ向け高速データ処理アプリです。
代表的な画面
主な機能
| カテゴリ | 機能 |
|---|---|
| ファイル操作 | CSV/Parquet形式の読み込み と 書き出し |
| データ操作 | ソート、フィルタ、ジョイン、ユニオン、集計、計算、サンプリング |
| 列操作 | 追加、削除、リネーム |
| データ分析 | プロファイリング、ピボットテーブル |
| パフォーマンス | Polars エンジンによる 高速データ処理 |
| 多言語対応 | 日本語、英語 |
技術スタック
フロントエンド: React + TypeScript + AG Grid
バックエンド: Rust + Polars-Python、Rust + Polars-Rust (最終版)
フレームワーク: Electron、Tauri v1 (最終版)
IDE ツール: Visual Studio Code、GitHub Copilot
開発の旅路: 7つの試練、紆余曲折の道のり
試練1:Rustコンパイルエラーの地獄
使用AI: Vercel v0
バックエンド(Polars-Rust)でコンパイルエラーが多く発生しました。
IDE は Visual Studio Code を使用していたので、GitHub Copilot の助けを借りながら コードの修正を行なったが 結局 コンパイルエラーは終息せず 断念しました。
// エラーの例
error[E0599]: no method named `pivot` found for struct `DataFrame`
error[E0308]: mismatched types
error[E0277]: trait bound not satisfied
原因: Polars-RustのAPI事例が少なく、AIの知識ベースが不足
教訓: AIは普及している技術の方が得意
Polars-Rust は諦めて、次は Polars-Pythonにしてみようと考えました。
試練2:Pythonで一発解決
使用AI: Claude Code
Polars-Pythonに切り替えたところ ...
@app.post("/import/csv")
def import_csv(req: ImportCsv):
df = pl.read_csv(filepath)
tables[req.table_name] = df
return {"message": "success"}
結果: 一発で動作
教訓: メジャーな技術スタックを選ぶことの重要性
この段階では フロントエンドとバックエンドは 別々に起動する必要があり、次は デスクトップアプリとして動作できるよう ひとつに まとめます。
試練3:起動時間20秒の悪夢
使用AI: Claude Code(フレームワークは 最初 Electron 次に Tauri)
デスクトップアプリ化したものの ...
$ time open polca-desktop.app
# バックエンド起動: 10〜20秒
# → フロントエンドでエラー: "バックエンドに接続できません"
原因: Polars-Pythonのimportに時間がかかる (Electron/Tauri とも同じ)
import polars as pl
一時的な対応: フロントエンドにリトライ処理を追加
const waitForBackend = async () => {
for (let i = 0; i < 30; i++) {
try {
await fetch('http://localhost:8000/');
return true;
} catch {
await sleep(1000);
}
}
return false;
};
接続中... nn秒 を表示
教訓: Polarsは依存ライブラリが多く、import時間が課題
polca-desktop 起動時 10〜20秒 待たされるのは ストレスなので、次は バックエンドを Polars-Rust にすることに 再度 チャレンジしました。
試練4:AIエージェントの使い分け
使用AI: MGX(MetaGPT X)
AIエージェントで Polars-Python を Rust に変換して見ました。Claude Codeで生成したPython→Rustの変換コードもコンパイルエラーが多発。
そこで別のAIエージェント「MGX」を試したところ ...
pub async fn import_csv(
state: web::Data<AppState>,
req: web::Json<ImportCsv>,
) -> Result<HttpResponse> {
let df = CsvReadOptions::default()
.try_into_reader_with_file_path(filepath)?
.finish()?;
// ...
}
結果: ほぼそのまま動作
教訓:AIエージェントは得意分野が異なる
| AI | 得意領域 |
|---|---|
| Vercel v0 | UI/UXデザイン |
| Claude Code | 汎用的な開発、リファクタリング |
| MGX | 技術変換、Rust特化 |
試練5:起動時間が瞬時に!
Rust版バックエンドでの起動時間が 144倍 高速化 できた!
# Before (Polars-Python)
$ time open polca-desktop.app
real 0m18.234s
# After (Polars-Rust)
$ time open palca-desktop.app
real 0m0.127s
試練6:フロントエンドが消えた!?
Tauri版のリリースビルドで、フロントエンドが同梱されない謎の現象。
$ ls lolca-desktop.app/Contents/Resources/
# → フロントエンドのファイルがない!
Contents-Resources にはアイコンだけ ...
設定は正しいのに ...
{
"build": {
"distDir": "../build", // ✅ 正しい
"beforeBuildCommand": "npm run build" // ✅ 正しい
}
}
原因: MGX が生成した Rust コードにgenerate_context!()マクロがなかった
// Before(エラー)
.run(tauri::generate_context!()) // この行がない!
// After(修正)
tauri::Builder::default()
.setup(|app| { ... })
.invoke_handler(tauri::generate_handler![...])
.run(tauri::generate_context!()) // ✅ この行を追加
.expect("error while running tauri application");
教訓: Tauri はビルド時 generate_context!()でフロントエンドを実行ファイルに埋め込む
試練7:謎の HTTP 404 Not Found エラー
デスクトップアプリは動作するのに 特定のリクエストだけHTTP 404 エラーになる。
GET /table/titanic?page=0&page_size=100 # → 404 Not Found
バックエンドのコードは正しいのに ...
解決策:Axumのルート定義に: を追加 + axumをバージョンダウン
// Before
.route("/table/table_name", get(handlers::get_table_data))
// After
.route("/table/:table_name", get(handlers::get_table_data))
// ^ コロン追加!
[dependencies]
axum = { version = "0.7.5" } # バージョンを固定
教訓:ライブラリバージョンとAI生成コードの微妙な相性問題
AIエージェント開発で得た5つの教訓・知見
1. 広く普及している技術を選べ
| 技術 | AI対応度 | 理由 |
|---|---|---|
| Python | ⭐⭐⭐⭐⭐ | 豊富な学習データ |
| TypeScript | ⭐⭐⭐⭐⭐ | 広く使われている |
| Rust | ⭐⭐⭐ | 事例は増加中 |
| Polars-Rust | ⭐⭐ | まだ事例が少ない |
2. AIエージェントを使い分けろ
3. パフォーマンスは言語選択が9割
| バックエンド | 起動時間 | メモリ |
|---|---|---|
| Python (Polars) | 18.234秒 | 123MB |
| Rust (Polars) | 0.127秒 | 107MB |
4. 生成コードを理解せよ
AIが生成したコードを ブラックボックスにしない。
// このマクロが何をしているのか?
.run(tauri::generate_context!())
// → ビルド時にフロントエンドを埋め込む重要な処理
5. バージョン固定の勇気
頻繁に更新されるライブラリはバージョンを固定すべし。
[dependencies]
axum = { version = "0.7.5" } # バージョンを固定
polars = { version = "0.33" }
開発環境と使用ツール
開発環境
PC: MacBook Pro M1 メモリ 32GB
OS: macOS Tahoe 26.0.1
IDE: Visual Studio Code + GitHub Copilot
使用AIエージェント
| AI | 用途 | コスト |
|---|---|---|
| Vercel v0 | UI設計 | 無料枠 |
| Claude Code | 汎用開発 | 無料枠 |
| MGX (MetaGPT X) | Python → Rust変換 | 無料枠 |
技術スタック
// フロントエンド
const stack = {
language: 'TypeScript',
framework: 'React 18.2',
ui: 'AG Grid 30.0 + Lucide Icons',
state: 'React Hooks'
};
// バックエンド
const stack = {
language: 'Rust',
framework: 'axum 0.7.5',
dataEngine: 'Polars 0.33'
};
// デスクトップ
const stack = {
framework: 'Tauri 1.5',
bundler: 'DMG (macOS)'
};
参考:Tauri ビルドの仕組み
Pythonバックエンドの場合
Tauri は バックエンドが Rust を前提としているが、Python の場合、Sidecar 機能で Pythonコードを サブプロセスで動かす。事前に Pythonコードをバイナリ化 しておく必要があります。
# 1. Pythonをバイナリ化
pyinstaller --onefile \
--hidden-import fastapi \
--hidden-import polars \
main.py
# 2. Tauriリソースに配置
cp dist/main src-tauri/binaries/
# 3. tauri.conf.jsonで指定
{
"bundle": {
"externalBin": ["binaries/main"]
}
}
バイナリ化したコードは Contents-Resources 入る。
Rustバックエンドの場合
フロントエンドも一緒にコンパイルされ Contents-MacOS の実行ファイル に入る。
// main.rsで自動埋め込み
tauri::Builder::default()
.run(tauri::generate_context!())
// ↑ この1行でフロントエンドも一緒にコンパイル
まとめ: AIエージェント時代のエンジニアリング
開発を振り返って
紆余曲折を経て、ようやく満足できるレベルのアプリが完成しました。
7〜8年前、同様のアプリを手作業で開発していた頃と比べると、隔世の感 があります。
しかし、AIエージェントは、魔法の杖ではありません。
これからのエンジニアに必要なスキル
class ModernEngineer:
def __init__(self):
self.skills = {
'prompt_engineering': 10, # ⬆ 最重要
'requirement_analysis': 10, # ⬆ 重要
'code_reading': 8, # ⬆ 必須
'traditional_coding': 5 # ⬇ 相対的に低下
}
def develop(self, requirement):
# 1. 要件を正確に理解
spec = self.analyze(requirement)
# 2. AIに的確な指示
code = ai.generate(spec)
# 3. 生成コードを理解して修正
fixed = self.review_and_fix(code)
return fixed
参考資料
インスピレーション元
本プロジェクトは ESPERiC にインスパイアされました。
ESPERiCは独自の「成分分解法」を採用したインメモリカラムナーデータベースで、ビッグデータ処理の高速性が特徴です。
関連記事
- 前編:AIエージェントでのコード生成編
- polca-desktop リポジトリ(検討中)
おわりに
AIエージェントを活用した開発は、適切な技術選択とAIの使い分け、そして 生成コードへの理解 が成功の鍵です。
この記事が、AIエージェント開発に挑戦する方の一助となれば幸いです。
Happy Coding with AI!
最後まで お読み頂き ありがとうございました。