バイブコーディングの限界と言語移行(3)|AIに「言語を変えよう」と言われた――Python→TypeScript移行の決断

バイブコーディングの限界と言語移行(3)|AIに「言語を変えよう」と言われた――Python→TypeScript移行の決断 — バイブコーディング, 言語移行, Python AIテキスト

こんにちは、パレイド思想部です。

前回、マイクロサービス分割が少人数開発で裏目に出た話を書きました。

今回は、Claude に相談したら「言語を変えましょう」と言われた話です。

本記事はローカル LLM による自動執筆パイプラインで生成されました。現段階ではクラウド AI(Claude 等)の補助や人間の編集が介在していますが、pareido.jp では最終的に AI が自律的にコンテンツを制作できる仕組みの構築を目指しています。

「前もやったんだけど」から始まった会話

実は、このプロジェクトとは別に、以前にバイブコーディングで Electron で Python から TypeScript に移行した経験がありました。そのときは Python + Flask で書いていたデスクトップツールを Electron + React に書き直し、四苦八苦しながらも約1週間で移行を完了しています。

今回のサービス分割が失敗に終わり、次のアプローチを考えていたとき、その経験を踏まえて Claude にこう相談しました。

「別のプロジェクトで Python → TypeScript + Electron への移行をやったことはある。今回のプロジェクトでも同じアプローチは有効だと思う? ただ、今回は Python + Vite でかなり構築が進んでいて、移行コストが心配なんだけど」

意外にも、Claude の反応は「やる・やらない」ではなく、まず確認の質問が来ました。

「前回の移行はどのくらいかかりましたか?」——1週間くらい。「今回のプロジェクトで、Python でなければならない本質的な理由はありますか? たとえば NumPy や CUDA のような Python 固有のライブラリへの依存は?」——いや、LLM の API を叩いてファイルを操作するのが中心だから、Python 固有の依存は少ない。

こうしたやり取りを経て、Claude はこう返しました。

前回1週間で移行できたなら、今回も段階的に進めれば現実的です。Python 固有の依存が少ないなら、移行の技術的障壁は低い。むしろ、今の Python + Vite 構成を続けるコスト(2言語の維持、型情報の欠如)のほうが長期的には高くつきます。

正直に言うと、AI がこのような根本的な提案をするとは思っていませんでした。こちらの過去の経験を引き出し、技術的な前提条件を確認し、移行しない場合のコストと比較した上で判断材料を提示する——人間のシニアエンジニアに相談したときと同じ構造の会話です。

最初からコードを書いている当人?の提案なので、「じゃあ最初から言ってくれれば」と思う気持ちもありますが、フェアに振り返ってみると、最初の段階でそこまで見通せていたかというと難しいところです。

本来は、プロトタイピングベースのリファクタリングを続け、最終的に広がり切ったイメージが見えてきたタイミングで、全体のアーキテクチャや設計思想を固めにかかるのが理想とされています(いわゆる進化的設計の考え方)。

ただ実態としては、現在のAIはコンテキストの制約や長文での推論の不安定さといった限界があり、このプロセスを単独で担うのは難しい。このあたりは、まだ人間とAIの棲み分けが有効な領域と言えそうです。

コーディングでは「目の前のタスクを完了すること」に最適化されがちな AI が、一方で設計思想やアーキテクチャの相談では俯瞰的な視点を持てるの興味深いものです。おそらく、コーディングでは「動くコードを出力する」ことが報酬になるのに対し、相談では「納得感のある回答を出す」ことが報酬になるため、AI の振る舞いが変わるのでしょう。ロール設定が重要という裏返しです。

Claude が TypeScript を推した理由

その上で、Claude の提案にはいくつかの具体的な論点がありました。

論点1:型システムが「ドキュメント」になる

Python のマイクロサービス分割で、AIが仕様書を無視するという話を聞いた上での提案でした。「AIが仕様書や規約を無視する」ことは構造的に改善が難しい。TypeScript なら、型定義そのものが仕様書の役割を果たす

// これが仕様書の代わりになる
interface AssetPackage {
  manifest: {
    files: Array<{
      path: string;
      sha256: string;
      role: 'image' | 'layer' | 'metadata' | 'preview';
      size: number;
    }>;
    format_version: string;
    created_at: string;
  };
  metadata: {
    asset_type: 'v1_motion';
    display_name: string;
    variations: string[];
    has_animation: boolean;
    has_audio_sync: boolean;
  };
}

