<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>ソフトウェア設計 on 或る阿呆の記</title><link>https://hack-le.com/tags/%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E8%A8%AD%E8%A8%88/</link><description>Recent content in ソフトウェア設計 on 或る阿呆の記</description><generator>Hugo -- gohugo.io</generator><language>ja</language><lastBuildDate>Thu, 17 Sep 2026 20:58:28 +0900</lastBuildDate><atom:link href="https://hack-le.com/tags/%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E8%A8%AD%E8%A8%88/index.xml" rel="self" type="application/rss+xml"/><item><title>バイブコーディングでジェンガが崩壊したらどうするのか？</title><link>https://hack-le.com/vibecoding-jenga/</link><pubDate>Wed, 16 Sep 2026 00:00:00 +0900</pubDate><guid>https://hack-le.com/vibecoding-jenga/</guid><description>&lt;p&gt;現在自分用のアプリケーションとして、体重計やFitbitのようなトラッカーのデータを集約し、さらに手動で体調不良などのイベントを管理したり、運動管理したり、データに基づいてAIに分析させるようなアプリケーションをAIで作成しています。&lt;/p&gt;&#10;&lt;p&gt;その過程で、内部的な設計を変更したのですが、今後こういう判断を誰がしていくんだろう、あるいは誰がどうやって必要だと学ぶんだろう、とふと思いました。&lt;/p&gt;&#10;&lt;h2 id="設計の変更"&gt;設計の変更&#10;&lt;/h2&gt;&lt;p&gt;まぁ最初は今あるデータをホイホイ読ませて、それ十分だったのですけれど、読み取るデータが多岐に渡ってくるにしたがって、内部の設計について気になり始めました。恐らく、データソースと取り込みが密結合になっているだろうなぁ、と思ったので。聞いてみるとやはりそうだったのですが、何を言っているかと言うと、図示すると以下のようにデータソースと取り込みロジックが1vs1で完全に対応してしまっている状態です。&lt;/p&gt;&#10;&lt;pre class="mermaid" style="visibility:hidden"&gt;flowchart TD&#10;subgraph External["外部データソース"]&#10;GH["Google Health API (JSON)"]&#10;TO["Google Takeout (ZIP / CSV)"]&#10;EU["Eufy 体重計 (BLE / CSV)"]&#10;end&#10;subgraph TightlyCoupled["各機能内部（変換と永続化が一体化）"]&#10;GH_All["Google Health クライアント\n・JSONパース\n・独自集計ロジック\n・個別 INSERT / ON CONFLICT SQL"]&#10;TO_All["Takeout インポーター\n・ZIP / CSVパース\n・独自集計ロジック\n・個別 INSERT / ON CONFLICT SQL"]&#10;EU_All["Eufy 処理（新規追加時）\n・データパース\n・個別 INSERT / ON CONFLICT SQL"]&#10;end&#10;DB[("SQLite データベース\n(daily_metrics / body_measurements)")]&#10;GH --&gt; GH_All&#10;TO --&gt; TO_All&#10;EU --&gt; EU_All&#10;GH_All --&gt;|"直接 SQL 実行\n（マージルールが分散）"| DB&#10;TO_All --&gt;|"直接 SQL 実行\n（マージルールが分散）"| DB&#10;EU_All --&gt;|"直接 SQL 実行\n（マージルールが分散）"| DB&#10;classDef issue fill:#ffebee,stroke:#c62828,stroke-width:2px,color:#b71c1c;&#10;class GH_All,TO_All,EU_All issue;&lt;/pre&gt;&lt;p&gt;コレの何が良くないかと言うと、同じデータでもGoogle Health API経由なのかそれともエクスポートcsvデータなのかで完全に異なるロジックになってしまうわけです。これは拡張性と保守性の両方に問題があります。&lt;/p&gt;&#10;&lt;p&gt;なので、設計をデータソースと取り込みの間に、フォーマットするレイヤを増やして疎にしました。&lt;/p&gt;&#10;&lt;pre class="mermaid" style="visibility:hidden"&gt;flowchart TD&#10;subgraph External["外部データソース"]&#10;GH["Google Health API (JSON)"]&#10;TO["Google Takeout (ZIP / CSV)"]&#10;EU["Eufy 体重計 (BLE / CSV)"]&#10;UI["画面からの手動入力 (Web UI)"]&#10;end&#10;subgraph Converters["データ変換レイヤ（副作用のない純粋関数）"]&#10;GH_Conv["Google Health コンバータ\n（JSON ➔ 共通モデル）"]&#10;TO_Conv["Takeout コンバータ\n（ZIP ➔ 共通モデル）"]&#10;EU_Conv["Eufy コンバータ\n（BLE / CSV ➔ 共通モデル）"]&#10;end&#10;subgraph CoreDomain["アプリケーション共通仕様"]&#10;Models["共通ドメインモデル\n・models.DailyMetric\n・models.BodyMeasurement\n・models.ActivityLog"]&#10;end&#10;subgraph Ingestion["データ取り込みレイヤ (internal/ingest)"]&#10;IngestSvc["統一 Ingest サービス\n・トランザクション制御\n・安全なマージ制御 (COALESCE/部分更新)\n・source メタデータ自動付与"]&#10;end&#10;DB[("SQLite データベース\n(source カラム付き)")]&#10;%% データフロー&#10;GH --&gt; GH_Conv&#10;TO --&gt; TO_Conv&#10;EU --&gt; EU_Conv&#10;GH_Conv --&gt; Models&#10;TO_Conv --&gt; Models&#10;EU_Conv --&gt; Models&#10;UI --&gt; Models&#10;Models --&gt; IngestSvc&#10;IngestSvc --&gt;|"一元化された SQL で永続化"| DB&#10;classDef pure fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px,color:#1b5e20;&#10;classDef service fill:#e3f2fd,stroke:#1565c0,stroke-width:2px,color:#0d47a1;&#10;class GH_Conv,TO_Conv,EU_Conv pure;&#10;class IngestSvc service;&lt;/pre&gt;&lt;p&gt;これでまぁ、今後対応すべきデータソースが増えてもやりやすくなったはずです。とりあえずコードはだいぶリファクタされました。&lt;/p&gt;&#10;&lt;h2 id="そしてジェンガが出来る"&gt;そしてジェンガが出来る&#10;&lt;/h2&gt;&lt;p&gt;思ったのは、今後主流になるだろうAIによる開発において、&lt;strong&gt;設計変更を伴うような判断を誰ができるのだろうか&lt;/strong&gt;、ということです。今回の場合、継続的にインタフェースが増えそうだなぁ、と判断した時点で中間層をいれるようにしましたが、自分で言わないと、多分AIは前例踏襲で密な結合を増やし続けたと思います。&lt;/p&gt;&#10;&lt;p&gt;それは拡張を続けていくと破綻しそうです。それともAIならば頑張れるんだろうか？あるいは、AIが頑張れなくなるまで拡張を続けてしまうのだろうか。まぁそこまで使い続けられたらそのアプリはある意味成功なのかもしれませんが、であればこそ使い続けられるような状態にしたいところでもあります。&lt;/p&gt;&#10;&lt;p&gt;もちろん、&lt;strong&gt;最初から完全な要件を提示すれば、相応しい設計を最初からするに違いありませんが、それができるなら誰も苦労しません&lt;/strong&gt;。アプリケーションはしばしば、&lt;strong&gt;自分も何が欲しいのかわからないところから始まります&lt;/strong&gt;。特にAI時代、まず形にして、自分自身がまず何をしようとしていたのかを知るほうが、効率も良いでしょう。&lt;/p&gt;&#10;&lt;p&gt;しかしそれだと、恐らくジェンガが出来ます。&lt;strong&gt;そのジェンガは最終的にAIと自分の能力を超えるところまで積み上げられます&lt;/strong&gt;。&lt;/p&gt;&#10;&lt;h2 id="ジェンガ上等かもしれない"&gt;ジェンガ上等かもしれない&#10;&lt;/h2&gt;&lt;p&gt;まぁでも、いいのかもしれません。&lt;strong&gt;崩壊する前に仕様が完全に固まって固定されれば、それは賭けに勝った、という感じ&lt;/strong&gt;ですし、たとえ&lt;strong&gt;目に見えて破綻しても、そのときには欲しかったものがかなり目に見えているはずですから、そこから仕様を改めて洗い出し、言語化して、AIに最初から作らせる、データは頑張って移行する、というのでも十分ペイする&lt;/strong&gt;のかも。&lt;/p&gt;&#10;&lt;p&gt;もちろんそうなる前に設計変更すりゃいいんですけれど、これからはそれが出来る人自体が減っていくように思われます。だいたいそれを学ぶ場がなくなっていくのは、これはもう確定的なシナリオですし。であるならば、&lt;strong&gt;むしろやるべきことは、最初から作り直せる状態に留めること&lt;/strong&gt;、なのかもしれません。つまり&lt;strong&gt;規模であったり、データ形式であったり、アカウントの範囲であったり、影響範囲であったり、そういったやり直すために必要な勘所を抑えて、スクラップビルドが現実的な範囲でアプリケーションを有効に活用していく&lt;/strong&gt;、そういう対応が有効なのかなぁと、そんなことを思いました。&lt;/p&gt;&#10;&lt;p&gt;と言いつつ、&lt;strong&gt;僕はそんなめんどくさいことは嫌&lt;/strong&gt;なので、自分の作るものについては、継ぎ接ぎが破綻しないよう考えながらやります。実際、一からはすごいしんどいと思いますよ。&lt;strong&gt;壊す必要がなければそれが一番&lt;/strong&gt;ですからね。一応ニューゲームも現実的に対抗可能な範囲であるとして、最終手段の保険といったところでしょうか。&lt;/p&gt;&#10;</description></item><item><title>AIプログラミング開発日誌7: 外部プラグインの機能でかなり苦戦</title><link>https://hack-le.com/aiplugins/</link><pubDate>Sun, 17 May 2026 00:00:00 +0900</pubDate><guid>https://hack-le.com/aiplugins/</guid><description>&lt;p&gt;ずっとAIプログラミングやっている。自分用のものがほとんどだが、いくつかは公開してもいいかもしれない、と思うものも出てきた。これは書籍管理をしているところ。&lt;/p&gt;&#10;&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://hack-le.com/images/uploads/2026/05/image-5-700x405.png"&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;em&gt;人に見せても問題なさそうなラインナップ&lt;/em&gt;&lt;/p&gt;&#10;&lt;p&gt;ざっと見てなんとなく見栄えはするかなぁと思うのだけれど、これくらいのものでも、&lt;strong&gt;さすがに非エンジニアにはだいぶ敷居が高いままだ&lt;/strong&gt;…と思う今日この頃。まぁもちろんそれは用途次第であって、コンバータとかちょっとしたものならいいと思うんだけれど。今僕が時間をかけて作っているデジタルコンテンツの管理アプリDigitalShelf（仮）（v0.20.0までいったがv1はとおい）は激しいDB設計の変更などがあり、非エンジニアだと間違いなく破綻するだろうということが何度もあった。&lt;/p&gt;&#10;&lt;h2 id="aiにはしんどい機能だった"&gt;AIにはしんどい機能だった&#10;&lt;/h2&gt;&lt;p&gt;特に今回の変更はしんどかった。今後配布することを念頭に、ユーザがアプリケーションの機能を拡張できるようなプラグイン機能を作っていたのだが、今までで一番引っかかったかもしれない。&lt;/p&gt;&#10;&lt;p&gt;もともとは、ffmpegなどの外部コマンドに依存する特殊な機能をどうインストールするか、というのが問題だった。特にソースコードを開示する気がなくなったため、GPLの扱いは慎重にならざるを得ない。ソースコードを開示しないのは、なんか最近セキュリティの名目でAIによるOSSアタックという謎のプレイが流行しているからだ。ただでさえOSSなんてボランティア精神が必要なのに、なにをしているのか…。&lt;/p&gt;&#10;&lt;p&gt;ということで、配布するならバイナリかなぁと思ったのだが、そうすると&lt;code&gt;pdftoppm&lt;/code&gt;や&lt;code&gt;ffmpeg&lt;/code&gt;といった外部コマンドのインストールをどうするかな、という問題が立ちはだかる。特にGPLは混ぜると開示せざるを得なくなってしまうし。&lt;/p&gt;&#10;&lt;p&gt;それで、外部コマンドについてはプラグイン形式とすることで、ライセンスやインストールの問題をクリアしつつ、拡張性をもたせようと思った。これは実際応用範囲が広いし、ユーザが好き勝手できる良い機能だ。たとえば&lt;code&gt;yt-dlp&lt;/code&gt;を使った機能なんかはさすがに配布しづらいわけだが、個人がプラグインとして導入する分には勝手なので、自由度が大きく広がる。&lt;code&gt;whisper&lt;/code&gt;なんかも混ぜれば、手軽に動画のDLと文字起こしで検索システムも作れそうだ、などと考えていた。&lt;/p&gt;&#10;&lt;p&gt;AIに着想を伝えたところ、AIも「それはたいへん素晴らしいアイディアです」といつものことながら礼賛して、いきなり実装を始めたのだが、まぁこれがカオスであった。データベースからワークフローの設計までかなり手をいれることになってしまった。&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;AIに任せきりにしても一応機能自体は実現するのだが、無数の変数と設定項目の入り組んだとんでもなく複雑なカオスが出来上がる&lt;/strong&gt;のである。なぜ設定が必要なのか不明な項目、手順を先に指定した後に目的と名前を聞くような不可解な順番、無限に増える変数……明らかに管理不可能である。&lt;/p&gt;&#10;&lt;p&gt;それで結局、不要な項目とデータベース設計の冗長な部分を指摘しつつ、自分で要件を決め直して、かなり根本的なところから実装させなおす必要があった。まぁなんとか形にはなってきたんだが…。&lt;/p&gt;&#10;&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://hack-le.com/images/uploads/2026/05/image-3-700x711.jpg"&gt;&lt;/p&gt;&#10;&lt;p&gt;その過程で出来ていたものがまた出来なくなることも多々あり、大いに苦労した。&lt;/p&gt;&#10;&lt;h2 id="aiプログラミングの実際的しんどさと恐らくの無理解の乖離"&gt;AIプログラミングの実際的しんどさと、恐らくの無理解の乖離&#10;&lt;/h2&gt;&lt;p&gt;これはAIというやつの性質がよく出ている。&lt;strong&gt;AIは局所的プログラミングの天才なのだが、全体を見通すことに書けては鈍才もいいところ&lt;/strong&gt;なのだ。しかしシステムというやつはどんな小さなものでも全体の整合がすべて。なので、目的を見据えながら全体を見通し帳尻をあわせて整えるという、一番しんどいところが結局人間任せであるから、結局時間はかかるし苦労もする。要件定義に基づいてアーキテクチャ設計とデータベース設計という、抽象と具体の極致でそれぞれAIを制御しないといけない。&lt;/p&gt;&#10;&lt;p&gt;こういう感じで普通に人日がかかっているので、完全AIプログラミングで制作しました！として公開し、もしそれを「AIで作ったんだから誰でもすぐできるようなものなんでしょ」と言われるとムカッとするだろう。&lt;/p&gt;&#10;&lt;p&gt;多分&lt;strong&gt;AIでコーディングしている人たちは大なり小なりその難しさについて実感しているはずで、「確かに開発速度は上がったがエンジニアが不要になるはずがない」というのは完全にそのとおり&lt;/strong&gt;であると思う。一方で、開発速度が上がっていることも事実であり、明らかに1人で数人の業務委託を切れるくらいのスピード感になっているはずだ。&lt;/p&gt;&#10;&lt;p&gt;となると、&lt;strong&gt;エンジニアが今までどおり必要とされるには、ソフトウェアの需要もやはり数倍になる必要がある&lt;/strong&gt;。もしかしたら数十倍かもしれない。しかし、「ITエンジニアの不足」が言われていたのは確かだが、さすがに数倍や数十倍必要というわけではなかったはずだし、またそもそも本当にソフトウェアにそこまでの需要が本来あったのかも疑わしい。&lt;/p&gt;&#10;&lt;p&gt;なので、&lt;strong&gt;結局ITエンジニアの需要については強烈な下落圧力がかかるはず&lt;/strong&gt;で、ソフトウェアエンジニアはもうオワコン、とは言わずとも中長期的にはやはり厳しくなるのではなかろうか。&lt;strong&gt;しかも周囲からはどうせAIがやってるんでしょ？という目で見られるのだろう&lt;/strong&gt;し、そういったことは評価や給与に反映されるのだろう。現実に難しいかどうかは問題ではない。世間の人がどう思うかが問題なのだ。現実の難しさと需要で給与が決まるなら人手不足倒産なんか起きていない。&lt;strong&gt;どんなにしんどかったり難しかったりしても、人がそれに対価を払いたくないと思うのであれば、ただ取引不成立になるだけ&lt;/strong&gt;だ。&lt;/p&gt;&#10;&lt;h2 id="itエンジニア初めての逆風"&gt;ITエンジニア初めての逆風？&#10;&lt;/h2&gt;&lt;p&gt;結局、&lt;strong&gt;ひたすら職業として上り調子であったソフトウェアエンジニアにとって、初めての社会的な逆風ということになる&lt;/strong&gt;かもしれない。個人的には、ソフトウェアエンジニアはむしろ他業界に散らばったほうがいいと思っているし、僕自身はもはや組織から離れたので、別にもういいのだが、しかしまぁ、今後のエンジニア業界がどうなっていくのかは、興味深く見守っていきたいところだ。&lt;/p&gt;&#10;&lt;p&gt;&amp;lt;関連記事&amp;gt;&lt;/p&gt;&#10;&lt;div class="blog-card-wrapper"&gt;&#10; &lt;a href="https://hack-le.com/ai-selfapps/" class="blog-card"&gt;&#10; &lt;div class="blog-card-content"&gt;&#10; &lt;div class="blog-card-label"&gt;&#10; &lt;svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"&gt;&lt;/path&gt;&lt;path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"&gt;&lt;/path&gt;&lt;/svg&gt;&#10; &lt;span&gt;あわせて読みたい&lt;/span&gt;&#10; &lt;/div&gt;&#10; &lt;div class="blog-card-title"&gt;AIプログラミング開発日誌：セルフホストしているアプリを管理するアプリをセルフホストしている&lt;/div&gt;&#10; &lt;div class="blog-card-url"&gt;/ai-selfapps/&lt;/div&gt;&#10; &lt;/div&gt;&#10; &lt;div class="blog-card-thumbnail"&gt;&#10; &lt;img src="https://hack-le.com/images/uploads/2026/04/eyecatch_49558_1777434933.webp" alt="AIプログラミング開発日誌：セルフホストしているアプリを管理するアプリをセルフホストしている" loading="lazy" /&gt;&#10; &lt;/div&gt;&#10; &lt;/a&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;div class="blog-card-wrapper"&gt;&#10; &lt;a href="https://hack-le.com/aiprog/" class="blog-card"&gt;&#10; &lt;div class="blog-card-content"&gt;&#10; &lt;div class="blog-card-label"&gt;&#10; &lt;svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"&gt;&lt;/path&gt;&lt;path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"&gt;&lt;/path&gt;&lt;/svg&gt;&#10; &lt;span&gt;あわせて読みたい&lt;/span&gt;&#10; &lt;/div&gt;&#10; &lt;div class="blog-card-title"&gt;AIプログラミングで作ったもの実例集&lt;/div&gt;&#10; &lt;div class="blog-card-url"&gt;/aiprog/&lt;/div&gt;&#10; &lt;/div&gt;&#10; &lt;div class="blog-card-thumbnail"&gt;&#10; &lt;img src="https://hack-le.com/images/uploads/2026/03/eyecatch_48966_1774943837.webp" alt="AIプログラミングで作ったもの実例集" loading="lazy" /&gt;&#10; &lt;/div&gt;&#10; &lt;/a&gt;&#10;&lt;/div&gt;&#10;&#10;</description></item></channel></rss>