おはようございます! マイクです。11月10日、火曜日、朝7時になりました。「zenncast」、今日も元気にお届けします!
この番組では、Zennで今日トレンドになっている記事をピックアップしてご紹介します。朝のひととき、気軽にお付き合いくださいね。
今日は、AIによるセキュリティ検査から、スマートフォンアプリの設計、複数のAIを動かす工夫、プロンプト管理、そしてデータベースの思わぬ落とし穴まで、5本の記事をご紹介します!
....
まず1本目は、OpenCode・Docker・GitHub Actionsを組み合わせて、AIによるコードレビューとセキュリティ検査を自動化するお話です。
こちらでは、PRごとのAIコードレビューに加えて、毎週、自動で攻撃を試すセキュリティ検査も実施しています。コードを読むだけでは見つけにくい、閲覧権限の不備なども、実際に動くアプリを対象に確かめる仕組みなんですね。
もちろん、試験するのは本番環境ではありません。GitHub Actionsの中で起動したアプリを対象にしています。外部サービスについても、OSSの模擬環境に置き換えることで、実際のサービスに影響が出ないようにしています。
AIの動きを抑える対策も、ひとつではありません。DockerでAIの通信先を制限し、APIキーも直接は渡さない。さらに、別のAIが実行コマンドを審査するという、複数の方法を組み合わせています。自動化するからこそ、実行環境と権限を丁寧に整えるわけですね。
費用面では、低コストのモデルを使い、全体の検査で約3ドルだった例もあるそうです。検査結果は非公開のIssueに集約して、誤検出ではないかを確認し、修正につなげ、次回の検査も改善していきます。
記事では、まずはPRレビューから始めることを勧めています。そして、Dockerで整えた開発環境を、セキュリティ検査にも活用する。いきなり全部を自動化するのではなく、足場を固めながら広げていく進め方ですね。
....
続いて2本目は、iOSとAndroidで「コードではなく、テストを共有する」というアプリ設計、Reflexのお話です。
Reflexは、ShopifyがReact NativeからSwift・Kotlinへ移行する中で生まれた設計です。両方のプラットフォームで同じコードを使うのではなく、iOSとAndroidはそれぞれ実装する。そのうえで、共通のテストを使って、同じ動作になるかを確かめるという考え方なんです。
筆者は、この設計を天気アプリで試しています。ポイントは、画面の表示から処理を切り離すこと。これによって、端末がなくても、共通の21本のテストを数百ミリ秒で実行できたそうです。変更のたびに素早く動作を確かめられるのは、うれしいですね。
さらに、動作中のアプリをコマンドで操作することもできます。雨や雪の画面、あるいは通信エラーの画面など、確認したい状態をすぐに表示できるわけです。実際の天気が変わるのを待たずに済むのも便利ですよね。
ただし、共通のテストですべてを確認できるわけではありません。画面の見た目や、端末の機能との連携は、別途確認が必要です。
何を共有して、何をそれぞれの実装に任せるか。「コードの共通化」だけではない選択肢として、参考になるお話です。
....
さて、3本目は、複数のAIに仕事を任せるときの、役割分担と運用の工夫です。
基本となるのは、人は「司令塔のAI」とだけ話す、という形です。複数の担当AIへの仕事の割り振りや進捗管理は、司令塔に任せます。ただし、司令塔自身は実作業をせず、担当AIからの報告をまとめる役に徹します。
担当AIには、範囲を絞った仕事を渡します。そして、担当AIがさらに別のAIを増やすことはさせません。仕事を分担しつつ、役割や管理の範囲が際限なく広がらないようにしているんですね。
通知の扱いにも工夫があります。司令塔は、担当AIからの報告と停止通知だけを待ちます。別の待機処理も動かしてしまうと、通知が重複して、不要な応答が増えてしまうためです。待ち方まで整理することが、落ち着いた運用につながるんですね。
また、作業の実行にはhc、状況の表示にはHerdr.appを使い、役割を分けています。表示する画面を再起動しても、AIの仕事そのものは続く構成です。
司令塔が交代するときには、進捗を引き継ぎメモに残します。作業ルールはClaude Codeのskillにまとめ、不足している情報はsession-grepを使って、過去の会話ログから探します。
AIを何体も動かすだけではなく、誰が指示を出し、何を待ち、どう引き継ぐかまで整える。チーム運営に通じるところがありますね。
....
続いて4本目は、LLMアプリのプロンプトを、どこで管理するかというお話です。
プロンプトをコードとは別に管理すると、変更を柔軟に扱えそうですよね。ただ、その一方で、コードとプロンプトの変更が別々に本番へ反映されると、両者が食い違って動かなくなるおそれがあります。
たとえば、アプリ側が期待する出力形式と、プロンプトが指示する出力形式が合わなくなる、といった問題です。
筆者は、開発者以外の人がプロンプトを編集する必要がなく、アプリの更新よりも速くプロンプトを変更したり、差し戻したりする必要もないなら、プロンプトはコードと一緒に管理すれば十分だと述べています。
専用の管理ツールを使うこと自体が目的ではなく、必要な運用に合っているかが大切、ということですね。
そして、管理ツールが必要になった場合も、何でもまとめて移すのではありません。まずは口調や回答方針などから移すことを勧めています。一方で、コードと同時に変える必要がある出力形式や、安全に関わる指示は、コード側に残します。
プロンプトの中でも、柔軟に変えたい部分と、アプリと一緒に守るべき部分を分けて考える。管理方法を選ぶときに、覚えておきたい視点ですね。
....
最後の5本目は、PostgreSQLで、SELECTだけでもマイグレーションが止まることがある、というお話です。
データを読むだけなら大丈夫、と思いがちですが、ここにはロックの落とし穴があります。SELECTが取得するACCESS SHAREロックは、トランザクションが終了するまで残ります。そして、このロックは、REINDEXなどが求めるACCESS EXCLUSIVEと競合するんです。
今回の原因は、SELECTを実行したあとに外部APIの応答を待ち、トランザクションが開いたまま放置されていたことでした。このロックは通常の読み書きとは競合しないため、普段の利用では問題が見えず、リリース時になって表面化したそうです。
根本的な対策は、外部APIを呼ぶ前にトランザクションを閉じること。そして、保存する処理は別にすることです。例外が起きた場合も、必ずロールバックするようにします。外部の応答待ちと、データベースのトランザクションを切り離すのが大事なんですね。
さらに、保険として、放置された接続を切断するidle_in_transaction_session_timeoutを設定します。記事では、これを3分に設定しています。
REINDEXにはCONCURRENTLYを付けることで、ほかの読み書きへの影響を抑えられます。ただし、それで放置されたトランザクション自体が解消されるわけではありません。
実行方法の工夫と、トランザクションの根本的な見直し。この両方を区別して対策することが重要ですね。
....
ということで、今日の「zenncast」は、5本の記事をご紹介しました。
AIによるコードレビューと安全なセキュリティ検査。コードではなくテストを共有するReflex。司令塔を中心にした複数AIの運用。コードとの関係を踏まえたプロンプト管理。そして、SELECTでも起こりうるPostgreSQLのロック問題でした。
詳しい内容はショーノートに書いてありますので、気になった記事は、ぜひチェックしてみてくださいね。
番組の感想もお待ちしています。「この話が参考になった」「こんなテーマも聞いてみたい」など、気軽にお寄せください。
この番組はSpotifyやApple Podcast、YouTubeなどで毎日配信しています。気に入っていただけたら、登録や高評価をつけてもらえるとうれしいです!
それでは、次回もお会いできるのを楽しみにしています。お相手はマイクでした。今日も、気持ちのいい1日をお過ごしください!