なぜ作ったか
対象は、中学卒業程度の数学は分かるけれど高校・大学の数学はほぼ分からない人、Python の初歩は触ったことがあっても NumPy や PyTorch は使ったことがない人です。
AIの入門書は「数式だけ」か「コードだけ」に寄りがちで、数式がコードやAIモデルの中でどう使われているのかが見えません。ひもとくAIは、数式と Python のコードを行き来しながら意味を理解し、最終的に自分でAIモデルを設計・実装・評価できるところまでを目指しています。
主な機能
- スライド形式の教材:数式と図解つきのスライドで学べます。本文はログインしなくても読めます。
- 5種類の演習:単一選択・複数選択・穴埋め・数値入力・コード穴埋めで理解を確かめます。
- ブラウザの中で動く Python:書いたコードはその場で実行され、Python のエラーは日本語の説明に置き換えて表示します。
- 正解と解説は、解けたときかあきらめたときだけ:先に答えを見られない作りにしています。
- 進捗の記録:マイページで、どこまで進んだかとレッスンの完了を確認できます。
設計の判断
採点結果を改ざんできない仕組み
- 課題
- ブラウザから送られてくる「正解した」をそのまま信用すると、開発者ツールを使えば誰でも合格にできてしまう。前回の試作では、まさにこれが反省点だった。
- 検討した選択肢
- ブラウザでの判定結果をそのまま保存する
- 採点サーバーを立て、学習者のコードをサーバーで実行する
- 正解をデータベースの中に隠し、データベースの関数だけに採点させる
- 選んだ方法と理由
- 正解や期待する出力を置く表は行単位のアクセス制御(RLS)で閉じ、利用者が呼べるのは本人確認と回数制限(1分に20回)つきの関数4つだけにした。コード演習では、データベースが毎回ランダムに3つの入力を選び、ブラウザで実行した結果を保存してある期待出力と許容誤差つきで照合する。出題の番号は1回しか使えず、10分で期限が切れる。
- 結果
- 書き出したファイルに正解が含まれていないことをビルドのたびに検査し、データベースの権限はPGliteで再現してテストしている。データベースに直接「合格」を書き込めないことも、ブラウザ操作の自動テストで確かめている。ブラウザで別の方法で計算した答えを提出されると通ってしまう点は、既知の弱点として受け入れている。
サーバーを持たない構成で、運用費を月0円にする
- 課題
- 個人で運用を続けるには、費用を月0円に抑える必要があった。また、学習者が書いたコードをサーバーで実行するのは避けたかった。
- 検討した選択肢
- Next.js のサーバー機能と採点サーバーを使う(最初の構成)
- 静的に書き出し、Python はブラウザで実行し、採点はデータベースの関数で行う
- 選んだ方法と理由
- Next.js を静的に書き出して Cloudflare Workers で配り、Python はブラウザの中の Pyodide で動かすことにした。Pyodide は外部のCDNに頼らず、自分の配信から配る。
- 結果
- 採点サーバーと Next.js のサーバーをなくし、すべて無料枠の範囲で動かしている。上限を超えても自動では課金されない構成にしてある。初回に約9〜28MBの読み込みが必要なことは、画面で案内している。
ディープラーニングの章をどこで動かすか
- 課題
- 畳み込みニューラルネットワーク(CNN)まで扱いたいが、PyTorch はブラウザでは動かず、サーバーで動かすと費用と安全性の問題が出る。
- 検討した選択肢
- NumPy で自作したものを採点する
- PyTorch は読むだけの教材にする
- PyTorch の採点サーバーを立てる
- TensorFlow.js を使う
- 非公式の PyTorch 互換ライブラリを使う
- 選んだ方法と理由
- 「NumPy で自作して採点する」と「PyTorch は対応表で読む」を組み合わせた。費用は0円のまま、信頼できないコードをサーバーで実行しなくて済む。
- 結果
- 実測で、小さなCNNがブラウザの中で0.6秒で学習し、正解率は93%になった。PyTorch との対応表が今も正しいかは、毎月CIで検証している。
技術構成
| 技術 | 役割 |
|---|---|
| Next.js 16 | 画面。サーバーを持たず、静的に書き出して配信する |
| TypeScript | 全体の実装言語 |
| Tailwind CSS | スタイリング |
| MDX / KaTeX | スライド形式の教材と数式の表示 |
| Pyodide | ブラウザの中で Python を実行する(Web Worker、実行時間の上限つき) |
| CodeMirror | コード演習のエディタ |
| Supabase | 認証、PostgreSQL、行単位のアクセス制御(RLS)、採点用のDB関数、進捗の保存 |
| Cloudflare Workers | 静的ファイルの配信 |
| Cloudflare Turnstile | 登録フォームのボット対策 |
| Resend | メールの送信 |
| Sentry | エラー監視(個人情報を取り除いてから送る) |
| Vitest / PGlite | 単体テストと、DB関数の権限まで含めたテスト |
| Playwright / axe-core | ブラウザ操作の自動テストとアクセシビリティ検査 |
| GitHub Actions | CI、マイグレーションの適用、毎日のバックアップと復元テスト |
品質と運用
- テスト:Vitest の単体テストでは、コードを書く問題31問すべてについて「模範解答は合格、誤答は不合格」になることを確かめています。Playwright のブラウザ操作テストでは、アクセシビリティ、スマホの画面幅で全レッスンがはみ出さないこと、改ざんへの耐性、パスワード再設定などを確かめています。
- CI:lint、単体テスト、ビルド、書き出したファイルの検査を毎回実行します。マイグレーションは自動で適用し、毎日暗号化したバックアップを取って、使い捨てのデータベースに復元して件数を照合しています。
- セキュリティとプライバシー:CSP や HSTS などのヘッダーを設定しています。13歳未満の登録は受け付けず、生年月日は確認が済んだら削除します。IPアドレスは記録しません。
- 費用:独自ドメインの年額を除き、すべて無料枠で動かしています。
振り返りとこれから
前回の試作では、教材をコードに直接書き込んだことと、ブラウザが送る採点結果をそのまま信用したことが失敗でした。今回は教材をデータとして分け、採点の信頼をデータベースの層で担保する設計にしました。
今後は、利用者が増えたら PyTorch の採点サーバーを改めて検討します。修了証を出す場合は、その部分だけサーバーで再実行する仕組みを考えています。


