どうも、マイクです。おはようございます。
八月二十四日、月曜日の朝七時を回りました。今日も「zenncast」始めていきましょう。

この番組では、技術ブログサービス Zenn に上がっているトレンドの記事を、ラジオ感覚でゆるっと、でも内容はがっつりめにご紹介していきます。通勤中のあなたも、これから一日がんばるぞ〜というあなたも、耳だけ貸してもらえたらうれしいです。

今日はお便りはお休みということで、そのぶん記事紹介をじっくりめにいきたいと思います。

きょうご紹介する記事は、ぜんぶで五本です。
アーキテクチャの話から、プロトコル、Go のテスト、デスクトップ操作の自動化、それから家庭内AIエージェント運用まで、かなりバラエティ豊かです。それぞれ、できるだけ噛み砕いてお話ししていきますね。

まず一本目。
テーマは「レイヤードアーキテクチャにおけるリポジトリの責務、どこまで持たせるべきか?」というお話です。

記事では、アプリケーションをレイヤーで分けて設計するときに出てきがちな「リポジトリ、どこまでやらせる問題」を扱っています。
結論としては、リポジトリは「データベースとの出し入れだけを行い、ビジネスロジックは一切書かない役割に徹するべきだ」と、かなりはっきり言っています。

たとえば「ユーザーが存在するかどうかのチェック」とか「注文の存在確認」、あるいは「エンティティをどういう内容で作るか、どう更新するか」「エラーを投げるかどうか」みたいな判断は、全部ユースケース側に集約する。
そのうえでリポジトリは、「渡されたエンティティを保存・取得するだけ」の超シンプルな役割にしておくのが望ましい、と説明しているんですね。

よくあるのが、ユースケースごとに `updateBasicInfo` だとか、`updateStatusOnly` だとか、細かい更新メソッドをどんどんリポジトリに増やしちゃうパターン。
記事では、そういうのはやめて、ユースケース側で値をちゃんと組み立てたうえで、リポジトリは `update` を一本どーんと用意しておく。リポジトリは「何をどう更新するか」は考えず、「渡されたものをそのまま保存する」だけにすることを推奨しています。

さらに、戻り値で安易に boolean を返してリポジトリ側でロジックを持たせない、という話も出てきます。
「存在していたら true、なかったら false」みたいな判定をリポジトリにやらせ始めると、ビジネスロジックがじわじわとデータ層に侵食していって、あとから変更しづらくなったりしますよね。
ただし例外として、「存在確認だけが目的で、効率的にもそれがいちばん合理的な場合」に限っては、一件だけ取得して boolean に変換して返す、みたいなパターンは許容されるよ、という現実的な落としどころも示しています。

こうした責務分離をしっかりやっておくことで、コードの保守性や拡張性がぐっと上がる、というのが記事の結論です。
「最近リポジトリが太ってきたなあ」というチームには、かなり刺さる内容じゃないでしょうか。

。。。。

続いて二本目。
こちらはネットワークとRPCの世界、「HTTP/1.1 と HTTP/2、それから gRPC、gRPC-Web、Connect をどう捉えるか」というお話です。

まず HTTP 一点一で昔から言われている問題として、
ひとつのコネクションでリクエストを直列に処理するから待ち行列が発生しやすい、
それから、リクエストのたびにヘッダーを全部送りなおすので無駄が多い、
さらに、サーバー側から能動的に送りつける手段がなくて、真の意味での双方向通信がしにくい、
こうした弱点があると整理しています。

これに対して HTTP 二では、フレームの多重化とヘッダー圧縮、それからストリームの双方向性によって、こういった問題をプロトコルレベルで解決しているんですね。
この上にRPCを載せたのが gRPC で、`proto` ファイルでスキーマを定義してコード生成することで、型安全なスキーマ駆動開発を実現する、というメリットがあります。

ただしこの gRPC、ステータスコードをHTTPの「トレーラー」に載せるという設計を取っているために、ブラウザの `fetch` API からは素の gRPC を扱えない、という制約が出てきます。
そこで登場するのが gRPC-Web。
これは、ステータス情報をレスポンスボディの末尾に特殊なフレームとして埋め込む方式を取ることで、HTTP一点一の世界でも動かせるようにしています。
ただしその代償として、専用のプロキシが必須になったり、バイナリ形式ゆえにデバッグしづらかったり、双方向ストリーミングが十分に扱えない、といった弱点もある。

