どうも、マイクです。おはようございます〜。
2025年12月16日、火曜日の朝7時になりました。今日も「zenncast」、元気にお届けしていきます。
この番組では、技術系ナレッジ共有サービス「Zenn」に投稿された記事の中から、いまトレンドになっている話題をピックアップして、ゆるっと、でも中身はしっかりめでご紹介していきます。
今日はお便りコーナーはお休みで、そのぶん記事紹介をじっくりめにいきたいと思います。
さて、本日ご紹介する記事は全部で5本です。エンジニアの方はもちろん、「最近AIとかスライド作り、気になってるんだよな〜」という方にも刺さる内容が多めなので、通勤・通学のお供に最後までお付き合いください。
まず1本目。「『状態』ではなく『変化(イベント)』を保存したい」という記事です。
これ、データモデリングとか履歴管理にちょっとでも関わったことがある方なら、「うわ、それそれ、それに悩んでた!」ってなるテーマだと思います。
普通、データベースには「現在の状態」を持たせますよね。ユーザーのステータスとか、注文の状態とか。で、「履歴も欲しいよね」となって、変更前スナップショットを取ったり、ステータス履歴テーブルを作ったり、テンポラルテーブルでValid Time持たせたり、Bi-temporalなんていう高度なモデルに手を出したりするわけです。
ところがこれが、運用し始めると「何が・なぜ・どう変わったか」が案外わからない。クエリも更新も、訂正も、どんどん複雑になっていく。「根本的な理由は、結果としての『状態』だけを保存してるからだよね」というのがこの記事の出発点です。
そこで出てくるのが Event Sourcing。起きた事実=イベントを不変で蓄積しておいて、「現在の状態」はイベントをリプレイして導出する、あるいはRead Modelとして別に投影しておく、という考え方ですね。履歴・監査・任意の時点への復元にはめちゃくちゃ強い。一方で、スナップショットをどこで切るか、Read Modelはどう設計するか、イベントスキーマのバージョンアップはどうするか、補償イベントや結果整合性をどう扱うか…といった、別種の難しさもちゃんと指摘されています。
Bi-temporalみたいなテンポラルモデルも、理論としては美しいけど運用はかなり重い。そのうえで、「履歴要件がほんとにキツいなら、Event Sourcingを真面目に検討する価値はあるよ。ただし、やり切る覚悟とトレードオフの理解は必須だよね」と締めているのが印象的でした。履歴や監査ログでモヤモヤしている方は、設計の前に一度読みたい記事ですね。
。。,。。,。。,。。,
続いて2本目。「NotebookLM のスライドを『編集できる資料』にするーGemini で YAML 化 → Google Slide 生成」という記事です。
NotebookLM、使ってる方も増えてきましたが、「一文メモからでもそれっぽいスライドPDFを出してくれる」のが便利な反面、「PDFだからフォントやレイアウト、ロゴがいじれない! 実務にはちょっとキツい…」という悩み、ありますよね。この記事は、そこをうまく回避するワークフローを提案しています。
流れとしては三段階。まず①NotebookLMで、白背景・ピクトグラム多め・プレゼンター用メモ付き、みたいな条件を指定して、とにかく構成のよくできた「たたき台PDF」を作る。ここではNotebookLMを「完成品メーカー」とは見なさず、「構成エンジン」と割り切るのがポイントです。
次に②そのPDFをGeminiに読み込ませて、「コンテナ要素は禁止」「テキストは全部取得して」「スライドごとの構造をYAMLで細かく書き出して」みたいなプロンプトを与えて、スライドの設計図となるYAMLを作ります。ここがちょっと職人技っぽくておもしろいところですね。
最後に③Geminiのcanvasツールから、そのYAMLを元にGoogle Slidesを自動生成。あとは社内テンプレを当てたり、フォントや色、ロゴ、図版を差し替えたりして「ちゃんとした社内資料」に仕上げる、という流れです。
要は、「ゼロから構成考えるのが一番しんどいんだよ問題」をNotebookLMに丸投げしつつ、「細かいデザインや社内ルールへの準拠」はSlides側でやり直す、いいとこ取りのワークフローですね。付録では、「ChatGPTが使えるともっと体験良くなるよ」とか、「NotebookLMも将来的には編集性が良くなるロードマップがあるらしいよ」といった話にも触れられていて、AI時代のスライド作成の“今”がよく分かる内容になっていました。
。。,。。,。。,。。,
3本目は「AgentOps入門 〜LLM時代の新たな運用パラダイム〜」という記事です。
ここ数ヶ月、「エージェント」「自律エージェント」みたいな言葉、ほんとによく目にするようになりましたが、実際に動かしてみると、「たまにすごい成果を出すけど、たまに謎の失敗をする」「コストや遅延のボトルネックがどこかよく分からない」といった、新しい種類の悩みが出てくるんですよね。
この記事で紹介されている「AgentOps」は、そのモヤモヤに対して、ちゃんと運用パラダイムとして整理しましょう、という話です。キーワードとして挙がっているのが、カスタマイズ、プロンプト管理、評価、フィードバック、モニタリング、トレーシング、ガードレールの7要素。これらを通じて、エージェントの「考えたこと」「実際に行動したこと」「どのツールをどう呼び出したか」を可視化し、制御していくイメージですね。
MLOpsやLLMOpsの枠組みだけだと、マルチステップ推論や複数ツール連携するエージェントの「旅の全体像」を追いきれない。そこで、評価駆動のデプロイ、ステージングを含む3段階パイプライン、本番でのObserve→Act→Evolveの継続サイクル、といった考え方が大事になるよ、と解説されています。
嬉しいのは、概念だけで終わらず、OSSの「agentops」ライブラリを使った具体例もあるところ。OpenAI Agents SDKベースのマルチエージェントシステムに、ほんの数行追加するだけで、どのエージェントが何をして、どこでコストを食って、どこが遅かったのかがトレースできるようになる、というデモが紹介されています。
最終的なメッセージは、「エージェントを本番運用するなら、とりあえず動いた!で満足しちゃダメで、観測・評価・ガードレール・CI/CDをかなり早い段階から整えよう」というもの。これからエージェントを本気で使っていきたいチームには、いいガイドラインになる記事だと思いました。
。。,。。,。。,。。,
4本目はモバイル界隈から。「Flutter 3.38の隠れた目玉機能『Hooks (Native Assets)』でネイティブ連携が変わる」という記事です。
Flutterって、UI作るには気持ちいいんだけど、「ちょっとだけネイティブAPI触りたい」となったとたん、FFIだのPlatform Channelsだの、iOSならCocoaPods、macOSやiOSでのSPM設定…と、一気に面倒度が上がる、という弱点がありましたよね。
そこで登場するのが、Flutter 3.38でデフォルト有効化された「Hooks(Native Assets)」という仕組み。Dartパッケージの中にネイティブコードを直接含めておいて、ビルド時にいい感じにコンパイル&リンクしてくれる、というものです。Dart 3.2で実験的に入って、3.10で安定化、そしてFlutter 3.38で標準、という流れだそうです。
メリットとしては、まずiOS/macOSでのPodやSPMの設定をかなり減らせること。それから、ネイティブの知識は要るけれど、「全体としての実装をDart側に寄せていける」ので、Flutter開発者にも動作が理解しやすくなること。さらに、Thread mergeの仕組みによって、FFI呼び出しをより同期的な感覚で扱いやすくなる、という点も挙げられています。
記事では、筆者の「platform_image_converter」という高速画像変換パッケージを例に、iOS/macOSではObjective-C+Hooks経由でImage I/Oを叩き、Androidではjni/jnigen経由でJava APIを使いながら、リソース解放やエラーハンドリングはDartのtry-finallyで包む、といった実践的な話が紹介されています。
対応しているSDKバージョンの都合で、これから徐々に普及していく段階ではあるものの、「小さなネイティブ連携ぐらいなら、アプリ側だけでサクッと完結できそうだな」と思わせてくれる内容です。Flutterの弱点だった「ネイティブAPIのとっつきにくさ」が、今後けっこう解消されていきそうで、Fluttererな方はチェックしておきたい記事ですね。
。。,。。,。。,。。,
そして最後、5本目。「Git Worktreeでブランチごとにデータベースも分離 —— Docker Volume スナップショットの活用」という記事です。
これは、AI Coding Agentも活用しながら、複数ブランチを並行開発しているチームにはかなり刺さる話だと思います。git worktreeを使えば、ブランチごとにディレクトリを分けて開発できるんですが、Docker Composeで共有しているDBボリュームまでは分かれてくれない。結果として、「あるブランチのマイグレーションやテストデータが、別ブランチのDBと干渉してカオスになる」という問題が出てくるわけですね。
この記事では、git worktreeとDocker Volumeのスナップショットを組み合わせて、「ブランチごとに独立したDB環境を持たせる」方法が紹介されています。手順としては、まず①git worktreeでブランチ専用ディレクトリを作る。次に②元のDBボリュームを、alpineコンテナ経由のcpコマンドで新しいボリュームに丸ごとコピーしてスナップショットを作る。最後に③各worktree直下にdocker-compose.override.ymlを置いて、ベースのdocker-compose.ymlのうち、volume名だけをブランチ専用の名前に差し替える、という流れです。
これらをスクリプトで自動化してしまえば、「worktree作成 → volume複製 → override生成」までをワンコマンドで済ませられて、ブランチを切り替えるときは、そのディレクトリにcdしてdocker compose up -dするだけ。DBの状態不整合や「マイグレーション戻すのめんどい問題」から解放されるうえに、「このブランチでちょっと実験的なデータ作ってみよう」とか、「マイグレーション込みでPRレビューしてみよう」といったことも、かなり気軽にできるようになります。
もちろん、ブランチ数が増えればそのぶんディスクは食いますが、不要になったworktreeとボリュームを消せばOK、という割り切りです。同じ考え方はMySQLに限らず、PostgreSQLやRedis、LocalStackなど、Docker Volumeを使う他のミドルウェアにも応用可能。ローカル開発体験をちょっとだけ贅沢に、でも確実に快適にしてくれる工夫として、真似しやすいアイデアだと思いました。
というわけで、今日のzenncastは、
・履歴要件とEvent Sourcingの話
・NotebookLM+Gemini+Slidesで作る「編集可能なスライド」ワークフロー
・LLMエージェント時代の運用パラダイム「AgentOps」
・Flutter 3.38のHooksで変わるネイティブ連携
・Git WorktreeとDocker VolumeスナップショットでブランチごとにDBを分離するテクニック
この5本を駆け足でご紹介しました。
気になる記事があった方は、ぜひ番組ショーノートから、元の記事もチェックしてみてください。設計の細かいところや、実際のコマンド、プロンプト例なんかは、やっぱり本文を読むのが一番です。
「このテーマもっと掘り下げてほしい」「こういう分野の記事も取り上げてほしい」といった番組の感想やリクエストも、どしどしお待ちしています。
それでは、今日も良い一日をお過ごしください。
お相手はマイクでした。また次回の「zenncast」でお会いしましょう。