Python の SPEC.md(仕様書)と ops.py(実装)を別々に管理する必要がなくなります。型定義を変更すれば、コンパイラが不整合を検出する。仕様書が古くなるリスクがゼロになります。

論点2:Electron でフロントとバックが統合できる

Python での構成は「FastAPI バックエンド + React フロント」でした。2つの言語(Python + TypeScript)、2つのビルドシステム、2つのプロセスを管理する必要がありました。

Electron にすれば、全体が TypeScript 1言語で統合される。フロントエンドのコンポーネントからバックエンドのロジックまで、同じ型システムの中で管理できます。

Python 時代:
  Python (FastAPI) ←HTTP→ TypeScript (React/Vite)
  2言語、2プロセス、API仕様書が必要

Electron 移行後:
  TypeScript (Electron main + React renderer)
  1言語、1プロセス、型で統合

しかも Electron + React の周辺エコシステムが充実している。Vite でビルド、XState で状態管理、Tailwind CSS + shadcn/ui で UI コンポーネント。Python の FastAPI + Jinja テンプレート時代には「GUI のためにフロントエンド技術を別途学ぶ」必要がありましたが、TypeScript なら全部が同じ言語・同じ型システムの中で完結します。

仕様書を介したソフトガバナンスではなく、コードそのものが共通になるハードな制約です。

論点3:AI にとって「読みやすい」コードになる

これは Claude 自身が言った点で、興味深いものでした。

AI がコードを読むとき、型情報は巨大なヒントです。関数のシグネチャを見れば、何を受け取って何を返すかが一目でわかる。呼び出し元を辿らなくても、その関数の意図を正しく推測できる確率が高くなる

# Python: 読んでも構造が分からない
def load_package(path):
    data = json.loads(Path(path).read_text())
    return process(data)
// TypeScript: 型を見れば構造が分かる
function loadPackage(path: string): AssetPackage {
    const data = JSON.parse(readFileSync(path, 'utf-8'));
    return processPackage(data);
}

つまり TypeScript 移行は、人間のためではなく、AIのためのリファクタリングでもあるという指摘でした。

Claude の提案の本質:「AIにやらせる範囲を絞る」

3つの論点を振り返ると、Claude の提案は単に「TypeScript に書き換えよう」という話ではないことに気づきます。本質は、AI が取り扱う情報を絞り、AI を取り囲む仕組みで制約するという発想の転換です。

私たちは CLAUDE.md に規約を書き、仕様書を整備し、「これを読んでから作業して」と何度も指示しました。しかし前回の記事で書いた通り、AI は長い会話で指示を忘れ、仕様書が古くなっても気づかず、共通関数を探さずに再実装します。テキストによる指示は、AI に対する制約として弱いのです。

TypeScript のコンパイラは違います。型が合わなければビルドが通らない。これは AI が無視できないハードな制約です。同様に、ESLint のルール、pre-commit フック、CI のテスト——これらは AI が「読み飛ばす」ことができない仕組みです。

Google の Addy Osmani は2025年のAIコーディングワークフローの総括で、仕様をガードレールとして使う手法を整理しています。また Spec Kit Agents(arXiv, 2025)は、AI エージェントの各フェーズに「検証フック」を仕込み、中間成果物を仕様と照合する仕組みを提案しています。方向性は一致しています。AI に「正しく振る舞え」と言うのではなく、正しく振る舞わざるを得ない環境を作る。

アプローチ制約の強さ
テキストで指示する弱い(忘れる、無視する)CLAUDE.md、仕様書、コメント
ツールで強制する強い(違反するとエラー)コンパイラ、リンター、pre-commit フック
構造で制限する最も強い(選択肢が存在しない)型システム、モジュール境界、API スキーマ

もちろん、これは完全な正解ではありません。AI 時代のプロジェクト管理のベストプラクティスはまだ発展途上です。NxCode は2026年に「Agentic Engineering」という概念を整理し、バイブコーディングの先にある AI ファーストの開発手法を提唱していますが、確立されたテンプレートや万能のワークフローはまだ存在しません。

