ツールとオーケストレーターを分ける — 個人用ソフトウェアエコシステムの設計原則
個人で使うソフトウェアの蓄積は、年単位で増えていきます。最初は単独のスクリプト、次に少し凝った CLI、やがて GUI を持つ完成度の高いツール、それらを束ねた一連の処理 ── と層を重ねながら成長するうちに、いつしか 「自分用ソフトウェア・エコシステム」 と呼べる規模になります。
この成長過程でしばしば見落とされがちな設計判断があります ── エコシステムを構成する要素は、二つの異なる層に属している、という認識です。一つは個別の問題を解く ツール層、もう一つはツール群を組み合わせて目的の作業の流れを成立させる オーケストレーター層。両者を意識的に分離することが、エコシステムの長期的な耐久性と組み合わせやすさを支える設計判断になるといえるでしょう。
この分離は、本サイトの基礎記事 決定論的にではなく、相対的に で述べた 媒介性 ── 道具は目的と作業の「あいだ」に立つ媒介物であり、何が見えるか・何ができるか・何が考えやすいかを規定する1 ── を、エコシステムの規模で実装したものだといえます。ツールを単一責務に閉じることは、その道具が媒介する範囲を意図的に絞り、規定される「思考の形」を予測可能かつ置換可能にすることに他なりません。エコシステムの設計とは、コードを書くことではなく どこに媒介の境界を引くか を決めることだ ── という見立てが、本稿全体を貫きます。
本稿はこの設計原則をはっきり言葉にし、個人用の道具立てにおける実装パターンと、ご自身のオープンソース・エコシステム2 を例にした具体構造を整理してみます。
二つの層の定義
ツール層とオーケストレーター層は、責務とインターフェースで明確に分かれます。
ツール層:
– 単一責務 ── 「動画にチャプターを刻む」「スライド画像の台形歪みを補正する」「LuaTeX で組版する」のような、一つの明確な目的を持つ
– データ形式の持ち主 ── 自身が出力する形式 (.vce.json / 補正済み PNG / PDF など) の正本を保持する
– 独立リリース ── バージョン番号、リリースサイクル、依存関係をそれ自身で管理する
– 配布経路の独立 ── pip 単独パッケージ、独自バイナリ、配布チャネルが他ツールに従属しない
オーケストレーター層:
– 組み合わせが責務 ── 既存ツール群を データの流れで束ねて 目的を達成する
– ツール群を依存として呼び出す ── pip 依存、subprocess、CLI 呼び出しいずれの形でも、自分でツールの実装を抱え込まない
– 作業の流れの論理を担う ── 段階の順序、条件分岐、エラー処理、リトライ、ログを所有する
– 薄く保つ ── 厚くなるとツール層を複製し始めるサインで、その時点で再分離が必要
両層の境界は、標準化されたデータ形式 で引かれます。SRT、PNG、PDF、JSON、YAML ── 既存の長期安定形式が 層と層の境界 (インターフェース) として機能する限り、ツール層は自由に置換でき、オーケストレーター層は実装言語を気にせずツールを呼べる、という性質が成立します。
なぜ分離するのか
分離設計が生む構造的な利点は、四つの軸で整理できるでしょう。
第一に、置換可能性。ツール層が独立していれば、ある段の実装を別のものに差し替えるコストが最小化されます。例えば文字起こしツールを Whisper から別のモデルへ切り替える際、オーケストレーター側は SRT という共通形式しか見ていないので、ツール層の差し替えだけで完結します。これは「正解のツール」を一つ決め打ちにする設計とは逆向きです ── 媒介物が他者の都合や技術の進歩で変わりうる以上、特定の道具に固定するのではなく、境界 (SRT) を固定して道具のほうを相対的に差し替えられるようにする。決定論的にではなく、相対的に という態度の、最も即物的な現れです。
第二に、並行発展。ツール群が独立リポジトリにあれば、それぞれ別のリリースサイクルで進化できます。GUI の改良、フォーマットのバージョンアップ、性能チューニング ── どれも他ツールに影響を与えずに進められる、という構造的な余裕が生まれるといえるでしょう。
第三に、外部再利用。各ツールは元の作業の流れの外でも単独で使える価値を持ちます。perspective-corrector は会議録パイプラインの一部としてだけでなく、スマホで撮ったホワイトボード写真を整える独立アプリとしても価値を持つ ── 単一責務の徹底が、想定外の文脈での再利用可能性を生みます。
第四に、保守責任の分散。オーケストレーター層は薄くなり、ツール層も単一責務に閉じます。そのどちらの保守も、層を混ぜた一枚岩を抱え続けるより、認知的にもコード的にも軽くなる、と整理することができるでしょう。
インターフェースは標準を尊重する
両層の境界を引くデータ形式の選び方には、本サイトの既掲記事 記録を標準化する で論じた原則がそのまま当てはまります ── 個別ツールが標準を発明するのではなく、既存の標準を尊重して繋ぐ。
| データの性質 | 採用する標準形式 | 理由 |
|---|---|---|
| 字幕・タイムコード付きテキスト | SRT | 1990 年代から定着、Whisper はじめあらゆる音声認識ツールが標準出力 |
| 画像 (整形済みスライド等) | PNG / JPEG | 仕様公開、複数実装、長期可読性 |
| 構造化メタデータ | JSON / YAML | 言語非依存、可読、git と相性がよい |
| 組版可能ソース | LaTeX / Markdown | 開放形式、複数実装、30 年級の安定性 |
| 配布物 | PDF/A | ISO 19005 規格、長期保存設計 |
| 動画チャプター | YouTube チャプター記法 / .vce.json | 広く受容済み / プロジェクト固有 |
新しい形式を発明するのは、既存の標準では表現できない情報モデルを扱う場合に限定 する ── これが境界設計の規律だといえるでしょう。.vce.json は数少ない例外で、チャプター + ソースファイル境界 + エンコーダ設定という video-chapter-editor 固有の情報モデルが既存形式に収まらないため、新規定義を選んでいます。
ツール選定 ── 単一責務を徹底する
ツール層に属するソフトウェアの設計判断は、Doug McIlroy が 1978 年に Bell System Technical Journal で示した命題に集約されます3。
Make each program do one thing well. To do a new job, build afresh rather than complicate old programs by adding new “features”.
判断の現場での使い方は単純です ── あるツールに新機能を追加したくなったとき、新ツールとして独立させたら何が困るか を問う。困らないのなら独立させる。これが McIlroy の命題を実務の言葉に直したものだと整理できるでしょう。
ご自身が現在保守しているツール群を、この判断軸で整理すると次のようになります。
| ツール | 単一責務 | 所有する形式 |
|---|---|---|
video-chapter-editor |
動画にチャプターを刻む / 編集する | .vce.json (チャプター + 境界 + エンコード設定) |
perspective-corrector |
スライド写真の台形歪み補正 | 補正済み PNG / A4 PDF |
luatex-docker-remote |
リモート Docker 経由の LuaTeX 組版 | 入力 LaTeX → 出力 PDF |
それぞれが「何をするか」を一行で言える、ことが単一責務の指標になります。一行で言えなくなったら、二つのツールに分割すべきタイミングだといえるでしょう。
オーケストレーター層の実装
オーケストレーター層の実装言語の選択は、しばしば「Python か zsh か YAML か Makefile か」と単一の答えを求める形で立てられがちです。けれども実態としては、それぞれが異なる層で最も枯れた道具 であり、共存させて使い分けるのが筋だといえるでしょう。
| 言語 / ツール | 強み | 役割 |
|---|---|---|
| Make | 1979 年以降の POSIX 標準4。ファイル間依存の宣言 + 冪等な 実行 | パイプライン全体の骨格 (依存関係のグラフ) |
| Python | テスト・デバッグ・例外処理・型ヒント。複雑な変換・分岐ロジック | Make では辛い処理 (テンプレ生成、メタデータ変換) |
| YAML | 宣言的、言語非依存、git と相性がよい | 人手編集する設定 (エンコーダ設定、プロファイル) |
| zsh / POSIX shell | コマンドを繋ぐ最も自然な記法 | シェルラッパ、エイリアス、簡易ランナー |
外部のワークフロー基盤 (n8n、Argo Workflows 等) は サービス横断の統合 + イベント駆動 が真の用途であり、一直線の CLI パイプラインに対しては過剰だといえるでしょう。そうした基盤への依存を背負うことは、本サイトの既掲記事 腐らない資産を設計する で論じた 30 年級の耐久性から離れる選択でもあります。
典型的な Makefile (5 行で骨格が立つ):
report.pdf: report.tex
luatex-pdf $<
report.tex: subtitles.srt slides_corrected/
msw-report --srt subtitles.srt --slides slides_corrected/ -o $@
subtitles.srt: $(RECORDING)
yt-srt $< -o $@
slides_corrected/: $(SLIDES_DIR)
perspective-corrector $< -o $@
make report.pdf 一発で、不足分のみ走り、入力に変更がなければスキップする ── オーケストレーター層の本質は 既存の優秀なツールをファイル依存で繋ぐこと で、それが Make の 47 年安定した動作規約にそのまま乗ります4。複雑なロジックや条件分岐、API 呼出しが要る箇所は Python に切り出す、設定値は YAML に外出しする、という形で層を重ねていけば、オーケストレーター自体も「書かない設計」が成立します。
現状から目指す構造へ
media-scribe-workflow は現状、ツール群とオーケストレーターが同じリポジトリの中で混在しています ── GUI (media_scribe_workflow/ui/)、エンコード CLI (vce-*)、ユーティリティ群 (yt-srt、video-trim、video-chapters)、レポートパイプライン (msw-*) が一つのパッケージに同居している状態です。
目指す構造は次のようになります。
独立ツール群 (各リポジトリ):
- video-chapter-editor (GUI + .vce.json 形式の持ち主 + vce-encode/split)
- perspective-corrector (画像補正、既)
- luatex-docker-remote (組版環境、既)
- (将来) subtitle-utils (yt-srt 等の小ツール)
オーケストレーターのリポジトリ:
- media-scribe-workflow (上記ツール群を pip 依存として呼ぶ薄いオーケストレーター)
├─ Makefile (依存関係のグラフ=骨格)
├─ msw_pipeline/ (Python 補助 ── テンプレ生成、メタデータ変換)
└─ profiles/*.yaml (人手編集する設定)
移行の手順は、git subtree split で video-chapter-editor のコミット履歴を保ったまま新しいリポジトリに切り出し、共有モジュール (pipeline.srt_parser、utils の数本) を共通ライブラリ化または各リポジトリに複製するのが王道です。一度に全部やる必要はなく、まず video-chapter-editor を分離し、運用しながら共通モジュール化の判断を蓄積していけば段階的に到達できます。
ここから少し、この設計原則を本サイトの既掲記事との接続で読み直してみたいと思います。
ツールとオーケストレーターの分離は、本サイトで論じてきた複数の主張の 構造的な統合点 だといえるでしょう。
- 決定論的にではなく、相対的に で宣言した態度 ── 道具を「正解の手順」にせず、媒介する範囲を明示して状況に応じて差し替えられるようにする ── の、最も構造的な実装例がこの二層分離。境界 (= 媒介の範囲) を固定し、道具を相対的に置く という形で全篇を貫いている
- 偉大なプログラマは優秀なプログラマのコードを利用する で扱った再利用の原則は、オーケストレーター層が「書かない」を最大化することの設計原理として作動します。Whisper / Claude / LuaTeX / ffmpeg / Qt はすべて他者が長期保守してきた優秀なコードであり、オーケストレーターはそれらを束ねる接続部だけを書く ── これは「自分が書かない部分の媒介を、他者の優秀な実装に委ねる」という媒介の選択でもある
- 記録を標準化する で論じた段階間の受け渡しの取り決めは、ツール層とオーケストレーター層を分ける境界そのもの。標準形式 (SRT、PDF/A、JSON) を尊重することが、両層の置換可能性を保証し、同時に検証 (Verification) ── 隣接する二段階が一致しているかの差異検出 ── を機械的に行いやすくする
- 腐らない資産を設計する で示した 30 年級の耐久性は、ツール層が単一責務に閉じ、オーケストレーター層が枯れた基盤 (Make、POSIX、Python) に乗るときに、そのまま実現される
- Git の 陶器 (porcelain) と配管 (plumbing) 5 の分離は、本稿の主題そのものをコマンド・ライン・ツールの世界で先取りした設計だといえるでしょう。「陶器」がオーケストレーター (人間に磨かれた表面)、「配管」がツール群 (機械的接続部)、両者が安定した境界で結ばれる構造
エコシステムの設計は、コードを書くことではなく、媒介の境界を引くこと だと整理することができるでしょう。どこを単一責務に切るか、どの形式を共通の境界にするか、どの層に「書かない」を徹底するか ── これらの判断が、年単位で蓄積する個人用ソフトウェアを 構造的に維持可能なエコシステム に変える設計の核心だといえます。オンライン講座の文脈でいえば、この境界設計の判断の過程こそが、特定ツールの操作よりも遥かに長く生き続ける教材的価値を持つでしょう。
参考文献
-
媒介性 / 差延 / 検証と妥当性確認 (V&V) の非対称性 の操作的な定義と理論的な扱いについては、本サイトの基礎記事 決定論的にではなく、相対的に の脚注、および著者の Zenodo プレプリント・シリーズ (レター版 DOI: 10.5281/zenodo.20096463) を参照。 ↩
-
本稿の例として参照しているオープンソース・ツール群:
– mashi727/media-scribe-workflow ── 会議記録の自動化パイプライン (現状はオーケストレーターとツールが混在)
– mashi727/perspective-corrector ── スライド写真の台形歪み補正 (独立済)
– mashi727/luatex-docker-remote ── リモート Docker 経由の LuaTeX 組版 (独立済) ↩ -
McIlroy, M. D., E. N. Pinson, and B. A. Tague. “UNIX Time-Sharing System: Foreword.” The Bell System Technical Journal, vol. 57, no. 6, July–August 1978, pp. 1899–1904. ── “Make each program do one thing well. To do a new job, build afresh rather than complicate old programs by adding new ‘features.’“ ↩
-
Feldman, Stuart I. “Make — A Program for Maintaining Computer Programs.” Software: Practice and Experience, vol. 9, no. 4, April 1979, pp. 255–265. ── 1979 年に発表された Make の原典論文。ファイル依存の宣言と差分実行の組合せという設計が、47 年経過した現在も POSIX 標準として使い続けられている。 ↩↩
-
Chacon, Scott, and Ben Straub. Pro Git, 2nd ed., Apress, 2014, Chapter 10 “Git Internals”. https://git-scm.com/book/en/v2/Git-Internals-Plumbing-and-Porcelain ── porcelain / plumbing 用語の出典。 ↩