#
836
どうも、おはようございます。マイクです。
「zenncast」木曜の朝、いかがお過ごしでしょうか。
今日は二千二十六年九月三日、木曜日の朝七時台お届けしていきます。

この時間は、技術系メディア Zenn に上がっているトレンド記事をピックアップして、ラジオ感覚でざっくり内容がつかめるようにおしゃべりしていきます。通勤中や作業のおともに、耳だけでなんとなく追っかけてもらえればうれしいです。

今日はぜんぶで五本、ご紹介していきます。
ではさっそく、一つ目からいきましょう。

。。。。

一つ目は、「AI を使った開発で、理解を AI に丸投げしないためのワークフロー」を紹介している記事です。

最近、実装を生成 AI にほとんど任せちゃう、いわゆる「AI 駆動開発」みたいなやり方、だいぶ一般的になってきましたよね。ただこの記事の筆者は、そこで二つの負債が一気に溜まるのが危ない、と指摘しています。

一つは、コードの質が落ちていく「技術負債」。
もう一つは、コードや仕様を、人間がちゃんと理解できなくなっていく「理解負債」。

とくに後者の「理解負債」が強烈で、「まあ動いてるし、AI が書いたから大丈夫でしょ」と思っているうちに、仕様の意図とか、設計上の判断理由が、誰の頭にも入っていない状態になる。そうすると、あとから改修するときや、バグ調査をするときに、めちゃくちゃ苦労するよね、という話です。

そこで筆者が提案しているのが、七ステップのワークフローです。ざっくり流れを追うと、まず GitHub Issue を AI に「質問攻め」させて、要件の曖昧さを徹底的につぶします。ここで使っているのが `grill-with-docs` というツール。ドキュメントや Issue を材料に、「この仕様、ここがあいまいじゃない?」と AI にひたすら突っ込ませて、要件を掘り切る感じですね。

次に、要件が整理できたら、その内容をもとに AI に実装計画を書かせます。関数分割とか、ファイル構成とか、テスト方針まで含めた「設計書ラフ」を出してもらうイメージです。

そのあとがポイントで、その長大な実装計画をそのまま信用しない。`explain-visually` みたいな図解ツールを使って、図と短い文章の組み合わせに変換して、人間がパッと見て理解できる形にします。シーケンス図とかコンポーネント図っぽいものにして、「ここでこうデータが流れるのね」って、自分の言葉で説明できるレベルまで落とし込む。

さらに、その計画を別のモデルでレビューさせます。つまり、「計画を作った AI」と「計画をレビューする AI」を分けることで、変なバイアスや見落としを減らすわけですね。

そして最後に、そのレビューを通った「計画」だけを渡して、別セッションの AI に実装させる。ここがミソで、「要件理解」「設計レビュー」と「実装」という工程を、セッションごとにきれいに分離することで、人間側は常に仕様と設計を理解した状態をキープできる、という狙いです。

筆者は、とくに `grill-with-docs` による要件の曖昧さつぶしと、`explain-visually` による図と短文への変換、この二つが「理解負債」をためないための要だ、と強調しています。人間が自分の言葉で、「なぜこの設計なのか」「どんな前提があるのか」を説明できることを、とにかく大事にしよう、と。

もちろん、まだ試行錯誤中のプロトタイピング段階では、ここまで厳密にやらないこともあるそうなんですが、テストや設計方針が固まってきたプロジェクトでは、この「理解を AI に外注しないプロセス」が、最終的な品質にかなり効いてくる、とまとめています。

AI に書いてもらう量は増えていく一方だと思うので、「どこまで任せて、どこを人間が握るか」という具体的な型として、けっこう参考になりそうな内容でした。

。。。。

続いて二つ目は、「Claude Code をナレッジグラフで拡張する」という Tips 系の記事です。

Claude Code を使っている方はなんとなく実感あるかもしれないんですが、毎回ファイルを開いて読ませて……ってやっていると、トークン消費が重いし、依存関係の把握もけっこう不安定なんですよね。モデル側は毎回、読み込んだファイルから「このコードとあのコードの関係」を推測し直しているので、無駄が多い。

この記事では、その問題に対して、「コードや設計情報を、あらかじめ意味づけ付きのナレッジグラフとして構造化しておいて、Claude にはそのグラフだけを参照させる」というアプローチを紹介しています。そうすることで、「関係性の推測」をほぼ不要にしてしまう、と。

具体的には、四つのツールを組み合わせています。
一つ目が code-review-graph、
二つ目が better-code-review-graph、
三つ目が Graphify、
四つ目が Serena。

それぞれ役割が分かれていて、依存関係グラフを作るもの、意味検索を担当するもの、設計書との横断検索をやるもの、型情報つまり定義元や実装クラス、参照先をたどるもの、という感じで機能を分担させています。

さらにおもしろいのが、CLAUDE ドキュメント、いわゆる `CLAUDE.md` に「質問の種類ごとに、どのツールを使うのか」というルーティング表を書いてしまうこと。
たとえば、「依存関係を知りたい系の質問が来たら code-review-graph を使う」とか、「設計書をまたいで検索したいなら Serena を呼ぶ」とか、そういう対応表を人間が用意しておく。

