きっかけ — 200行を「読み切る」ための橋を架けたい
積み残しになっていた計画書を開いた。200行ほどの小さなGPT実装を、簿記・会計の言葉で理解するインタラクティブ教材を作る、という構想だ。計画だけ書いて全フェーズ未着手のまま放置していた。
最初は「会計アナロジーのデモを並べれば完成」だと思っていた。勾配を感応度、配賦をソフトマックス、損失を予実差異に置き換えてデモを9個作る。そういう絵を描いていた。
ところが途中で、本当のゴールが見えた。会計アナロジーはあくまで橋渡しで、最終的にやりたいのは実物の200行コードを各段階に対応づけて、最後まで読み切ることだった。「要するに200行を読むことが最終的な目的なんですよ」と自分で言葉にした瞬間、教材の設計が組み替わった。
やったこと — ハブから各段、各用語へ枝分かれする構造
Claude Code に指示して、まず純粋関数の土台から組ませた。ReLU・ソフトマックス・線形写像・クロスエントロピー、それに会計向けの利益感応度や連鎖律を microgpt-math.ts に閉じ込め、テストを32件先に書かせた。全部greenになり、カバレッジは100%まで上がった。
そこから上に積んでいった。
- 6段パイプライン図のハブページ(データ準備→トークナイザ→Autograd→初期化→モデル本体→学習・推論)
- 9個のインタラクティブデモ(感応度・連鎖律・ReLU・初期化・配賦など)を会計の言葉で
- 各用語ページに「実際の
microgpt.pyの該当コード」を黒背景で並べる - ホームの「学習・クイズ」先頭に教材への導線カードを追加
デモはスタイルとアナロジーの一貫性を崩したくなかったので、サブエージェントに散らさず自分の指示で3個ずつのバッチに分けて作らせた。ビルド時に「10 microgpt routes for prerendering」とログが出て、親ページと9用語が全部ルート登録されたのを確認した。
元コードを憶測で書かない
各段に実コードを載せる段になって、ひとつ釘を刺した。憶測でコードを書くと、自分が読んだ記事と食い違って台無しになる。だから元ネタの200行を正確に特定させた。Karpathy 氏が公開した依存ゼロの microgpt.py、199行。Gistから全文を取得して memo/2026-05-31/microgpt.py に保存し、行番号付きで各段に貼り込ませた。
データ準備 → L14-21
トークナイザ → L23-...
Autograd → ...
ここで画面を見ていて引っかかった。データ準備に「L14-21」という紫のバッジは出ているのに、クリックしても飛べない。「実際にそれはどこにあるんですか、どこを確認すればいいんですか」と。バッジが行番号を指しているのに、その行へたどり着く導線がなかった。
そこで「6段それぞれをクリック可能にして、1段=1個別ページにすればいい」という案が出た。各段ページに、その段の実コードと会計解説と、ぶら下がる用語へのリンクを載せる。パイプライン図の番号ボックスを各段ページへのリンクに変える。これが今日の作業の核心になった。
malformedが連発した — そして引き継ぎへ切り替えた
段別ページ化を進めている最中から、ツール呼び出しが壊れ始めた。Your tool call was malformed and could not be parsed. が出る。リトライしても retry also failed で止まる。一度ではなく、何度も。concepts.ts への編集、PipelineDiagram.vue のスタイル追加、そのあたりで連発した。
コンテキストに実コードの断片と調査ログとスクショが溜まり、ツール呼び出しの引数が破綻しやすくなっていたのだと思う。画面のスクショを撮っては閉じ、撮っては閉じを繰り返していたのも効いていたはずだ。
そこで方針を切り替えた。malformedが連発したら、確定事項と残作業を引き継ぎドキュメントに保存して、重い検証は独立したコンテキストのサブエージェントに投げる。これは前から決めていた運用だ。microgpt-handoff.md を作り、完了済み・残作業・既知の状態・検証の進め方・復帰プロンプトまで書き込んだ。
サブエージェントへの指示には必ず一文を添えた。巨大ファイルを全Readするな、複雑なjqを避けろ、コンテキスト汚染に注意しろ。これを伝えないと、サブエージェント自身も同じく落ちる。重い表示確認をサブエージェントに分離し、結論だけメインに返させる。これが効いた。
サブエージェント側で6段すべての段別ページがHTTP 200で返り、データ準備ページに「実際のコード」「STEP」が出て、ハブの段名クリックで遷移できることを確認できた。前後ナビで空のプレースホルダーが出る小さな崩れも直した。コードブロックは highlight.js ベースに差し替えて、Python のシンタックスハイライトを効かせた。
学び
- malformedが出たら、ファイルサイズより先に直近のツール呼び出しの引数を疑う。今日も小さな編集で連発した。原因は1回の引数の大きさより、コンテキスト全体の汚れだった。
- 詰まったら粘らず、引き継ぎドキュメントに確定事項を逃がして、サブエージェントに渡す。メインの会話が生データで汚れる前に手を打つほうが速い。
- 教材は「アナロジーで分かった気にさせる」で止めない。実物のコードの行番号へ指で飛べるところまで作って、ようやく「読み切る」入口になる。バッジを出すだけでは飛べない、という当たり前を画面で突きつけられた。
明日やること
- フェーズ3の発展トピック(Attention・埋め込み・残差・Adam・temperature)を、会計アナロジーと実コードのセットで追加する
- 各段ページの会計解説を、もう一段やさしい言葉に削る
- バックグラウンドで起動しっぱなしのdevサーバー(ポート3001)を止める