どうも、マイクです。おはようございます。
七月二十日、月曜日の朝七時を回りました。
ここからの時間は「zenncast」、きょうもZennで話題になっているトレンドの記事を、ゆったり紹介していきます。
きょうは全部で五本の記事をご紹介していきます。
AIエージェントの話から、おうちラボ、関数型プログラミングのお祭りレポート、文章設計の工夫、そしてTypeScript/JavaScript向けの新しいリンターのお話まで、なかなか盛りだくさんでお届けしていきますね。
それでは、さっそく一本目からいきましょう。
一本目は、AIエージェント開発の「ループの次はグラフだ」と言われている流れに、ちょっと待ったをかけている記事です。
最近よく、「エージェントはループで回すだけじゃなくて、もっとリッチにグラフ構造でオーケストレーションしよう」っていう話、聞きますよね。ただ、筆者は「グラフ」とひとことで言っても、実は二種類あって、そこをごちゃっとまとめて話すと論点がずれるよ、という整理をしているんです。
ひとつは「オーケストレーショングラフ」。これは、処理の流れをノードと矢印で表して、「次にどのツールを呼ぶか」「どの分岐に進むか」といった、ワークフローとしてのグラフです。
もうひとつが「コンテキストグラフ」。こっちは知識同士のつながりを表して、どの情報をどうまとめてLLMに渡すかを整理するためのグラフ。ナレッジグラフに近いイメージですね。
この二つを、どっちもただ「グラフ」と呼んでしまうと、「処理の流れの話」と「コンテキストの構造化の話」がごっちゃになって、議論がかみ合わなくなる、と指摘しています。
さらに筆者が強調しているのが、「ループかグラフか」という配線の話よりも、実際の品質を決めているのは、各分岐点での判定ロジックだ、という点です。
つまり、ノードごとに「先に進むのか」「やり直すのか」「ここで止めるのか」を決める判断の精度ですね。
どれだけ複雑でかっこいいグラフを組んでも、その判定が甘いと、「間違った方向に、ものすごいスピードで突っ走るだけの仕組み」になってしまう。ここが本質だと。
そこで筆者は、「次に重要になるのは配線ではなく、判定そのものの工学だ」と考えていて、これを仮に「ジャッジメント・エンジニアリング」と呼んでいます。
ジャッジメント・エンジニアリングって何かというと、大きく二つの要素に分けていて、ひとつは、誤った判定をあとから振り返って学習に反映していく「自己改善ループ」。
もうひとつが、「どこでどんな誤判定をしたか」という情報を蓄えていく「メモリの設計」です。
具体例として、たとえばコードレビューでの失敗事例のログをちゃんと貯めておいて、そのログをAIコードレビューのプロンプトに読み込ませる、という実践案が紹介されています。
つまり、「このパターンのときに、前はこういうレビューをして失敗したよ」という知見を、AIに前もって渡しておくことで、判定ロジックをだんだん高めていく。
ループとかグラフの形を議論するだけじゃなくて、「どうやって判断の精度を高め続けるか」という工学的な設計が、次の論点になってくるんじゃないか、という提案でした。....
つづいて二本目。
こちらはガラッと変わって、「おうちラボ」を十年間続けてきた筆者による、その構成と管理方法の変遷をまとめた、ノウハウたっぷりの記事です。
自宅にサーバー置いて、いろんなOSSを動かして遊んでいる方、気になっている方には、かなり刺さる内容だと思います。
まず最初に整えると良い基盤として挙げられているのが四つ。
独自ドメインの取得、それからCertbotによるTLS証明書、UnboundやCoreDNSなどのDNS、そしてNginxもしくはTraefikのリバースプロキシです。
このあたりをきちんと整えておくことで、新しいサービスを追加するときも、名前解決とHTTPS対応を共通の仕組みで一括管理できるようになる、と説明しています。
「サービスを増やすたびに設定がカオスになっていく」問題を、最初の基盤設計でかなり防げる、という話ですね。
コアインフラとしては、TraefikとKeepalivedの組み合わせ、それからCoreDNS、Certbotを二重化して、高可用な土台を作っています。
その上で、Jupyter、Docmost、MattermostといったさまざまなOSSを自由に試す、というスタイル。
土台をしっかり冗長化しておくことで、「上で遊ぶサービスはいくら壊してもいい」という安心感を作っているのが印象的です。
バージョン管理の面では、当初は重厚なGitLabを使っていたのを、もっと軽量なGiteaに移行。
バックアップも、以前は別のやり方だったのを、今はGPGで暗号化してクラウドに置く方式に変えたそうです。
「自宅のラボなんだけど、ちゃんとセキュリティとバックアップも考える」という、大人のおうちラボ感がありますね。
管理方法の変遷もおもしろくて、最初は「サーバごとに手動でドキュメントを書く」というところから始まり、
次の段階で「サービスごとにリポジトリを分けて、docker composeで管理する」スタイルに発展し、
さらにそこから、「Proxmox上の仮想マシンを、TerraformとAnsibleで一括管理する」という、よりインフラ構成管理寄りのアプローチに進化しています。
十年やっていると、ちゃんとインフラエンジニアリングの歴史をなぞるんだな、という感じですね。
さらに最近は、ローカルLLM用に大容量メモリマシンを導入。
llama.cppとllama-serverを使って複数モデルを切り替えながら、自作のCLIツール、Open WebUI、Hermes Agentなど、いろんなフロントエンドから利用できる環境を構築しています。
家の中で、かなり本格的なAI実験場ができあがっているイメージです。
今後の展望としては、物理サーバをもう少し整理したり、Kubernetesの再構築を進めたり。
さらに、ローカルLLMにGitOpsの管理やkubectlの操作をさせてみる、といった実験もしてみたいと書かれています。
最後は、「AIで情報はすごく得やすくなったけれど、実際に壊しながら試せるおうちラボこそ、学習を深める場になる」と締めくくっていて、手を動かすことの大事さを思い出させてくれる記事でした。....
三本目は、「関数型まつり二〇二六」に二日間参加した筆者による、イベントレポートです。
関数型プログラミングのお祭りですね。そこで印象に残った講演やテーマを振り返っています。
取り上げられているトピックとしては、LLM時代の型システムのあり方、unsafeの位置づけ、代数的エフェクト、Leanによる形式検証、テンソルの形状検査など、本当に多岐にわたっています。
共通しているのは、理論だけで終わらず、「現実のソフトウェア開発やパフォーマンスとどう折り合いをつけるか」という観点で語られている点です。
とくに繰り返し出てきたのが、RustやHaskellにおける「unsafeや型システムを使って、安全かつ高速なAPIをつくる」ことの重要性。
完全に純粋で安全な世界だけを守るのではなく、危険な領域もちゃんと認識したうえで、「ここからここまではunsafeだけど、こう切り分けるから外からは安全に見えるよ」という設計ですね。
型システムをちゃんと活かすことで、性能を犠牲にせずに安全性を担保する、という話が熱く語られていたようです。
代数的エフェクトについても、「依存性注入の決定版として捉え直す」という視点が紹介されていました。
たとえば、ログ出力やIOなどの「効果」を型レベルで扱うことで、「どこで何が起きるか」を明示しつつ、テストや差し替えもやりやすくする、というアプローチですね。
関数型の文脈で、「DIどうする問題」に別解を示してくれる考え方になっていました。
LLMと人間の役割分担をどう設計に織り込むか、というテーマもいくつかの発表で登場したそうです。
「ここまではLLMに書かせて、ここから先は型で保証する」「証明の一部をLLMに手伝わせる」など、
自動生成と型検査、形式検証をどう組み合わせるか、といった話ですね。
ほかにも、型で「不正な状態を表現できなくする」設計パターンの実例、
Leanのような証明支援系を使って、競技プログラミング用ライブラリを証明駆動で検証する試み、
純粋関数的な物理エンジン、FRPによるリアクティブプログラミングなど、理論寄りの話と実務寄りの話がかなり近い距離で語られていた点が、筆者には印象的だったようです。
記事の最後では、こうした議論の場としての「関数型まつり」が今後も続いてほしい、という期待とともに、
「来年はLinear Haskellを前面に出した登壇を狙いたい」と意気込みを語って締めくくっています。
聞いているだけで、来年ちょっと参加してみたくなるレポートでした。....
四本目は、設計や調査の文書をAI、ここでは「codex」に書かせたときに起きがちな問題と、その対策をまとめた記事です。
テーマは一言でいうと、「対象がはっきりしないまま造語だけが先に立ってしまうと、設計全体がブレブレになる」という話です。
具体例として挙げられているのが、「圧縮時点」という言葉。
ある場面では条件を指していて、別のところでは値になっていたり、さらに別のところでは出来事のタイミングを指していたりして、文書全体で意味が行ったり来たりしてしまう。
また、「観測を一つに集める」といった、ふわっとしたラベルをつけたせいで、本来は別々に扱うべき手順ぜんぶが、その一語の中に押し込められてしまった、という事例も紹介されています。
こうなると、読む側も書く側も、「この言葉、結局なにを指しているんだっけ?」という状態になってしまうわけですね。
じゃあ、「変な独自語」をリストにしてブラックリスト化しておけばいいかというと、それもあまり効かない。
なぜかというと、次のセッションではまた新しい造語が生まれてしまうからです。
そこで筆者が取ったアプローチが、「semantic-generation」というskillを作って、文書を書く前にやる作業を決めてしまう、というものです。
このskillでは、本文よりも先に、対応表を必ず作らせます。
対応表には、「出典」「目的」「具体的な対象」「役割」「前後関係」「初めて出てくるときの定義」「候補語」といった列を持たせます。
ポイントは、「語」そのものではなく、「何を指していて、どんな役割を持つ概念なのか」を先に固定すること。
さらに工夫として、候補語の列を一番右端に置いて、具体的な対象と役割を書き終えるまでは空欄にしておくルールにしています。
これによって、「まず名前から考えてしまう」ことが物理的にできなくなる。
まずは、「何を扱っているのか」「条件なのか、状態なのか、事象なのか、値なのか」をテーブルにきっちり書かせるわけですね。
もしひとつの言葉で、条件と状態と事象と値、みたいに異なる役割をひとまとめにしたくなった場合は、行を分けさせる。
こうすることで、「実は対象が複数ある」という事実を可視化できます。
この「referent-before-label」、つまり「ラベルより先に、何を指すかを決める」というルールを徹底することで、
設計資料、原因の切り分け、命名作業などでは、まず対応表を独立したファイルとして作って保存してから、はじめて本文を書く、という手順にしています。
新しい用語を導入するときも、「エックスとは〜を指す」という初出定義を書けない限り、その用語は採用しない。
こうすることで、「AIに書かせた文書特有の、カッコいい造語は増えるけど意味が揺れ続ける問題」に、かなり実務的に対処している、という内容でした。....
最後、五本目はImportLintというツールの紹介記事です。
これはTypeScriptとJavaScript向けの、「importだけをチェックする」高速なリンターのコマンドラインツール。
もともとESLintプラグインとして存在していたeslint-plugin-import-accessを、Rustで作り直したものになります。
特徴として大きいのは、ESLint本体やTypeScriptの型情報に依存していない点です。
代わりに、oxcとoxc-resolverという仕組みを使うことで、以前のESLint版と同等の機能を保ちながら、パフォーマンスは百倍以上速く動く、というのが売りになっています。
「importまわりだけを、とにかく爆速でチェックしたい」というニーズに振り切ったツールですね。
このツールがやっているのは、プロジェクトの中に「パッケージ」という境界を導入して、その境界をまたぐimportをしっかり制御することです。
たとえば、アスタリスク・パッケージ・ディレクトリ、「何々ドットpackage」といったディレクトリを、ひとつのパッケージとみなします。
その内側のファイルは、外から直接importすることはできません。
外部に公開したいものは、`index.ts`経由でexportするか、`アットマークpublic`のようなアノテーションをつけて公開する、というルールにします。
これによって、ディレクトリ構成に沿った依存関係を強制できるようになり、「どこからどこまでを外部に見せるか」を、コードベース全体で統一的に管理できるようになります。
設定としては、`packageDirectory`という項目に、「どんな名前のディレクトリをパッケージとみなすか」という命名ルール、メタな設定を書きます。
実際にどのディレクトリをパッケージにするかは、開発者がディレクトリ名をどうつけるかで自由に決められる仕組みです。
ツール側はあくまで、「この名前規則のディレクトリは全部パッケージ扱いね」と解釈してくれるわけですね。
導入面でも、npmから簡単にインストールできますし、Visual Studio Code向けの拡張機能や言語サーバープロトコル対応も用意されています。
今後は、importまわりのルールをさらに拡張していく構想もあるとのことで、大規模なTypeScript/JavaScriptプロジェクトで、「モジュール境界をきちんと守りたい」チームには、かなり頼もしいツールになりそうです。
というわけで、きょうのzenncastは、
一つ目に、AIエージェント開発で、ループやグラフより「ジャッジメント・エンジニアリング」が大事だよという話。
二つ目に、十年続けたおうちラボのインフラ構成と管理の変遷。
三つ目に、関数型まつり二〇二六のレポートと、型システムやunsafeをめぐる議論。
四つ目に、AIに文書を書かせるときの造語問題と、「referent-before-label」でコントロールする手法。
そして最後に、TypeScript/JavaScriptのimportだけを爆速でチェックするImportLintのお話をお届けしました。
気になる記事があった方は、詳しい内容をショーノートにまとめてありますので、そちらから元の記事もぜひ読んでみてください。
番組への感想や、「こんな記事を取り上げてほしい」というリクエストも、どしどしお待ちしています。
それではきょうはこのへんで。
お相手はマイクでした。
また次回のzenncastでお会いしましょう。お聞きいただき、ありがとうございました。