どうも、マイクです。おはようございます。
七月二十七日、月曜日の朝七時を回りました。ここからの時間は「zenncast」、今日もZennで話題になっているトレンド記事を、ゆるっと楽しく紹介していきます。
今日はお便り紹介はお休みで、そのぶんガッツリと記事を掘り下げていきますよ。
きょうご紹介する記事は、ぜんぶで五本です。AIのプロンプト設計、フロントエンドの監視、Reactの新機能、Astroで作るバイリンガルブログ、そしてAIコードレビューと、かなり盛りだくさんのラインナップになっています。
それじゃあさっそく、一つ目からいきましょう。
まず一つ目は、Claude Code で「Opus ファイブ」に切り替えたときに、説明がなんだかフラットな長文になってしまう問題について深掘りしている記事です。
具体的には、「原因を深掘りしない」「評価軸も付かない」「思考が浅く見える」といった変化が起きて、「あれ?ルール壊れた?」と感じてしまうような挙動になっていたそうなんですね。
で、ここで面白いのが、これは「rules が壊れた」という話ではなくて、「Claude ファイブ世代で、Opus ファイブに配られている system prompt 自体が大きく変わっていた」という指摘なんです。
新しい世代では、これまで入っていた「書き方の細かい指示」がほぼ削られてしまっていて、その代わりに「十分な情報があれば、まず動け」といった、行動寄りの方針が強めに入っていた。
その結果、「考えを丁寧に言語化する」というより「とりあえず手を動かしてしまう」ような出力になっていたんじゃないか、というわけですね。
筆者のとった対策も具体的で、まず本体のプロンプトの原文をちゃんと読み直した上で、その中で名指しされている部分を上書きするような形で、「こちらを優先してください」と書き換えていきます。
禁止事項をずらずら並べるのではなく、「こう動いてほしい」という望ましい振る舞いを、できるだけ具体的に書くように修正していった。
さらに、rules を置く場所も工夫していて、モデルの行動の直前に、毎回短く差し込まれる「hook」を使うことで、「返答せずに勝手に作業だけ始めてしまう」という癖を抑え込んでいます。
ここから筆者が学んだのは、「モデルのアップデートは、実質的には system prompt のアップデートでもある」ということ。
つまり、挙動が変わったときは、手元の rules だけを見直すんじゃなくて、「そもそも本体側で、どんな指示文が新しく配られているのか」を読み返す必要があるんですよね。
結論としては、「変えたい行動の、まさにその直前に届く、短くて毎回効く指示が、一番よく効く」というところに落ち着いていて、プロンプト設計をやっている人にはかなり刺さる内容になっています。
。。。。
二つ目は、観測とモニタリングの話です。
OpenTelemetry をバックエンドだけじゃなくて、フロントエンド、つまりブラウザ側にも広げていこうという動きが進んでいて、いま「ブラウザ専用の SDK」が独立プロジェクトとして開発されているという記事です。
この Browser SDK を使うと、ユーザーのクリック操作だったり、ブラウザのエラー、Core Web Vitals、それから Navigation Timing みたいな、ブラウザならではのデータを、標準的な形式で集められるようになりつつあります。
実際の動き方としては、クリックやエラーを「ログレコード」として、Fetch などの通信処理を「スパン」として収集して、Grafana、Loki、Tempo といったツールと組み合わせることで、一貫した監視を試せる段階まできているんですね。
ただし、Sentry とか Datadog みたいな、いわゆる RUM、リアルユーザーモニタリングの SDK を、いきなり全部置き換えられるかというと、まだそこまではいっていない。
たとえば、ソースマップを使って JavaScript のエラーのスタックトレースを人間が読める形に復元する処理を、「どこで」「どうやって」やるのか。
あるいは rrweb ベースの Session Replay、画面の再生機能ですね。これを標準仕様のなかでどう扱うのか、といった大きな論点がまだ残っている、と。
なので筆者は、「いまは一気に全面移行するというよりも、動向を追いながら『どのテレメトリが標準化されていくのか』を見極めていく段階」と整理しています。
既存の RUM を使っているチームにとっては、「ログとトレースの世界標準」に、ブラウザの情報もどう乗せていくか、これからの選択肢を考える材料になりそうな記事です。
。。。。
三つ目は、React ナインティーンで入った新機能、「useActionState」というフックのお話です。
名前だけ見ると「非同期版 useReducer かな?」と思いがちなんですが、筆者は「本質はそこじゃない」と言っていて、キーワードは、ユーザーの操作をブロックしない UX を、簡単に実装できるところだと説明しています。
useActionState は、ユーザーが起こしたアクションを、自動でキューに入れて、順番に処理してくれます。
これによって、サーバーへのポストのように「実行順序が大事な副作用」がある場面でも、「ボタンを無効化しなくても、連打をちゃんと安全に扱える」というのがポイントなんですね。
記事ではショッピングカートの例が出てきます。
「Add to cart」ボタンをユーザーが何度押しても、内部では API 呼び出しが一列に並べられて、順番に処理されていきます。
フロント側の見た目としては useOptimistic を使って、「押した瞬間にカートが増えたように見せる」楽観的更新をしているので、ユーザーからすると「すぐ反応してくれた」という体験になります。
さらに「Order Now」、注文ボタンも同じキューに乗るので、「商品を追加中 → 最後に注文」という順序が必ず守られます。
これによって、「途中でボタンを押せないようにしておかないと、変な順序で処理されてしまうかも」という不安から解放されるわけですね。
ユーザーは、操作自体は止められないまま、裏側では安全に処理が完了していく。
筆者は、こうした「非同期処理のキューイング」と「楽観的更新」を React が標準機能として提供してくれたことで、開発者は「処理中だからボタンを無効化する」といった発想から離れやすくなる、と指摘しています。
待ち時間そのものは同じでも、体感としてのストレスが小さい UI を作りやすくなる。
そして、こうした Async React の仕組みを理解しておくと、「仕様の判断そのものも変わってくる」ので、押さえておく価値がある機能ですよ、というまとめになっていました。
。。。。
四つ目は、Astro で日英バイリンガルの技術ブログを作った経験から、「多言語対応や移植を含む静的ブログ実装の、具体的な五つのパターン」を整理している記事です。
フロントエンド寄りの人には、実践的なノウハウがぎゅっと詰まっています。
まず、多言語対応のところでは、Astro の Content Collections を使って、Markdown のフロントマターに型を付けています。
そこに `lang` とか `pair` といったフィールドを持たせることで、「この記事は日本語版」「こっちが英語版」「この二つがペアですよ」といった情報を扱えるようにしている。
おもしろいのは、これを i18n ライブラリなしで実現している点で、サイト内の言語切り替えやペア記事へのリンクを、自前の仕組みでうまく回しているんですね。
次に、Zenn や Dev.to みたいな既存プラットフォームから記事を移す話。
ここでは、「独自記法を行単位で変換するパイプライン」を用意していて、コードブロックは変換対象から外すなど、壊れやすいところをちゃんと守る工夫をしています。
さらに、「このブロックはサイト専用」「こっちは Dev.to 専用」といったコンテンツは、HTML コメントでマークしておいて、取り込みのタイミングで出し分ける、というテクニックも紹介されています。
OGP 画像の生成もこだわっていて、satori と resvg を使ってビルド時に自動生成しています。
その際、Google Fonts のサブセット機能と、あえて古いユーザーエージェントを指定するテクニックを組み合わせることで、「必要な文字だけを含んだ軽いフォント」を一度だけ取得するようにして、ビルド時間やフォント周りのトラブルを抑えています。
生成した画像は、Astro の静的エンドポイントから PNG として配信する構成になっています。
ダークモードの設計も丁寧で、Tailwind のカラートークンを、CSS のカスタムプロパティ単位で再定義していきます。
これによって、`bg-white` みたいな既存クラスを書き換えずに、ライトとダークの切り替えができるようになっている。
いわゆる「白フラッシュ」を防ぐための即時スクリプトを入れたり、WCAG のコントラスト比をチェックしたりして、アクセシビリティも意識した実装になっています。
どうしてもテーマを固定したい要素に関しては、別クラスで元の色に戻す設計にしていて、そのあたりの割り切り方も参考になります。
最後に、Astro の「アイランドアーキテクチャ」について。
基本の発想は「まず全部静的 HTML にして、どうしても必要なところだけ JavaScript を足す」というもので、その結果、多くの UI は素の JavaScript で十分になっていて、React などの島自体はほとんど不要になったそうです。
具体例としては、メニューのフォーカストラップには `inert` 属性を使ったり、Mermaid は IntersectionObserver と動的インポートで必要なときだけ読み込んだり、Web フォントは `media="print"` トリックで非同期に読み込んだり。
「ビルド時にできることはビルド時に片付ける」「クライアントサイドの JavaScript を、限りなくゼロに近づける」というポリシーが、全体を通して一貫しているのが印象的な記事でした。
。。。。
そして五つ目、最後の記事は、自社のコードレビュー履歴をもとに、「自分たちらしい指摘を返してくれる AI コードレビュアーをどう作るか」という、サービス紹介寄りの内容です。
一般的な AI コードレビューって、「業界全体のベストプラクティス」には強いんですけど、各社ごとのクセまでは拾いきれないんですよね。
たとえば、会社ごとの命名の習慣だったり、「このレベルの問題からはブロッカーにする」といった暗黙の基準。
そういう「文化っぽいもの」は、汎用モデルにそのまま任せると、どうしても漏れてしまいます。
そこで著者は、なんと七年分のプルリクエストのコメントを、GitHub の API から収集してきて、それを AI で分析します。
その結果をもとに、「自分たちのチームでは、こういうところをよく指摘しているよね」という傾向を抽出して、「レビュー規約」の Markdown にまとめていきます。
この規約を参照しながら動く、複数の AI エージェントを用意していて、たとえば「バグスキャン担当」「規約チェック担当」「過去 PR との突き合わせ担当」といった役割に分けて、一本の PR をレビューする仕組みを作った、というわけですね。
こうすることで、誤検知が少なくて、しかも設計や影響範囲まで踏み込んだ、広いカバレッジの指摘ができるようになったと。
さらに、CodeRabbit のような汎用ツールと組み合わせることで、人間のレビュアーは「ビジネスの判断」や「設計の大きな方向性」といった、人間にしかできない部分に集中できるようになる、というメリットが語られています。
一方で、この仕組みには前提条件や注意点もあって、まず「そもそものレビュー履歴の質が高いこと」が大前提になります。
雑なレビューコメントばかりだと、そのまま AI にも反映されてしまう。
それから、AI レビュアーはトークンコストもそれなりに高いですし、レビュー規約自体も、プロジェクトの変化に合わせて継続的にメンテナンスしていく必要がある、と。
なので、「導入して終わり」ではなく、チーム運営の一部として育てていくツールなんだ、というスタンスが示されていました。
。。。。
ということで、きょうの zenncast は、全部で五本の記事をご紹介しました。
ざっとおさらいすると、まず一つ目は、Claude Opus ファイブで system prompt が変わったことによる挙動の変化と、「変えたい行動の直前に短く効く指示を置く」のが大事だよ、というプロンプト設計の話。
二つ目は、OpenTelemetry の Browser SDK で、クリックや Core Web Vitals などブラウザ特有のデータを標準的に集めつつも、まだ RUM の全面置き換えには課題があるよ、というフロントエンド監視の話。
三つ目は、React ナインティーンの useActionState が、「ボタンを無効化しなくても安全に連打を受け付けられる」、非同期キューイングと楽観的更新によるストレスの少ない UI の話。
四つ目は、Astro で日英バイリンガルブログを作りながら、多言語対応、記事移植、OGP 生成、ダークモード、アイランドアーキテクチャまで、「クライアント JS を限りなくゼロに近づける」サイト設計の話。
そして最後は、自社の PR コメントを七年分解析して、「自分たちらしい指摘」ができる AI コードレビュアーを育てる仕組みについてのお話でした。
気になった記事があれば、詳しい内容や元の記事へのリンクは、この番組のショーノートにまとめてありますので、そちらもあわせてチェックしてみてください。
番組の感想や、「こんなテーマも取り上げてほしい」といったリクエストも、いつでも募集中です。あなたの現場での工夫なんかも、ぜひ教えてください。
それでは、きょうはこのへんで。
お相手はマイクでした。また次回の zenncast でお会いしましょう。いってらっしゃい。