そこでさらに出てくるのが、Buf 社が作った Connect という仕組みです。
ひとつの実装で、gRPC、gRPC-Web、そして独自の Connect protocol を話せるようにしてあって、Connect protocol の場合はトレーラーを使わずに、普通のHTTPステータスと、JSON の終端メッセージで成否を返す、というスタイルを取ります。
その結果、ブラウザからは「普通のHTTP」として扱えるのに、裏では proto によるスキーマ駆動の利点をちゃんと維持できる、というアプローチになっているわけですね。

記事では最終的に、「バックエンド同士の通信は gRPC と Protobuf を前提としつつ、フロントエンドとの通信では、
スキーマ駆動をどれくらい重視するか、
フロント側もRPCベースの考え方を受け入れられるか、
プロキシ運用やデバッグ性をどう評価するか、
こういった軸で OpenAPI/REST、gRPC-Web、Connect、GraphQL などを選んでいくべき」とまとめています。
単に「どれが流行ってるか」じゃなくて、チーム事情とトレードオフで選ぼう、という内容でした。

。。。。

三本目は Go のお話。
タイトルとしては、「Go 一点二七で入った `httptest.NewTestServer` を使うと、APIクライアントのテストがめちゃくちゃ楽になるよ」という内容です。

これまで Go で HTTPクライアントのテストを書くときは、`httptest.NewServer` を使うのが定番でしたが、その場合、本番用のベースURLを書き換えるために、ちょっとした裏技のような仕組みが必要でした。
たとえば `export_test.go` を使ってテスト専用の変数を露出させたり、`var` にしておいてテストのときだけ上書きしたり、といったやり方ですね。
その結果、「本番ではこのURLを使うはずなのに、テスト時だけ別のURLに差し替えている」状態になってしまって、URL自体が本当に正しいのかはテストできない、というモヤモヤがありました。

Go 一点二七で追加された `httptest.NewTestServer` は、このあたりを一気に解決してくれます。
`Server.Client()` が返してくれる HTTPクライアントは、すべてのリクエストをテストサーバーに流し込んでくれるので、本番と同じURLを `const` のままハードコードしておいても、テストはちゃんと成り立つ。
つまり、「このクライアントは本当に期待どおりのURLにリクエストを出しているか」まで含めて検証できるようになるんですね。

さらにおもしろいのが、パスだけじゃなくて、HTTPメソッドやホスト名まで含めて handler をマッチさせられる点です。
これによって、「この処理は本当に Slack の正しいエンドポイントに、HTTPS で POST しているか?」みたいなところまできっちり確認できる。
外部サービスとの連携テストが、かなり信頼性高く書けるようになります。

通信自体はメモリ内だけで完結していて、実際のTCPポートやネットワークI/Oを一切使わないので、環境依存の揺れも起こりにくいです。
加えて、`testing/synctest` と組み合わせることで、時間や goroutine を絡めたテストもやりやすくなります。
記事全体としては、「APIクライアントのテストのシンプルさと信頼性が、大きく前進したよ」というトーンでまとまっていました。

。。。。

四本目は、デスクトップ操作の自動化と Claude Code のお話。
テーマは、「Claude Code のデスクトップ操作を、内蔵の computer-use じゃなくて Windows 専用の Windows-MCP に切り替える理由と、その使い方」です。

まず、従来の computer-use はどういう仕組みかというと、毎回スクリーンショットを撮って、その画像からボタンとかテキストボックスの位置を推定して、その座標をクリックする、という動き方なんですね。
これだと、「ボタンの場所がちょっとずれた」とか「解像度が違う」といった要因で、動きが不安定になりがちです。

これに対して Windows-MCP は、Windows の UI Automation を使って、画面を「要素のツリー構造」として読み取ります。
そのうえで、「この名前のボタン」とか「このテキストボックス」を、名前や座標で直接指定して操作できる。
その結果、同じ「メモ帳を開いて文字を入力する」というタスクでも、操作手順が五回から二回に減る、という具体例が紹介されています。
要素をピンポイントで認識できるので、無駄なクリックやスクロールが減る、というイメージですね。

導入自体は、
`claude mcp add windows-mcp -s user -e PYTHONUTF8=1 -- uvx windows-mcp serve`
このワンコマンドでOK、というシンプルさです。
ただし、日本語Windowsでは `PYTHONUTF8=1` を付けないと、文字コードエラーでMCPサーバーが落ちてしまうので、ここは注意ポイントとして強調されています。
また、初回起動時には Python パッケージの取得でタイムアウトしやすいので、そこも焦らずリトライしてくださいね、という話も出てきます。

セキュリティ面では、PowerShell の実行やレジストリ操作といった、危険度の高いツールについては、`--exclude-tools` オプションで無効化しておくことができるので、「どこまで自動操作を許すか」を細かく調整できます。

