AIに実装させると速い。ただし「何を作るか」を決めるところは速くならない。
SE歴20年の筆者が、iPhoneの写真をNASへ退避するツールを作った。書いたコードより先に、4つの実装方式を比較して3つを捨てる作業があった。そこで気づいたのは、5つ書いた要件のうち、方式を決めたのは2つだけだったということだ。
残り3つは、どの方式を選んでも実現できた。つまり選択に何も効かなかった。要件を並べる作業と、選択肢を消す要件を見つける作業は別物だった。
要件を5つ書いた。効いたのは2つだった
5つの要件
作りたかったものはこうだ。
| ID | 要件 |
|---|---|
| ① | 未退避の写真だけを追加で退避したい |
| ② | 家族それぞれのiPhoneに対応したい |
| ③ | 過去に別手段で退避した分も「退避済み」と判定したい |
| ④ | 退避したあとiPhone側を削除したい |
| ⑤ | 年月フォルダで探しやすく格納したい |
一見どれも同じ重さに見える。実際、書いた時点では優先度をつけていなかった。
③と④だけが選択肢を消した
方式を検討し始めて分かったのは、③と④だけが「できる/できない」を分けるということだった。
③は「NAS上にある数千〜数万のファイルを全部走査してハッシュを取り、索引を作る」という処理を要求する。この処理をどこで動かすかで、実行環境が決まってしまう。
④は「削除は取り返しがつかない」という性質から、消す前に「NAS側に確かに存在し、中身が一致する」ことを検証する仕組みを要求する。検証できない方式は、そもそも削除まで到達できない。
一方①②⑤は、どの方式を選んでも実現できた。①の重複判定は判定基盤さえあれば方式を問わない。②はユーザーごとに保管領域を分ければいいだけ。⑤は命名規則を決める話で、実装場所とは無関係だ。
気づいたこと
要件を書き出す作業と、その要件が選択肢を消すかどうかを判定する作業は、まったく別だった。前者は誰でもできる。後者をやらないと、要件が5つあるのに全部同じ重さに見えて、方式を決められない。
逆に言えば、選択肢を消す要件さえ見つかれば、残りは後回しでいい。今回で言えば③④の2つを軸に方式を選び、①②⑤は選んだ方式の中でどう作るかの話に落ちた。
4つの方式を、要件で潰した
案A:iPhoneだけで完結させる
iPhoneのファイルAppはSMBのファイルサーバに直接接続できる。ショートカットAppと組み合わせれば「写真を検索→ファイルを保存→写真を削除」まで組める。開発者ライセンスも要らない。PCを経由しないので理想に近い。
③で落ちた。 ショートカットには、NAS上の既存ファイルのハッシュを取って照合する手段がない。できるのは「バックアップ済みアルバムに入れたかどうか」程度で、それは「このアプリで移したものだけ」のタグ付けにすぎない。過去の資産とは突合できない。
④でも落ちた。 転送が途中で切れたことを検知する手段がないまま、削除に進むことになる。
案B:Windows PCにUSB接続する
WindowsはiPhoneをMTP(Media Transfer Protocol)デバイスとして認識する。エクスプローラの「Apple iPhone」がそれで、標準の「写真の取り込み」と同じ経路だ。Microsoftがポータブル機器の中身を扱うために策定したプロトコルで、Windows側にクラスドライバが標準で入っている。
③④の両方を満たせた。 PCからNASをSMBで読めるので全走査・ハッシュ索引化ができる。コピー→ハッシュ再照合→検証OKのものだけ削除、という手順も組める。
案C:NAS上でアプリを動かす
NASの中でプログラムを動かせば、走査は速い。
成立しなかった。 うちのLinkStationは基本的にユーザープログラムを載せられない。そもそもiPhone側から写真を取りに行く手段がないので、要件以前の問題だった。
案D:市販アプリを買う
PhotoSync等を買えば、案Aの課題(安定性・SMB対応)はほぼ解決する。金で解決できるならそれが一番速い。
③⑤で落ちた。 転送は解決するが、既存資産との突合と、既存ファイルの再配置は解決しない。ここは製品の守備範囲外だった。
結果
| 案 | ③既存資産との突合 | ④検証つき削除 | 判定 |
|---|---|---|---|
| A: iPhone単体 | × | × | 落選 |
| B: Windows+USB | ○ | ○ | 採用 |
| C: NAS上で実行 | — | — | 成立せず |
| D: 市販アプリ | × | ○ | 落選 |
表を作ると、③の列がほぼ勝敗を決めているのが見える。「過去に別手段で退避した分も退避済みと判定したい」という一行が、方式をひとつに絞り込んだ。
この要件は、本当に必要だったのか
落とせば案Dで済んだ
正直に書くと、③を落とせば市販アプリで済んだ。買ってきて設定すれば終わりで、自分で作る必要はなかった。
それでも③を残したのは、NASに何年分もの写真が既に散らばっていたからだ。手動でコピーしたもの、別のアプリで送ったもの、整理されていないフォルダ。ここを無視して新しく全部コピーすると、同じ写真が二重三重に増える。「増える」のは容量を空けたい目的と真逆なので、落とせなかった。
実際どうだったか
作って動かしたら、数字で答えが出た。2台目のiPhoneを繋いだとき、写真3,235件を退避した一方で、5,122件が「もうNASにある」と判定された。
何も考えずに全部コピーする方式だったら、この5,122件が丸ごと二重保存になっていた計算になる。③を残した判断は、この数字で答え合わせができた。
逆に、消えた要件もある
当初は「iPhoneに繋がなくても自動で退避したい」という願望があった。案Aを最初に検討したのはそれが理由だ。
これは③④と両立しなかったので諦めた。ただし完全に捨てたわけではなく、日常のラフな保全はWi-Fi経由、重い初期作業はUSB経由という役割分担に落ち着いている。実際、既存資産6,114件の索引化はPC側でしかできなかったが、日常の追加はスマホアプリから流すだけで済んでいる。
要件は「満たす/満たさない」の二択ではなく、どの経路で満たすかまで分解すると、諦めたつもりのものが半分だけ残ることがある。
AIに実装させる前にやること
速くなるのは実装だけ
Claude Codeを使えば実装は速い。ただし今回で言えば、速くなったのは案Bを選んだ後の話だ。4案を比較して3つを捨てる作業は、要件と手元の環境を突き合わせる人間側の仕事だった。
ここを飛ばして「iPhoneの写真をNASに退避するツールを作って」と投げると、たぶん動くものは出てくる。ただし③を満たさない実装になる可能性が高い。要件として言っていないからだ。そして③を満たさない実装は、動いてはいるが二重保存を量産する。
言っていないことが満たされないのは、実装に限らない。AIにブログを書かせたら数字を捏造した話では、「出典のない数字を書くな」と指示していなかったせいで本番に嘘の数字が載った。指示していない条件は勝手には守られないという点で、構造は同じだ。
「選択肢を消す要件」を先に探す
今回の学びを一般化するなら、要件を並べたあとに一度こう問う。
この要件を落としたら、選べる方式は増えるか?
増えるなら、それは方式を決める要件。優先して検討する
増えないなら、どの方式でも実現できる要件。後回しでいい
今回は5つのうち2つがこれに該当した。逆に言えば3つは、後回しにしても方式選定には影響しなかった。全部を同じ重さで考えていると、この差が見えない。
仕事の現場だと、IPAの非機能要求グレードのように、要求項目を網羅的にリストアップしたうえで要求レベルを段階的に示す枠組みがある。個人開発でそこまでやる必要はないが、「全部の要件が同じ重さではない」という発想自体は同じだ。今回やったのは、その簡易版を自分の5要件に当てただけとも言える。
なおAIに相談する場合も、この判定は自分でやったほうがいい。「要件を5つ挙げたが、方式を絞り込むのはどれか」と聞けば答えは返ってくるが、その要件を落とせるかどうかは、自分の事情でしか決められない。今回で言えば「NASに既存資産が散らばっている」という自宅の事情を知らなければ、③の重さは判定できなかった。
この線引きはClaude Code /goalで自走させたときの完了条件の書き方とも重なる。手を動かす部分を任せるほど、任せる前に決めておく部分の比重が上がる。
よくある質問
- Q要件を全部満たす方式が無かった場合はどうしますか?
- A
今回はたまたま案Bが③④の両方を満たしましたが、満たす方式が無ければ要件を落とす判断になります。落とす順番は「選択肢を消さない要件」からです。どの方式でも実現できる要件は、方式を決めたあとで作り込めるので、先に諦める必要がありません。逆に③のような要件を落とすと、選べる方式が一気に増えるかわりに作りたかったものが変わります。
- Q市販品で済むかどうかは、どこで見分けましたか?
- A
「その製品の守備範囲に入っているか」で見ました。PhotoSync等は転送の安定性やSMB対応という課題を解決する製品で、そこは実際に解決します。ただし「NAS上に既に散らばっている過去の資産と突合する」のは転送ツールの仕事ではありません。自分の要件が製品のカテゴリからはみ出していると気づいた時点で、買っても解決しないと判断しました。
- Q要件は最初から5つに整理できていましたか?
- A
いいえ。最初は「iPhoneの容量を空けたい」という願望だけでした。5つに分かれたのは方式を検討しはじめてからで、「これはどうやって実現するんだ」と詰まるたびに要件として立ち上がってきた形です。特に③は、NASの中を見て過去の写真が散らばっているのを確認してから追加しました。要件定義を先に完了させてから設計に入る、という順番では進みませんでした。
- QWindows PCにUSB接続する方式(案B)を選んだ決め手は何ですか?
- A
WindowsがiPhoneをMTPデバイスとして標準認識し、PC側から写真を取得できることが決め手でした。PCからはNASもSMBで読めるため、既存ファイルの全走査とハッシュ索引化ができます。コピー後にハッシュを再照合し、検証OKのものだけiPhone側を削除する手順も組めました。要件③④を同時に満たせたのは案Bだけでした。
まとめ
3点にまとめる。
- 要件には「選択肢を消すもの」と「消さないもの」がある。 今回は5つのうち2つだけが方式を決め、残り3つはどの方式でも実現できた。並べただけでは、この差は見えない
- 消す要件を先に見つければ、残りは後回しでいい。 ③④を軸に方式を選び、①②⑤は選んだ方式の中でどう作るかの話に落ちた
- その要件を落とせるかどうかは、自分の事情でしか決められない。 ③を落とせば市販アプリで済んだ。落とさなかったのは、NASに既存資産が散らばっているという自宅の事情があったからだ
実装の速さの話はClaude Codeで個人サービスを作った正直な話に書いた。そちらは案Bを選んだあとの、手を動かすフェーズの記録になっている。

