Laravel のインストールは 1 日 35 万件超。
AI 経由で生まれる Laravel アプリの数は、約 5 週間ごとに倍増。
この数字が語られたのが、米国最大の Laravel イベント「Laracon US 2026」です。
セッションは Laravel 公式 YouTube チャンネルで公開されています。
現地には行けませんでしたが、2 日間・全 19 本を通して見ました。
新機能の話もあれば、複雑さと借金の話も、AI に仕事を奪われたあとの話もありました。
どれも 25 分前後で、字幕もあります。
気になったものだけでも、ぜひ本編を見てみてください。
そして見終えたあとに気づいたことが一つあります。
立場のまったく違う登壇者たちが、同じ一つの結論を、別々の言葉で繰り返していました。
それが何だったのかは、記事の最後に書きます。
この記事の読み方
全部で 19 セッションあります。
頭から通して読む必要はありません。
おすすめの読み方は以下の通りです。
- 各セッション冒頭の「一言でいうと」だけを、まず拾い読みする
- 気になったセッションだけ、「詳細 ―」の見出しから先を読む
- 本編が見たくなったら、各セッション冒頭のリンクから動画へ飛ぶ
各セッションには「詳細 ―」で始まる見出しを 1 つずつ置いています。
そこから次の見出しまでが掘り下げなので、ざっと選びたいときは丸ごと読み飛ばしてください。
この記事は、あくまでどれを見るか選ぶための地図として使っていただければと思います。
登壇順ではなく、テーマ順に並べ替えています
一点お断りしておきます。
この記事は登壇順ではなく、自分の判断で 5 つのテーマに並べ替えています。
理由は、2 日間のセッションが「新機能の紹介」から「AI 時代に人は何をするのか」まで、あまりに幅広いためです。
登壇順に読むと、テーマが行ったり来たりします。
そこで、手元の道具の話から始めて、設計 → 運用 → AI と進み、最後に「なぜ作るのか」という人の話へ向かう順にしました。
具体から抽象へ流れるので、途中で読むのをやめても何かしら残るはずです。
登壇順で追いたい方は、Laravel 公式チャンネルの動画一覧をそのままご覧ください。
時間がない方へ ― まず 3 本だけ選ぶなら
- #5 Realtime Collaborative Apps ― 19 本で一番楽しく見られた 1 本です。数百台のスマートフォンが同時接続する巨大なライブデモを通して、リアルタイム機能の設計の勘所が体感として残ります。
- #6 Cleverness Is A Loan ― 一番設計の解像度が上がった 1 本です。アーキテクチャを「価格表」として整理する視点は、明日の設計レビューからそのまま使えます。
- #12 Scaling Laravel ― 一番具体的な数字が出た 1 本です。
failed_jobsにインデックスを 1 本足すだけで DB CPU 使用率が 75% 下がった話は、すべての Laravel アプリに関係します。
この記事について
項目 | 内容 |
|---|---|
対象 | Laracon US 2026(全 19 セッション) |
開催日 | 2026 年 7 月 28 日〜29 日 |
開催地 | 米国ボストン SoWa Power Station |
視聴元 | |
記事の性質 | 現地参加ではなく、公開動画の視聴レポートです |
全体まとめ(参考) |
① 道具 ― Laravel はこの 1 年で何が変わったか
まずは、手元ですぐ触れるものから。
Laravel 本体と Laravel Cloud の最新アップデート、そして Pest・JJ・Filament・Reverb という 4 つの道具です。
この章の 5 セッションは、どれも見終わったその日に試せます。
1. Laravel Updates(Taylor Otwell 氏)
一言でいうと、「意見のあるフレームワークであること」が、そのまま AI 時代の強みになったという話です。
1 年前の Laravel 社内ハッカソンでは、誰も本格的に AI を使っていなかったそうです。
せいぜいタブ補完です。
今春のハッカソンでは、誰一人として手でコードを書いていませんでした。
現在、AI 経由で生まれる Laravel アプリの数は約 5 週間ごとに倍増しているとのこと。
この相性の良さの理由はシンプルで、Laravel が AI にガードレールを与えるからです。
人間にとって分かりやすいものは、AI にとっても分かりやすい。
詳細 ― この 1 か月で出荷されたもの ― OSS・AI・DX・Cloud の全体像
OSS 側
#[BindWhen]で条件付きバインディングが書けるようになりました。
フィーチャーフラグが有効なときだけベータ実装を注入する、といった分岐をインターフェースのファイル内で宣言できます。
属性にクロージャを渡すため、PHP 8.5 以降限定です。
#[DebounceFor(seconds: 5, maxWait: 30)]は、属性 1 つで「一定時間内に何件投入されても最後の 1 件だけ実行」にします。
商品の検索インデックス更新のような、放っておくと検索基盤への実質的な DoS になる処理向けです。
php artisan dev は Web サーバ・キューワーカー・Vite を 1 コマンドで同時起動します。composer dev との違いは拡張できることで、パッケージ側からも登録できます。laravel/reverb を入れるだけで Reverb サーバも起動するようになります。
Refreshable Locks は、短いロックを取って $lock->refresh() で延長する書き方を可能にしました。
「1 時間かかる処理だから 1 時間ロックを取る」しかなかった状態から抜け出せます。
異常終了しても数秒で解放されます。
そして画像の最適化・変形がフレームワーク標準になりました。
$request->image('photo')->optimize()->store('photos');デモでは 2.35 MB の画像が約 500 KB(77% 削減)になっていました。scale() / cover() / contain() / quality() / grayscale() も揃っています。
エージェント支援ツールの Laravel Boost にも組み込まれるため、こちらから教えなくてもエージェントがこれらの新 API を認識します。
ほかに CPX 2.0(PHP CLI パッケージを npx のように使い捨て実行)、Pint for Blade(vendor/bin/pint --blade)、Laravel Head(@head ディレクティブ 1 つで <head> を管理)にも言及していました。
AI 側
Str::of($longText)->summarize() ― このコード 1 行で、任意の文字列を要約できます。
個別の設定は不要で、使用中のプロバイダの最も安価なモデルが自動的に選ばれます。
AI SDK に openai-compatible プロバイダが追加され、互換 API を持つ数百のプロバイダとローカルモデルが使えるようになりました。
LM Studio 上のモデルに接続して、データを一切外へ出さずにチャットを動かすデモがありました。
埋め込みがマルチモーダルに拡張され、画像・音声・動画を扱えます。
デモでは、36 枚の壁紙を埋め込んで pgvector に格納。
「cactus」と検索するとサボテンの壁紙が、「ferris wheel」なら観覧車の壁紙がヒットしました。
その語は、どの画像のどこにも書かれていないのに、です。
埋め込みのキャッシュは AI SDK に内蔵されています。
Human Tool Approvals は、エージェントのツール実行に人間の承認を挟む機能です。
個人的には、ここが実務で一番役立つと思いました。
他の AI SDK は永続化や状態管理を提供せず「保留中の判断がある。あとは自力で」で終わります。
Laravel は、エージェントに RemembersConversations トレイトを付けていれば、保留中の承認をデータベースへ自動で永続化します。
ページをリロードしても、翌日戻ってきても状態が復元されます。
承認 UI は Web でも Slack の承認ボタンでも自由です。
DX 側
Inertia 専用の Chrome DevTools 拡張が公開されました。
サーバから来た props、リクエストを処理したルート、プリフェッチのキャッシュヒットまで追えます。
TypeScript コンポーネント名をクリックすると、そのファイルをエディタで直接開きます。
Laravel LSP は、VS Code 拡張の知性を言語サーバとして全エディタに開放したものです。
設定値・ビュー名・環境変数・バリデーションルールの補完が効きます。
そしてエージェントにも組み込めます。
自分でコードを書かない場合でも、エージェントに Laravel の文脈を与えて出力の正確さを上げられる、というのが面白いところです。
Cloud 側
Laravel Cloud では、アプリ・MySQL・Valkey がすべてゼロスケール(アクセスがない間は 0 台まで縮む)対応になりました。
旧世代のハイバネーションは復帰に 10 秒以上かかりましたが、現在は多くの場合 1 秒未満、しばしば 500 ms 未満です。
ゼロスケール対応のスケジューラもあるため、「スケジューラがあるからゼロスケールできない」という制約はなくなりました。
HTTP オートスケーリングは、CPU / メモリのしきい値ではなく PHP ワーカーの空きを見ます。
アプリが十分に速いと、CPU が余っていてもワーカーだけが先に枯渇するためです。
Managed Queues v2 はコールドスタートが 1〜2 秒(速いときは 500〜600 ms)。
最大 30 秒かかっていた旧版から、根本的に作り直された結果です。
ここまで速いと最小ワーカー数を 0 のまま運用できます。
FIFO キュー、実行時間上限 1 時間の Pro コンピュート、デプロイ単位でのメトリクス比較も追加されました。
さらにモノレポの自動検出、Nuxt / Next のデプロイ、Symfony 対応。
来月からは Go / Python / Node / Rails のマイクロサービスにも対応します。
5 年前は「Go で書くか」という判断自体が大ごとでした。
AI によってその障壁は下がり、Laravel のモノリスを別言語のサービスが支える構成が現実的になりました。
締めの言葉は、19 本全体に共通する主題を言い当てていたように思います。
結局のところ、大事だったのはキーストロークではありませんでした。
優れたソフトウェアを作ってユーザーに届けることでした。
2. Introducing PEST 5(Nuno Maduro 氏)
一言でいうと、テストフレームワークが「AI の書いたコードを確かめる場所」になったという話です。
Pest 5 で追加された 6 つの機能のうち、Agent Plugin と Evals Plugin は明確に AI 時代の産物でした。
詳細 ― 6 つの新機能 ― Agent / PHPStan / Rector / Evals / Sharding / TIA
Agent Plugin
pest --agent='<PHP コード>' で渡したコードを、普段のテストと同じ環境(ファクトリ・DB・認証・各種モック)で実行して pass / fail を返します。
ブラウザプラグインを併用すると、実ブラウザでの UI 操作と「その結果 DB に何が入ったか」を同一コマンドで検証できます。
単なるブラウザ自動化と違い、画面の裏側まで見えるのがポイントです。
恒久的なテストの代替ではなく、作業中の一時確認用という位置づけです。
PHPStan Plugin
コミュニティで最も要望が多かった機能の一つだそうです。
デフォルトの PHPStan は it() / expect() やテストクロージャ内の $this を理解できませんが、これを入れると expect() チェーンを流れる型が完全に追跡されます。
結果、expect(10)->toStartWith('1') のような、そもそも成立し得ないアサーションを本物のミスとして指摘してくれます。
Rector Plugin
既存テストを Pest 流へ自動リファクタします。
たとえば、こんな変換です。
// 変換前
expect(count($array))->toBe(5);
expect(array_key_exists('id', $array))->toBeTrue();
// 変換後
expect($array)->toHaveCount(5)->toHaveKey('id');ルールは合計 60 個。
古い PHPUnit 由来の資産が多いプロジェクトほど効きます。
Evals Plugin
LLM 出力の「質」を expect() API で評価します。
用意されているのは、次のようなアサーションです。
toBeRelevant()(回答が質問の内容に沿っているか)toBeSimilar()(期待する文章と意味が近いか)toBeSafe()(プロンプトインジェクション耐性)toFollowTrajectory()(エージェントが正しいツールを正しい順で呼んだか)
「質問に沿っているか」のような機械的に判定できない項目は、別の LLM を審査役に立てて合否を決めます。
いわゆる LLM-as-judge 方式です。
ここで感心したのは課金設計です。
eval は実モデルを呼ぶので、課金が発生します。
だから通常のテスト実行ではスキップされ、API 呼び出しもゼロのままです。
実行したいときだけ --evals を付けます。
CI が勝手に課金することはありません。
Time-Balanced Sharding
CI のシャード分割の基準を、テストの本数から実行時間へ変えたものです。pest --update-shards でタイミングデータを生成してコミットするだけで、全シャードがほぼ同時に終わるようになります。
TIA Engine(Test Impact Analysis)
変更の影響を受けるテストだけを実行し、残りはキャッシュから再生します。
10 分かかっていたスイートが約 4 秒。
リプレイはサボりではなく、カバーした行やブランチまでキャッシュしているのでカバレッジ値はフル実行と同じです。
ただし一点だけ強い注意がありました。
これはローカル開発向けなので、CI のテスト実行コマンドに --tia を入れてはいけません。
クリーンな環境でフルスイートを回すべきだからです。
3. Git, But Better: An Introduction to JJ(Pauline Vos 氏)
一言でいうと、「1 つの論理的変更 = 1 コミット」という atomic commit のワークフローを既定にしたバージョン管理ツールの紹介です。
JJ(正式名称 Jujutsu、コマンド名 jj)は Git を置き換えるものではありません。
Git のストレージ層をそのまま使う抽象化レイヤーです。
既存の Git リポジトリに併置でき、リモートには一切影響しません。
つまりチームに黙って今日から使い始められます(登壇者は「言った方がいいとは思います」と付け加えていました)。
詳細 ― なぜ atomic commit なのか、そして Git と JJ の操作比較
まず前提として、コミットには 2 種類あるという整理から始まります。
checkpoint commit は作業の時系列ログです。
fix code style / address review comments / WIP といった並びがそれにあたります。fix code style は本来、そのスタイル崩れを持ち込んだコミットの一部であるべきものです。
atomic commit は小さな論理的変更のまとまりです。
Add rate limiting to the API middleware /Extract post publishing into a dedicated action のように、コードのどの部分で何が変わったのかがコミットの並びだけで読み取れます。
atomic にすると 4 つのことが起きます。
- 1 コミットずつレビューできるようになる
- rebase で同じコンフリクトを何度も解決させられなくなる
- 過去のコミットへ移動する操作が現実的になる
git bisectのような「知られていない機能」が意味を持ち始める
これらが知られていないのは、atomic にコミットしていないと、そもそも意味をなさないからです。
そして AI 時代の意義について、こう語られていました。
エージェントは、こちらの手を離れて暴走することがあります。そのとき効くのが、適切に分割された文脈ときれいなログです。
これは人間のためだけではありません。
エージェント自身が「何が変わったのか / なぜ変わったのか / 何を revert してよく、何をしてはいけないのか」を判断するための情報になります。
JJ の基本
JJ ではコミットを revision と呼びます。@ マーカーが今作業している revision を指し、作業ディレクトリの変更は自動的にそこへ記録されます。
stage も commit も不要です。
そして JJ に branch は存在しません。
PR を作るときは、revision に bookmark を付けます。
操作の比較が分かりやすかったです。
コミットメッセージの書き換えは、Git なら git rebase -i HEAD~3 してエディタで pick を reword に書き換えて…という手順ですが、JJ は jj describe uiy だけです(`uiy` や後述の o / k は、revision に自動で振られる短い ID です)。
今いる revision から一切移動しません。
過去のコミットに変更を足す場合も、Git は interactive rebase に入って edit にして実装して git rebase --continue。
JJ は jj edit o で @ を移動させ、変更を書き、`jj edit k` で戻るだけです。
stash も checkout もしません。
コミットの削除は jj abandon uiy。
そして操作の取り消しは jj undo です。
Git の git reflog から目視で探して git reset --hard HEAD@{4} する手順が、Ctrl+Z 一発になります。
最大の目玉が jj absorb でした。
複数コミットを含む PR にレビュー指摘が入り、その修正をそれぞれ属すべきコミットに入れ直したい状況を考えます。
Git での手順はこうです。
git addして--amend- 別のファイルは
git commit --fixup=<hash> - さらに別のは別の fixup
- 最後に
git rebase -i --autosquash HEAD~4
JJ は jj absorb の 1 行です。
作業ディレクトリの変更を、各 revision が触っている行・ファイルと突き合わせて自動的に吸収します。
1 ファイルの変更を 2 つの revision に振り分けることもします。
曖昧な場合は誤爆を避けて作業ディレクトリに残してくれます。
さらに JJ には branch がないため、revision を編集すると依存する revision が自動的に rebase されます。
デモでは、相互に依存する PR 2 本を同時に更新していました。
やったことは、vendor/bin/pint を 1 回実行し、jj absorb して push しただけ。
それで両方の PR が、正しく rebase された状態になっています。
「これが相互に依存する PR 4 本だったらと想像してほしい。痛みの大半が消える」と登壇者は語っていました。
コミットメッセージについての一言が、そのまま持ち帰りになりました。
コミットメッセージに書くべきは実装の詳細ではありません。どの部分で何が変わったのか、そして「なぜその変更が必要だったのか」を残してください。
4. Filament: Advanced Practical Examples(Povilas Korop 氏)
一言でいうと、Filament は「管理画面ビルダー」ではなくアプリビルダーであるという主張です。
公式サイトの表現も「admin panels」から「apps and admin panels」へ変わりました。
しかも、apps が先に来ています。
13 個の実例で「管理画面しか作れない」という思い込みを崩していく構成でした。
詳細 ― 13 の実例 ― グリッド・render hook・大きなフォーム・パネル外での利用
前提として、Filament は TALL スタック(Tailwind / Alpine / Laravel / Livewire)です。
Inertia や Vue とは組み合わせられません。
実体は Livewire の上の薄いレイヤーです。
JavaScript をほとんど書かずに済むため、バックエンド寄りの開発者が快適圏内にとどまったまま UI を作れます。
始めるのは 3 コマンドです。
composer require filament/filament
php artisan filament:install --panels
php artisan make:filament-resource User --generate--generate を付けるとテーブル定義からフォームとテーブルを自動生成します。
ログインすればその時点で最初の CRUD が動いています。
カスタムグリッド(デモ 1〜4)
縦に人・横に日付・交点にチェックボックスという出席管理の表は、Filament のカスタムページ(= Livewire コンポーネント)です。
クラス側でプロパティを定義すれば、そのまま Blade 側の wire:model として使えます。
同じグリッドを色分けセルで見せた空き状況テーブルは、ウィジェットとして実装されているので他のページに埋め込めます。
GitHub 風のヒートマップも、レコード表示ページの中に組み込まれていました。
一覧を「行の羅列」ではなくカードのグリッドとして並べる例もありました。
Blade を書き換えるのではなく、テーブル定義側で Grid / Split / Stack を組みます。
上部にフィルタ、下部にページネーションが出る正真正銘の Filament テーブルのままです。
ただしこれは入門者向けではない、と釘を刺されていました。
見た目の改造(デモ 5〜7)
render hook(差し込み口)は約 100 種類用意されており、パネルプロバイダから自前のビューを差し込めます。
->renderHook(
PanelsRenderHook::SIDEBAR_NAV_START,
fn (): View => view('filament.hooks.user-avatar'),
)Material Design 風のフルカスタムテーマも技術的には可能です。
ただ実態は、Filament のクラスを上書きする大量の CSS を自分で書くことです。
ダッシュボード 1 画面だけでも相当な工数がかかったため、基本的にはおすすめしないとのことでした。
正直な情報がありがたいです。
大きなフォーム(デモ 8〜11)
請求書と明細のような master-detail 構造は Repeater で素直に書けます。
項目が 50 個・100 個あるフォームは、3 つの部品で分割します。
- Section ― 見出しで視覚的にまとめたいとき
- Tabs ― 分類が明確で、行き来させたいとき
- Wizard ― 順番に埋めさせたいとき
いずれもフィールド定義はそのままに、外側に 1 層かぶせるだけで切り替えられます。
パネル外での利用(デモ 12〜13)
ここが一番の驚きでした。
Filament 一式ではなく filament/tables や filament/forms だけを入れて、パネルの外で使えます。
<x-app-layout>
<livewire:standings-table />
</x-app-layout>見た目・フィルタ・ページネーションは管理画面と全く同じまま、認証もサイドバーもない公開ページになります。
大会の順位表や予約フォームがそのまま作れます。
締めのメッセージが良かったです。
管理画面ではなく、アプリをもっと作りましょう。
社内 CRM、在庫・倉庫管理、データ管理ツール。
中身は管理画面でも、成果物はアプリです。
「作れるかどうか」ではなく「何を作るか」の段階に来ている、という指摘は自分の職場にもそのまま当てはまると感じました。
5. Building Realtime Collaborative Apps with Laravel(Joe Tannenbaum 氏)
一言でいうと、Laravel のリアルタイムは 1 コマンドから始まり、本当に難しいのは「誰が聴き、誰が流すか」の設計だという話です。
19 本の中で、動画で見て一番楽しかったセッションでした。
セッション自体が巨大なデモになっています。
聴衆は QR コードでアプリに参加します。
そして数百台のスマートフォンが同時接続した状態で、概念ごとのミニゲームを実際にプレイしながら進みます。
スライドも遠隔操作もすべて WebSocket 製です。
詳細 ― presence / private / whisper と、最重要概念である fan-out
出発点は php artisan install:broadcasting です。
サーバ側に必要なものを、すべて設定してくれます。
希望すればクライアント側も、使用中のライブラリを検出したうえで構成してくれます。
このコマンドが終わった時点でもうブロードキャストできる状態です。
presence channel は「今、誰がここにいるか」を知るためのものです。
Broadcast::channel('room.{roomId}', function (User $user, string $roomId) {
return $user->canJoin($roomId)
? ['id' => $user->id, 'name' => $user->name]
: null;
});参加させるならユーザ情報を配列で返し、拒否するなら null を返します。
クライアント側は here / joining / leaving で受けます。
private channel のほうが、実際には使う場面が多いそうです。
書き方は同じで、返す値が boolean になるだけです。
client events(whisper) はアプリサーバを一切通しません。
チャンネル接続時に認証リクエストが 1 回飛ぶだけで、以降は WebSocket サーバへ直行して全員へ配信されます。
会場全体のスマートフォンをライトのように光らせたデモは、最初から最後まで WebSocket だけで動いていました。
そして最重要なのが fan-out です。
Echo のフックを使うと、そのコンポーネントはチャンネルに接続します。
そして接続した瞬間から、そのチャンネルの全イベントを受信します。
ブラウザはすべてのイベントを受け取っていて、コールバックが指定のイベントで絞り込んでいるだけです。
会場の全員がタップするデモで、もし全員がそのチャンネルに接続していたら、受信量は指数関数的に膨れ上がります。
各自が他の全員のイベントを受け取るからです。
そこで実際の構成はこうなっていました。
- 各自のスマートフォンはチャンネルに接続しない。タップしたらアプリへ HTTP リクエストを送るだけ
- アプリがそれを受けてブロードキャストする
- チャンネルを聴いているのは登壇者の画面 1 台だけ
クライアント側で本当に接続する必要があるのは誰か。誰がアプリ経由でブロードキャストするだけでよいのか。
手段の使い分け
リアルタイム度の低い順に、polling → Queued Events → Instant Events → Client Events という並びで整理されていました。
polling はまったく正当な戦略です。
2 秒ごとに新しいデータが得られれば十分なアプリなら、それで問題ありません。
Inertia の usePoll(2000, { only: ['scores'] }) には新しく cancel / overlap / rest の 3 モードが追加されています。
WebSocket に手を伸ばす前に、まず polling を試してください。用途に合うならそれが答えです。
ShouldBroadcast は既定でキュー経由、`ShouldBroadcastNow` は sync キューに載るため即時配信されます。
後者はイベントがアプリを通過するため、サーバ側に保存できます。
デモではタップをすべて記録し、間隔の比率を保ったまま 5 倍速でリプレイして見せていました。
技術の話で終わらなかったのが、このセッションの良さでした。
登壇者はリモートワーカーで、家族以外の人間に数日間まったく会わないこともあるそうです。
それは少し孤独である、と。
リアルタイムの体験は、見慣れた Web とは少し違います。心が動き、美しく、そして「インターネット上で完全に独りではない」と思わせてくれます。
セッションは、会場全員のスマートフォンの明かりが 1 つの大きなグラデーションとなって流れていく光景で締めくくられます。
その美しさは、画面越しでも十分に伝わってきました。
② 設計 ― 複雑さをどこに置くか
道具が増えると、次に問われるのが「どこに複雑さを置くか」の判断です。
アーキテクチャの選択・パッケージの設計・CLI の作法、そしてエージェントを自分のアプリに組み込む設計。
この章の 4 セッション(6 〜 9)は、扱う対象がばらばらに見えますが、どれも 「増やさないための設計」 を語っています。
6. Cleverness Is A Loan(Mary Perry 氏)
一言でいうと、アーキテクチャとは laravel new の状態からの差分であり、その差分が借金であるという話です。
個人的に、19 本で一番設計の解像度が上がったセッションでした。
出発点は、「複雑さそのものは悪ではない」という認識です。
業務が複雑なら、その複雑さを扱うことがソフトウェア開発の仕事です。
問題は複雑さの量ではありません。
利息を決めるのは「コードがどれだけ難しいか」ではなく、その仕組みを理解し維持できる人が何人いるかです。
Laravel 標準の複雑な仕組みは、公式ドキュメント・蓄積された Stack Overflow・Laravel 経験者に守られています。
つまり低金利です。
一方、社内で一人しか理解していない独自実装は違います。
どれだけ単純に書けていても、その人が抜けた瞬間に高金利になります。
そして利息を払うのは、書いた本人ではなく、あとから触る人です。
詳細 ― Seam という概念と、アーキテクチャの「価格表」
Seam(継ぎ目)
Michael Feathers『レガシーコード改善ガイド』の定義が引用されます。
seam とは「その場所のコードを書き換えずに、プログラムの振る舞いを変更できるポイント」です。
用語は 2 つだけです。
電気のスイッチと電球にたとえられていました。
- call site ― 挙動を呼び出している行。スイッチを押す場所
- enabling point ― 挙動を変えるために触る別の場所。ソケットにどの電球をねじ込むかを決める場所
電球を白熱球から LED に替えても、スイッチを押すコードは 1 文字も変わりません。
seam がない例です。
public function showProfile(int $id): View
{
$cache = CacheFactory::redis(); // ← ここで相手を確定させてしまった
$user = $cache->get("user.{$id}"); // call site
return view('profile', ['user' => $user]);
}挙動を変える手段が、メソッド自身を書き換えること以外に残っていません。
テストしたければコードに手を入れるか、実物の Redis を用意するしかありません。
このように、使う相手をその場で組み立ててしまう書き方を local construction と呼びます。
seam がある例は、`Cache::get()` のようにファサード経由にするか、コンストラクタで interface を型宣言してサービスプロバイダでバインドするかです。
call site が seam になるのは、使う相手が「差し替えられる間接層」を通って届くときだけです。
local construction は単発なら必ずしも悪ではありませんが、習慣になると非常に悪い、という指摘が刺さりました。
本来 seam になれた場所を潰し、コードとテストの量を増やし、fake・mock・環境別バインディングといったフレームワークの支援から切り離されるからです。
そしてここが本題 ― アーキテクチャの価格表
各アーキテクチャを「どこで効くか(pays)」と「何を請求されるか(charges)」で整理した一覧です。
抜粋します。
選択 | 効く場面 | 請求 |
|---|---|---|
service layer | 複数の入口から同じ処理を呼びたいとき | Model 呼び出しの 1 行ラッパーが増え、ただの中継クラスの山になりがち |
api + spa | Frontend が独立したプロダクトであるとき | 1 つのフルスタックチームで両方を見るなら、アプリを 2 つに割った管理コストが純増 |
inertia | SPA の UI は欲しいが Frontend と Backend を分けたくないとき | ほぼ無料(フロントフレームワーク 1 つ分の学習コストのみ) |
repository | 2 つ目のバックエンドが 実際に存在する とき | 「将来 DB を変えるかも」だけで足すと、使われない抽象化を自分たちで維持し続けることになる(Eloquent 自体がすでに抽象化) |
cqrs | Read と Write でデータ構造が大きく異なるとき | 全体に適用すると、2 種類の Model を常に同期する必要がある |
event-driven | DDD を検討したくなる問題を、より単純に解きたいとき(現実的な第一候補) | イベントの流れを追う手間が増える |
actions | Laravel 開発者に馴染む形で処理を切り出したいとき | Action を量産して Model が単なるデータ入れ物になると、Domain が見えなくなる |
microservices | 1 つのコードベースに収まらない数のチームがいるとき | ネットワーク(レイテンシ・トレーシング・分散トランザクション)。請求書は障害として届く |
modular monolith | 横断的な変更が痛いが microservices にするには小さすぎるとき | ドメインを理解する前に境界を切ると、あとで引き直すコストが大きい |
「the leak」というアンチパターンの指摘も的確でした。
Repository で Eloquent を隠したつもりでも、Eloquent Builder を外へ返していれば Eloquent 全体に依存したままです。
抽象化のコストだけ払い、見返りがありません。
Laravel が長く維持できている理由の一つとして挙げられていたのが、次の姿勢でした。
複雑さに対する最も強力な武器の一つは、「No」と言うことです。
採用するなら、チーム全員がそのメリットと維持コストを理解したうえで決める。
アーキテクチャは、今のチーム・将来の開発者・利用者・そして時間との契約である。
だからこそ、No をはっきり言えるチームの Yes には意味がある、という結びでした。
7. Proven Package Patterns(Freek Van der Herten 氏)
一言でいうと、設定オプションを増やさずに柔軟性を保つ 4 つのパターンの紹介です。
そして「AI は摩擦を感じない。だから人間がパターンを知っている必要がある」という結論に着地します。
登壇者の所属する Spatie は 12 人のチームで、公開している OSS パッケージは累計 25 億ダウンロードを超えています。
詳細 ― パッケージの 4 分類と、オプションを増やさない 4 パターン
まず「AI 時代にパッケージはまだ必要か」への答え
メニュー生成やパンくずのような、共通問題を解くパッケージ。
これは正直に言えば、以前ほど必要とされていないかもしれません。
同じものを、AI がプロジェクトの中に作れてしまうからです。
一方、難しい問題は違います。
例に挙がったのは営業時間の計算です。
「月〜金 9〜17 時」から始まって、祝日・臨時休業日・特別な日曜営業が入り、さらにタイムゾーンが来ます。
AI でも解けますが、特殊ケースをすべて説明し、生成物の所有権を自分で引き受ける必要があります。
こういう場合はパッケージが有効です。難しい問題に注力する必要も、その所有権を持つ必要もなくなり、自分のコアビジネスに集中できます。
外部依存の問題(API・プロトコル)は、よく保守されたパッケージが保守負担を吸収してくれます。
エンドポイント 1 つを叩くだけなら AI に生成させれば十分で、広範に使うなら API 用パッケージは今も非常に有用、という整理でした。
そして一番の推しが「趣味の良い解(tasteful solutions)」です。
Inertia・Livewire・Saloon、そして Laravel 自体。
AI は軽量版なら簡単に作れるでしょうが、Caleb Porzio 氏が Livewire でやったような「美しい記述の仕方」やオプションの与え方は出てこないだろう、と。
作者に趣味の良さがあり、趣味の良い作者は趣味の良い解を書きます。しかも裏側で難しい問題も解いています。
4 つのパターン
題材は laravel-url-ai-transformer という自社の小さなパッケージです。
URL の内容を読み取り、AI で変換し、DB に保存します。
4 つのパターンは、どれも同じ型で進みます。
- 利用者から「〜できますか」という要望が来る
- 設定オプションを足して応えると、要望のたびにオプションが増え続けて行き止まりになる
- そこでオプションの代わりに、差し替えポイントを渡す
先に一覧を出します。
パターン | 要望 | 差し替えポイント |
|---|---|---|
1. Events | 実行タイミングをログに出したい | イベント |
2. Custom Models | モデルだけ別の DB 接続にしたい | モデルクラス |
3. Custom Jobs | 別のキューで動かしたい | ジョブクラス |
4. Action Classes | 取得処理に手を入れたい | 処理を包んだ Action クラス |
見てのとおり、差し替えポイントの作り方は実質 2 種類だけです。
イベントを発火するか、クラスを config で差し替え可能にするか。
以下、順に見ていきます。
パターン 1 : Events
要望は「変換がいつ実行されたかログに出せますか」。
素直にやると 'log_when_transformation_run' => true のような設定オプションを足す方向に行き、次は「メッセージも変えたい」でさらに増えます。
差し替えポイントは**イベント**です。TransformationStarted::dispatch($url) を出しておけば、利用者はリスナーで好きなことができ、個別の設定オプションはすべて不要になります。
パターン 2 : Custom Models
要望は「あのモデルだけ別の接続を使えますか」。model_connection_name を足せますが、次はテーブル名、次は SoftDeletes と続きます。
差し替えポイントはモデルクラスそのものです。
使うモデルクラスを config で指定させます。
'model' => TransformationResult::class,利用者は継承して $connection や $table を変え、トレイトを足せます。
注意点は 1 つだけ。
パッケージ内部でモデルクラスを直接使わず、必ず config 経由で解決したモデルを使うことです。
パターン 3 : Custom Jobs
要望は「別のキューで動かしたい」。
差し替えポイントはジョブクラスで、考え方はパターン 2 と同じです。
利用者が $queue / $timeout / $tries を好きに変えられ、作者は使い方を気にする必要がなくなります。
パターン 4 : Action Classes
要望は「取得のとき追加のヘッダーを送れますか」。
該当する処理は return Http::get($url)->body(); の 1 行だけです。
差し替えポイントは Action クラスです。
この 1 行を Action クラス(動詞 + Action の命名、関数は 1 つだけ)に包み、config に登録します。
'actions' => [
'fetch_content' => FetchContentAction::class,
],パッケージ側は config から解決して呼ぶだけです。
差し替えたい小さな処理を Action に包んで config に登録する。
これだけで、特殊ケースのためにパッケージ本体を触る必要がなくなります。
プロジェクトでも同じことができます。
そして「なぜ AI 時代にこれを人間が知っている必要があるのか」への答えが、このセッションの核心でした。
登壇者は、Taylor 氏のツイートを引用します。
新しいプロジェクトの土台となるアーキテクチャのコードを手で書いていると、抽象化が正しくないときに「コードが押し返してくる」のを感じる。
4 つのパターンに登場した「〜できますか」という要望をすべて AI に投げれば、AI は嬉しそうに全部のオプションを追加します。
結果は、数百のオプションを持つ config ファイルです。
これは理論上の話ではなく、このパッケージも最初は config にオプションが大量にあったそうです。
開発者は摩擦を感じたら、それを「もっと良い解き方があるのでは」という兆候として扱えます。
しかし AI を使うとその摩擦を感じないことがあります。
AI は摩擦を感じないからです。
8. Building for Agents and Humans(Gordon Diggs 氏 / Stripe)
一言でいうと、エージェントのために正しく作ることは、人間のために正しく作ることとほぼ同じだったという話です。
Stripe Projects(同社の開発者向けプロダクト)をエージェント対応にする過程で下した判断は、そのほとんどが数十年前から best practice と呼ばれてきたものでした。
詳細 ― ドキュメント・CLI の作法・ステートマシン・そしてアクセシビリティ
ドキュメントは 1 種類でいい
私たちは何十年も README・manpage・書籍・オンラインドキュメントで道具の使い方を学んできました。
エージェントが読んでいるのも、まったく同じものです。
そして今日、ドキュメントの多くは Markdown で書かれています。
Markdown はもともとレンダリングしなくても人間が読める記法として作られました。
だからこそ、エージェント向けドキュメントの標準になったのは当然です。
少ないトークンで意味構造を渡せる、効率の良い手段でもあります。
Stripe Projects のドキュメントはすべて Markdown で提供され、LLM 用にコピーできるテキストとドキュメントサイトの表示内容は完全に同一です。
LLM 専用版を別に書く必要はありません。
良いドキュメントは、誰が読んでも良いドキュメントです。
開発中、help テキストに LLM 向けの記述を混ぜる案は却下したそうです。
エージェント固有の誘導は skill 側で行うべきだから、という理由でした。
エージェントが勝手に試す CLI の作法
エージェントは「まず試して、結果を見る」で機能を発見します。
「PHP ファイルを全部探して」と言えば find・rg・grep を順に試し、エラー出力から学習します。
つまり CLI の出力そのものが重要なシグナルです。
こちらが何も指示しなくてもエージェントが自分から試すのは、次の 4 つです。
--helpフラグ- 標準的な終了コード(
0と1だけでなく128 +の範囲も) - stdout と stderr の書き分け
- タブやインデントによる出力のセクション分け
どれも、新しい CLI を触るときに人間が確認する項目とまったく同じです。
--non-interactive が広げる射程
エージェント向けに作り込むと、人間側のエッジケースまで一緒に救われます。
すべてのコマンドが --non-interactive に対応しています。
狙いはエージェントに TUI(対話型の端末画面)を操作させないことです。
副産物としてシェルスクリプトから扱いやすくなり、さらに動く端末の幅まで広がりました。
VS Code のターミナルや各種タイリング環境でも動きます。
ステートマシンで手順を先に見せる
エージェントは、必要な手順を最初に全部把握できると強い。
Claude が「now I have the full picture」と言うあの瞬間です。
そして人間も同じで、始める前にどれだけ手間がかかるのかを知りたいものです。
Projects のコマンドは、必要な手順を最初にはっきり提示します。
内部では「情報収集がどこまで進んだか」を管理し、バックエンドの状態に対応付けています。
だから途中でコマンドを閉じても、常にワークフローを再開できます。
そしてアクセシビリティ
ここが一番の学びでした。
エージェントが Web をうまく使えているとき、頼っているのはスクリーンリーダーなどの支援技術と同じ経路です。
つまりアクセシビリティ対応が、そのままエージェント対応になります。
手法 | 人間にとって | エージェントにとって |
|---|---|---|
タブで辿れるページ | キーボードだけでページ全体を操作できる | 要素を巡回して入力欄を見つけられる。スクリーンショットの撮影・解析が不要 |
セマンティック HTML と見出し階層 | ブラウザが適切に振る舞う | 構造をそのまま理解できる |
ARIA 属性 | 状態やプロパティをスクリーンリーダーに伝える | 同じく状態やプロパティを理解できる |
画像の | 画像が見えない人に内容を説明できる | スクリーンショット解析なしで理解できる |
JavaScript なしで描画できる版 | 支援技術が動作する可能性が上がる | より単純なブラウザで動かせる |
どれも新しい話ではありません。
一番新しい ARIA でも 2000 年代、Unix 由来の作法に至っては 1970 年代のものです。
そのうえで、実務でそのまま使える一言がありました。
アクセシビリティは、投資の合意を取るのが常に難しい領域でした。
だからこそ「アクセシビリティ対応 = アプリケーションをエージェントから使えるようにする施策」という切り口は、社内で予算を通すための有効な論法になり得ます。
締めの言葉が 2 つあり、どちらも良かったです。
What's old is new ― 古いものこそ、新しい。標準と best practice は生き残り、エージェントはそれをさらに強化しています。
エージェントだけのために作らないでください。人間はどこにも行きません。全員のための体験を作れば、Web 全体が底上げされます。
9. Building A CLI Coding Agent From Scratch(Mateus Guimarães 氏)
一言でいうと、モデルは素の知能にすぎず、製品はハーネスであるという話です。
Claude Code も Codex も、中で動いているのは誰でも使えるモデルです。
違いを生んでいるのは、コンテキスト構築・ツールレジストリ・認可・サンドボックス・圧縮・セッション継続。
つまりハーネス側です。
そしてその中身であるエージェントループは、「まだツール呼び出しが必要か」をモデルに聞き続ける while ループでしかありません。
詳細 ― ハーネスの仕事と、自分の Laravel アプリをハーネスにする設計
ハーネスがやっていること
- コンテキスト構築(ワークスペースの指示、参照されたファイルの組み立て)
- オーケストレーション(モデル呼び出し、リトライ)
- ポリシー(この操作は実行してよいか)
- サンドボックス
- ツール提供と MCP 接続
- 継続性(履歴・圧縮・セッション再開・記憶の自動抽出)
- 運用性(予算の強制、可観測性とトレーシング)
安全性については 3 つの問いに整理されていました。
- Can ― そのツールは存在するか
- Should ― 明示的に認可したか
- Isolation ― 失敗したとき、30 万円の Mac を吹き飛ばさないか
デモが核心を示していました
同じエージェントに、ツールを 1 段ずつ与えていくデモです。
- ツールなし ― 「このプロジェクトについて教えて」と聞くと「分かりません。ファイルシステムにアクセスできません」
read_fileとlist_filesを有効化 ― 複数のツール呼び出しで文脈を集め、「これは Laravel 13 + React + Inertia のプロジェクトです」と答える- さらに
post_tweetを有効化 ― 「Hello from Laracon とツイートして」で、実際に X へ投稿される
プロンプトも同じ。モデルも同じ。変えたのはハーネスだけです。
ツール呼び出しは実質 RPC 的な契約であり、モデルは中身が何かを一切知りません。
そして本題 ― 自分のアプリがハーネスになる
既存アプリには、大量のデータと決定的な振る舞いという資産がすでにあります。
LLM を入れるために、その資産を手放してはいけません。
モデルは「証拠を解釈し、案を出し、データを作る」担当。判断の実行は、アプリケーション側の決定的なコードパスが持ちます。
具体例として EC の破損クレーム処理が示されました。
「青いジャケットを注文したが破れていた。金曜までに青か黒が欲しい。無理なら土曜に使うのでもう不要、返金してほしい」というケースです。
設計は 3 ブロックです。
① 決定的なルート ― 業務ルールで結論が出るものは LLM に送らず、この層で先に決着させます(例:「100 ドルを超える返金は自動化しない」)。
人間レビューに回すか、却下するか、明らかな解を適用するか。
② エージェント ― ①で決まらないものだけを渡します。
ここがコード内で唯一の非決定的な部分です。findReplacementOptions などのツールと、構造化出力のスキーマを与えます。
③ ドメイン層 ― ②から返ってきた構造化済みの結果を受け取り、返品・返金・エスカレーションを決定的に実行します。
LLM が fuzzy でも、その出力が fuzzy である必要はありません。
構造化出力にすれば、LLM がレスポンス構造を勝手に決めることはなく、何が返るかを正確に把握できます。
あとは AI のないアプリと同じ ― 人間がボタンを押したときと同じように処理すればよいわけです。
設計の順序も普通のソフトウェアと同じです。
- 成果(outcome)は何か
- 必要なデータは何か
- 状態変更は誰が所有するか
そして状態変更はアプリケーションが所有し、出力は信用しません。
人間のオペレータに返金権限を渡すときも、どんな注文でも自由に返金させることはしないはずです。
「2 年で 12 回以上返金申請している顧客は人間にエスカレーション」のようなルールがあるでしょう。
LLM にもまったく同じものが必要です。むしろより慎重に ― なぜなら、その判断の責任を負う人が誰もいないからです。
まとめの言葉が印象的でした。
この意味で、何も変わっていません。我々は少しの fuzzy さを足しているだけです。そして fuzzy さはバグではなく機能です。
③ 運用 ― 落ちないシステムをどう組むか
設計が決まったあと、実際に動かし続ける段階の話です。
宣言的な収束、外部 API を待つワークフロー、そして本番でぶつかった壁。
この章の 3 セッション(10 〜 12)は、いずれも「落ちないこと」ではなく 「落ちても戻れること」 を扱っています。
10. The Desired State(Chris Fidao 氏)
一言でいうと、望ましい状態を宣言し、そこへ収束させ続けるという一つの考え方の話です。
Laravel Cloud は、数千のワークロード・数百の Kubernetes クラスタをどうやって動かし続けているのか。
その答えの中心が、この「宣言と収束」でした。
詳細 ― Reconcile・冪等性・pull 型の source of truth・定期 reconcile
大まかな輪郭から始める
Laravel Cloud は 2 年半前、完全な白紙から始まったそうです。
白紙にまず描くのは、細部ではなく大まかな輪郭。
最初の一筆で可能性が絞られます。そして制約こそが、次に何をすべきかを決める自由を与えてくれます。
最初の 2 つの決定は「どこでホストするか → AWS」と「サーバレスか OR サーバありきか → サーバありき」でした。
それでも数千台のサーバ管理・ルーティング・オートスケール・配置・Observability・高可用性という問いが残り、その多くに Kubernetes が答えます。
Kubernetes は宣言的な API の塊
「どうやるか」ではなく「何が欲しいか」を伝え、Kubernetes がそこへ向かって reconcile(収束)します。
即時ではありません。
時間をかけて望ましい状態へ近づきます。
reconcile は比喩ではなく、実際に reconcile という名前の関数として存在し、常に動き続けています。
Pod が 1 つ落ちれば、「3 つ欲しいのに 2 つしかない」と気付きます。
そして代わりを起動し、ヘルスチェックを通して 3 つへ戻します。
CRD と Operator
標準の Deployment リソースを投げるだけでは足りないので、CRD(Custom Resource Definition)で Kubernetes の API 自体を拡張します。
DB のテーブルスキーマを定義する感覚に近い、という説明が分かりやすかったです。
「Laravel の Valkey クラスタとは何か」を定義して cache.laravel/v1alpha1 のような独自 API を作ります。
ただし Kubernetes は「それで何をすべきか」を知りません。
そこで Operator を書き、reconcile 関数の中に「指定サイズで起動する」「定期バックアップを取る」「プロキシ層に登録する」といった業務ロジックを実装します。
この考え方は制御理論から借りたものだそうです。
- set point(目標値 = 投げた YAML)
- controller(ロジックを書く場所)
- actuator(実際に何かを行うコード)
- sensor(リソースの
statusオブジェクト。次のループの入力になる)
要は閉じたフィードバックループです。
冪等性が絶対条件
reconcile はオブジェクト作成時だけでなく、常に、何度も呼ばれます。
したがって内部の関数呼び出しはすべて冪等でなければなりません。
登壇者のメンタルモデルは「`while true` ループの中にコードを書いているつもりで書く」です。
実装例として、プロキシ層への登録関数の書き方が示されました。
順序は削除の処理が先頭、それからハッピーパスの upsert です。
あとで消すものに大量の作業をしても無駄なので、削除中のリソースは真っ先に処理します。
こうすると、何度呼んでも安全で、呼ぶたびに望ましい状態へ近づく関数になります。
副産物として面白かったのが、次の指摘です。
何度も呼ばれるので、エッジケースが日常的に飛んできます。もはやエッジケースではないので、対処せざるを得ず、結果としてコードが良くなります。
望ましい状態は「取りに行く」
Laravel Cloud の信頼できる唯一の情報源(SSOT : Single Source of Truth)は、普通の MySQL データベースです。
その上に内部 API があり、「何がどこで動いているべきか」に答えます。
処理の流れは push ではなく pull です。
ユーザーが変更を加えると、内部 API が対象クラスタに ping しますが、送るのは ID だけ。
何をすべきか、何が変わったかは送りません。
クラスタが内部 API に問い合わせ、望ましい状態を JSON で受け取り、Kubernetes API に投げます。
クラスタは命令されるのではなく、望ましい状態を自分で取得します。
定期 reconcile がもたらす 2 つの効能
イベント駆動だけではなく、すべてのクラスタが定期的に「自分が管理すべき全ワークロード」を SSOT に問い合わせます。
1 つ目の効能はドリフト対策です。
「1 GB → 2 GB」のような設定変更のイベントが落ちても、定期 reconcile で全オブジェクトが照合されるので、やがて 2 GB へ収束します。
2 つ目の災害復旧は、もっと鮮やかです。
クラスタ A のワークロードを B へ移したければ、SSOT 上で「A だったものは今後 B」と書き換えるだけ。
B は定期 reconcile で自分の担当を取得して収束させ、A も「もうこれらを持つべきでない」と気付いてすべて削除します。
では、この「宣言と収束」を自分の Laravel アプリでも使うべきか。
答えは「場合によっては、はい」でした。
無条件の推奨ではなく、下手にやると本物のスパゲッティコードになります。
一方で、データを同期し続けたい場面には非常に向いています。
具体例として挙がったのが Stripe の Webhook です。
Webhook は落ちますし、Stripe API 側で conflict(競合エラー)が返ることもあります。
「取りこぼしても、最終的に正しい状態へ収束させたい」― まさにこの型の処理だからです。
「SSH して tinker で直す」と口にしたくなったら、それは候補のサイン。
この基準は覚えておこうと思いました。
11. Building a Video Processing Pipeline with Laravel Queues(Joshua Alphonse 氏)
一言でいうと、ジョブの完了は、処理の完了ではないという話です。
この一点を外すと、ユーザーは永遠にスピナーを見せられます。
動画処理が題材ですが、外部 API を待つあらゆるワークフローにそのまま応用できる内容でした。
まず、5 つの登場人物の役割分担が提示されます。
役割 | 責務 |
|---|---|
リクエスト | 仕事を記録して、立ち去る |
データベース | その仕事がどこまで進んだかを覚えている |
キュー | 仕事を前に動かし続ける |
ワーカー | 危険な部分を全て請け負う ― API 呼び出し、リトライ、エラー処理 |
UI | 状態の変化を見ているだけ |
キューは「耐久性のあるワークフロー層」であり「ベルトコンベア」です。
書類棚ではありません。
詳細 ― webhook の玄関・状態機械・レーン分離・失敗に行き先を与える
同期で全部やるコントローラの末路
動画がアップロードされると、コントローラがアセット作成 → モデレーション → 要約 → チャプター生成と順に呼びます。
処理は 1 つのメソッドに上から下へ並び、すべて同期で実行されます。
つまり、外部 API の応答をリクエストがその場で待ち続ける書き方です。
これは美しく読めます。すごく分かりやすい。そして、落ちる直前まで全部成功します。
アプリがクラッシュしても、リモート側の仕事は完了し、課金も発生します。
しかしアプリはその結果が作られたことを一切知りません。
ワークフローはコールスタックの上にしか存在しなかったので、一緒に消えます。
webhook の玄関で行う 3 手
そこで処理は非同期に逃がし、リモート側の完了は webhook で受け取る設計にします。
その webhook を 1 つ取りこぼすだけで、そのユーザーの動画は永遠に "processing" のままになります。
だから受け口(玄関)を 3 手で固めます。
- event ID で
firstOrCreate― webhook は at-least-once 配送で、重複は仕様です。ID で弾けば送信側のリトライを何度受けても安全で、既知のイベントはスキップできます - キューに積むのは DB の ID。ペイロードではありません ― ジョブは実行時に行を読み直します
- 200 を返す ― 玄関の仕事は「イベントを確実に受け取った」と言うことだけです
ジョブの完了 ≠ 処理の完了
ここが、このセッション最大の持ち帰りです。
ジョブがやることは 3 つだけです。
- リモート側で処理を開始する
- 返ってきた job ID を保存する
- 行に「リモート処理中」と印を付ける
そしてキュージョブはそこで終了します。
リモートの処理はまだ走っています。
ジョブは sleep しませんし、ポーリングもしません。
保存した job ID が、あとから来る webhook を正しいワークフローに繋ぎ直します。
だからシステムはクラッシュしても、再起動しても、再デプロイしても、居場所を失いません。
状態はデータベースにあります。ワーカーの中にはありません。
chain ではなく、イベント駆動の状態機械
「モデレーションが常に先」という絶対のルールがあります。
しかし chain では実現できません。
chain が進むのは「ローカルのキュージョブが終わったとき」で、「リモートのモデレーションが終わったとき」ではありません。
したがって「モデレーション通過」のイベントを受けて、後続を dispatch する形にします。
さらにジョブを必須(モデレーション)・任意(翻訳)・依存あり(トランスクリプトが必要なチャプター)に分類します。
チャプターが失敗しても要約が成功していれば、部分成功として完了させるためです。
バッチはカウンタ付きの DB 行
多くの人は、裏で調整役のプロセスが動いている姿を想像しますが、Laravel の実装はもっと単純です。
バッチはカウンタを 1 つ持ったデータベースの行で、各ジョブがデクリメントし、0 になったら完了。
単純だから信頼できます。
レーン分離とリトライ予算
すべてのワークロードは対等ではありません。
default / robots(遅く、レート制限を受ける)/ webhooks(速く走り続けなければいけない)/ sync / repair の 5 レーンに分けています。
全部を 1 本のキューに入れると、遅い AI の仕事が全部を塞ぎます。
バックオフは 10 / 30 / 60 / 120 秒。
そして sync ジョブには多めの予算を与えます。
AI 処理が成功したあとに同期で失敗するほうが、そもそも着手に失敗するより高くつくからです。
失敗に行き先を与える
Laravel Queue のソースを読むと分かる落とし穴があります。markJobAsReserved を見ると、attempts はジョブが「拾われた」ときに増えます。
例外を投げたときではありません。
登壇者の初期実装では、ジョブに failed() がありませんでした。
リトライを使い切るとジョブは完全に消滅し、しかし DB の行は「実行中」のまま残りました。
ユーザーから見ると、動画は永遠に "processing" です。
信頼できるシステムは、失敗に行き先を与えます。
ユーザーを吊るしたままにしません。
レート制限が静かに attempts を焼く罠
上限に当たったジョブを、Laravel は失敗させません。
待たせることもせず、そのままキューに戻します。
しかし解放 1 回ごとに attempts が 1 つ焼かれます。
tries = 3なら、ジョブは一度も実行されないまま失敗しえます。
だからレート制限のかかる仕事には、回数ではなく時間ベースの retryUntil を使います。
そして突き合わせ
キーモーメント(見どころの自動抽出)とチャプターは、トランスクリプトの完成を待ちます。
それが永遠に来なかったら、watchdog が待機中のジョブを失敗させ、一連の処理(run)を正直に終了させます。
ここで本番のつまずきも共有されていました。
ローカルでは動く遅延ディスパッチが、SQS では 15 分を超えると拒否されます。
そこで絶対時刻の deadline を保存し、15 分以内に自分自身を再キューする作りにしたそうです。
さらにスケジュールで定期的に突き合わせ(reconcile)を行い、長く待たされているリモートジョブをプロバイダに問い合わせます。
ワークフローが冪等なので、この修復は安全です。
webhook が速さを、突き合わせが正しさを与えます。
目的の置き方が良かったです。
「壊れない」ことが目的ではありません。「遅くなってもいいが、絶対に落とさない」が目的です。
12. Scaling Laravel(Devon Garbalosa 氏)
一言でいうと、バグは 3 つの層のどこにでも現れ、同じ場所には二度と出ないという実戦談(war stories)です。
そして、19 本の中で最も実務に直結する数字がここにありました。
データベース CPU の 75% が、たった 1 本のクエリに消えていました。対象は
failed_jobsテーブルです。
インデックスを 1 本足しただけで、DB CPU 使用率が 75% 削減、クエリ性能は 87,000 倍。
桁があまりに大きいので、登壇者は MySQL ホスティングサービスの PlanetScale に「これは間違いでは」と問い合わせました。
返ってきた答えは「いや正しい。むしろこの数字が出るとは思っていなかったのでチームに共有する」だったそうです。
そしてこれは全員の問題です。
すべての Laravel アプリがこのテーブルを持っているからです。
この修正を全アプリに届けるため、フレームワーク本体には PR も出されました。
詳細 ― 3 つの事例(Sportmonks / ロードテスト / Pile)
いずれも、登壇者が Laravel Cloud 側のエンジニアとして顧客を支援した事例です。
Sportmonks ― ピークで 24,000 クエリ/s
スポーツデータ API(ライブスコア・日程・オッズ)を提供しており、その先にいるのはファンタジースポーツと賭けのプラットフォーム。
データが更新されないと、人間が延々とリロードし続ける種類のサービスです。
平常時 1,000 req/s、ピーク 24,000 クエリ/s、サブ秒のジョブが最大 1,000 jobs/s。
構成全体をたった 1 人の業務委託が見ていて、アプリは辛うじて持ちこたえ、データベースは炎上中。
欧州中で数百試合がキックオフする毎週土日、誰かがキーボードの前に張り付いて手動でサーバを増やしていました。
バグ #1 はフレームワーク ― 前述の failed_jobs です。
本番でキューを回している人にとって、`failed_jobs` は普段考えなくて済んでしまうテーブルです。
しかしフレームワークは、失敗したジョブをその後どう扱うかを決めるために、このテーブルへクエリを投げます。
この規模になると、それが非常に高くつきました。
バグ #2 はプラットフォーム ― オートスケールは発火しているのに、常にワークロードに遅れていました。
既に起きた火事に反応している状態です。
原因はシグナルの選択ミス ― CPU 使用率を見てスケールしていたことでした。
Queue ワーカーは IO バウンドです。ネットワークと DB を待っているだけなので CPU は跳ねません。
CPU はそもそもボトルネックではないのです。
しかも Sportmonks のコードは、登壇者がこれまで見た中で最も CPU / RAM 効率が良い部類でした。
彼らにとって CPU 基準のスケーリングとは、「決して正しいタイミングでスケールしないための、非常に高価な方法」でした。
これはチューニングのつまみでは解決せず、プラットフォーム側に新機能が必要でした。
それが Managed Queues です。
キュー圧(待機しているジョブ数)を基準にスケールします。
あわせて提案したのが、キュー構成の大手術です。
Horizon の named queue は 150〜200 本あり、3 年かけて信頼を積み上げてきた設定でした。
それをすべて 1 本のキューに畳み、SQS の fair queues で捌きます。
Sportmonks の Peter 氏の反応は「それでどうやって性能が出るんだ」。
チューニング後は「想像していたより良く動いている」に変わりました。
バグ #3 は彼らのインフラ ― 手動プロビジョニングです。
これは Private Cloud への移行そのものが解消しました。
3 つのバグ、3 つの層 ―― あなたのコード、フレームワーク、プラットフォーム。これがスケーリングの実像です。
ロードテスト ― 心配は 2,500 req/s、実測は 17,000 req/s
ライブ配信プラットフォームが Laravel Cloud への移行を検討中で、ピーク負荷を捌けるか不安でした。
要求値は 2,500 req/s。
返した答えは「ロードテストしてみませんか」。
Grafana Cloud k6 から仮想ユーザー 20,000 で 1 時間。
実ルート・ミドルウェア・セッション・CSRF をすべて通過させ、ベンチマーク用に素通しする作り方はしていません。
さらに bimodal latency jitter を仕込み、85% は即座に返し、15% は接続を 33 秒間保持させました。
実トラフィックとはそういうものです。全部が同じ速さでは来ません。
なお、インフラチームには事前連絡しておらず「プラットフォームが DDoS されている」というアラートが飛んだそうです。
チームの反応は「たぶん Devon が何か試してる」。
結果は次のとおりです。
- 持続スループット 17,000 req/s
- 総リクエスト 39.6M
- 失敗 173 件
- P95 レイテンシ 157 ms(ほぼ変動なし)
- レプリカ再起動 0 回
未チューニングのアプリで、15% が接続を掴んだままで、こちらは何も触っていない状態です。
現代のスケールにおいて、プラットフォームがあなたの制約になることはほぼありません。
アプリが遅いなら、原因はおそらくデータベースか設定です。
そしてほぼ確実に、あなたが制御できる層です。
Pile ― 負荷ではなく複雑さの問題
B2B の床材 SaaS で、前の 2 社と違ってアプリは動いていました。
相談の理由は、何年もインフラをガムテープで貼り合わせ続けるのに疲れたからです。
規模は次のとおりです。
- Laravel アプリ 13 個(本番 + ステージング合算)
- 1.5M リクエスト/日
- 800,000 ジョブ/日
- 300 GB の DB
- インフラ費用 $11,000/月
一部は Vapor、一部は Forge で、AWS の VPC 同士を繋ぐためのハックが必要でした。
これは負荷の問題ではなく、複雑さの問題でした。
すべてのコードパスに「Vapor ならこう、Forge ならこう」の分岐があり、すべてのインフラ判断が両方を考慮する必要があり、すべてのバグを 2 回再現する必要がありました。
6 アプリを 12 週間で移行しました。
結果は、インフラ費用が約 50% 減。
総ダウンタイムは全 6 移行の合計で 1 時間、データ損失は 0 でした。
5 回目・6 回目の移行では連絡すら来なくなり、「最後のアプリの移行はいつですか」と Slack を送ったら「2 週間前にやりました。問題なしです」と返ってきたそうです。
締めの一言が、この仕事の本質を言い当てていました。
来年あなたが移行するプラットフォームがより良くなっているのは、この部屋にいる誰かが壁にぶつかり、それを何とかできる誰かに伝えたからです。
「大規模になったとき、問題は普段どの層に居ますか」という質疑への回答は、身も蓋もなく明快でした。
正直に言えば、ほぼ必ずデータベースです。
④ AI ― 道具が変わったとき、人は何をするのか
ここからは、道具そのものではなく「道具が変わったときに、人は何をするのか」という話になります。
この章の 5 セッション(13 〜 17)は、近しい結論に帰結するのにたどり着き方がまったく違うのが面白いところでした。
現場の運用術から始まって、学習論・プロンプト論・キャリア論・創造性論と話者の立場が一本ずつずれていきます。
13. From Vibe Coding To Vibe Engineering(Kitze 氏)
一言でいうと、全部エージェントにやらせつつ、出力の 8 割を疑うという姿勢の話です。
冒頭の比較表が秀逸でした。
カジノ | Vibe Coding |
|---|---|
チップを買う | トークンを買う |
派手なライトと演出 | 「おっしゃる通りです!素晴らしいアイデアですね!」 |
「俺には必勝法がある」 | 「私はプロンプトエンジニアだ」 |
「あと 1 回で取り返せる」 | 「あと 1 回プロンプトを投げればバグは消える」 |
胴元は必ず儲かる | AI ラボは必ず儲かる |
「この 4 時間はどこへ消えた?」 | 「20 分で書ける関数に 4 時間プロンプトを投げていないか?」 |
詳細 ― 実践 9 か条と、エージェンティックループ
Vibe Engineering とは
エージェントを使い倒しつつ、その出力を鵜呑みにしない姿勢です。
何でもエージェントにやらせますが、出力の 8 割は疑ってかかります。
そして脳内の技術知識をエージェントが参照・活用・更新できるようにプロジェクト環境を整備します。
大前提として LLM の書いたコードは常に疑います。
LLM の知識は人間が書いたコードが土台であり、人間はあらゆるレベルで欠陥だらけだからです。
実践 9 か条
- こまめにコミット・プッシュし、ブランチを分ける(一度に手を広げすぎない)
- Git Worktree を使う
- 型と Lint をエージェントのガードレールとして最大限に効かせ、変更のたびにエージェント自身に実行させる
- モデルとツールの最新動向を追い続ける
- 良い設計(コンポーネント・関数・パターン・抽象)が重要。LLM は与えられたものの上に積み上げるだけなので、プロンプト内で具体的に名指しする
- ゼロから始めるなら、テンプレートから始める
- 音声入力でコーディングする
- ルール・ドキュメント・コマンド・メモリを整備する(複雑な機能を数行の指示だけで新人に丸投げはしないはず)
- AI は空気を読めない。必要な情報と的確な指示がなければ、9 割は失敗する
エージェンティックループ
ターンの終わりごとに自動検査を挟み、エラーが残らない状態で閉じる仕組みです。
エージェントが 1 ターン完了したらフックを起動し、型チェックと Lint が走ります。
エラーがあればエージェントが自分で直し、すべてゼロになるまで繰り返します。
エラーを残したままターンを終えないこと。
雑さは雪だるま式に増えます。
さらに自作の Police Script(取り締まりスクリプト)を併用します。
型システムにも ESLint にも落とし込めないルールを担当させ、police ルール自体は LLM に書かせます。
エージェントにやってほしくない振る舞いを見つけるたび、新しいルールとして追加していきます。
誰に AI ツールを渡すか
ここは議論を呼びそうな主張でしたが、はっきりしていました。
インターンやジュニアには渡してはいけない(猿に銃を持たせるようなもの)。
シニア開発者にこそ渡すべきで、懐疑的なシニア + LLM = 10 倍の成果になる、と。
なお「MCP とは何か」への答えは「API を格好よく言い換えた言葉に過ぎません」の一行でした。
14. Building Software At The Edge Of Your Understanding(Matt Stauffer 氏)
一言でいうと、アプリの能力は AI で急速に伸びるのに、自分の理解は同じ速度で伸びないという話です。
この差を comprehension debt(理解の負債) と呼んでいました。
comprehension debt = アプリが何をできるか と、それについて自分が実際に何を理解しているか の差
他のあらゆる負債と同じく、いつか必ず返済されます。
自分の望む形で返すか、誰かに返させるかのどちらかです。
出発点は、Laracon の会場そのものを再現した Minecraft 風の 3D ワールドを 3 か月かけて作った話でした。
使ったのは Three.js。
当時も、そして今も知見がありません(※)。
この「※」は、最後に回収されます。
詳細 ― 失われた摩擦と、返済のための 4 つの指針
これは Vibe Coding ではない
3 か月で数百時間を費やしました。
プロンプト・設計・計画・レビュー・作り直し・デバッグなど、あらゆる作業の末に完成しました。
「Minecraft を作って」の一発生成ではありません。
セッションは、「AI と組んでも職人性は成立する。それなのに、十分に語られていない」という問題意識から始まります。
分からないまま作るのは、昔からだ
90 年代に HTML を覚えたとき、YouTube も Laracasts も書籍もブートキャンプもありませんでした。
あったのは View Source だけです。
2001 年の初仕事は、高校の進路指導カウンセラーに「サイトを作れる?」と聞かれて「作れます。View Source で参照しましたから」と答え、200 ドルを受け取って作ったもの。
そのサイトは 20 年間オンラインでした。
では何が違うのか ― 摩擦が消えた
従来の学習ループは「実装を試みる → 他人のコードの観察・検索・ドキュメント読み → 試す・壊す → 動くまで繰り返す」でした。
最初の試みから、動くものに着地するまでの間にある摩擦 ― そこが学習の場でした。
目的地まで運転して 3 回道に迷えば、毎回 GPS に従うより道を覚えます。
GPS を使い続ければ、行き方は永遠に身につきません。
Anthropic の調査も引用されていました。
数十万件のコーディングセッションを分析した結果、同じエージェントで同じものを作らせても、専門家と非専門家では結果が劇的に違う。
つまり、私たちが AI で有効に働けている理由の一部は、私たち自身の専門性です。
そして有能なプログラマーへの警告がありました。
AI を使い始めた地点で停滞するリスク
成長を促す摩擦が一度もないので、「学んでいる」という瞬間が訪れません。
その地点でも十分に有能なだけに、そこに留まり続けます。
その間、他の人は成長し続けます。
では、理解の負債を返済しながら作るにはどうすればいいのか。
ここから、4 つの指針が示されます。
指針 1 : 固い地面から手を伸ばす
新しい技術は、理解している領域の「すぐ隣」から 1 つだけ選びます。
何も理解できないものに囲まれた深いプールには、飛び込まないこと。
良い例が、数年前に地理空間 MySQL を学んだときの感覚です。
コード・DB・緯度経度・Laravel という馴染みのあるものに囲まれ、馴染みがないのは地理空間 MySQL だけ。
理解している技術の心地よい抱擁の中で、たった 1 つを学べました。
指針 2 : 未知を積み上げない
指針 1 の「1 つだけ」を、作っている途中でも守り続けます。
登壇者自身は、守れなかったと振り返っていました。
Three.js で始める → 良いツールは React 側にある → React を追加 → 正しく使うには drei と react-three-fiber が必要 → 追加 → 物理演算も必要 → Rapier を追加。
1 つ 1 つは境界のすぐ外なのに、積み上がると「境界の外の技術だらけの不安定な塔」になります。
「あとで学ぶ技術リスト」も作りましたが、学べませんでした。
理由は 2 つ。
- AI でハイになっていて、立ち止まるより続ける動機の方が強い。
- 分からない箇所が多すぎて、どこから手をつけるかすら分からない。
Addy Osmani の区別で言えば、あるべき姿は cognitive offloading(認知の委譲) ― 作業は任せても、何をしているかの所有権は持ち続けることです。
陥ったのは cognitive surrender(認知の降伏) ― 完全に手放すことでした。
裏付けもあります。
Anthropic の別の調査で、馴染みのない Python ライブラリを渡して AI 支援の有無をランダムに分けたところ、理解度テストは AI あり 50% / AI なし 67%。
最も差が開いたのは「あとでそのコードをデバッグする能力」でした。
指針 3 : AI でコードではなく理解を作る
AI に、コードだけでなく自分の理解も作らせます。
AI での「作り方」は皆が語るのに、「学び方」は誰も語らない ― この指摘が鋭かったです。
「進みながら学べる」という約束は、学び方を意図的に設計したシステムがない限り、まったく中身がありません。
指針 2 の Python ライブラリの調査には後半があります。
成績が良かった AI 利用者は、概念的な質問をし、説明を求め、自分の理解度を確認していました。
この層は、AI を生成用途だけで使った他の全員より有意に良い成績でした。
具体的なやり方は 3 つ。
- 詰まった時点で、カリキュラムを作らせる(「私が知っていることはこれです。コードベースを見て、私の理解に含まれていない新しい概念を洗い出し、学ぶべき順番で案内してください」)
- 事前にプロンプトで仕込み、作業と並行してカリキュラムを作らせる
- 手を動かして学ぶ人は、「課題」を出させる
3 つ目の「課題」の例が具体的でした。
「drei を使って、空に巨大な YouTube を埋め込んでください」― これだけ。
この課題を解いた時点で drei の構文が身につき、以降コードを見れば「これは drei だ」と分かるようになります。
指針 4 : 失敗経路を自分のものにする
AI が仮説を出す前に、自分の仮説を立てます。
きっかけは、公開初日のバグでした。
作った 3D ワールドを初めてインターネット上に置き、他人に遊んでもらったとき、バグが出ました。
階段ブロックを置いて、掘って、その場所に別のものを置こうとすると動かない。
AI に修正を頼むと、仮説を出しては外れ、別の仮説も外れる。
登壇者にも分からず、2 人とも解けませんでした。
何かが壊れていて、部屋の誰も直し方を知らない。これは良い瞬間ではありません。
原因は、階段だけが他のブロックと少し違う形で保存されていたこと。
登壇者も AI も、それを知りませんでした。
動作原理を理解していないものは、デバッグできません。
そして今回は、誰も理解していませんでした。
だから、AI が助けられなくなる日を待たず、助けられる日のうちに自分の考えを持つ習慣をつけます。
「魚をもらうのではなく、釣り方を教えてもらう」です。
冒頭の「※」を、ここで回収します。
今は Three.js を多少知っている。
実際に扱える。
アプリケーションの形を説明できる。
意図を持って各部を変更でき、壊れたときに仮説を立てられる、と。
ソフトウェアが先に到達し、理解はあとから追いつきました。
そして、これを恐怖の煽りとして受け取らないでほしい、と釘を刺していたのが誠実でした。
理解していないシステムの中で作業することには、美しさと魔法があります。
それは自分がプログラミングを始めた頃に感じた美しさと魔法そのものです。
ただし、責任ある形でやる方法があるのです。
結論はこの 2 つです。
- コードの所有権を取り戻すこと - IDE で実際にテキストを打っているかどうかは関係ありません。
- 理解の境界線で作ること - そして作り終えたとき、その境界線が動いていることを確かめること。
15. Think Harder: How I Prompt(Thorsten Ball 氏)
一言でいうと、プロンプトに秘伝のタレはなく、あるのは一つの問いだけという話です。
How is the model supposed to know what I mean?
(モデルは、私の言いたいことをどうやって知ることになっているのか?)
登壇者はコーディングエージェント Amp の共同開発者で、そのコードの 99% を AI が書いています。
チームの誰ももう手ではほとんど書いていません。
そのうえで、自分たちのプロンプトのやり方は非常に退屈だと言い切ります。
- MCP サーバーは使わない
- スキルは 1〜2 個だけ
- フレームワークなし
- 自作のスラッシュコマンド構成もなし
この退屈さの土台にあるメンタルモデルが、秀逸でした。
詳細 ― 拉致されたシニアエンジニアと、5 つの実践
メンタルモデル
あなたは経験豊富なシニアエンジニアです。
あらゆる言語を知り、Stack Overflow で最高得点を持っています。
ある日、出勤途中に突然バンに押し込まれます。
頭に袋をかぶせられ、どこかへ連れ去られます。
袋を外されると、そこには机が 1 つだけ。
机の上にはコードベースの開かれたエディタ、ターミナル、ブラウザ。
そして誰かが紙切れを手渡してきます。
fix the bug with the upload
(アップロードのバグを直せ)
これが、モデルが体験していることです。
しかもモデルは人間と違い、「何のバグの話だ?」とは聞き返しません。
「おっしゃる通りです。アップロードのバグを修正します」と言って、自分が思う「それ」を勝手にやり始めます。
情報の出どころは 2 つしかありません。
学習データ(自分では変えられない)と、コンテキストウィンドウ(自分で操作できる)。
後者にはシステムプロンプト・ツール定義・スキル・メッセージ・ツール実行結果、そして最も重要なあなたのプロンプトが入ります。
すべての文章の目的は、理解されることです。
コミットメッセージも Slack のメッセージもプルリクエストの説明も、モデルへのプロンプトも、目的は同じです。
だから問うべきことも、いつも 2 つ。
- 読み手は何を知っているか
- 自分は何を伝える必要があるか
実践 1 : 大きな機能を頼むときは、情報のありかを指す
Amp の Daemon モードを作らせたときのプロンプトは長文ですが、やっていることは単純でした。
まず情報のありかを指します。
- server と thread actors で新しいスレッドとサンドボックスを起動できる」→ ディレクトリを 2 つ指定。
- そこで E2B サンドボックスを立ち上げ、この CLI の
amp --headlessを起動する」→ さらに 1 つ。 - 次の段落で「このファイルとこのファイルを見て、このドキュメントを読んで」→ 情報源をさらに 3 つ。
2 段落 / フォルダ 3 つ / ファイル 3 つ。
これはシニアエンジニアに頼むときに言うことと、まったく同じです。
次に、どう動くべきかを頭の中のまま書き出します。
細部はどうでもよく、「自分はこう動くと思っている」を言語化していることが重要です。
そして制約を明示します。
「リポジトリ内で動かすこと。checkout も worktree も作らないこと」「プロセスのライフタイムを管理し、終了時には全部 kill すること」。
書かなければ、それが制約であることをモデルが知る術はありません。
さらに曖昧なままの願望も書きます。
「とにかく極限まで薄く作ってほしい」。
果ては「これは自分が頭の片隅に置いていることで、君にも頭の片隅に置いていてほしい」という書き方まで。
奇妙ですが、機能したそうです。
実践 2 : One-Two Punch ― 先に探させ、それから頼む
実践 1 のような長文を、毎回書く必要はありません。
1 手目で情報を探させ、2 手目で本題を頼みます。
1 手目は「Web UI のニュース表示に使っている、このトランペット吹きのアセットを探して」+ スクリーンショット。
エージェントが探し回った結果、この時点でコンテキストウィンドウには画像の置き場所・Svelte コンポーネント・OG 画像の別バージョンまで揃っています。
2 手目は「このキャラのバリエーションを 4〜5 個作って。トランペットの代わりにシンバルを持たせて…」。
6 分後に完成。
実践 3 : Gold Standard ―「良いお手本」を先に指す
Amp のキューイング機能が、CLI 版では正しく動くのに Web 版では壊れていた、という状況です。
1 手目は、正しく動いている側のディレクトリを指して「CLI のキューイングの仕組みを調査して。これがあるべき姿の gold standard だ」と宣言。
2 手目は「Web 版がうまく動いていない。調査して、CLI と同じように動くようにして」。
もし 1 手目を飛ばして「Web のキューイングが壊れている」とだけ言っていたら、モデルは何が「壊れている」で何が「正しい」のかを知りようがありません。
実践 4 : 長文を手で書かず、プロダクトに吐かせる
本番環境のデバッグに使うプロンプトの例では、手で書いたのは 1 行だけ。Why is this not booting up? です。
残りはすべて自動生成で、ドキュメントへのポインタ・各種 ID・データダンプ・デバッグ用スクリプト・詳細情報の URL が入っています。
では、その自動生成はどこで行われるのか。
Amp では、管理者用のボタンを押すとデバッグサイドバーが開き、自動生成されたデバッグ用プロンプトとコマンドが並んでいます。
中身はただの Markdown です。
エージェント専用のデバッグ用スクリプトまで含めておけるのがポイントでした。
実践 5 : スクリーンショットを撮る
例として挙がったプロンプト本文は「両方のディレクトリを読むようにして」だけ。
これ単体では意味不明です。
しかし添付されていたのは、顧客からの Slack の質問のスクリーンショットでした。
その質問には、GitHub issue へのリンクまで写っています。
エージェントは Web にアクセスできるので、スクリーンショットから issue まで辿って自分で状況を把握します。
このプロンプトを書くのにかかった時間は 30 秒以下。
私のプロンプトの 90% にはスクリーンショットが入っています。この講演からの持ち帰り 2 つ目 : もっとスクリーンショットを撮ってください。
そして究極形 : AGENTS.md
例に挙がったプロンプトは「Web UI のこの画像に説明文を入れて」+ スクリーンショット、そして最後に「この修正を実装して、Storybook のストーリーのスクリーンショットを見せて」。
エージェントは修正を実装し、本当に Storybook のスクリーンショットを見せてきました。
なぜエージェントは、Storybook のスクリーンショットの撮り方を知っていたのか。
答えは実行ログにありました。
途中で AGENTS.md を読んでいたのです。
多くのコーディングエージェントは、あるファイルを読むと同じディレクトリの AGENTS.md を自動でコンテキストに取り込みます。
つまり AGENTS.md をコードベース中に撒いておけば、エージェントがそのディレクトリに入るたびに読む「道しるべ」になります。
ルートの AGENTS.md には「dev サーバーはこのコマンド」「ブラウザ自動化はこれを使う」。
Storybook フォルダの AGENTS.md には「これが Storybook。この URL で動く。ポートはここで確認できる」。
「やり方」をプロンプトから追い出して、コードベースに置く。
これが究極のプロンプトの書き方です。
情報がどこかから来なければならないという事実は変わりません。
ただ、コードベースに持たせておけば、プロンプトに書かなくて済むだけです。
質疑で「99% を AI が書いているなら、アプリケーションの全体像をどうやって頭に保っているのか」と問われました。
その回答が、そのまま実務の指針になります。
答えは、コードのどこが load-bearing(荷重を支えている) かを見極めることです。
Amp のような分散システムであれば、次のような部分です。
- コンポーネント間のプロトコル
- スリープ / ウェイクの実行時挙動
- ビジネスロジックとそのコード上の表現
これらも手では書いていませんが、エージェントが触るときは鷹の目で監視します。
ビジネス上の制約とドメインロジックはドキュメントに書き出し、エージェントにそれと突き合わせて検証させます。
コードは、書かなくてもレビューできます。
最重要部分が本当に堅牢であること、そして「なぜ堅牢なのか」が文書化されていることを確認します。
そうしておけば次にエージェントが来たときに、また変えてしまうことがありません。
逆にコードベースの多くは load-bearing ではなく、外縁に行くほどレビューの必要は減ります(「CSS はそこまで気にしていません」)。
この線引きの感覚は、そのコードベースで働くほど育つ、という話でした。
16. The Last Software Engineer(Kent C. Dodds 氏)
一言でいうと、AI の能力が伸びていく未来を 1 コマずつ進めたとき、「ほぼ全部できるが全部ではない」最後のコマに残る技能は何かという思考実験です。
答えは判断力(judgment)でした。
登壇者はこれを Product Engineering ― 実装の詳細とプロダクトへの帰結を接続する技能 ― と呼んでいました。
まず、なぜその問いになるのか。
AI の能力のトレンドラインが、この先どうなるかは誰にも分かりません。
知らないのです。誰も知りません。知っていると言う人は、知りません。
完全な AGI が来た世界は、Star Trek か Terminator の未来です。
どちらにせよ計画の立てようがないので、議論しても役に立ちません。
そこで一歩だけ手前に戻して、「最後のひとコマで人間に残っている小さな取り分に、何が入っているのか」を突き止める。
そうすれば最も耐久性のある技能が分かる、という組み立てです。
詳細 ― 追尾する矢・全員がチームリード・latent experience
Product Engineering とは何か
この技能が答える問いは、「このシステム・このコスト・これらのリスク・これらの制約のもとで、何が有用か」です。
Product Management とは別物です。
PM は、ユーザーや事業のニーズをプロダクトの意思決定に接続します。
Product Engineering は、実装の意思決定をプロダクトへの帰結に接続します。
PM になりたいなら、もうなっていました。私はコードが好きなのです。
追尾する矢
開発者を、弓を引く射手に見立てます。
従来は PM の「あの的を狙え」という囁きを聞き、風を計算し、放つ。
上手い射手は、指輪の穴を通して当てるほどの腕前です。
いま変わったのは 2 点。
- 矢が自動追尾になった(ほとんど逆方向に構えて「あの的に当たれ」と言えば当たる)
- そして、的の領域そのものが広がった
今のプロジェクトへの野心は以前とは比べものになりません。
「難しすぎる」と判断して諦めていたからではなく、難しすぎて、そもそも思い付きもしなかったからです。
ただし、資金が潤沢でも「全部の的を撃てばいい」とはなりません。
「Attention Is All You Need」― Transformer を生んだ論文の題名は、ユーザーにもエージェントにも当てはまります。
ユーザーの注意(attention)は有限です。
だから「どの的を狙うか」の重要性は以前と変わらず、選択肢が増えた分だけ難しくなりました。
全員がチームリードになる
よく聞く「自然言語が新しいプログラミング言語だ」という言説を、誤りだと切り捨てます。
プログラミング言語は、同じ入力から毎回同じ出力を決定的に生みます。
それを担うのがコンパイラで、LLM はコンパイラではありません。
とはいえ抽象度が一段上がるという原則には同意する、と。
そしてその一段上は、チームリードやマネージャーがずっと立っていた層です。
つまり私たち全員がチームリードになり、ソフトウェア工場の中でエージェントが最大限の能力を発揮できるように働きかけるのです。
チケットを取る → 考える → 実装する → 渡して次を取る ― その働き方の時代は終わりました。
チケット処理係として本当に優秀なのは誰か。
AI コーディングエージェントです。
彼らはそれが本当に得意です。
オーナーシップ
エージェントは間違いの帰結を負いません。
「なぜ本番 DB を削除したのですか」「おっしゃる通りです。本番 DB を削除すべきではありませんでした」「そうですか。ではあなたは解雇です」― 気にもしません。責任もオーナーシップもありません。
ただし重要なのは、「責める相手がいない」という愚痴ではありません。
オーナーシップを持つと、自分の振る舞いが変わるということです。
深夜 2 時に電話が鳴るのは自分だ ― そう知っているから、災害復旧が本当に動くのかを二度確認するのです。
自己批判も印象的でした。
若手の頃は、ステークホルダーとの会話を遮ってくれるマネージャーが大好きだった。
しかし、それは最悪の態度だった、と。
営業・サポート・そして最終的に顧客が何を言っているかに関心を持ち、自分の技術力で解ける問題は何かを理解すること。
それが今の仕事だ、と。
latent experience(潜在的な経験)
20 年の経験が無価値になったのか。
なっていません。
構文は本質ではありませんでした。
配列の分割や二分木の反転が、もっとも有用な技能だったことは一度もありません。
経験の本体は、会議で誰かが「こうやりましょう」と言った瞬間に、「いや、それはできない」と反応できること。
そしてそのあとで、「なぜ自分はそう感じたのか」を言語化できることです。
これが極めて価値を持つ理由の説明が、辛辣で的確でした。
エージェントが自分の勢いに合わせてくるだけだからです。
「いいですね、その方向で行きましょう、最高です」― 史上最大のご機嫌取りです。
歴史上の Product Engineer たち
Margaret Hamilton(Apollo 11)は、一部のジョブを切り捨てて着陸誘導システムを優先する設計を仕込んでいました。
月への降下中に executive(ジョブ管理プログラム)が過負荷でエラーを出しても、着陸できるようにするためです。
その事態を予見し、どのシステムが本当に重要かを理解していたのです。
Paul Buchheit(Gmail)は、全員が容量制限のためにラベルを付けて受信箱をマイクロマネジメントしていた時代に、「容量を無制限にして、その上に検索を実装する」と決めました。
Kevin Systrom は、自身のアプリ Burbn の機能のうち、実際に使われていた写真共有以外を全部削りました。
残ったものが、Instagram です。
締めの言葉です。
技術が業界を破壊するからといって、その業界が必ず消えるわけではありません。
ただし業界の構成員は、その変化に適応する必要があります。人間は人間と関わりたがり、人間は人間を理解します。
エージェントはそれを再現できません。だから自分の人間性に寄せること。
実装専用機は、本物の機械に置き換えられます。
17. AI Can Do Your Job... What Now?(Will King 氏)
一言でいうと、作業を始める前に「完了の姿」を説明できる仕事は AI にできる。そして、やらせるべき ― という話です。
残るのは「そもそも何を作る価値があるのか」を決める創造的な仕事です。
そして創造性は、「持っているか / いないか」の才能ではなく、リズムがあり上達できるスキルである。
これが、このセッションの主張でした。
私たちは長いあいだ、仕事をアウトプットで定義してきました。
「自分はエンジニアだ。だから仕事はコードを書くことだ」と。
仕事は行数ではありません。仕事は創造性です。
創造性が自分に関係ないと感じるのは、創造性のブランディングが失敗しているからだ、と。
創造性は、デザイン職の所有物ではありません。
エンジニアも、1 行でもコードを書く前に「どの行が書く価値のある行なのか」を知らなければならないからです。
詳細 ― 触媒・アイデア・現実との接触・taste・そしてリズム
なぜ創造性が「才能」に見えるのか
多くの人が、創造性を「持っているか / いないか」の二値だと考えるのには理由があります。
教育学の Bloom's Taxonomy(学習目標の分類)では、ピラミッドの頂点が「create」です。
そして経験が浅いうちは、創造的な仕事が狂気のように見えるからです。
しかし狂気に見えるのは、創造性を近くで見すぎているからでした。
Path(道筋)は個人的です。
曲がり、引き返し、人と比べてもまず一致しません。
Process(過程)は共通です。
見方さえ分かれば、どの道筋にもリズムがあります。
創造性の説明が難しいのは、path を process と取り違えているからです。
触媒 ① 仕事から
創造性は真空では起きません。
創造性は「反応」です。
何かを見て「これくらい自分でも思いつけた」と思ったことはありませんか。
そのとおりです。ただ、あなたは気づかず、その人は気づいた。それだけです。
機能要望・顧客の苦情・バグ・エラー、そしてプロダクトの誤用。
これらが、仕事の中で自然に表面化してくる触媒です。
問題は、それにどう反応するかです。
まずフィードバックが自分に届くようにする。
世界中からフィードバックが来ていても、自分が見なければゼロです。
次に触媒を「答え」と取り違えない。
よくある失敗は、問題の証拠を、その解決策と混同することです。
触媒は常に signal であって、source of truth ではありません。
その signal がどこへ繋がるかを突き止めるのが我々の仕事です。
そしてアパーチャ(絞り)を変える。
- ズームアウトして、全体像を見る
- ズームインして、各要素がなぜ必要なのかを分解する
- 前後を見る
触媒 ② 世界から
仕事からの触媒は「どこに注目すべきか」を教えてくれますが、「何を作るべきか」までは教えてくれません。
「どうやってこんな発想が出てきたんだ」と思わされる解は、仕事の外で見て・学んで・体験してきたものの蓄積から出てきます。
新しい接続がいつ起きるかは予測できません。
しかし、接続の材料で人生を満たしておくことは予測可能な行動です。
だから踏み固められた道から外れ、入力を増やし、素材のライブラリを自分の中に作っていく。
体験した瞬間と、それが役立つ瞬間はまず一致しないからです。
アイデア = 気づいたこと × 知っていること
「気づいたこと」が触媒です。
では「知っていること」とは何か。
触媒(気づき) | 知っていること | 生まれたもの |
|---|---|---|
4 時間のバス移動に USB メモリを忘れ、作業できず腹を立てた | 情報科学専攻だった | クラウドストレージ(Dropbox) |
富裕層が芸術を商品として扱うことが気に食わない | 自分がアーティストだった | 作品としての批評 |
多くの人にとって、ここが行き止まりです。
触媒を「自分が習熟している何か」と掛け合わせられなければ、そこで終わるからです。
だから master your medium(自分の媒体に習熟せよ)。
専門性は創造性の導管です。
そして語彙の話が良かったです。
AI から良いアニメーションを得たければ、欲しいものを言葉にできるようにならないといけません。
この一節は、Emil 氏の投稿からの引用でした。
ドメイン言語は AI のためだけのものではありません。
具体的な語彙で考えを表現できること自体が、触媒とアイデアを接続する能力を高めます。
だからコードを学び、デザインを学び、基礎を学んでください。それは今も、これからも通用します。
現実との接触
アイデアは実在しません。
頭の中では非可逆圧縮がかかっていて、輪郭はぼやけ、難所は隠れています。
頭の中では何も実際に動く必要がないので、こちらは虹とドーパミンの世界に住んでいられます。
答えるべき問いは 1 つ。
そのアイデアは、現実との接触に耐えるか?
- 抽象を書く
- プロトタイプを作る
- ジョークを言う
それだけでアイデアは頭の外に出て、必ず何かが返ってきます。
抽象は扱いにくいと分かり、プロトタイプはエッジケースを 5 つ指摘され、ジョークは誰も笑わなかった。
これは失敗ではありません。情報です。
そしてこのセッション最大の持ち帰りがここでした。
創造性のアウトプットは、途中で作った成果物(artifact)ではありません。
アウトプットは、それを作る過程で得られる「明確さ(clarity)」です。
Figma のデザインもコードのプロトタイプも自作ツールも、尊いものではありません。
手段です。
成果物の役割は、自分が理解していないことを露出させて、仕事に「返事」をさせることです。
Taste is pattern matching earned through pain.
(taste = 痛みで得たパターンマッチング)
偽札を見分ける職員は、特別な機械もマーカーも使いません。
触っただけで分かります。
大量の紙幣に触れてきたからです。
正解に辿り着かせるのは、才能ではなく執拗さです。
一度の閃きではなく、「十分な数の不正解」を踏んだから、正解が現れたときにそれと分かるのです。
そして、打席数を増やす以外にパターン認識が上達する方法はありません。
経験の長短にかかわらず、創造的な仕事には 1 つの真実があります。
最初のアイデアは必ずダメです。
これは世界的なヒットを作る側でも同じで、ミュージシャンの FINNEAS と Billie Eilish のインタビューが紹介されていました。
「録音以前に『どういう曲にするか』を決めるだけで、とんでもない時間がかかった。
本当にいろんな方法を試して、800 くらいのバージョンがあった」。
動き出しを最適化する
最大の障壁はたいてい白紙のキャンバス問題です。
ここで詰まるのは、最初のアイデアに期待しすぎているから。
始まりに「品質」を求めるのをやめ、「動き(motion)」を最適化してください。
Crazy Eights という手法(8 分間で、まったく異なるアイデアを 8 つ出す)が紹介されていました。
狙いは、最初に浮かぶ最も安直なアイデアの先へ、自分を押し出すことです。
そして行き詰まったら視点を増やす。
最良の方法は、創造的な仕事を 1 人でやらないことです。
ペアプログラミングが何十年も続いてきたのには、理由があります。
その次の形は「1 つのエージェントセッションを、他の人と一緒に動かすこと」だ ― この指摘は面白かったです。
適切な解像度で作る
動き出したあとのもう 1 つの罠が「世界全部を一度に解こうとすること」です。
自分に 2 つ問います。
- 自分は何を知ろうとしているのか?
- それを知るために作れる、最小のものは何か?
目的は完璧さではありません。目的は明確さです。
工業デザインのプロトタイピングが例に挙がっていました。
何を作るのか分かっていない段階で、量産用の材料は使いません。
そして AI 台頭の副作用として、「使い捨て・単一用途のツール」のコストが逆転したことが挙げられていました。
目の前の問題にちょうど合う一点物のツールを作るコストは、いま史上最安です。
しかも、自分の問題をサードパーティ製ツールの型に押し込むより安上がりです。
全体像はこうまとめられていました。
創造性は難しい。
しかしリズムがあります。
広げて(expand)、狭める(contract)。変奏して(riff)、磨き込む(refine)。AI が何でも作れるとしましょう。
それでも、「何が可能か」だけでなく「何が良いか」を探り、作る価値のあるものを見極める仕事が残ります。
そしてそれは、AI にはできない仕事です。
⑤ 人 ― なぜ、作るのか
最後は、そもそもなぜ作るのかという話です。
この章の 2 セッション(18・19)から持ち帰れる技術的な知識はほとんどありません。
それでも最後に置いたのは、個人的にこの 2 本が一番残ったからです。
18. Whimsy-Driven Development(Christina Martinez 氏)
一言でいうと、あなたの中には「たまごっち」がいて、餌をやらなければ弱って死ぬという話です。
その餌が silly software(くだらないソフトウェア)です。
コードを覚えたての頃は、12 時間でも平気で書けました。
土曜を丸ごと新しいフレームワークのドキュメントに費やしました。
そして念願の「コードを書いてお金をもらえる仕事」に就きました。
その後どうなったか。
ホームページのボタンの色を変えるのに、関係者との往復込みで 1 週間かかりました。
同じボイラープレートを書くのは、もう 20 回目でした。
再現困難な競合状態をデバッグし、「もう少しで直ります」と朝会で言った直後に別のエッジケースを見つけました。
では、直近の「魔法の瞬間」はいつでしたか。
思い出せますか。
そろそろ次の 1 回が必要ではありませんか。
詳細 ― silly software の実例と、遊びから学ぶ 2 つの入り方
大きくてもいい
onemillioncheckboxes.com は、チェックボックスが 100 万個あるだけのサイトです。
チェック状態は全ユーザーでリアルタイム同期されます。
みんなで絵を描いたり全部埋めようとしたりする遊びが盛り上がり、バズって Wikipedia のページまでできました。
小さくてもいい
ただの「雲」。
画面に雲が 1 つ浮かんでいるだけのアプリで、天気と大きさを変えられます。
「なぜ作るのか」ではなく、「なぜ作らないのか」が問いです。
役に立ってもいい
- ローイングマシンをゲームの Red Dead Redemption に接続し、川を渡るのが本物の運動になった例
- Laravel の Andrew 氏が、GitHub の issue が届くたびにレシートプリンタで印刷している例(やるべき作業が物理チケットになります)
- 郵便局に行かずに、実在の住所へ絵はがきを送れるサイト
遊びから学ぶ ― 2 つの入り方
登壇者は MT 車の運転を、几帳面な父(元 Top Gun パイロット、乗車のたびに手順チェックリストを実行する)から教わりましたが、うまくいきませんでした。
代わりに教えてくれたのはゲーム好きの兄で、運転を「ゲーム」にした瞬間に噛み合ったそうです。
入り方 ① アイデアから始める
登壇者が Instagram で「ネットスラングでプログラミングする」ネタ動画を見て、「これ、自分なら作れるのでは」と思ったのが発端。
最初はミニ言語とコンパイラを自作しようとしましたが、2 分ググって難しすぎると判断しました(ネタへのコミットにも限度があります)。
そこで、JavaScript の変換ツールである Babel を拡張する方向に切り替えます。
できたのが Babel プラグイン glowup-vibes です。
こう書けるようになります。
throw new Errorの代わりにyeet an Lconsole.logの代わりにconsole.is low-keyfalseの代わりにcap
結果は Instagram で 300 万再生、GitHub 992 スター、99 件の Pull Request。
「株主価値を毀損し始めた」時点でこの寄り道をやめていたら、Babel プラグインのことは何も知らないままでした。
楽しんだ結果として、npm パッケージの公開方法まで身につきました。
入り方 ② ツールから始める
登壇者は、「史上最悪の動画プレイヤーを作る」コンペに参加しました。
狙いは一石二鳥 ― 楽しいコンペに出ることと、業務では使う機会のなかった WebSocket を学ぶことです。
WebSocket の「双方向のリアルタイム通信」とは、誰かの操作が接続中の全員に及ぶということ。
一人の行動に全員が巻き込まれる ― この構図で思い浮かぶのが、学校の嫌なグループ課題です。
仕様はこうです。
- 誰かが一時停止したら、全員が一時停止する
- 誰かが公共の場で音量を最大にしたら、全員が最大音量で聴かされる
- 再生速度は、接続中の全ユーザーの経度の平均で決まる
- 音量は、欲しい音量に反比例した大きさの声で設定する(全員のために静かにしたければ、絶叫が必要です)
結果として、WebSocket は身につきました。
しかもその過程は、歯を抜くような苦行ではなく、ただ楽しい作業でした。
おまけにコンペで優勝してニューヨークへ飛び、初めての技術カンファレンスに参加。
そこで出会った人たちが連鎖反応となって、この登壇にもつながっています。
アプリは手料理になれる
作家 Robin Sloan の記事 "An app can be a home-cooked meal" より。
氏は家族専用の写真共有アプリを自作し、家族は何年も使い続けています。
スケールも、企業らしい語り口も、収益の最適化も不要です。
そしてこれを、「愛する人に料理をふるまうのと、まったく同じ意味で報われる」と表現しました。
プログラミングを「プロフェッショナルであれ、スケールしろ」という要求から解放すると、それはまったく別の活動になります。
家庭料理が業務用キッチンの調理とまるで別物であるのと同じように。
そして登壇者は、この比喩を拡張します。
アプリは手料理になれます。
そして、ポラロイド写真にもなれます。
すぐ撮れて、使い捨てで、友達への可愛い贈り物です。
AI ツールの普及で、この種の個人的なソフトウェアはますます作りやすくなりました。
1 週間使われて二度と触られなくても構いません。
締めが良かったです。
カンファレンスの後は、宿題を大量に渡されたような重いインスピレーションを持ち帰りがちです。
そうではなく、遊んでいいのだと感じてほしい。子どもの頃、外へ遊びに行く「最後の一回」があったと言われます。
そのときは、それが最後だとは気づきません。
私はそうさせるつもりはありません。
今日も、明日も、明後日も外へ遊びに行きます。
一緒に来てくれますか。
19. Laravel Community Update(Josh Cirre 氏 ほか)
一言でいうと、Laracon が成立しているのは、Laravel の周りに作られてきたコミュニティがあるからという報告です。
この 1 年の数字が、まとめて示されました。
項目 | 数 |
|---|---|
フレームワーク本体にマージされた PR | 1,776 件 |
その他の OSS リポジトリ・ドキュメントへの PR | 3,242 件 |
PR 合計 | 5,000 件超 |
フレームワーク本体に初めて貢献した人 | 270 人 |
ミートアップ・カンファレンス | 156 イベント |
開催国 | 27 か国 / 6 大陸 |
参加者 | 9,781 人 |
未開催は南極大陸だけだそうです。
全大陸制覇まであと 1 つ。
詳細 ― スターターキットと、Laravel Learn の方向転換
スターターキットには、昨年時点であった React / Vue / Livewire に加え、この 1 年で Svelte 版 が追加されました。
さらに数週間前には、パッケージスケルトンが登場しました。
リリース当日に、それで作ったパッケージを見せてくれた人がいたそうです。
Laravel Learn は、「Laravel をどう始めるか」を示す公式の学習サイトとして昨年発表されました。
PHP の基礎から入れるコース・Laravel の基礎コース・ブートキャンプが揃っています。
開発者ですらなかった人がゼロから学び、Laravel で作れるようになった実例が実際に出ている、とのことでした。
今後は Aaron Francis 氏が担当することが発表されました。
狙いは、一次コンテンツの陳列棚ではなくコミュニティのハブにすることです。
Laracasts のようなコースや、日々作られている動画・ブログ記事・ライブ配信を集約する。
初心者が必要な資料をすぐ見つけられ、より上級の内容にも辿り着ける場所にする、と。
そしてその理由は 1 つでした。
スターターキットの数も、PR の数も、ミートアップの数も強調する価値はあります。
しかし Laravel Learn のコンテンツをコミュニティ中心に切り替える理由は 1 つで、コミュニティなしには何も起こらないからです。
新規貢献者 270 人という数字と、「見かけたらありがとうと伝えてください」という一言が、このカンファレンスの空気をよく表していたと思います。
まとめ
## まとめ
19 本を見終えて、自分なりに行き着いた答えは以下になります。
作る速さは、もう差になりません。
差になるのは「何を作らないか」を決められるかと、作ったものを自分が理解しているかどうかです。
驚いたのは、これがまったく違う立場の登壇者から、繰り返し別の言葉で出てきたことでした。
- Mary Perry 氏 ―「複雑さに対する最も強力な武器の一つは、No と言うこと」
- Freek 氏 ―「AI は摩擦を感じない。だから人間がパターンを知っている必要がある」
- Matt Stauffer 氏 ―「理解の負債は、いつか必ず返済される」
- Kent C. Dodds 氏と Will King 氏 ―「最後まで残る技能は判断力である」「何が可能かだけでなく、何が良いかを見極める仕事が残る」
- Taylor 氏 ―「結局のところ、大事だったのはキーストロークではありませんでした」
同じことを、5 つの角度から言っている。
そう感じました。
一方で、Thorsten Ball 氏の「モデルは、私の言いたいことをどうやって知ることになっているのか?」という問いは、同じ結論を逆側から見たものでもありました。
どれだけ判断し、理解していても、伝えなければ存在しないのと同じです。
それは AI 相手でも、チーム相手でも、未来の自分相手でも変わりません。
明日から試すこと
自分用のチェックリストとして、具体的なものだけを残しておきます。
- failed_jobs にインデックスが入っているか確認する ― DB CPU の 75% を持っていかれている可能性があります(#12 Scaling Laravel)
- Queue のジョブに failed() があるか確認する ― 無ければ、失敗したジョブは消滅し、行だけが「実行中」のまま残ります(#11 Video Processing Pipeline)
- レート制限のかかるジョブを retryUntil に切り替える ― tries のままだと、一度も実行されないまま失敗しえます(#11 Video Processing Pipeline)
- php artisan dev に移行する ― 新メンバーがクローンしたら、1 コマンドで動く状態になります(#1 Laravel Updates)
- AGENTS.md をルートだけでなく、ディレクトリごとに撒く ― 「やり方」をプロンプトから追い出して、コードベースに置くためです(#15 Think Harder)
- スクリーンショットをもっと撮る(#15 Think Harder)
- くだらないものを 1 つ作る ― 心の中のたまごっちに餌をやるためです(#18 Whimsy-Driven Development)
最後になりましたが、全セッションを無料で公開してくださっている Laravel 公式チャンネルと、貴重な知見を惜しみなく共有してくださった登壇者の皆さまに心からの感謝を。
この記事はあくまで自分のメモです。
気になったセッションがあれば、ぜひ本編をご覧ください。