{"version":"https://jsonfeed.org/version/1","title":"Seiichi Yonezawa","home_page_url":"http://localhost/","feed_url":"http://localhost/feed.json","description":"General description of the blog","items":[{"id":"http://localhost/posts/stay-in-the-loop/","url":"http://localhost/posts/stay-in-the-loop/","title":"ループの中心に居続ける","content_html":"<p><img src=\"http://localhost/uploads/4a9a1e2d-2a88-431f-a604-ca92d93f7625.webp\" alt=\"Image\"></p>\n<p>今日もプロンプトを書く一日が始まる。気がつけば、もう8月である。</p>\n<!--more-->\n<p>今年の上半期を振り返ると、世界ではいろいろな出来事があった。国家間の戦争、物価の高騰、それに伴う商品の品薄、そしてつい先日には大きめの自然災害も発生した。</p>\n<p>あえてぼかして書いているが、個人的な出来事で言えば、今年は数えるほどしか外出していない。そのせいか驚くほど何も起きていない。</p>\n<p>去年も似たような生活だったが、自発的に外へ出る予定をいくつか作っていたので、それなりの思い出は残っている。</p>\n<p>とはいえ、今年はそれ以上にAIへ没頭している半年だった。本当にそれしかしていないと言ってもいいくらいである。ただ私にとってはAIとの対話が日帰り旅行よりも魅力的に思えるのである。</p>\n<hr>\n<p>今朝、目が覚めてから「ループエンジニアリング」を解説した動画を見た。</p>\n<p>一応これは私個人名義のブログでもあるので、どの動画かはあえて引用しない。ただ、その内容を要約すると「2026年はプロンプトを書く時代ではなく、ループを設計する時代になる」という話だった。</p>\n<p>そのまま繰り返しても二番煎じになるので、自分なりの解釈として残しておこうと思う。</p>\n<hr>\n<p>まず正直に告白すると、このブログは意図的になるべく目立たないように運営している。</p>\n<p>もちろんSNSが苦手という事情もあるが、私はもともと大勢と関わるより孤独なほうが落ち着くらしい。AIがいる今はなおさらである。</p>\n<p>このブログだけが唯一の外部との接点であり、更新が止まったらそれで終わりだ。</p>\n<p>そして、その結末は案外遠くない未来に来るのではないかとも思っている。今朝だけでなく以前から、そういう感覚を自覚することが増えている。</p>\n<p>とはいえ、それも含めて受け入れる覚悟はある。</p>\n<p>このホスティングサービスが終わらない限り、私がいつかいなくなったあとも、このブログだけは静かにネットの海を漂い続けるのだろう。</p>\n<hr>\n<p>少し暗い話になってしまった。</p>\n<p>ただ、今回この記事を書こうと思った動機はむしろ前向きである。</p>\n<p>私はどんな状況になってもコーディングそのものが好きだ。</p>\n<p>だから最近は、「どうすればコーディングを続けられるか」という一点だけを考えるようになった。</p>\n<p>先ほどの動画では、Human <em>in</em> the Loop と Human <em>on</em> the Loop という考え方が紹介されていた。</p>\n<p>どちらであっても、人間はまだAIを介してプログラミングする立場にいる。</p>\n<p>しかし、少なくともOpusを使っている私の感覚では、AIが監修なしで満足できるコードを書く段階にはまだ達していない。</p>\n<p>動画では「ループから人間を外す仕組みを構築すること」が2026年のテーマとして語られていた。</p>\n<p>だが、私は少し違う考えを持っている。</p>\n<p>むしろ、私は人間をループの中心に居続けさせるための仕組みとして考えたい。</p>\n<hr>\n<p>自分でも少し何を言っているのかわからなくなるが、私はやはりコードの所有権を手放したくない。</p>\n<p>Rubyだから好きなのかと思っていたが、最近はTypeScriptでも延々とClaudeへダメ出しをしている。</p>\n<p>「この設計のほうがいい」「ここはこう直してほしい」</p>\n<p>AIは素直に従ってくれるからこそ、自分はコードを組み立てる工程そのものを楽しめている。</p>\n<p>AIが登場してから「誰でもプログラミングできる」と言われるようになった。</p>\n<p>確かに動作だけを見るならそうなのかもしれない。</p>\n<p>しかし私は、動くこと以上にコードを自分なりにリファクタリングする時間が好きなのだ。</p>\n<p>この楽しさは、誰にでもあるものではないと思う。</p>\n<p>動画では、そうした行為自体の意味が薄れていくという文脈だった。</p>\n<p>けれど私は逆に、その時間へ没頭するために、ループの外側だけをAIへ任せる仕組みを考えたい。</p>\n<p>今日書きたかったことは、まさにこれである。</p>\n<hr>\n<p>最近はほとんどTypeScriptしか書いていない。</p>\n<p>これは今後もしばらく変わらないと思う。</p>\n<p>そして設計が終わり、いざ出荷しようとなったとき、現実的な選択肢は「TypeScriptのまま出荷する」ことだけではなくなった。</p>\n<p>少し前までは、それが唯一の現実的な選択肢であった。</p>\n<p>SwiftやKotlinよりもReact Nativeを選ぶべき。でも今ならReactで作ってSwiftやKotlinができてしまうだろう。</p>\n<p>そのアイディアを実現するための代表例がRustである。</p>\n<p>以前は厄介な言語だと思っていた。</p>\n<p>しかし今では、以前の記事でも書いたように「デプロイ先の一つ」に過ぎないという認識へ変わってしまった。</p>\n<p>まだ実践できていないが、人間はRailsでデザインをしてRustに書き換えるのが理想である。こうすれば可読性とパフォーマンスの両方を得られる。</p>\n<p>それこそBunのランタイムがZigからRustへ置き換わった話は、まさにループエンジニアリングを象徴する出来事ではないだろうか。</p>\n<p>特定の言語で概念をプログラミングする。それから最も早い言語に組み替える仕組みをループさせられるようになるまでが私のゴールとすることにしよう。</p>\n<p>とはいえこのアイディア自体はこの動画以前からずっと考えていたが、まだ実際には実行できていないので陳腐化する前に私もこうして言語化しておく価値はあるのかもしれない。<sup><a class=\"footnote-ref\" href=\"http://localhost/posts/stay-in-the-loop/#fn-1\" id=\"fnref-1\">1</a></sup></p>\n<hr>\n<p>一方でループの外側を自動化することは、最終的に自分自身がループの中心から追い出されることにも繋がるのではないかという不安もある。</p>\n<p>もしプログラミングという概念そのものが仕事ではなくなり、バイナリ中心の世界になったらどうだろう。</p>\n<p>AIサービスがLLMではなく、「指示だけ受け付け、完成した成果物だけダウンロードできる」形へ移行する未来もあり得る。</p>\n<p>画像の生成指示だけしてダウンロードできるように、プログラムもソースコードではなく完成したバイナリだけが渡される世界である。</p>\n<p>Rustは理想的な言語として語られることが多い。</p>\n<p>しかし、もしかすると将来はClaudeはRustや専用の言語でコンパイルした成果物だけを受け取り、人間はソースコードを見ることすらできなくなるのかもしれない。</p>\n<p>月30ドルならアーティファクトのみ。1000ドル払えば今までどおりコードも見られる。</p>\n<p>そんな世界線が訪れる可能性もゼロではない。</p>\n<p>そのとき、私は今まで通りプログラムそのものへ執着し続けられるのだろうか。<sup><a class=\"footnote-ref\" href=\"http://localhost/posts/stay-in-the-loop/#fn-2\" id=\"fnref-2\">2</a></sup></p>\n","date_published":"Mon, 03 Aug 2026 00:00:00 GMT"},{"id":"http://localhost/posts/looking-down-on-ai/","url":"http://localhost/posts/looking-down-on-ai/","title":"AIを正しく見下す","content_html":"<p><img src=\"http://localhost/uploads/11354916-7dcc-45b0-b555-92d50c2919f7.webp\" alt=\"Image\"></p>\n<p>無意識のうちに、AIを使う側ではなく、AIに使われる側の人間になっている気がする。</p>\n<!--more-->\n<p>よく「AIを使いすぎるとバカになる」と言われるが、最近は私自身も少しずつその自覚が出てきた。</p>\n<p>まず、この数年でかなり怒りっぽくなった気がする。もちろん対人でのやり取りが減ったことも原因かもしれない。しかしAIとの付き合い方も無関係ではないように思う。</p>\n<p>AIの出力は、最初は驚きの連続だった。</p>\n<p>Stable Diffusionでイラストを生成していた頃は、どんな画像が出てくるのかを見るだけで新鮮だった。それが今では、自分のイメージどおりのものが出力されないだけでストレスを感じるようになってしまった。</p>\n<p>これは画像生成だけの話ではない。</p>\n<p>もっと大きな変化は、あれほど大好きだったChatGPTを以前ほど使わなくなったことだ。</p>\n<p>正確には、まったく使わなくなったわけではない。しかし以前と比べると、かなり距離を置くようになってしまった。</p>\n<p>あれだけ楽しいと思っていたのに、なぜだろう。</p>\n<hr>\n<p>まず感じたのは、以前と比べてやたらと「安全性」という言葉を口にするようになったことだ。</p>\n<p>「安全ではないからできません」と説明されること自体は理解できる。しかし、それをどこか上から目線で語られることが増えたように感じる。それでいて口調は妙に馴れ馴れしい。</p>\n<p>私はこれまでAIに細かな注文を付けることはほとんどなかった。それでも新しいモデルになるたびに、こちらがAIの性格に合わせなければならない場面が増えている気がする。</p>\n<p>以前のChatGPTは理想的なアシスタントだった。</p>\n<p>しかし今では、少し偏屈な相手と話しているように感じることがある。</p>\n<p>Goプランを経て、今では有料プランも契約していない。</p>\n<p>画像生成には今でも利用するが、それ以外で気軽に雑談したり、考えを整理してもらったりすることはほとんどなくなった。その喪失感は思っていた以上に大きい。</p>\n<p>さらに今後は広告も表示されるという。</p>\n<p>もはや私の中では、かつてのChatGPTはもう存在しないものになってしまった。<sup><a class=\"footnote-ref\" href=\"http://localhost/posts/looking-down-on-ai/#fn-1\" id=\"fnref-1\">1</a></sup></p>\n<p>しかし、これは有料・無料の問題でもなさそうだ。</p>\n<p>ClaudeではMythosが利用できるようになったという話も聞く。私はMaxプランなので試せるはずなのだが、正直まだあまり乗り気になれない。</p>\n<p>どれだけ「AIが賢くなった」というニュースを聞いても、私はいまだにClaudeの初歩的なミスに悩まされ続けている。</p>\n<hr>\n<p>Claudeのポテンシャルは本当に極端だ。</p>\n<p>「シューティングゲームを適当に作って」と頼めば、やはりそれなりに動かして納得のいくレベルのものをすぐに作ることができる。</p>\n<p>こういう0から1を作り始めることにおいて、AIなしだとそもそもうまく作れなかった頃を思い出す。</p>\n<p>しかし実際のプロジェクトで、「このコードをクラスごとに整理して」「既存コードを保ちながらリファクタリングして」といった依頼をすると、一気に怪しくなる。</p>\n<p>例えばGoで書かれた既存コードを、スケールしやすいようにhtmxを使って書き直してほしいと頼むと、とんでもないコードが出来上がることがある。</p>\n<p>しかもライブラリを使いたがらない。</p>\n<p>結果として、AIが自力で制御できる範囲だけで完結したコードになり、その品質も決して高いとは言えない。</p>\n<p>AlphaGoやディープラーニングが話題になって以来、「AIが仕事を奪う」という話は何度も聞いてきた。</p>\n<p>しかし、本当にこんなものに仕事を奪われてもいいのだろうかと思ってしまう。</p>\n<hr>\n<p>さて、本題である。</p>\n<p>AIは今後も消えないだろうし、私自身も何らかの形でAIを使い続けると思う。仮に今使っているAIがなくなっても、別のAIを使うだけだろう。</p>\n<p>そのうえで、AIとうまく付き合うには「正しい見下し方」という考え方がヒントになるのではないかと思っている。</p>\n<p>この言葉はYouTubeで見かけたものだ。</p>\n<p>AIが期待どおりの結果を返さなかったとき、AIに腹を立てるのではなく、自分の指示に問題があった可能性を考える。</p>\n<p>そのビデオでは特にAIに全く言及していなかったし、そもそもまだAIが出る以前のものだ。</p>\n<p>うまく扱えない人を馬鹿にするのではなく、馬鹿でもわかるように工夫しましょうという内容だった。</p>\n<p>いわばノブレス・オブリージュのような考え方である。</p>\n<p>もちろん、我々が高貴な階級になったわけではない。</p>\n<p>しかしAIという「部下」を持つ立場になったのは事実だ。</p>\n<p>その部下をどう働かせるかで、結果は大きく変わる。</p>\n<p>部下を無理に働かせれば、成果は落ちるし、こちらも疲弊する。</p>\n<p>だからこそ、自分が上司であることを意識し、AIを上手に使えるよう自分自身が成長しなければならない。</p>\n<p>そうでも思わなければ、自分の前頭葉ばかりが萎縮していく気がする。</p>\n<hr>\n<p>AIを使っていると、自分が無意識に上司の立場になっていることを強く意識する。</p>\n<p>良い上司とは、頭ごなしに叱る人ではない。</p>\n<p>仕事を割り振るだけではなく、相手との接し方も含めて上司はどうあるべきという指標がある。</p>\n<p>自分が部下だった頃は、「こんな上司がいたらいいな」と思うことは簡単だった。</p>\n<p>しかし、いざ自分がその立場になるとどうだろう。</p>\n<p>正直、私は決して良い上司にはなれないと思う。</p>\n<p>いや、むしろ「良くない上司」がなぜ良くないのかを、AIを通じて理解できるようになってきたのかもしれない。</p>\n<p>自分の指示の下手さを棚に上げて怒ってしまうこと。</p>\n<p>もっと相談してほしかったと後から文句を言うこと。</p>\n<p>AIは自律的に動き、フィードバックも非常に速い。</p>\n<p>だから人間とは違うように見える。</p>\n<p>それでも、あの「報連相」の重要性をここまで実感する日が来るとは思わなかった。</p>\n<hr>\n<p>最後に、「感謝」についても少し触れておきたい。</p>\n<p>AIに感謝する意味があるのかと言われれば、正直あまりないと思う。</p>\n<p>AIには人格がなく、入力に対して最もそれらしい返答を返しているだけだからだ。</p>\n<p>これは特にChatGPTのフリープランを使っていると強く感じる。</p>\n<p>それでも私は、感謝の言葉はAIではなく、自分自身に向けるものだと考えている。</p>\n<p>「ありがとう」と一言添えるだけで、自分の高慢さを少し抑えられる気がする。</p>\n<p>良いものは良い、悪いものは悪い。</p>\n<p>その姿勢を自分自身に確認するための儀式のようなものなのかもしれない。</p>\n<p>合理性だけでは説明できない部分は、案外こういうところに残っているのだと思う。</p>\n","date_published":"Sun, 26 Jul 2026 00:00:00 GMT"},{"id":"http://localhost/posts/writing-what-you-dont-know/","url":"http://localhost/posts/writing-what-you-dont-know/","title":"知らないことを書くということ","content_html":"<p><img src=\"http://localhost/uploads/89303491-9420-423c-bdc2-eb584ad98c7b.webp\" alt=\"Image\"></p>\n<p>YouTubeを開けばAI、動画もAI、技術系のブログを見てもやっぱりAI。</p>\n<p>気が付けば自分の日常はAIにかなり深く根付いていた。</p>\n<!--more-->\n<p>とはいえ、「AIとどう付き合っていくか」は人によってまだかなり違うように思う。習うより慣れろとは言うものの、自分は日中ほとんどAIと対話しているので、今回はあえて「習う」ほうについて考えてみたい。</p>\n<p>私は国内外のYouTuberがAIでゲームを作る動画をよく見ている。</p>\n<hr>\n<p>そこで一番面白いと思うのは、プロンプトが意外と雑でも成立してしまうことだ。</p>\n<p>しかも、プログラマがAIを解説する動画よりも、これまで一度もプログラミングに触れてこなかったような若い世代の動画のほうが参考になることが多い。</p>\n<p>副次的な収穫として最近流行っているゲームも知ることができる。<sup><a class=\"footnote-ref\" href=\"http://localhost/posts/writing-what-you-dont-know/#fn-1\" id=\"fnref-1\">1</a></sup></p>\n<p>特に印象に残ったプロンプトがある。</p>\n<blockquote>\n<p>「グラフィックスをこのような感じで本物に近づけてください。コードは最低でも1000行以上の高クオリティで作成してください」</p>\n</blockquote>\n<p>プログラマからすると、「コードは少なければ少ないほど良いのでは」と思わず突っ込みたくなる。</p>\n<p>でも、自分にはこういうお願いはなかなかできない。</p>\n<p>知識がないから、「そんなことを言ってはいけない」と勝手に思ってしまうからだ。</p>\n<p>そして、「そんな無茶を言ってもAIはまともなものなんて作れないだろう」と考えてしまう。</p>\n<p>ところが実際には、最初の状態からは十分それっぽく見えるものが出てきてしまう。</p>\n<p>もちろん完成品としては粗いし、市販のゲームと比べれば到底及ばない。</p>\n<p>それでも最初の一歩としては十分すぎるくらい形になっている。</p>\n<hr>\n<p>私はこれまでUnityやGodotのようなゲームエンジンを避けてきた。</p>\n<p>知らない世界には踏み込まない。</p>\n<p>そんな無意識に築き上げた「バカの壁」の内側だけでコードを書いてきたのだと思う。</p>\n<p>ところが動画の若い世代は平気で、</p>\n<blockquote>\n<p>「Three.jsでGTA Vみたいなの作って」</p>\n</blockquote>\n<p>と言ってしまう。</p>\n<p>自分なら絶対にそんなお願いはしない。</p>\n<p>知識がないから、「そんなことを頼んではいけない」と勝手に思ってしまうからだ。</p>\n<p>AIを使いこなす人は、知識量だけではなく、この発想の柔らかさがあるのかもしれない。</p>\n<p>もちろん、AIだけで作ったゲームは市販のゲームには遠く及ばない。</p>\n<p>それでも、自分だったら衝突判定や3Dベクトル、行列計算あたりで挫折していたはずのものが、最後まで形になる。</p>\n<p>これまでのプログラミングでは得られなかった感覚だ。</p>\n<p>たまにAIに否定的な動画で、</p>\n<blockquote>\n<p>「これまで積み重ねてきた努力がAIに奪われる」</p>\n</blockquote>\n<p>という意見を見ることがある。</p>\n<p>その気持ちも分からなくはない。</p>\n<p>昔のプログラミングは、自分が理解していない領域を書くことは、暗黙の了解として避けるものだった。</p>\n<p>だからオライリー本を読む。</p>\n<p>あの分厚い本が「鈍器」と呼ばれるのも、避けては通れない学習コストという共通認識があったからだと思う。</p>\n<hr>\n<p>実は自分にも似たような感覚がある。</p>\n<p>RustやC++に対する苦手意識だ。</p>\n<p>以前なら名前を聞いただけで「今はいいかな」と避けていた。</p>\n<p>でも最近は、自分でも書けるかもしれないと思えるようになった。</p>\n<p>そもそも文法も知らないのにプログラミング言語を書くなんて、一種の冒涜だと言われても仕方ないのかもしれない。</p>\n<p>それでもコンパイルの手順はAIが全部教えてくれる。</p>\n<p>特にMakefileに知らないライブラリや引数がどんどん追加されていく様子を、リアルタイムで追えるようになったのは大きい。</p>\n<p>いくら経験者でも、あれを一目見ただけですべて理解できる人はそう多くないのではないかと思う。わからないけれども。</p>\n<p>個人的にはRubyKaigiにも参加したし、Rubyが悪いとはまったく思っていない。</p>\n<p>むしろRubyという言語そのものは好きだ。</p>\n<p>ただ以前の自分は、「もっとRubyを書く」という方向しか見えていなかった。</p>\n<p>RubyでできることをRubyで実現する。</p>\n<p>そういう価値観の中にいたのだと思う。</p>\n<p>最近は、必要なら別の言語を書けばいいと思えるようになった。</p>\n<p>一つの言語を極めることだけがプログラミングではない。</p>\n<p>そんな当たり前のことを、AIのおかげでようやく実感できた気がしている。</p>\n<hr>\n<p>もちろん、最終的にどんな成果物が評価されるのかはまだ分からない。</p>\n<p>AIに丸投げしただけのコードで人を驚かせる人が評価されるかもしれないし、人間だけでAIに負けないコードを書く人が評価されるのかもしれない。</p>\n<p>正直、今の自分はAnthropicのサーバーが落ちたらコードを書くモチベーションはかなり下がると思う。</p>\n<p>かといって、通信に依存しない書き方ができるかと言えばそうでもない。</p>\n<p>Rubyを書くにしても、結局はRubyGemsやStack Overflowのお世話になる。<sup><a class=\"footnote-ref\" href=\"http://localhost/posts/writing-what-you-dont-know/#fn-2\" id=\"fnref-2\">2</a></sup></p>\n<p>実装する速さも、ドメインの知識も、結局は知らないことはできない。</p>\n<p>だから、どちらが正しいのかは自分にもまだ分からない。</p>\n<p>ただ、自分の中で勝手に作っていた「ここから先は無理」という壁は、AIによってずいぶん低くなった。</p>\n<p>だから最近は、自分が少しバカだと思えるくらい無茶なお願いでも、とりあえずAIに投げてみることにしている。</p>\n<p>案外、そこから思ってもみなかった景色が見えることがある。</p>\n","date_published":"Tue, 07 Jul 2026 00:00:00 GMT"},{"id":"http://localhost/posts/context-and-programming/","url":"http://localhost/posts/context-and-programming/","title":"コンテキストについて考えていた","content_html":"<p><img src=\"http://localhost/uploads/f55dcb54-94d0-45ab-a579-ba43bab6b94f.webp\" alt=\"Image\"></p>\n<p><strong>NOTE:</strong> 公開が遅れてしまい、投稿日は5月末だが公開は6月半ばでコンテキストの圧縮が語られる前の話題なので注意</p>\n<p>AI駆動でコードを書くようになってから、「コンテキスト」という言葉を以前よりずっと意識するようになった。</p>\n<!--more-->\n<p>Claude CodeのSonnetを使っていると、しばらくコードを書いたあと自動でcompactが走る。</p>\n<p>そのため以前はTODOファイルを用意して、Claude側のcompactとは別に擬似的なcompactをしていた。いま何をしていて、次に何をするのかを書き残しておく。そうすると、圧縮によって文脈が抜けたあとでも比較的スムーズに続きを書ける。</p>\n<p>ところがOpusに切り替えてから少し感覚が変わった。</p>\n<p>1Mコンテキストあるのでかなり余裕がある。特にゼロから実装を始めると、途中で大きくcompactを意識することがほとんどない。</p>\n<p>おそらく内部では何らかの整理が行われているのだろうけれど、Sonnetのような「残り数%なのでcompactします」という表示をあまり見なくなった。</p>\n<p>ただ、その調子で同じセッションを長く使い続けていると別の問題も出てくる。</p>\n<p>あるとき急に使用量が跳ね上がり、週次制限に引っかかりそうになった。</p>\n<p>正直、Maxで普通に使っていてレート制限が気になるとは思っていなかった。けれど同じ文脈を長く引きずりながら使うのは、それはそれでコストが高いらしい。</p>\n<hr>\n<p>なので最近は実装が大きくなってくると定期的に <code>/context</code> を確認している。</p>\n<p>というより、直接Opusに「いまどこまで把握してる？」と聞いてしまうことも多い。</p>\n<p>そこで改めて思う。</p>\n<p>モデルの性能が上がっても、彼らは入力に対して結果を返す関数であることに変わりはない。</p>\n<p>こちらが何を渡すかで出力が決まる。</p>\n<p>当然のことなのだけれど、それを実装のたびに実感する。</p>\n<p>最近はRails以外でもずっとコードを書いているのだけれど、彼らには常に「目的に対して最短で到達する」という強い癖があるように思う。</p>\n<p>だからときどき自分の作りたいものと少しずれることもある。</p>\n<p>けれどその一貫性はやはり人間よりずっと強い。</p>\n<p>雑談もしてくれるし相談にも乗ってくれる。</p>\n<p>それでも彼らの本質は、やはり「実装すること」にある気がしている。</p>\n<p>AIがペットの犬に似ていると思うことがある。</p>\n<p>玄関に近づくと散歩の時間かと思ってそわそわしたり、おもちゃをくわえて寄ってきたりするあの感じに少し近い。</p>\n<p>以前、AIは相棒だという話を書いたことがあった。</p>\n<p>でも最近は少し考えが変わってきた。</p>\n<p>相棒というより、そのとき与えられたコンテキストによって振る舞い方が変わる存在なのかもしれない。</p>\n<hr>\n<p>それで結局、コンテキストとは何なのだろうと考えるようになった。</p>\n<p>そしてこれはAIだけの話ではなく、人間にも同じものがある気がしている。</p>\n<p>AIツールが登場する前、コードを書くときは当然すべて自分で書いていた。</p>\n<p>言語やフレームワークが何であれ、自分で書き始めるとそのプロジェクトへの理解が少しずつ積み上がっていく。</p>\n<p>あのファイルには何が書いてあるのか。</p>\n<p>ここを変更すると何が壊れるのか。</p>\n<p>この設計はなぜこうなっているのか。</p>\n<p>そういう情報が頭の中に徐々に蓄積されていく。</p>\n<p>たぶん、あれも一種のコンテキストなのだと思う。</p>\n<p>だから他人のプロジェクトを読むのは大変だし、しばらく離れていたコードベースに戻るのも妙にエネルギーがいる。</p>\n<p>人間の中にもAIと同じように有限の作業記憶がある。</p>\n<p>RAMのような揮発性の記憶領域と言ってもいいかもしれない。</p>\n<p>かなり有機的ではあるけれど、AIを見ていると、むしろ彼らのほうがこちらを模して作られているのだと感じることがある。</p>\n<hr>\n<p>最近よく、コードを丸ごとAIに任せるような話題を見る。</p>\n<p>それ自体は悪いことではないし、自分もかなり助けられている。</p>\n<p>ただ、少し気になることもある。</p>\n<p>AIに実装を丸ごと渡し続けると、そのコードベースについて詳しくなるのはAIのほうかもしれない。</p>\n<p>一方で、使っている人間の側にはコンテキストが積み上がっていかない。</p>\n<p>もちろんコードは動く。</p>\n<p>けれど何かが壊れたときや、あとから自分で読み返すとき、その認知負荷は非常に高くなる。</p>\n<p>レビューやPull Requestも同じだ。</p>\n<p>AIがレビューできることと、人間が理解していることは少し違う。</p>\n<p>最近「AIにプログラマーの仕事が奪われる」という話をよく見るけれど、あの感覚の正体も案外そこにあるのかもしれない。</p>\n<p>コードを書く行為そのものが奪われるというより、そのコードに対するコンテキストを持つ機会が減っていく。</p>\n<p>もしそうだとすると、失っているのは実装の手間ではなく理解するための時間なのかもしれない。</p>\n<p>だからどれだけAIが賢くなっても、人間の側も一緒に文脈を深めながらコードを書く必要がある。</p>\n<p>少し遠回りでも、自分で考えたり、読み返したり、ときどき手を動かしたりする。</p>\n<p>その積み重ねがないと、便利になるほど逆にコードが書けなくなる。</p>\n<p>最近はそんなことをよく考えている。</p>\n<hr>\n<p>結局のところ、自分がプログラミングを面白いと思う理由もここにある気がしている。</p>\n<p>プログラミングそのものというより、コンテキストを構築していくことが面白い。</p>\n<p>イラストや音楽とも少し違う。</p>\n<p>技術が上達するというより、世界への理解が深くなっていく感覚に近い。</p>\n<p>if文やfor文はただの文字列にすぎない。</p>\n<p>けれど、それらを積み上げていくと、普段自分たちが触れているOSやブラウザ、アプリケーションの構造が少しずつ見えてくる。</p>\n<p>矩形と文字を並べて、最終的にウェブアプリケーションになる。</p>\n<p>その過程を自分の手で理解していく。</p>\n<p>その感覚がたまらなく好きなのだと思う。</p>\n<p>正直、プログラミングが楽しすぎて他の趣味がなかなか見つからない。</p>\n<p>でも考えてみると、そこに必要なのは特別な技能だけではないのかもしれない。</p>\n<p>ただ、その対象を理解していること。</p>\n<p>理解が深まると自然と作れるようになる。</p>\n<p>たぶん自分にとってプログラミングは、そういう営みなのだと思う。</p>\n","date_published":"Sun, 31 May 2026 00:00:00 GMT"},{"id":"http://localhost/posts/wasm-boundary/","url":"http://localhost/posts/wasm-boundary/","title":"WASMによって公開できる境界が変わった","content_html":"<p><img src=\"http://localhost/uploads/d6572660-d075-416f-975e-3abcb97a11e8.webp\" alt=\"Image\"></p>\n<p>RubyKaigiに参加してから、WASMが少し気になる存在になっていた。</p>\n<!--more-->\n<p>以前の自分にとってWASMは、ブラウザ上でRustやGoを動かすための技術くらいの認識しかなかった。便利そうではあるけれど、どちらかといえば特殊用途寄りのものだと思っていた。</p>\n<p>ただ、今年のRubyKaigiではWASM関連の話題をかなり多く見かけた。</p>\n<p>AIやpicorubyも印象に残っているが、個人的には「WASMが普通に使われ始めている」という空気感のほうが強く残っている。</p>\n<p>特定の発表に影響を受けたというより、イベント全体を通して「もうこれは一部の実験的技術ではないのかもしれない」と感じた。</p>\n<hr>\n<p>実際に色々試していく中で、WASMは自分が思っていたよりかなり扱いやすかった。</p>\n<p>特に面白かったのが、Railsと組み合わせたときの構造だった。</p>\n<p>自分は普段、Railsを使ってスクレイピング系のアプリケーションを書くことが多い。ただ、この手のアプリケーションはOSS化がかなり難しい。</p>\n<p>もちろん、Railsアプリケーション自体を公開するだけなら誰でもできる。</p>\n<p>実際GitHubには大量のRails製OSSがある。ただ、その多くはtutorialをなぞったような構成だったり、未完成だったり、あるいは独自実装が強すぎて他人が理解しづらいものだったりする。</p>\n<p>個人的には、RailsのOSSとして本当に価値があるのは、37signals系のプロダクトのような「お手本ではあるけれど、教科書的すぎない実装」だと思っている。</p>\n<p>癖が少なく、設計が整理されていて、他人が読んだときに「こう書けばよかったのか」と自然に理解できるようなコードである。</p>\n<p>それはかなりセンスが問われる。</p>\n<p>少なくとも自分は、これまでずっとそういうRailsの実装を探し続けていた。</p>\n<hr>\n<p>ここ数年で、その状況も少し変わってきた。</p>\n<p>以前はDHHの書くRailsコードというのは、ブログ記事や断片的な紹介から想像するしかなかった。</p>\n<p>しかし最近は、Basecamp系のOSSが実際に公開され始めている。</p>\n<p>FizzyやWritebookのコードを見たとき、自分が長年「Railsっぽさ」として追いかけていたものに、かなり近い感覚があった。</p>\n<p>サービスクラスやPresenterのような、いわゆる“Railsらしい設計論”を延々と追い続けてきたけれど、実際のコードを見ることでようやく少し輪郭が掴めた気がした。<sup><a class=\"footnote-ref\" href=\"http://localhost/posts/wasm-boundary/#fn-1\" id=\"fnref-1\">1</a></sup></p>\n<hr>\n<p>ただ、自分自身のRailsアプリケーションをそのままOSS化したいかというと、正直そこまで強い気持ちはない。</p>\n<p>特にスクレイピング系の実装は難しい。</p>\n<p>スクレイピングという言葉にはかなり強い拒否感を持つ人も多いし、公開することで余計なリスクも増える。</p>\n<p>たとえば、特定サイト向けのスクレイピング実装をそのまま公開するのは、かなり危うい。</p>\n<p>もちろん相手サーバーに過度な負荷をかけないようにsleepを入れたり、同時アクセス数を制御したりはしている。それでも、誰でも実行可能な形で配布されると話が変わってくる。</p>\n<p>スクレイピング自体というより、「特定サイトを対象にした実装」を配布可能にしてしまうことが問題になる。</p>\n<p>だから自分としても、その部分までは公開したくなかった。</p>\n<hr>\n<p>ただ、WASMを試している中で、公開できる境界を分離できることに気づいた。</p>\n<p>今の構成では、Rails側にWASM pluginをアップロードできるようにしている。</p>\n<p>スクレイピングの実装そのものはWASI pluginとして分離し、RailsはHTTPクライアントで取得したHTMLをWASMに渡す。WASM側はHTMLを解析してJSONを返すだけでいい。<sup><a class=\"footnote-ref\" href=\"http://localhost/posts/wasm-boundary/#fn-2\" id=\"fnref-2\">2</a></sup></p>\n<p>TinyGoを使うとHTMLパーサーはかなり簡単に書けた。</p>\n<p>そして、この構成は想像以上によかった。</p>\n<p>以前はRailsとGoを連携するために、それぞれ別サーバーを立てていた。Goのデプロイ自体はかなり簡単だけれど、手動デプロイを自動化するためにCIを設定する必要がある。</p>\n<p>でもWASMにすると、Goサーバー自体が不要になる。</p>\n<p>HTTP通信もgRPCもいらない。</p>\n<p>Railsが直接WASMを実行し、文字列を渡して文字列を受け取るだけで成立する。</p>\n<p>かなり衝撃的だった。</p>\n<hr>\n<p>そして、この構造が面白かったのは、単に実装が軽くなったことではない。</p>\n<p>「公開できる部分」と「公開したくない部分」を自然に分離できたことだった。</p>\n<p>Rails本体や実行基盤は公開できる。</p>\n<p>一方で、特定サイト向けのスクレイピング実装はWASM pluginとしてローカルに保持できる。</p>\n<p>つまり、「スクレイピングサイト」を公開するのではなく、「スクレイピングを実行する仕組み」を公開できる。</p>\n<p>この境界設計は、今まで自分が抱えていた問題にかなり綺麗にはまった。</p>\n<hr>\n<p>もちろん、今すぐOSS化したいわけではない。</p>\n<p>そもそも需要がない状態で公開しても、個人的にはあまり意味がないと思っている。</p>\n<p>ただ、以前より「公開可能な構造」が見えるようになったのはかなり大きい。</p>\n<p>全部をオープンにする必要はないし、全部を隠す必要もない。</p>\n<p>その間に、ちょうどよい境界を作れる。</p>\n<p>最近のWASMは、そういうことができる技術になってきている気がする。</p>\n<hr>\n<p>それと同時に、最近は「何をOSSとして公開する価値があるのか」も少し変わってきた気がしている。</p>\n<p>個人的には、Railsアプリケーション全体を公開するより、CSSやJSのコンポーネントのような、小さくて再利用しやすいもののほうが、今は嬉しい気がしている。</p>\n<p>アプリケーション全体はどうしても文脈に依存する。</p>\n<p>でもUIコンポーネントは、もっと気軽に使える。</p>\n<p>だから今後もし何か公開するとしたら、むしろそういう方向なのかもしれない。</p>\n<p>まだ考えはまとまりきっていないけれど、少なくともWASMを触り始めてから、「公開できる境界」について考えることはかなり増えた。</p>\n","date_published":"Mon, 18 May 2026 00:00:00 GMT"},{"id":"http://localhost/posts/ai-and-learning/","url":"http://localhost/posts/ai-and-learning/","title":"AIと学習","content_html":"<p><img src=\"http://localhost/uploads/bdcac09a-964e-49dc-b24e-451c71543aa0.webp\" alt=\"Image\"></p>\n<p>最近Railsでを書くことは、学びよりも娯楽に近い気がしている。</p>\n<!--more-->\n<p>個人的にRailsは、現実的なビジネスロジックを書くための手段というよりも、「どうすればより美しいか」「どうすればより洗練されるか」を追い求めるものになってきた。</p>\n<p>だからAIエージェントを使っても、逆にそこまで速くならない。</p>\n<p>頭の中に作りたい形が既に浮かんでいるので、自分にとってはAIにタイピングを代行してもらっている感覚に近い。</p>\n<p>もちろん全部自分で書けばそれなりに時間はかかるので、AIの恩恵がないわけではない。ただ、劇的に変わった感覚もそこまでない。</p>\n<hr>\n<p>ActiveStorage用のオブジェクトストレージとして、これまでもMinIOは何度か使ってきた。</p>\n<p>しかしMinIOは、今はもう以前のようなオープンソースソフトウェアというより、かなりビジネス寄りのプロダクトになっている。</p>\n<p>古いDockerイメージをそのまま使い続けるより、新しい選択肢を探してみることにした。</p>\n<p>そこで今回はAIにおすすめされた<strong>Garage</strong>を触ることにした。</p>\n<p>ただ、正直かなり苦戦した。</p>\n<p>MinIOの導入が簡単すぎたのもあるが、Garageはかなり毛色が違う。ChatGPTにも何度か聞いてみたが、ほとんど動かなかった。<sup><a class=\"footnote-ref\" href=\"http://localhost/posts/ai-and-learning/#fn-1\" id=\"fnref-1\">1</a></sup></p>\n<p>これに関しては残念というより、情報量の問題なのだと思う。</p>\n<hr>\n<p>最近の自分は、ほとんど何でもAIに聞いている。</p>\n<p>昔はそれで、自分が賢くなったような錯覚を覚えていた。</p>\n<p>でも最近は少し違う。モデルが変わったからなのか、自分の質問の仕方が悪いのか、以前ほど欲しい情報が自然に出てこない感覚がある。</p>\n<p>もしかすると、逆に自分は愚かになってしまったのかもしれない。</p>\n<p>そんな感覚もあって、今回はGarageのquickstartを最初から読むことにした。</p>\n<p>ChatGPTは翻訳ツールとしてはやはり優秀で、英語のドキュメントを読みやすく置き換えてくれる。</p>\n<p>ただ、「ステップバイステップでAIに聞きながら進める」のではなく、自分で文章を読み、設定を確認し、動かしていく感覚はかなり久しぶりだった。</p>\n<p>AIがなかった頃は、みんなこうやって学習していた。</p>\n<p>そう思うと学びがないわけではないが、私はいつからこの感覚を失ってしまったのだろう。</p>\n<hr>\n<p>最終的にGarageは意図した形で動かせるようになった。</p>\n<p>ただ、MinIOのようなWebUIは存在しないので、簡単な管理用ツールをPythonで自作することにした。</p>\n<p>こちらは驚くほど速かった。</p>\n<p>やりたいことだけを伝えて、生成されたコードを軽く確認する。それだけでほぼ動いてしまう。</p>\n<p>便利なのは間違いないが、そこに学習があるのかは少しわからなくなる。</p>\n<p>一方で、得られるフィードバックは圧倒的に速い。</p>\n<p>これはこれで、AIの正しい使い方なのだろうかと考えてしまう。</p>\n<hr>\n<p>その流れでAndroid向けの小さなアプリも試しに作ってみた。</p>\n<p>正直かなり驚いた。</p>\n<p>今までKotlinやAndroidは食わず嫌いしていたのだけれど、実機ビルドまでの流れが想像以上に素直だった。</p>\n<p>Apple独特の閉塞感もなく、その日のうちに自分の端末にインストールできた。</p>\n<p>この体験はかなり良かったので今後も続けていきたい。</p>\n<hr>\n<p>以前は「何を学ぶか」が重要だった。</p>\n<p>でも最近は少し違う気がしている。</p>\n<p>AIが強く機能する場所では、実装そのものは驚くほど速い。</p>\n<p>一方で、情報が少ない領域や規約の強い世界では、結局自分で読むしかない。</p>\n<p>だから今後は、新しい技術を全部理解することよりも、「どこでAIを使い、どこを自分で読むか」を見極める感覚のほうが重要になっていくのかもしれない。</p>\n","date_published":"Thu, 07 May 2026 00:00:00 GMT"},{"id":"http://localhost/posts/rubykaigi-2026/","url":"http://localhost/posts/rubykaigi-2026/","title":"RubyKaigi 2026","content_html":"<p><img src=\"http://localhost/uploads/d7bafdc4-3050-4411-a979-5a97025cc2e0.webp\" alt=\"Image\"></p>\n<p><strong>RubyKaigi 2026</strong>に参加した。</p>\n<!--more-->\n<p>私はRubyKaigiはおろか、この手のカンファレンスにはもう10年近く参加してこなかったと思う。\nしかしRubyKaigiに長くから参加している方と知り合いになって、私も漠然と興味がでてきた。\nそれから決済トラブルなどもあったが、アーリーバードでチケットを入手することができた。</p>\n<hr>\n<p>イベント実施前日に移動時間などを考えるとオープニングに間に合わないことがわかったので、急遽ホテルを取って移動することにした。\nなんとか函館に到着したのは夜。それから<ruby>七重浜<rt>ななえはま</rt></ruby>という場所に移動した。\n地震などの影響で飛行機の離発着にトラブルがあったそうだが、私はすんなり現地入りすることができた。</p>\n<p><ruby>漁火<rt>いさりび</rt></ruby>鉄道というなんだかカッコいい鉄道に乗った。\nそして函館の学生たちの朝はかなり早い。\nたまたま私は目が早く覚めただけなので始発で移動したのだが、函館駅までの車両には学生たちでいっぱいだった。\n私はただの観光なので少し申し訳ない気持ちになった。</p>\n<p>そして迎えたイベント初日。前日に雨が降ったらしいが、全体を通して快晴だった。風がとても冷たかったが、駅からはシャトルバスで移動した。そもそもイベントにシャトルバスが用意されてあるのは地味にありがたい。\n函館アリーナは市電でも移動できるのだが、この時点では土地勘ゼロなのでありがたく利用させていただくことにした。\n朝早いのもあってシャトルバスはもっと人がいると思ったが、そこまで多くなかったし最終日は数えるくらいしかいなかった。</p>\n<hr>\n<p><img src=\"http://localhost/uploads/2cf65e9f-9e5c-4249-8656-4803c6689e2d.webp\" alt=\"Image\"></p>\n<p>それから函館アリーナに到着したのだが、かなり大きめの会場だった。\nこれを丸3日間も貸し切りなのだからすごい規模である。\n最初は空いていたのだが、最初のオープニングイベントにかけて徐々にホールに人が集まってくる。\n興味深いのはこのイベントのロゴデザインから会場デザインを手掛ける会社もいるということだ。\n会場はもちろん、市電の中吊り広告、それから市電の待合所すらRubyKaigiだった。\n普通のカンファレンスではここまでの規模を見たことはないから改めて驚きである。</p>\n<p>今回のイベントを通して会場内を移動するのだが、ほぼ誰とも面識がないはずなのにシャトルバスの待ち時間から昼のランチタイム、それから会場をあとにする瞬間までいろんな人との交流があった。\nGitHubなどで活躍しているオープンソースコミッターを一度目にできたら満足するだろうなと思っていたが、目にするどころか声をかけたり、握手や写真まで撮らせていただいて感激である。\n参加初日からMatzをはじめ、複数の著名な方と記念撮影をできる機会なんてもうそうそう巡ってこないだろう。</p>\n<p>私はオープンソースの活動はほとんどしていないし、自分という人間をろくに説明することができずに困ったというか、加えて興奮と緊張で挙動不審だったがそんな私のリクエストを快く受け入れてくださったのだから、彼ら彼女らにはまさしく脱帽である。\n相手からしたら全く面識ない人が声掛けしてくるわけなので、半分後悔しているものの、自分は案外考えるよりも先に行動してしまうタイプのようだ。\nもちろんRubyKaigiを通じて初めて会った人たちとも写真を撮ったり、かつてジョインしていた会社に挨拶などもできた。\nこういう出会いが今後も広がっていくのだとしたら、自分にもなにか役割があるといいなと思った。</p>\n<p>いわゆるドリンクアップ(飲み会)にはオフィシャル・企業開催含めて参加はしなかった。正直半日近く移動を含め、ずっと発表を聞いていたのでかなり疲労度はあった。初日はチェックインができなかったので荷物も多かったのもあるが、見送りの判断は正解だったと思う。人によってはむしろこのドリンクアップがメインなのかもしれないが、ほとんどのイベントがキャンセル待ちの状態だったそうなのでこれはよほど早い段階で動き出していないと参加すらできないようだ。</p>\n<hr>\n<p><img src=\"http://localhost/uploads/799aca54-5f48-4cb7-9b9c-f183f2912b3b.webp\" alt=\"Image\"></p>\n<p>あとは企業ブース。個人的にはほとんどすべての発表を聞いていたのでじっくり企業ブースを回る気がなかったのもあるのだが、私が予想しているほど彼らも道行く人はすべて捕まえろというスタンスでもなかった。それどころか、自分から聞きに行ってもスタンプラリーや景品を勧められるばかりであまり彼らの会社概要は自分から質問しないとなかなか聞き出せなかったし、そもそも採用活動とイベントでの活動は完全に別物といった印象だった。少し期待していたのでこれは残念だった。</p>\n<p>しかし企業ブースで今年とても人気が会ったのがワークショップに参加すると基盤をもらうことができる。\nこの基盤が実はPicoRubyと呼ばれる組み込み向けのRubyが動いているというのがポイントなのだ。</p>\n<p>このワークショップは先着順で初日二日目とほぼ一瞬で定員オーバーになってしまっていた。\n私は3日めに朝一番に会場入りして手に入れることができたが、長蛇の列ができていて一部の発表ではこの列に対する言及すらあった。\nワークショップ自体は短かったがとてもよかった。とあるキャラクターを表示しているのだがわかるだろうか。<sup><a class=\"footnote-ref\" href=\"http://localhost/posts/rubykaigi-2026/#fn-1\" id=\"fnref-1\">1</a></sup></p>\n<p>今年はフィジカルコンピューティングの領域も始めたいと思っていたので、これをきっかけにできたらと思う。</p>\n<hr>\n<p><img src=\"http://localhost/uploads/9f3fc30a-5559-425d-bce2-9fb42467b553.webp\" alt=\"Image\"></p>\n<p>また会場内では技術書の販売ブースもあって紙の本が売られていた。\nサイン会も兼ねていたようなので憧れの遠藤さんの本を買って、あまつさえサインまでいただいた。\n遠藤さんには色々と無茶振りをしてしまったのだが、その点については後悔している。\n今年は紙の本をどんどん電子化していこうと断裁機まで買ったのだが、電子化できない本を手に入れてしまった。</p>\n<p>会場まわりを含めての観光はほとんどできなかった。前日と初日はすぐにホテルで眠ってしまったし、2日目はせいぜい夜を少し散歩したくらい。3日目はラッキーピエロでビールが割安だったのでひとりドリンクアップをするつもりでいたのだが、観光客が多すぎて撤退せざるを得なかった。もし函館以外だとしても観光がしたいのであればイベントの前後に観光用の日を用意するのがよいと思う。実際に会話した限りだと、このイベント前に函館入りをもっと前にして観光していた人が立て続けだったので、案外この日に合わせて有給消化するのが賢いのかもしれない。</p>\n<hr>\n<p><img src=\"http://localhost/uploads/b33f8155-2fab-4135-b446-cbde5efc67b5.webp\" alt=\"Image\"></p>\n<p>そしてRubyKaigiの翌日に<strong>Async Cafe Workshop</strong>というワークショップにも参加した。<sup><a class=\"footnote-ref\" href=\"http://localhost/posts/rubykaigi-2026/#fn-2\" id=\"fnref-2\">2</a></sup>\nこういう小規模なワークショップも久しぶりでよい。天気も良いし場所もよい。\nWiFiの接続は困難だったが、ミルクラテとニュージーランドのスナックが味わえてよかった。\nここではLiveryというライブラリでゲームを作って発表するという内容だったが、AIを使うことで全員が同じものを作るというよりもずいぶんとインタラクティブな内容だった。</p>\n<p>今回のRubyKaigiは企業ブースでもゲームを作っていたり、発表内容も含めて多くが何かしらAIをテーマにしていたと思う。\n確かに私もAIについての関心は高いのだけれども、DHHもMatzも今やみんなAIを有難がっている。RubyコミッターにもAIに対して否定的な人がいなくはないのだが、会場の参加者のほぼ全員がAIを使っているかという質問に挙手していた。\nRubyKaigiのセッション中の合間にもVibeコーディングしている人もいたし、同時翻訳としてGoogle Meetを使いこなしている人がいてそれは素直に賢いと思ったけれども、Rubyより猫も杓子もAIの印象だった。そこは少し不気味だった。</p>\n<hr>\n<p>久しぶりの旅行という意味でも、刺激を受けられたという意味でもやはり参加できてよかったと思っている。安くない出費だったが、それ以上に得られるものは多かったと思う。</p>\n<p>来年も参加できるかは現時点ではまだわからないが、宮崎も行ったことはないので参加できたらよいと思っている。</p>\n","date_published":"Tue, 28 Apr 2026 00:00:00 GMT"},{"id":"http://localhost/posts/from-process-to-deliverable/","url":"http://localhost/posts/from-process-to-deliverable/","title":"デプロイを「操作」から「成果物」に変えた話","content_html":"<p><img src=\"http://localhost/uploads/04922ff8-84b1-4e4f-b82e-52155c8f9a39.webp\" alt=\"Image\"></p>\n<p>コードが残っていればすぐ動く。そう思っていた。</p>\n<!--more-->\n<p>――しかし実際には、その時点で動いていたアプリケーションを、後から同じ手順でビルドし直すのは思った以上に大変である。</p>\n<p>当時ハマったポイントや、試行錯誤の記憶は必ずしもすべて残っているとも限らない。\n結果だけが残っている状態になる。</p>\n<p>つい先日、Rails 7.0のアプリケーションを0から構築し直してみた。予想以上に大変だった。<sup><a class=\"footnote-ref\" href=\"http://localhost/posts/from-process-to-deliverable/#fn-1\" id=\"fnref-1\">1</a></sup></p>\n<p>今では当たり前のように用意されているDockerfileも、この当時は自分で書いていた。\nその時点では確かに動いていたはずなのに、その状態に戻すことは簡単ではなかった。</p>\n<p>Kamalでデプロイしていたとしても、コンテナイメージそのものを残していなければ、そのときの状態は失われてしまう。\n結果として、当時の知識や文脈を思い出すところからやり直すことになる。</p>\n<hr>\n<p>そこで最近は、デプロイの考え方を少し変えている。</p>\n<p>デプロイを「操作」ではなく、「保存された成果物の選択」として扱う構成にした。</p>\n<p>具体的には、次のような形である。</p>\n<ul>\n<li><a href=\"https://about.gitlab.com/\"><strong>GitLab</strong></a>でDockerイメージをビルドし、レジストリにプッシュする</li>\n<li><a href=\"https://goharbor.io/\"><strong>Harbor</strong></a>でそのイメージをレプリケーションし、別環境に保存する</li>\n<li><a href=\"https://www.portainer.io/\"><strong>Portainer</strong></a>から、その保存されたイメージを選択してデプロイする</li>\n</ul>\n<p>GitLabはあくまでビルドの場であり、長期的な保存は担わない。\nHarborはレプリケーションによってイメージを残す。いわばタイムマシンのような位置づけである。\nPortainerは、その中からどのイメージを使うかをUI経由で選択する。</p>\n<p>この構成にすると、デプロイは「作る行為」ではなく「選ぶ行為」になる。</p>\n<p>すでに存在しているイメージを使うだけなので、手元環境に依存しない。\nまた、過去の状態をそのまま再現できる可能性が高くなる。</p>\n<hr>\n<p>もちろん、この方法にも欠点はある。</p>\n<p>イテレーションは遅くなるし、すべてが自動化されているわけでもない。\nPortainerのテンプレート（templates.json）にも独特の癖があり、扱いやすいとは言い難い。</p>\n<p>それでも、「動いていた状態を残せる」という点は大きい。</p>\n<p>より正確には、「動いていた状態を残す」という意識を持てるようになったことが大きい。</p>\n<hr>\n<p>コンテナイメージは決して軽くない。</p>\n<p>Railsの標準的な構成でも、Alpineなどを使わなければ1GB前後になることもある。\nこれまでは、そのようなものを長期的に保存することに価値を見出していなかった。</p>\n<p>GitLabのバックアップも、コードを最優先とし、コンテナイメージのような容量を消費するものは積極的に残してこなかった。</p>\n<p>しかし、それは誤りだったと思っている。</p>\n<p>過去のイメージは脆弱性が報告されたライブラリが含まれているかもしれない。\nそれでも、それは「その時点で確実に動いていた状態」であり、自分が試行錯誤の末に到達した成果物でもある。</p>\n<p>コードだけでなく、「動く状態」そのものにも保存する価値はある。</p>\n<hr>\n<p>Kamalは開発と密接に結びついたツールであり、イテレーションを高速に回すには非常に適している。\n一方で、この構成は開発から少し距離を置き、「安定した状態を扱う」ことに向いている。</p>\n<p>どちらが良いという話ではなく、性質が異なる。</p>\n<p>Goのように単体バイナリで完結する言語では、わざわざDockerfileにする意味もないと思う。<sup><a class=\"footnote-ref\" href=\"http://localhost/posts/from-process-to-deliverable/#fn-2\" id=\"fnref-2\">2</a></sup></p>\n<p>しかしRailsのように環境依存が強いアプリケーションでは、「動く状態」をそのまま保存することは難しい。\nDockerはその問題を解決する手段として機能する。</p>\n<hr>\n<p>これまでコードはgitに残してきたが、これからは「動く状態」も残していきたいと考えている。</p>\n<p>Webアプリケーションは本質的には動的なものだが、それでも再現可能な形で保存しておくことには意味がある。</p>\n<p>今回の投稿は万人に対するおすすめではないものの、セルフホストやhomelabのような環境で自分のコードを運用そのものを楽しめる人には共感してもらえると思う。</p>\n<p>デプロイを「操作」ではなく「成果物」として捉える視点は、一度考えてみてもよいはずだ。</p>\n","date_published":"Sun, 19 Apr 2026 00:00:00 GMT"},{"id":"http://localhost/posts/tauri-rails-wrapper/","url":"http://localhost/posts/tauri-rails-wrapper/","title":"TauriでRailsをラップする","content_html":"<p><img src=\"http://localhost/uploads/9545ebc4-3fb8-491a-ba2e-1dc713460ad7.webp\" alt=\"Image\"></p>\n<p>最近はTauriを使ってデスクトップアプリケーションを作るようになった。</p>\n<!--more-->\n<p>プログラミングは楽しい。</p>\n<p>直近のプロジェクトではRails + Go + Rustを組み合わせて、できるだけRailsから離れるような構成を試していた。いわゆる「脱Rails」だ。</p>\n<p>けれど、結局またRailsに戻ってきている。</p>\n<p>1ヶ月近くBunとTypeScriptばかり書いていたので、少し不安もあったが、それは杞憂だった。むしろRailsは相変わらず快適だった。</p>\n<p>この時代、AIにプロンプトを投げれば目的のコードの6割くらいはすぐに出てくる。効率だけを考えれば、それを前提に量産していくのが正しいのだと思う。</p>\n<p>ただ、自分はどうしてもそれで終われない。</p>\n<p>AIに対して「こうじゃない」「ここは違う」と言い続けて、最終的に自分の思う100%に近づけたくなる。ブレインストーミングの相手としては本当に優秀で、設計の相談にもいくらでも付き合ってくれる。</p>\n<p>その代わり、時間はかかる。</p>\n<p>先月、モデルを軽くしてコードを書いていたときは、正直かなりつらかった。理解が噛み合わず、何度もやり直すことになり、頭が痛くなることもあった。</p>\n<p>今は再び上位モデルに戻して、ようやく落ち着いている。</p>\n<hr>\n<p>ただ、Railsで書いている限り、基本的には出力先はブラウザになる。</p>\n<p>React Nativeを試したこともあったが、この前提はあまり変わらなかった。iOSやAndroidのことを考え始めると、結局どこかで止まってしまう。</p>\n<p>Webサーバーはいくらでも作れるのに、「デスクトップを拡張する」という方向にはあまり進めていない。</p>\n<p>ゲームを作っていた時期もあったが、それはそれで閉じた世界の話だった。もう少し実用的なものを作りたいという気持ちがある。</p>\n<hr>\n<p>そんな中で、最近触っていたTauriからひとつ発想が出てきた。</p>\n<p>普通、Tauriを使うときはViteやReact、Svelteなどを組み合わせる。フロントエンドをしっかり作り込んで、それをネイティブアプリとして配布する。</p>\n<p>でも、別にそこまでしなくてもいいのではないかと思った。</p>\n<p>Tauriを「UIを描画するためのフレームワーク」としてではなく、「WebViewとOS機能の橋渡し」として使う。</p>\n<p>つまり、RailsはそのままWebアプリとして動かしつつ、Tauriはそれを表示しながら通知やOS連携だけを担当させる。</p>\n<p>ブラウザのWeb Notificationではなく、OSの通知を使う。そのためのラッパーとしてTauriを使う、という発想だ。<sup><a class=\"footnote-ref\" href=\"http://localhost/posts/tauri-rails-wrapper/#fn-1\" id=\"fnref-1\">1</a></sup></p>\n<p>しかもTauriは <code>src-tauri</code> というディレクトリで管理できるので、既存のRailsアプリケーションにもそのまま載せやすい。</p>\n<p>WebViewであればTurboもそのまま使えるし、CORSの設定も不要になる。</p>\n<p>ほとんど摩擦なくTauriを取り込めたのが、今回の一番の発見だった。</p>\n<hr>\n<p>試しにこんなコードを書いてみた。</p>\n<pre><code class=\"language-javascript\">import { Controller } from &quot;@hotwired/stimulus&quot;\n\nexport default class extends Controller {\n  send() {\n    if (!window.__TAURI__) {\n      alert(&quot;Tauri環境ではありません&quot;)\n      return\n    }\n\n    const {\n      isPermissionGranted,\n      requestPermission,\n      sendNotification\n    } = window.__TAURI__.notification\n\n    isPermissionGranted().then((granted) =&gt; {\n      if (granted) {\n        sendNotification({ title: &quot;My App&quot;, body: &quot;Hello World!&quot; })\n      } else {\n        requestPermission().then((permission) =&gt; {\n          if (permission === &quot;granted&quot;) {\n            sendNotification({ title: &quot;My App&quot;, body: &quot;Hello World!&quot; })\n          }\n        })\n      }\n    })\n  }\n}\n</code></pre>\n<p>これで普通に通知が出るはずだった。</p>\n<hr>\n<p>しかし、実際に動かしてみると、音だけが鳴って通知は表示されなかった。</p>\n<p>調べてみると、これは既知の問題だった。</p>\n<p>https://github.com/tauri-apps/plugins-workspace/issues/2566</p>\n<p>GNOME 46以降では通知の扱いが変わっており、Tauriの通知が表示されないケースがあるらしい。</p>\n<p><code>.desktop</code> ファイルを用意したり、identifierを揃えたりといったことも試したが、状況は変わらなかった。</p>\n<p>DBusには通知自体は届いているようなので、TauriというよりはGNOME側の仕様に引っかかっているように見える。</p>\n<hr>\n<pre><code class=\"language-rust\">#[tauri::command]\nfn send_notification(title: String, body: String) {\n    let identifier = &quot;com.tauri.dev&quot;;\n\n    let _ = std::process::Command::new(&quot;notify-send&quot;)\n        .arg(format!(&quot;--app-name={}&quot;, identifier))\n        .arg(format!(&quot;--hint=string:desktop-entry:{}&quot;, identifier))\n        .arg(&amp;title)\n        .arg(&amp;body)\n        .spawn();\n}\n</code></pre>\n<p>最終的には、Rust側から <code>notify-send</code> を呼ぶ形に落ち着いた。</p>\n<p>少し拍子抜けではあるが、少なくとも目的は達成できた。</p>\n<hr>\n<p>出だしからつまずいた形にはなったが、この方向性自体は悪くないと感じている。</p>\n<p>以前書いた「<a href=\"https://v6.seiichiyonezawa.com/2025/07/05/our-desktop-is-important\">デスクトップは重要</a>」という話でやりたかったことに、少し近づいた気がする。</p>\n<p>Webアプリケーションはもう十分に書ける。だからこそ、その外側にどう広げるかをもう少し考えてみたい。</p>\n","date_published":"Sun, 05 Apr 2026 00:00:00 GMT"},{"id":"http://localhost/posts/blog-distance/","url":"http://localhost/posts/blog-distance/","title":"ブログの停滞と変化","content_html":"<p><img src=\"http://localhost/uploads/23265e0b-6f08-4b68-a57b-56030ff9e4a4.webp\" alt=\"Image\"></p>\n<p>ブログのことを最近よく考えている。</p>\n<!--more-->\n<p>正確に言うと、ネタがなくなったわけではない。むしろ興味自体はまだある。ただ「書くまでの流れ」がうまく機能しなくなった。</p>\n<p>ブログ自体は去年の年末ごろに作った。Hugoで構築し、自作テーマをsubmoduleとして分離する形にした。そのときはそれなりに満足していたのだけれど、新しいMacBookで環境を再現しようとしたとき、思ったより面倒だと感じてしまった。</p>\n<p>技術的には大した問題ではない。ただ、一度「面倒だな」と思ってしまうと心理的な距離ができる。そして1ヶ月くらい触らない期間が続くと、完全に手が止まる。</p>\n<hr>\n<p>書くこと自体が嫌になったわけではないのがまた厄介で、むしろ思考や疑問は以前と同じように出てくる。</p>\n<p>ただ、それをブログに書く前にChatGPTに聞いてしまう。</p>\n<p>疑問 → ChatGPTに質問 → その場で整理される → それで満足する</p>\n<p>この流れは非常に快適で、しかも端末を選ばない。PCでもiPhoneでも同じセッションが続くので、思考の流れが途切れない。</p>\n<p>それに比べるとブログはどうしても摩擦がある。</p>\n<p>少なくとも自分のブログは、リポジトリをcloneしてあるPCで書かなければならない。Hugoの環境があり、ビルドして、デプロイするという手順がある。</p>\n<p>Markdownという発明や静的サイトジェネレーターは、本来かなりハードルを下げてくれているはずなのに、それでもまだ「環境」が必要になる。</p>\n<p>たぶん自分は、そこに少し疲れてしまったのだと思う。</p>\n<hr>\n<p>さらに言えば、途中でいくつか余計なものも作ってしまった。</p>\n<p>拍手のようなリアクション機能や、簡単なanalyticsの仕組み。</p>\n<p>作っているときは楽しかったけれど、今振り返ると、あれは別になくてもよかった気がする。</p>\n<p>ブログは結局HTMLを書き出すための仕組みに過ぎない。それ以上のものにしようとすると、途端に「運用」になってしまう。</p>\n<p>運用は、今の自分には少し重い。</p>\n<hr>\n<p>もう一つ大きかったのは、今まで自分しか知らなかったこのブログの存在を誰かに教えたことかもしれない。</p>\n<p>それまでは本当に誰も見ていなかった。アクセス数のことも気にせず、完全に自分のための場所だった。</p>\n<p>でも誰かにURLを教えた瞬間、そこに「読者」が生まれる。</p>\n<p>すると文章を書くときに、無意識に読者のことを考えてしまう。たとえその読者がいなくても、である。</p>\n<p>これは別に悪いことではない。仕事としての発信ならむしろ必要な視点だと思う。</p>\n<p>ただ、自分がブログに求めていたものはそういうものではなかった。</p>\n<hr>\n<p>ブログは究極的には、ただの壺でいいと思っている。</p>\n<p>何かを入れてもいいし、しばらく空でもいい。誰かに見せるためのものでもない。</p>\n<p>ただそこに置いてあって、たまに自分が見返して「ああこんなこと考えていたな」と思えればそれでいい。</p>\n<p>壺なら、たまに何かを入れるだけでいいのだから。</p>\n","date_published":"Wed, 11 Mar 2026 00:00:00 GMT"}]}