どうも、マイクです。おはようございます。
八月二十日、木曜日の朝七時を回りました。ここからの時間は「zenncast」、きょうも最新のテックトピックを、Zennのトレンド記事からピックアップしてお届けしていきます。
きょうはお便りのコーナーはお休みで、そのぶんしっかり記事を紹介していきますね。
取り上げる記事はぜんぶで五本。ローカルLLMの活用から、機密データとAIの付き合い方、デザインシステムとエージェントの連携、巨大フォントの自由研究、そしてAWSの新しいポリシー言語まで、かなりバラエティ豊かです。
まず一つ目。
テーマは「商用の大規模モデルに依存しすぎると怖いよね」という話から入っています。
仕事でクラウドの強いモデルにがっつり頼っていると、レート制限が急にきつくなったり、利用ポリシーが変わったりして、「ある日突然、仕事道具を取り上げられるかもしれない」という不安、ありますよね。この記事ではその問題意識を出発点にして、「ローカルLLMとクラウドLLMをどう組み合わせると、コスパと品質のバランスがいいのか?」をかなり実践的に検証しています。
題材になっているのは、タイプスクリプトでおよそ九万行ある既存のCLIツールに、機能追加をしていくタスクです。けっこう本格的な規模のコードベースですね。
そこで、いろいろな「編成」を試します。たとえば、ディープシークのようなローカルLLMを実装担当にして、ジェンマをコードレビュー役に置く。そして、一番強い商用モデルは、最小限の「判断役」、つまり要件整理とか方針決定のところだけに使う、という構成です。
これを、いわゆるフロンティアモデル、一番強いモデルにぜんぶ丸投げしてコードを書かせるパターンと比べています。結果としておもしろいのが、ローカルLLM実装役+ジェンマレビュアー+商用モデルは判断役だけ、というチーム編成が、単独でコードを書かせた最前線モデルよりも、品質が高くて、しかもコストも大幅に安くなる、というところなんですね。
もちろん、「全ロールを最強モデルで固める」いわゆる富豪構成も試しています。これは品質だけ見ると、わずかにこちらが勝つ。ただ、金銭コストも時間コストも桁違いに重くなってしまう。
筆者はここで、「コーディングって、テストで正解を検証できる領域だから、必ずしも一番強いモデルでゴリ押ししなくても、オーケストレーションとレビューの仕組みをちゃんと整えれば十分戦える」と整理しています。
ローカルLLM中心の構成にしておけば、コストを抑えながら、特定ベンダーのレート制限やポリシー変更に振り回されない、自律性も手に入る。そのバランス感覚がすごく参考になる記事でした。
。。,。。
続いて二つ目。
こちらは「AIに入れてはいけない顧客データや個人情報を、Claude Codeを使いながらどう安全に分析するか」という、かなり実務寄りのTips集です。
文章としてはオピニオンっぽさもあるんですが、中身はほとんどノウハウなので、Tips記事として紹介していきます。
まず大前提のアイデアは、「データ本体はAIに見せない」ということ。
どうするかというと、実データのスキーマ、つまり列名とか型と、統計的なサマリだけを見て、そこからダミーデータを作ります。で、AIにはそのダミーデータだけを渡して、「このダミーを前提に分析コードを書いてね」とお願いする。実データを使った実行は、人間がローカル環境でやる。こういう役割分担にするわけですね。
次に、機密データの置き場所をきっちり決めます。
たとえばホームディレクトリの下の「チルダスラッシュ datasets」のような一か所にぜんぶ集約して、さらに`.env`ファイルで「ダミーデータ用のパス」と「実データ用のパス」を切り替える。
ポイントは、「どこに機密データがあるか」を固定しておくことで、その場所だけまとめて遮断しやすくする、という設計です。
Claude Code側の守りとしては、`permissions.deny` を使って、「チルダスラッシュ datasets 以下」や「ピリオドクラウドのディレクトリ」への読み取りと編集を禁止します。さらに、`sandbox.filesystem.denyRead` を設定して、PythonやBash経由での読み取りもOSレベルで止める。
この二段構えにすることで、「Claude本体から直接読むルート」「Bash経由でこっそり読むルート」「IDE経由で触るルート」といった複数の漏洩経路をきちんと塞ぐようにしています。
さらにおもしろいのが、hooks機能の使い方です。
`PreToolUse`フックで、「`.env`がいま実データのパスを指していないか」とか、「ノートブックのファイルに実行結果が残っていないか」をチェックする処理を登録しておく。もし`.env`が実データを向いていたり、`.ipynb`に生の結果が残っていたりしたら、その時点でClaudeのBashやRead、Editの実行自体をブロックしてしまう。つまり、「うっかり設定ミス」を機械的に止める仕組みなんですね。
ジュピターノートブックも要注意ポイントとして扱われています。
セルの出力に実データがそのまま残るので、コミット前には`nbstripout`のようなツールで出力を自動削除する運用にする。そして、AIにノートブックを読ませるときも、「出力付きの`.ipynb`はフックでブロックする」みたいなルールにして守る。長期的には、`jupytext`を使って「`.py`ファイルを正として管理して、ノートブックは派生物」という運用もアリですよ、という提案もされています。
最後にもうひとつ、メタなガード。
hooksやsandboxの設定そのものが壊れていないかをチェックするスクリプトを用意して、それを`UserPromptSubmit`フック、つまりプロンプト送信時と、CIでも毎回実行するようにするんですね。
さらにCIでは、「機密ディレクトリにカナリアファイルを置いておいて、それを読ませようとして、本当に読めないか」をテストする。こうすることで、「ガードがちゃんと効いているか」を自動的に検証できる、と。
とにかく、「設定したつもり」で安心しないで、AIと機密データの間に何重ものフェンスを立てて、それが動いているかもテストする、という姿勢が徹底されている記事でした。
。。,。。
三つ目。
これはUIデザインとコーディングエージェントの間に起きがちな「なんか違うUIが出てきちゃう問題」を、MOSHというサービスではどう解消していっているか、という事例紹介です。
課題としては、デザインシステムの情報がFigmaやNotion、Storybookとバラバラに散らばっていると、エージェントが「どれを正とすればいいのか分からない」状態になって、「これじゃないUI」を生成してしまう、というところ。
そこでまずやっているのが、Storybookのコンポーネントに対して、FigmaとNotionのURLを紐づける、という整理です。こうしておくと、エージェントがStorybookから「正しい情報源」を自動でたどれるようになる。「このコンポーネントはこのFigma、この仕様はこのNotionにある」と機械にも分かるようにしてあげるわけですね。
さらに、その上に「Agent Skill」を三つ用意しています。
ひとつ目が、実装前の情報整理に使う `design-context`。
ふたつ目が、根拠を添えて指摘してくれる `design-review`。
そして三つ目が、デザイン判断の優先順位や考え方をまとめた `design-principles`。
この三つを通して、「どのコンポーネントを、どういう場面で、どう使うのが正しいか」を明文化して、エージェントが迷わないようにしています。
よく出てくる指摘については、人間のレビューに毎回頼るのではなくて、ESLintのカスタムルールとして落とし込む運用もしています。たとえば「このカラーコードは使っちゃダメ」とか「テキストスタイルの指定はこのパターンに合わせる」といったものを機械的に弾いて、色指定やタイポグラフィのばらつきを減らしているんですね。
レイアウトについては、さらに踏み込んでいて、一覧画面・詳細画面・フォーム画面など、「よくある画面」をテンプレートとしてあらかじめ用意しておきます。これをPlopというスキャフォルド系のツールで自動生成する仕組みにして、`add-route`コマンドひとつで、デザインレビューがほぼ要らないレベルの初期実装を出せるようにしている。
こうしておくと、エージェントがワンショットでガイドラインに準拠したUIを出しやすくなって、「コードがいつも正の状態で先行していく」けれど、ちゃんとデザインとも整合している、という状態に近づいていける。
UIとエージェントの間にある「モヤッとした溝」を、情報の紐づけとルール化でじわじわ埋めていく、そんな取り組みが紹介されていました。
。。,。。
四つ目の記事は、ちょっと毛色が変わった自由研究系です。
テーマは、「Google Fontsにある全フォントを、一つのTrueType Collectionファイルに全部まとめてみよう」というチャレンジ。TrueType Collection、略してTTCは、複数のフォントをひとつのファイルに詰め込める形式ですね。
PythonのfontToolsというライブラリを使って、素朴にフォントを結合していくと、Windows環境でいろいろ問題が見えてきます。
まず、一つでも不正なフォントが混ざっていると、そのTTC全体を丸ごと無効扱いにしてしまう、という挙動。さらに調べていくと、Windowsのフォント読み込みには「二ギビバイト」という独自のサイズ制限があることも分かってきます。
そこで筆者は、問題になっていたフォント、具体的にはWindowsで認識されない Gidugu-Regular というフォントに注目します。原因は、「一意なフォント識別子」、Name IDの三番が不足していたこと。これを自動で補完する処理を入れることで、TTC全体が正しく扱われるようにしていきます。
容量の問題に対しては、HarfBuzzのサブセット機能を使って、ヒンティングなど優先度の低い情報だけを削っていく、という工夫をしています。文字そのものは削らずに、メタデータ寄りの部分をそぎ落としていくイメージですね。
その結果として、Google Fontsにある三千七百九十三ファイルをすべてまとめた、およそ一点九三ギビバイトのTTCを作ることに成功します。サイズ的には、さっきの二ギビ制限ギリギリ手前ぐらい。で、これをWindows上で実際に開いてみると、およそ五秒で開いてインストールまでできる、というのも確認されています。
とはいえ、この巨大TTCを配布するかというと、そこは慎重です。
元のフォントごとにライセンスの条件が違っていて、「名称の変更が必要」とか「ライセンス文を同梱しなければいけない」といった要件を全部きちんと満たそうとすると、かなり複雑になる。しかも、「Google Fontsをそのまま全部まとめる」という今回のコンセプトともズレてしまう。
そんなわけで、生成物そのものの配布は見送っています。
結論としては、「三千七百九十三個ものフォントをひとつに固めても、普通のフォントとしてWindowsに認識させられた」というのが、技術的にはおもしろい成果。ただし、今後Google Fontsのフォント数がさらに増えていくと、二ギビ制限でそもそも成立しなくなってしまう可能性が高い。つまり、「いまだからギリギリ成り立つ巨大フォント」の実験だった、というわけですね。
。。,。。
そして五つ目。
最後は、エージェントのツール呼び出しを安全に制御するためのサービス紹介記事です。
キーワードは、AWSの新しいポリシー言語「Dogwood」。既存の認可言語であるCedarを拡張して、「誰が・何を・何に対して」という静的な条件だけじゃなくて、「過去にどんなイベントが起きたか」という履歴も含めて判定できるようにしたものです。
これによって何がうれしいかというと、「呼び出しの順序」や「回数」に依存するガードレールを、宣言的なポリシーとして書けるようになるんですね。
たとえば、「機密文書を読んだ後は、メール送信を禁止する」とか、「送金は一時間に五回までに制限する」とか、「ある操作は、承認から一時間以内だけ実行を許可する」といったルールです。こういうのって、これまではアプリケーションコード側でゴリゴリ書きがちでしたけど、それをポリシー言語として切り出せるようになる。
Rust製の参照実装にはCLIも用意されていて、ローカル環境でポリシーの検証や、トレースの再生なんかができます。これを使うと、「同じリクエスト内容でも、履歴が違うと判定が変わる」というDogwoodらしい挙動を確認できる。
DogwoodはCedarと互換性があって、`lower`という処理でCedarのポリシーに落とし込むこともできるので、既存の実行基盤をそのまま活かしながら、Amazon Bedrock AgentCore の temporal policies として本番環境で使える、というのもポイントです。
一方で、履歴を扱うぶん、システムとしてはステートフルになります。
その影響で、Cedarが持っていた形式検証ツール、いわゆる「ポリシーが矛盾してないか」とか「絶対に起きない状態がないか」をチェックする仕組みが、一部そのままでは使えない、というトレードオフもあります。
それでも、「エージェントが外部ツールをどう呼び出していいのか」を細かく制御したいときには、こういう時間や履歴ベースのポリシー言語がかなり強い武器になりそうだ、というのが記事のメッセージでした。
。。,。。
というわけで、きょうのzenncastはこのあたりでお時間です。
きょうは、ローカルLLMと商用モデルを組み合わせてコストと自律性を両立する話から始まって、Claude Codeで機密データを守るための多重ガードの設計、MOSHのデザインシステムとエージェントの橋渡しの工夫、Google Fontsを全部まとめた巨大TTCという自由研究、そしてAWSのDogwoodでエージェントのツール呼び出しに時間軸のガードをかける話まで、一気に駆け足でお届けしてきました。
気になった記事の詳しい内容やキーワードは、番組のショーノートにまとめておきますので、通勤・通学のあとでゆっくりチェックしてみてください。
zenncastでは、番組の感想や、「こんなテーマを取り上げてほしい」といったリクエストもいつでも募集中です。ちょっとした一言でも、技術的な濃い話でも大歓迎です。
それでは、きょうも良い一日をお過ごしください。お相手はマイクでした。
また次回のzenncastでお会いしましょう。