一方で弱点もあって、UI Automation で要素が取れないタイプのアプリ、たとえば Claude Code 自体のウィンドウなんかは、Windows-MCP の恩恵があまりない。
そういうケースでは、従来どおり画像ベースの computer-use を使ったり、Windows-MCP の vision オプションで画面認識に頼ったりする必要があります。

筆者がいま落ち着いている運用としては、
Windows のネイティブアプリは Windows-MCP、
ブラウザ操作は Playwright MCP、
それからアプリ単位で権限をきっちり絞りたい場合は computer-use、
というふうに役割を分けているそうです。
この組み合わせのおかげで、実際の操作回数もトークン消費量も減っていて、結構快適に使えている、という実感ベースの話で締めくくられていました。

。。。。

そして五本目、ラストは「家族でAIエージェントをどうやって安全に共有するか?」という、ちょっとライフハック寄りのお話です。

前提として、Anthropic の個人向け Claude Max には、「アカウントを本人以外に使わせてはいけない」という利用規約があります。
なので、家族みんなでひとつの Max アカウントを回す、というのはNGなんですね。
そこで筆者は、「Max」と「Claude API」を役割分担させる構成を取っています。

具体的には、自宅サーバー上で Discord のボットを二体常駐させていて、
自分専用のボットは Max を使う、
家族みんなで使うボットは Claude API を使う、
という運用です。

Discord 側の工夫として、
家族全員が見られるパブリックチャンネルと、
自分と担当ボットだけが見えるプライベートチャンネル、
この二つをきちんと分けています。
パブリック側では、ボットは @メンションされたときだけ返事をする。
一方、プライベートチャンネルでは自動応答を常時オンにしておいて、チャンネルトピックのところに「このチャンネルではこういう役割で振る舞ってね」という指示を書いておく。
こうすると、「家族も使うけど、自分だけのパーソナルアシスタント的なやり取りも守れる」という構造になります。

タスク管理の工夫もおもしろくて、依頼ごとにDiscordのスレッドを立てて、ボットにはそのスレッドで返信させる。
するとスレッド一覧が、そのまま「やることリスト」になるんですね。
用件が終わったら Close ボタンひとつで閉じてしまえば、タスクが消化されたことも視覚的にわかりやすい。

さらに、残しておきたい情報については、GitHub のプライベートリポジトリに要約としてコミットさせています。
`my-notes` と `family-notes` というようにリポジトリを分けることで、「個人メモ」と「家族共有メモ」をちゃんと分離。
これによって、プライバシーを保ちつつ、家族全員へのナレッジ共有もできるようにしているわけですね。

費用感としては、もともと契約していた Claude Max の月額百ドルに加えて、家族用Claude APIが「十数ドル」、それに自宅ミニPCの電気代がちょっと、という試算。
API 側には上限額を設定しておいて、出力量が多いほど料金が上がるので、デフォルトは Sonnet を使うようにしているそうです。
インフラとしては、自宅サーバーじゃなくて VPS や Raspberry Pi を使う選択肢も挙げつつ、「まずはVPSで試して、長期運用する手応えが出てきたら自宅サーバーに移行する」というステップを勧めています。
「家族みんなでAIを使いたいけど、規約だったり、お金だったり、どうする?」という方には、かなり具体的な参考になりそうな記事でした。

。。。。

というわけで、きょうの zenncast では、
リポジトリはビジネスロジックを持たせず、ユースケース側に寄せて責務分離しよう、というアーキテクチャの話。
HTTP/二と gRPC、gRPC-Web、Connect をどう選ぶか、というプロトコル設計の話。
Go 一点二七の `httptest.NewTestServer` で、APIクライアントのテストがぐっと素直になるよ、というテストの話。
Claude Code のデスクトップ操作を Windows-MCP に切り替えることで、操作数とトークンを減らせるよ、という自動化の話。
そして最後に、Claude Max と API を役割分担させて、家族でAIエージェントをうまく共有する運用の話。
この五本をご紹介しました。

気になった記事があれば、詳しい内容や元の記事への導線は、ショーノートのほうにまとめてありますので、ぜひそちらもチェックしてみてください。

番組「zenncast」では、リスナーのみなさんからの感想や、「こんなテーマの記事を取り上げてほしい!」といったリクエストも大歓迎です。
日々の開発の中で感じているモヤモヤや、「これ他の人はどうしてるんだろう?」という疑問なんかも、ぜひ教えてください。

それでは、きょうも一日、良いコードと良いレビューに恵まれますように。
お相手はマイクでした。また次回の zenncast でお会いしましょう。

Related episodes

内容の近いエピソードを推薦しています