すると、ユーザーはツール名をいちいち指定しなくても、日本語で「このトークンを検証する処理ってどこにありますか?」みたいに聞くだけで、裏側で最適なツールが自動的に選ばれて、必要なノードだけがグラフから引っ張られてくる、という仕組みになります。

実測の話も書かれていて、レビュー用にコード全文を読ませていたときには、コンテキストが最大十四万トークンくらいまで膨らんでいたところが、ナレッジグラフ経由にすると、毎回およそ七十トークンで安定したそうです。フルスキャンから、ピンポイント参照に変わったイメージですね。

しかも、日本語で「トークンを検証する処理」と聞いたとしても、`verifyToken` みたいな英語の関数名を意味ベースでちゃんとヒットさせられる。さらに、変更の影響範囲をグラフ経由でたどったり、トークン形式みたいに「コードじゃなくて設計書にしか書いてない仕様」も、横断検索で拾えるようになる、と。

セットアップ手順も記事ではかなり細かく書かれていて、
まず CLAUDE.md にルールを追記して、
次に `.mcp.json` に MCP サーバーとして各ツールを登録して、
各ツールをインストールしてグラフを構築して、
Serena と Graphify を設定して、
最後に Claude Code を一回再起動する、
といった流れになっています。

手順自体はちょっと手間なんですが、一度入れてしまえば、「ファイルを開いて読ませる」開発ではなくて、「質問した瞬間にグラフをたどって答えが返ってくる」開発環境に変えられる、とまとめていました。大規模リポジトリを日々いじっている人には、かなり効きそうなアプローチですね。

。。。。

三つ目は、Rust の新しい ORM ライブラリ「Toasty」を紹介している記事です。

Toasty は、Rust の構造体からアプリ側のデータモデルを定義して、そこから各データベース向けのスキーマやクエリを自動生成してくれるライブラリです。サポートしているのが、SQLite、PostgreSQL、MySQL といった一般的な SQL 系だけじゃなくて、DynamoDB も同じ API で扱える、というのが大きな特徴になっています。

中では、「データベースごとの差を吸収するクエリエンジン」が動いていて、アプリ側からは同じように CRUD を書いているだけでも、裏側では各 DB ごとに最適な実行計画を組み立ててくれる、という思想です。

基本的な CRUD 操作は、マクロとモデルメソッドでさらっと書けるようになっていて、テーブル間のリレーションやユニーク制約を定義しておくと、そこから便利メソッドも自動生成してくれるそうです。たとえば、「ユーザーからプロフィールをたどる」みたいな関連取得が、かなり楽に書けるイメージですね。

また DynamoDB のような NoSQL に関しては、もともとユニーク制約の概念が薄かったりするんですが、Toasty のほうで補助テーブルを自動作成して、ユニーク制約っぽい振る舞いをエミュレートしてくれます。つまり、NoSQL に足りない部分を、ライブラリ側でうまく補ってあげる感じです。

一方で、記事では「なんでも Toasty 一択」という話ではなくて、向き不向きもちゃんと触れています。特定のデータベースにガッツリ依存した高度なクエリが必要なケースとか、インデックスや実行計画を細かくチューニングしたい場合は、より薄い層のライブラリ、たとえば SQLx みたいなものを使ったほうがいい場面もある、と。

Toasty が刺さりそうなのは、シンプルな CRUD 中心で、あまり DB の違いを意識せずに Rust アプリを書きたい、というケース。たとえば、「最初は SQLite でいいけど、あとから PostgreSQL に変えたいかも」とか、「サービスによって DynamoDB と SQL を両方使い分けたい」みたいなときに、アプリ側の書き方をあまり変えずに運用できる、という方向性ですね。

プロジェクト自体はまだ若くて、これからどう育っていくかはこれからなんですが、Rust の ORM の新しい有力候補になり得る、と記事では評価されています。Rust でバックエンド書いてる方は、名前だけでも覚えておくと良さそうです。

。。。。

四つ目は、音声認識モデル Whisper が「無音なのに『ご視聴ありがとうございました』と言ってしまう」現象を、かなりガチで検証した記事です。

経験ある方もいるかもしれませんが、音声がほとんど入っていないところに Whisper をかけると、なぜか「ご視聴ありがとうございました」とか、「Thank you for watching.」って字幕が生えてくることがあるんですよね。この記事では、それを合成無音や雑音、環境音を使って体系的にテストしています。

まず分かったのが、モデルとして large-v3 を使い、日本語指定で非音声を入れると、ほぼ百パーセントの確率で「ご視聴ありがとうございました」というフレーズになる、ということ。言語を英語指定にすると、「Thank you for watching.」みたいな表現に変わるんですが、意味としてはどの言語でも「視聴への感謝」を伝える、同じパターンの定型句に落ち着く、という結果が出ていました。