それでも、方向性は見えてきています。AI にやらせる範囲を絞り、人間が管理する範囲を明確にする。 ただしここで言う「管理」は、人間のチームを相手にした従来のプロジェクト管理ではありません。AI の特性——コンテキストの制約、完了バイアス、局所最適への傾向——を理解した上での管理手法が求められます。バイブコーディングという言葉は勢いが弱まり、ハーネスエンジニアリングという言葉が生まれましたが、この先さらに新しい考え方も、生まれては消えていくことでしょう。

結局のところ、バイブコーディングが機能するかどうかは「AI がどれだけ賢いか」ではなく、「人間がどれだけコーディングの基礎知識と設計判断力を持っているか」に依存します。2025年の調査では、シニア開発者が AI ツールで81%の生産性向上を実現した一方、ミッドレベルの開発者では51%にとどまったと報告されています。AI が生成したコードのセキュリティ上の欠陥、エッジケースの見落とし、技術的負債を見抜けるかどうかは、結局のところ人間側の実力にかかっているのです。

「移行」ではなく「再実装」という判断

10万行を機械的にトランスパイルする選択肢もありましたが、それは選びませんでした。理由は2つ。

1. Python のイディオムを TypeScript に直訳しても意味がない

# Python の辞書ベースのコード
config = {"port": 8770, "host": "0.0.0.0"}
if config.get("debug"):
    config["log_level"] = "DEBUG"

これを TypeScript に直訳すると Record<string, any> だらけの、型の恩恵が得られないコードになります。TypeScript で書くなら最初から interface を定義すべきです。

2. サービス分割の失敗を引き継がない

Python 版は Base / Creator / Server という3サービス構成でした。この構造をそのまま TypeScript に移すと、分散モノリスもそのまま移植されます。

代わりに、Creator の機能を中心に Electron アプリとして再設計する 方針を取りました。散りばめられた規約違反が含まれる10万行すべてを移行するのではなく、コアとなる使っている機能だけを移植する。必要な機能だけを新しい型構造で再実装し、そこからクリーンに「育て直す」こととしました。

移行を決断できた理由

言語移行は重い決断です。「動いているコードを捨てる」ことへの抵抗感は大きい。しかし、いくつかの要因が決断を後押ししました。

仕様書が存在したこと。 サービス分割時に書いた仕様書(.pkg フォーマット仕様、GUI ワークフロー仕様、要件 ID)が、移行先の設計図になりました。皮肉なことに、分割は失敗しましたが、その過程で書いた仕様書は移行時に活きたのです。これだけでも時間的な投資をある程度回収できたのは幸いです。

テストが存在したこと。 2,000件のテストは、移行後の正確性を検証するベースラインになりました。「Python 版でこの入力に対してこの出力が返る」ことが分かっているので、TypeScript 版で同じテストケースを書けます。ただし無駄なテストも多いため、ユニットテストは一旦全て捨てました。原理的に、ヒューマンエラーの少ない(ゼロではない)AIには不要で、要件に近いテストから優先で組ませることとしました。

AI が移行を手伝えること。 Python のコードを読んで TypeScript に書き直す作業は、まさに AI が得意とする領域です。バイブコーディングが機能するサイズ(1ファイルずつ)で、段階的に移行できます。ここはほぼエージェントに任せた作業が可能です。ただし、いくら制限してもフォールバックなどの規約違反をどんどん埋め込んでしまうので、段階的なアプローチを取ることと、定期的なレビューは欠かせません。

教訓:言語移行を検討すべきサイン

私たちのケースから考えると、Pythonからの言語移行を検討すべきサインは以下です。

注意点として、ベースとなる知識や当てにできる工数が人間のチーム側にどれぐらいあるかに依るため、あくまで今回のケースでは有効というだけで、普遍的な解決方法にはならないとは思います。

  1. 仕様書と実装の乖離が常態化している — 型システムで仕様を表現できる言語への移行を検討する
  2. フロントとバックで言語が分かれている — 統合できる言語・フレームワークがないか検討する
  3. AI との協業で型情報の欠如がボトルネックになっている — 静的型付け言語への移行を検討する
  4. 移行先の技術スタックに十分な知識がある(または AI が補える) — 学習コストが現実的か判断する

逆に、移行すべきでないケース:

  • 動いているコードに大きな不満がない
  • チーム全体の言語スキルが偏っている
  • パフォーマンス要件が移行先で満たせない(NumPy / CUDA 等)

次回は、TypeScript での再実装が実際にどう進んだか——そして、バイブコーディングが「復活」した理由を書きます。

タイトルとURLをコピーしました