どうも、おはようございます。マイクです。FMラジオ風テック番組「zenncast」、本日も始まりました。今日は2025年12月14日、日曜日の朝7時台。みなさん、いかがお過ごしでしょうか。これからこの時間は、Zennで話題になっているトレンド記事をわかりやすく、ゆるっと紹介していきたいと思います。
今日は全部で5本、テック好きにはたまらないラインナップをご用意しています。デザインパターンから、Goランタイムの新機能、日本の住所問題、数学で解くパズル、そしてエージェントワークフローまで、幅広く攻めていきますよ。
まず1本目。タイトルは「俺が一番好きなデザインパターン『Strategy Pattern』の話」。
この記事ね、「if文が増えてきて関数がキモくなってきたな〜」っていう、あの嫌〜な瞬間に効く話です。著者が一番好きなデザインパターンとして挙げているのが、このストラテジーパターン。ポイントは「アルゴリズムをオブジェクトとしてカプセル化して、実行時に差し替え可能にする」ところなんですね。
PyTorchを題材にしていて、モデル構築・学習・予測をひとつの大きなif-elseのかたまりで書いていくと、どんどん分岐が増えて、拡張もテストもつらくなるよね、というところからスタートします。そこで、各モデルの実装を担う「Strategy」と、それを使って実験を回す「Context」に役割を分離してあげる。そうすると、新しいモデルを足すときに既存コードをほとんどいじらなくてよくなったり、単体テストがしやすくなったり、設定ファイルとか引数で簡単に「今日はこの戦略で動かそう」って切り替えられるようになるんですね。
さらにおもしろいのが、Factoryパターンとの合わせ技。どの戦略を選ぶか、というロジックを別コンポーネントに追い出せるので、コードの見通しがぐっとよくなります。Template Methodとの比較もされていて、「継承より委譲を」という考え方から、Strategyの柔軟性を高く評価しているのが印象的でした。if-elseが増えてきて、関数がダルんと太ってきたなと感じたら、「これ、Strategyにできないかな?」と一度立ち止まってみよう、というメッセージの記事でした。
。。,,。。
続いて2本目。タイトルは「runtime/secret でGoのランタイムから秘匿情報を消す」。
Goを書いている方はちょっとワクッとする話題ですね。Go 1.26で入る予定の新パッケージ、runtime/secret の紹介記事です。キーワードは secret.Do と secret.Enabled。この secret.Do って何をしてくれるかというと、その中で実行される関数のあいだに使われたレジスタとかスタックの中身を、実行が終わったタイミングで消してくれるんです。で、ヒープ上のデータも、GCで「もう到達できないね」と判断されたら消してくれる。つまり、パスワードみたいな秘匿情報がコアダンプから抜かれにくくなる、という仕組みですね。
ただし万能ではなくて、対応環境はLinuxのamd64とarm64だけ、とか、グローバル変数は対象外、ゴルーチンを新しく起動しちゃうとそこまでは守れない、などの制約があります。記事では実験として、普通のパスワード入力プログラムだとcoreファイルから入力値が見えちゃうけど、secret.Doで囲んであげるとスタック上のパスワードは見えなくなる、という検証をしています。さらに、panicを起こしてみたり、runtime.Goexitを呼んでみたり、mapを使ったりと、いじわるケースもいろいろ試していて、外部メモリを直接触るような特殊なことをしない限り、スタック上の秘匿情報はちゃんと消えてくれるだろう、という結論。
一方で、ヒープ上のデータはこの仕組みの外側なので、そこはGC任せになるよ、という注意喚起もあります。パスワード周りをGoで扱うとき、「どこまでやれば十分か?」という観点の参考にもなる記事でした。
。。,,。。
3本目に行きましょう。タイトルは「緯度経度からの住所検索!〜日本の住所に絶望し、希望を見つけるまで〜」。
これは日本の住所と格闘したエンジニアの、汗と涙の物語です。やりたいことはシンプルで、「地図をドーンと埋め込むほどじゃないけど、緯度経度からパッと見て場所が分かる表示をしたい」。そこで、「丁目レベルくらいの住所を表示して、詳しく見たい人はGoogle Mapsに飛べるようにしよう」という方針を立てます。
逆ジオコーディングのAPIはいろいろありますが、日本の住所って、市区町村の境界や丁目・番地の扱いがとにかく複雑で、APIによって出てくる階層も精度もバラバラ。OpenCageを使っても、正解データと完全一致するのは約84%にとどまったそうです。「残り16%をどうするんだ問題」があるわけですね。
そこで著者が取ったのが、「そもそも正解データとして使っていた国土地理院の位置参照情報を、自前で全部取り込んじゃおう」という大胆な作戦。街区レベルで約2000万件のデータを自社DBに入れて、空間インデックスを使って最寄りの住所を探す仕組みに変えました。さらに、Geohashをキーにしたキャッシュをかませることで、レスポンスも高速化。
結果として、精度・コスト・運用のしやすさ、全部の面で外部API利用よりいい構成になった、というお話です。「日本の住所に絶望し」とタイトルにあるとおり、最初は外部APIだけではどうにもならないギャップに苦しんだんですが、「正解ソースをそのまま持ってくる」という発想で、一気に希望にたどり着いた、というのが気持ちいいですね。地理情報を扱うサービスを作っている人は、かなり刺さる内容だと思います。
。。,,。。
4本目。タイトルは「クロックパズルを単因子論で解く」。
これは数学好き、パズル好きにはたまらない一本です。複数の時計とボタンが連動して動く、いわゆる「クロックパズル」を、整数行列と単因子論、つまりスミス標準形を使って、ちゃんと理論立てて解いていこう、という内容です。
ここでの発想が面白くて、時計の状態を「Z/3Z × Z/4Z × Z/5Z」の元として表現します。モジュロ3とか4とか5の世界ですね。ボタンを押す操作は Z³ の加法として表し、それが時計の状態に、ある行列Aを通した線形変換として作用する、というふうにモデル化します。最終的にやりたいのは、「全部0、つまり揃った状態にできるか?」なので、これは「ある線形方程式系が解けるかどうか」の問題に帰着される。
ここで出てくるのがスミス標準形です。整数行列の基本変形を積み重ねることでスミス標準形が必ず存在する、という事実を、きちんと構成的に証明しつつ、その計算をHaskellで実装していきます。vector-sizedという型レベルでサイズを持つベクタのライブラリと、Stateモナドを組み合わせて、安全に行列操作をしていくあたりも、実装として読みどころです。
最終的には、拡張した行列 \~A のスミス標準形 S と、それに対応するユニモジュラ行列 U,V を求めて、単因子がすべて1であることを確認。つまり、どんな初期状態からでも解が存在するよ、という結論になります。具体的な例では、「ボタンaを2回、cを1回押せばOK」といった解が導かれる。さらに、大規模な行列だと途中で係数が爆発するので、Kannan–Bachemみたいな高速アルゴリズムの研究もされているんだよ、という話にも触れています。
身近なパズルをきっかけに、抽象代数の世界にスッと入っていける、すごくいい入門記事になっていました。
。。,,。。
そしてラスト5本目。タイトルは「🐸 なぜ今、Agentic Workflowなのか - Graflowの設計思想」。
LLMを使った自律エージェント、いわゆるSuperAgentが流行ってきている一方で、本番運用をちゃんと考えると、「全部を完全自律に任せるのは怖いよね」という現実的な悩みが出てきます。この記事では、その中間解として「Agentic Workflow」という考え方を推していて、その設計思想にもとづいて作られた新しいオーケストレーションエンジン「Graflow」を紹介しています。
タイプとしては、完全自律なType Cではなく、構造化されたフローの上に局所的な自律性を持たせるType Bが現実的、というスタンス。Graflowは、でっかいSuperAgentの中身は「Fatノード」として扱って、そこは外部のフレームワーク(たとえばGoogle ADKとか)に委ねてしまう。その代わり、タスク間の連携や分散実行、人間の承認を挟むHITL(Human in the Loop)といった、ワークフローとしての部分に特化しているのが特徴です。
LangGraphとの比較も面白くて、LangGraphみたいにあらかじめ条件分岐やループをガチッと定義するのではなく、タスクの中から `next_task` や `next_iteration` を返すことで、実行時に動的にフローを制御できるようになっている。これによって、長時間走り続ける処理にも向いた設計になっていて、ユーザーが明示的にcheckpointを切って、そこからresumeできる仕組みもあります。
さらに、HITLとcheckpointを組み合わせて「人が承認したら先に進む」みたいなフローを作れたり、Redisベースの分散ワーカーで水平スケールができたり、Pythonの演算子をうまく使ったDSLでワークフローを定義できたりと、プロダクション運用をきっちり意識した機能が揃っています。Dockerハンドラーでコンテナをまたいだ実行ができるとか、型安全なチャンネル共有とか、並列グループごとのエラーポリシー、LangFuseやOpenTelemetryとの連携によるトレーシングなどなど。
LangGraphが「SuperAgentもワークフローも丸ごとフルスタックでやる」方向性なのに対して、Graflowは「ワークフロー専門で、SuperAgentは外部に任せる」という責務分離を掲げているのが面白いところです。2025年1月にOSSとして公開予定とのことで、来月ですね。エージェント系の実運用を考えている人は、要チェックのプロジェクトになりそうです。
というわけで、今日の「zenncast」は5本立てでお届けしました。
ざっとおさらいすると、まずはif-else地獄を救ってくれる「Strategy Pattern」の魅力について、次にGo 1.26の新パッケージ runtime/secretで秘匿情報をどう守るか。3本目では、日本のややこしい住所に絶望しつつ、国土地理院データを自前で持つことで希望をつかんだ逆ジオコーディングの話。4本目はクロックパズルをきっかけに、スミス標準形と単因子論でパズルを解き明かす数学のお話。そして最後は、完全自律ではない現実的な「Agentic Workflow」とGraflowの設計思想を紹介しました。
気になった記事があれば、詳しい内容へのリンクは番組のショーノートにまとめてありますので、そちらからぜひ実際の記事を読んでみてください。
「zenncast」では、番組の感想や「こういうテーマ取り上げてほしい!」といったリクエストも大歓迎です。ラジオネームを添えて、気軽に送ってください。
それでは、そろそろお別れの時間です。日曜日の朝、最後までお付き合いありがとうございました。次回の「zenncast」でまたお会いしましょう。お相手はマイクでした。ではでは、良い一日をお過ごしください。