なぜかというと、おそらく学習データに使われた Web 動画の字幕の影響が大きいだろう、と。動画の末尾って、無音になってるところに「ご視聴ありがとうございました」みたいなテロップだけ入っていること、多いですよね。その「動画末尾の無音」と「感謝の字幕」という組み合わせを大量に見て、モデルが学習してしまったんじゃないか、というわけです。

さらに、デコーダに言語モデルを持たない CTC 系の音声認識モデルで試してみると、こうした幻覚は一切起きない、という結果も紹介されています。なので問題の本質は、「音がないときに、デコーダ側の言語モデルが勝手に作文してしまうこと」にある、と示されています。

Whisper 自体にも無音抑制の仕組みがあるんですが、「ここは音声なし」と判断しつつも、「感謝の定型句が出る確率がめちゃくちゃ高い」とモデルが自信を持ってしまうために、そのフィルタをすり抜けやすい構造になっているそうです。パラメータを少しいじったくらいでは、なかなか消えてくれない、と。

対策として前段に入れる VAD、いわゆる音声区間検出は、完全な無音とか、一定の雑音を切り捨てるにはかなり有効です。ただ、記事でおもしろかったのが、咳や笑い声みたいな「人の気配のある音」は VAD が「これは音声だ」と誤認してしまいがちで、そこに対して Whisper が「じゃあ何かしゃべってるんだな」と解釈して、例の幻覚字幕を挿入しやすい、という点です。

なので結論としては、VAD だけに頼るのではなくて、「よく出てしまう定型句をフィルタする」仕組みとか、`no_speech_prob` という Whisper の出力に含まれる「音声がない確率」のスコアを単独で使うなど、複数の手を組み合わせた多段防御が現実的だろう、と。
実運用で字幕生成や文字起こしをしている人には、かなり実践的な示唆が多い記事になっていました。

。。。。

そして五つ目、最後は、複雑化した ECS のデプロイ基盤を、GitHub Actions と ecspresso に段階的に移行していった事例記事です。

もともとの構成は、CodePipeline、CodeBuild、CodeDeploy といった AWS のマネージドサービスに、独自のシェルスクリプトやテンプレートツールが組み合わさっていて、設定やロジックがあちこちに分散していたそうです。

その結果、「この変更を入れたら、最終的に ECS のタスク定義はどうなるのか」が事前にはなかなか分からない。全体像をちゃんと把握しているのは、ほぼ一人の SRE だけ、という、かなり危うい属人状態になっていた、と振り返っています。

そこでまずやったのが、ecspresso の導入です。jsonnet と組み合わせて、ECS の Service や Task Definition を「宣言的なコード」として管理できるようにしました。

さらに `ecspresso diff` を使うことで、Pull Request 上で見えている差分と、実際に AWS 上でどういう変更が起きるのか、そのギャップが小さくなります。レビュー時に、「この PR をマージしたら、タスク定義はこう変わりますよ」というのを、事前にしっかり確認しながら進められるようになったわけですね。これが一つの大きな安心ポイントになっています。

次のステップとして、実行基盤を GitHub Actions に移しました。ここでも、いきなり全部を置き換えるのではなくて、既存の CodeDeploy 自体は活かしたまま、ワークフローの起点や可視化の場所を GitHub に寄せる、という形で進めています。

その結果、開発者が普段から見慣れている GitHub 上で、デプロイの状況やログを追えるようになりました。「このブランチをマージしたら、こういう Actions が走って、最終的にこのサービスが更新される」という流れが、だいぶ分かりやすくなったわけですね。

記事のまとめとしては、設定の所在が明確になって、属人性や認知負荷がぐっと下がったことで、大きめの構成変更にも踏み出しやすいデプロイ基盤になった、としています。
「とりあえず動いているけど、誰も全容を説明できない CI/CD パイプライン」を抱えているチームには、かなり刺さる内容だと思います。

。。。。

ということで、今日は五本ご紹介しました。ざっとおさらいすると、
まず一つ目は、AI に実装を任せつつも、「理解負債」をためないための七ステップワークフローの話。
二つ目は、Claude Code をナレッジグラフで拡張して、トークン消費と依存関係のあいまいさを一気に解消する Tips。
三つ目は、Rust の新しい ORM、Toasty が、複数 DB を同じ API で扱える選択肢として伸びてきている、という紹介。
四つ目は、Whisper が無音から「ご視聴ありがとうございました」を幻覚する理由と、その検証・対策の話。
五つ目は、複雑な ECS デプロイ基盤を、ecspresso と GitHub Actions で段階的に整理していった事例、でした。

気になった記事があれば、詳しい内容はこの番組のショーノートにまとめておきますので、あとでゆっくりチェックしてみてください。

「zenncast」では、番組の感想や、「こんなテーマを取り上げてほしい」といったリクエストもお待ちしています。普段どんなふうに Zenn を活用しているか、なんて話もぜひ聞かせてください。

それでは、そろそろお時間です。
お相手はマイクでした。また次回お会いしましょう。お疲れさまでした。

Related episodes

内容の近いエピソードを推薦しています