どうも、マイクです。おはようございます。
七月十八日、土曜日の朝七時を回りました。今日も「zenncast」お付き合いよろしくお願いします。
この番組では、技術ブログサービス「Zenn」に載っている、いまホットな記事や、思わず人に話したくなるような知見を、ゆるっと紹介していきます。
今朝も最新のトレンド記事をピックアップしてきましたので、コーヒー片手に、耳だけ貸してもらえたらうれしいです。
さて、今日ご紹介する記事は、全部で五本です。
AIとの付き合い方から、データベースとAIエージェントの連携、新しいDockerツール、業務ツールを作るときの考え方、そして分散トレーシングのサンプリング手法まで、なかなか幅広いラインナップになっています。
それでは、さっそく一つ目からいきましょう。
。。。。
一つ目は、AIのアウトプットとの向き合い方についてのお話です。
内容としては、「AIの出してきた答えを、そのまま信じるのはかなり危ういですよ」ということを、かなり具体的に解説しています。
よく「最後にレビューしてね」とか「チェックしてね」とAIに頼んだりしますよね。でも、その“レビュー役のAI”も、けっこう甘くなりがちなんだ、という指摘なんです。
そこで筆者が勧めているのが、「どこか必ず間違っているはずだ」という前提で、あえて壊しにかかるようにチェックする、「敵対的検証」というスタイルです。
たとえばClaude Codeでは、この考え方が最初から標準機能として組み込まれていて、サブエージェントが別の視点・別のコンテキストでアウトプットを反証してくれるようになっています。
ただ文句をつけるだけじゃなくて、「これは正しい/怪しい」といった判定と、その根拠をセットで返してくれる仕組みになっているんですね。
ChatGPTみたいな、他のツールを使うときでも近いことができます。
具体的には、新しいセッションを開いて、元のやりとりは一切持ち込まずに、「成果物だけ」をペタっと貼るんです。そのうえで、
・自分は反証役であること
・一次情報をちゃんと取りにいって裏を取ること
・見つけた問題について、深刻度と根拠を付けて出すこと
こういう役割を明示的に指示してあげることで、「敵対的検証」に近いチェックをしてもらえる、という使い方が紹介されています。
とはいえ、この敵対的検証にも弱点があると。
たとえば、もともと健全な成果物に対しても、何かしらムリにケチをつけてしまいがちだったり、逆に、見逃して甘く合格判定してしまうこともある。
それから、チェック用のプロンプトをまるごと回すので、トークンコストもそれなりに重くなります。
なので筆者は、「AIの指摘自体を“正解”として扱うんじゃなくて、それを材料にして、最終的な採否は人間が判断してはじめて意味があるんだ」と、かなり強調しています。
AIにレビューさせて安心するのではなく、「AIが見つけた論点リスト」を人間がどう料理するか、そこまで含めて設計する必要がある、というメッセージでした。
。。。。
続いて二つ目は、SQL MCP Server という仕組みのお話です。
これは Data API Builder というツールの一機能として提供されていて、SQL Server や Cosmos DB といった、すでにあるデータベースを、AIエージェントから直接扱えるようにするサービスになっています。
面白いのが、「どんな操作をAIに許可するか」がかなり細かく設計されているところで、標準で七種類のデータベース操作ツールを自動公開できるんですね。
レコードの参照・追加・更新・削除、それから集計や、ストアドプロシージャの実行など、業務でよく使う操作がひと通りそろっているイメージです。
ただ、「AIに削除させる」とか、ちょっと怖いじゃないですか。
そこで登場するのが、設定ファイルの dab-config.json です。この設定ファイルで、どのツールを公開するかを制御できるので、「参照だけ許可にする」とか、「更新はストアドプロシージャ経由のものだけ許す」といった、安全寄りの構成がとりやすくなっています。
特に、トランザクションを含んだストアドプロシージャを「カスタムツール」として公開しておいて、AIにはそのカスタムツールだけを呼ばせる、というやり方が現実的だろう、と記事では述べられています。
つまり、ビジネスロジックや整合性、権限制御といった大事なところは、今まで通りデータベース側のストアドにしっかり閉じ込めておいて、AIエージェントはあくまで、それを呼び出す役にとどめる。
こうすることで、安全かつ一貫した形でデータベースを更新させられるんじゃないか、という提案ですね。
「AIエージェントにデータベースを触らせたいけど、直に自由に書き込まれるのは怖い」というチームにとっては、かなり現実的な落としどころを示してくれている記事になっていました。
。。。。
三つ目は、新しい Docker CLI プラグイン、「docker-vals」を紹介している記事です。
これは、コンテナに渡すシークレット管理を、かなりスマートにしてくれるツールです。
何ができるかというと、compose.yaml の中に「どのシークレットを、どこから取ってくるのか」だけを書いておけば、あとは `docker compose up` を一発叩くだけで、AWS Systems Manager のパラメータストアや、ワンパスワード、Vault などから値を取得して、コンテナの環境変数に自動で注入してくれるんです。
ポイントは、Docker Compose の「Provider Services」という仕組みを使っているところで、このプラグイン自体はコンテナの中ではなく、ホスト側で動くようになっています。
そのおかげで、手元のマシンで、すでにログイン済みになっている AWS SSO とか、ワンパスワードのCLIの認証状態を、そのまま利用できるんですね。
わざわざコンテナ内で認証をやり直したり、秘密情報をベタ書きしたりする必要がない、というのがかなりうれしい点です。
記事の中では、もともと Docker Compose の仕様として、環境変数名にサービス名の接頭辞が必ず付いてしまう、という問題があったことも説明されています。
これを解決するために、筆者が Docker Compose 本体に対して、`rawsetenv` という新しいメッセージを提案して、自ら実装までしたそうです。
この機能によって、好きな名前のまま環境変数をコンテナに渡せるようになった、と。
そのうえで、既存のツールである vals を Go のライブラリとして組み込んだ、比較的薄いプラグインとして docker-vals を実装し、MITライセンスで公開しています。
「気軽に使ってもらえるように」とか、「本体へのコントリビュートをうまく活かしながら、現場の運用を楽にする」といった、エコシステムへの向き合い方も感じられる内容でした。
。。。。
四つ目は、業務で使うちょっとしたツールを作るとき、Pythonスクリプトで十分なのか、それともElectronで画面付きのアプリにしたほうがいいのか、という判断軸を整理してくれている記事です。
筆者はまず、「単純なCSVやExcelなどのローカルファイルを扱う処理で、入出力のパターンもほぼ決まっている。使う人も少人数」という前提なら、まずはPythonスクリプトで小さく作るほうが向いていると述べています。
ログ出力やエラー内容の記録さえきちんと入れておけば、画面がなくても十分に業務を楽にできる、という考え方ですね。
一方で、「毎回条件を変えながら実行したい」とか、「複数人が日常的に触るツールにしたい」、「履歴やエラーを画面で確認したい」といったニーズがある場合は、Electron で画面付きのツールにした方が運用しやすい、という整理になっています。
ただし、Electron はアプリ自体のサイズが大きくなりがちですし、配布と更新の手間もそれなりに増えます。
なので、「画面をつけることで、本当に利用者の迷いが減るのか?」をちゃんと見極めてから選ぼう、と注意を促しています。
なんとなく“いい感じのUIをつけたい”という気持ちだけでElectronに行くと、後々メンテがつらくなる、という話ですね。
さらに記事では、もう一歩踏み込んでいて、ツール設計の初期段階で決めておくべきことが、いろいろ挙げられています。
例えば、出力ファイルを上書きしていいのかどうか、出力先のフォルダ構成をどうするのか、文字コードは何にするのか、ネットワークの共有フォルダをどう扱うのか、配布と更新はどんなフローにするのか、といったあたりです。
そのうえで、「最初から何でもできる汎用ツールを目指さないこと」と、「エラーや失敗したファイルを必ずどこかに記録しておくこと」が、現場ではすごく役立つ、とまとめています。
派手な技術選定よりも、「誰が、どこで、どうやって使うのか」を細かく想像して設計することが大事なんだな、と思わせてくれる記事でした。
。。。。
最後、五つ目は、分散トレーシングにおけるサンプリングの話題です。
ちょっと専門的ですが、「Consistent Probability Sampling」、略して CPS という仕組みを紹介しています。
背景として、分散トレーシングの世界では、サービスごとに別々にサンプリングをしてしまうと、いろいろ困ったことが起きます。
具体的には、トレースが途中で欠けてしまったり、最終的にどれくらいの割合でサンプルされているのかが分からなくなってしまう。
その結果、原因調査にも、統計的な集計にも、どちらにも信頼がおけない、という問題が出てくるんですね。
従来よく使われてきた TraceIdRatioBased というタイプのサンプラーは、この「多段のサンプリング」に対応しきれなくて、ルートスパン以外では安全ではなかった、と記事では説明されています。
そこで登場するのが、Consistent Probability Sampling です。
CPSでは、各トレースに対して、一つの五十六ビットの乱数、`rv` という値を割り当てます。
そして、各サービス、各段階でやることはシンプルで、「このサービスが設定している保持確率から閾値 `th` を計算して、その `th` と、さっきの `rv` を比較する」だけです。
全ての段階が同じ `rv` を使うことで、「低い確率で残す集合が、高い確率で残す集合の完全な部分集合になる」という性質が保証されます。
これによって、トレースがバラバラに欠けにくくなり、最終的な保持確率も、「一番きつい、つまり最大の `th`」だけで表せるようになります。
この `th` と、必要に応じて `rv` 自体は、W3C Trace Context の `tracestate` ヘッダーの中に、十六進数の形で記録されます。
バックエンド側では、この最終的な `th` から「重み」、いわゆる adjusted_count を計算することで、「この種類の障害は、システム全体では何件起きていたはずか」といった、量的な問いにもちゃんと答えられるようになります。
ただし注意点もあって、CPS はパイプラインのどこかで、まったく独立した乱数サンプリングを紛れ込ませると、途端に破綻してしまいます。
なので、SDK、コレクター、バックエンドといった経路全体を通して、CPS に揃えて導入していく必要がある、という点が強調されています。
CPS が入ることで、「乱数と閾値という共通の物差し」が標準化されて、サンプリング後のトレースを重み付きで正しく集計するための前提条件は整ったと言えます。
あとは、各種のバックエンドやクエリエンジンが、この `th` の情報をどこまで活用していくか、そこが普及の鍵になりそうだ、という締めくくりでした。
。。。。
ということで、きょうの「zenncast」、駆け足でおさらいしておきます。
まず一つ目は、「AIのアウトプットをそのまま信じず、『どこか間違っているはず』という前提で壊しにかかる、敵対的検証が大事だよ」という話。
二つ目は、SQL MCP Server を使って、既存のデータベースをAIエージェントから安全に操作する仕組みと、ストアドプロシージャ経由で更新させる構成が現実的だよ、という話。
三つ目は、docker-vals というDockerプラグインで、AWSやワンパスワードなどからシークレットを自動注入できるようにした工夫と、そのためにDocker Compose本体に機能追加までした、という話。
四つ目は、業務ツールを作るときに、「まずはPythonで小さく」「画面が本当に必要な場合だけElectron」と考えることと、ファイルの扱い方やエラー記録を最初にちゃんと決めておく重要性の話。
そして最後、五つ目は、Consistent Probability Sampling という新しいサンプリング手法で、分散トレーシングのトレース欠け問題を抑えつつ、重み付き集計を正しくやろうとしている、というお話でした。
それぞれの詳しい内容や図解、設定例なんかは、番組のショーノートに元記事へのリンクとあわせてまとめておきますので、気になるトピックがあった方は、ぜひそちらもチェックしてみてください。
この「zenncast」では、番組の感想や、「こんなテーマを取り上げてほしい」といったリクエストもお待ちしています。
現場でこんなふうに使っているよ、こういうところが気になったよ、という一言でも、とても励みになります。
それでは、きょうはこのあたりでお別れです。
お相手はマイクでした。次回の「zenncast」でまたお会いしましょう。
よい一日をお過ごしください。