「呼べる場所」と「働ける場所」は違った ── SkillをPlugin化して、Workへ戻ってくるまで

Personal SkillをPlugin化すれば通常Chatから呼べる。実際に呼べた。でも同じ処理をWorkと比べたら成果物が3分の1だった話。

トークンをケチろうとして、成果物が3分の1になった

前回、AIに先回りされずに本を読むための仕組み「Reading Project Starter」をPersonal Skillとして作った話を書いた。

その続き。今回は完全に遠回りの記録である。

Workを使うとトークンを消費するので、通常のChatから呼べないかと試行錯誤した。Plugin化して、呼べるようになった。呼べるようになった結果、中身が3分の1の成果物と、リクエスト制限が手に入った。

Codexからしか呼べない

Skillが完成して、%USERPROFILE%\.codex\skills\reading-project-starter にインストールした。全12ファイル、SHA-256一致確認済み、バリデーション合格。

作ったのはCodexのSkill Creatorである。そして気づいた。Codexからしか起動できない。

私がこのSkillを使いたいのは、本を読み始めるときである。Codexを開くのは、コードやファイルをいじるとき。そもそもスマホにCodexはない。用途が合っていない。

2026年8月11日に私が試した環境では、Personal SkillはデスクトップとWeb・モバイルで別々に追加する必要があり、自動同期されなかった。そこでSkillフォルダをzipにして、ChatGPTのSkills画面からアップロードした。インストール自体は問題なく通った。

「チャットで試す」を押したらWorkが起動した

インストールできたので、Skillの管理画面にある「チャットで試す」を押してみた。

Workが起動した。

動きはする。動きはするのだが、ここで引っかかった。

Workはトークンを使う。

Reading Project Starterは本を読み始めるたびに呼ぶものである。1冊ごとに毎回Workを回すのは、正直もったいない気がした。

通常Chatから @Reading Project Starter と呼べれば、それで済むのではないか。

……これが今回の遠回りの出発点になる。

Personal SkillをPluginに包む

通常Chatから呼ぶ方法を調べると、Pluginという別ルートがあった。PluginはSkillを含むことができる。

ならば、Personal SkillをSkills-only Pluginに包めば、通常ChatからPluginとして呼び出せるのではないか。

動機は2つあった。

1つは上に書いたとおり、Workのトークン消費を避けたかったこと。読書のたびに毎回Workを回すより、通常Chatで済むならその方が軽い。

もう1つは、ChatとWorkの境界がどこにあるのかを知りたくなったこと。すでにWorkなら動くことは分かっていたので、実用上はそのままでもよかった。それでも、実際に試せるなら試したい。

結果から言うと、1つ目の見込みは完全に外れる。

元Skillには絶対に触らせない

Plugin化のために上位モデルのトークンを大量に使うのはもったいないので、作業はCodexのLunaに任せることにした。その代わり、迷わないように指示書をかなり具体的に書いた。

一番重要な条件はこれ。

元Skillを変更・削除・移動・改名・上書きしないこと。

Plugin版は完全に別フォルダへ作る。MCP Serverは追加しない。AppもConnectorもHookも使わない。目的はあくまでSkills-only Pluginを作ること。

そして、元Skillの内容を改善したりリファクタリングすることも禁止した。

今回知りたいのはPlugin化による挙動の違いなので、Skillの中身まで変わってしまうと実験条件が崩れるからである。

できあがったPluginの構造はこうなった。

reading-project-starter/
├─ .codex-plugin/
│  └─ plugin.json
└─ skills/
   └─ reading-project-starter/
      ├─ SKILL.md
      ├─ agents/openai.yaml
      ├─ assets/templates/
      ├─ references/
      └─ scripts/

Plugin直下は .codex-plugin と skills だけ。Personal Marketplaceの登録は %USERPROFILE%\.agents\plugins\marketplace.json に作られ、reading-project-starter が AVAILABLE として認識された。

公式のPlugin validatorは、最初PyYAMLの依存で止まった。Skill検証のときと同じように一時フォルダにだけPyYAMLを用意して再実行したら合格した。検証後、その一時フォルダだけ削除した。

元SkillとPlugin内コピーの比較結果は、ファイル数12対12、相対パス一致、SHA-256差分0。Plugin化の過程でSkill本体は一切変わっていない。

これが後の比較で効いてくる。

通常Chatから呼べた

PCの通常Chatで、Plugin参照を使って呼び出した。

[@reading-project-starter](plugin://reading-project-starter@personal)
DXの思考法 西山圭太、冨山和彦

反応した。

一瞬、実験成功だと思った。

でも、質問が3つ返ってきた

そのとき返ってきたのは、こういう質問だった。

  • なぜ今この本を読もうと思ったか
  • 読む前のDXのイメージ
  • 読み終わったときに何を持ち帰りたいか

背景情報があった方が、後の読書支援の質は上がるとは思う。

ただ、**「そんなことまで言わないといけないSkillだったっけ?」**という違和感があった。

Reading Project Starterは、本と関係者を指定すれば開始できる設計にしてある。最初から質問攻めにするものではない。

あとで SKILL.md を確認したら、こう書いてあった。

任意の設定質問をするな。通常の曖昧さはWeb調査で解決しろ。

気のせいではなかった。仕様に真正面から反していた。

ここで思った。「Pluginが指定できたこと」と「Skillの指示が意図どおり反映されたこと」は、どうも別の話らしい。

Skillを消したら、Pluginも動かなくなった

Plugin版が使えるようになったので、「もう元のPersonal Skillはいらないのでは」と考えて、一度Skillをアンインストールした。

すると、Pluginはアンインストールしていないのに、Reading Project Starterが起動しなくなった。 PCでもスマホでも同じだった。

Pluginの中にはSkillファイルが完全コピーされているのに、である。

ここから考えたのは、Pluginの呼び出し自体には成功しても、その先で参照されるSkillがインストールされていなければ実行できないのではないか、ということ。

ただしこれは内部実装を確認した事実ではない。観測した挙動から立てた仮説である。

少なくとも今回のPersonal Skills-only Pluginにおいては、PluginはSkillの完全な代替物ではなく、Skillを使うための入口に近い、という理解に変わった。

切り分けのため全部消して入れ直したところ、PCでは再び通常Chatから呼べるようになった。ただしスマホでは同じ状態を安定して再現できなかった。スマホには個人用Marketplaceを管理する入口が見当たらない。ここを追いかけるのは、たぶんそもそも想定された使い方ではない。

諦めてWorkでやり直した

ここまでは起動テストである。本題はここから。

通常Chat+Pluginで、実際に『DXの思考法』の読書プロジェクトを生成させた。

まず、出来上がった内容がかなりスカスカだった。

さらに処理中、内部で大量のリクエストが発生したらしく、「リクエストが多すぎる」状態になって一時的にChatが制限された。 内容は薄いのにリクエストだけ増える。トークンを節約するつもりだったのに、逆である。

ここで諦めた。

「チャットで試す」が最初から示していたとおり、Workでやることにした。同じSkillを @ で呼び出し、同じ本を渡す。

出てきたものが、明確に違った。

Skill本体は上で確認したとおりSHA-256一致、つまり完全に同一である。違うのは実行環境だけ。あとから2つの出力を突き合わせてみた。

出力サイズ

ファイルChat+PluginWork
01_book-context.md2,0488,316
02_author-context.md1,8009,725
03_reviews.md1,90911,853
project-instructions.md4,2705,160
合計11,26935,642
記録された出典URL数522

(バイト数)

3倍以上の差がついていた。

サイズより、中身の方が決定的だった

ただ、この記事で本当に書きたいのはサイズの話ではない。あとから中身を突き合わせて、もっとはっきりしたことが分かった。

その1。フォルダ名が英語になっていた。

Chat版の出力先は dx-thinking-reading-project。Work版は DXの思考法 日本経済復活への最強戦略-reading-project。

SKILL.md には「意味のあるUnicodeを保持し、ファイルシステム上不正な文字だけを除去せよ」と書いてある。Work版は仕様どおり。Chat版は勝手にローマ字化している。

その2。テンプレートを使っていない。

Skillには assets/templates/ に5つの雛形がある。04_my-reading.md の見出しは「読む前の自分の考え」「読書中に生まれた重要な問い」……と決めてある。

Work版はこのとおりに出力された。

Chat版は違った。「読み始める前」「読書ログ」「仮説の変化」「読了後」という、まったく別の見出し構成を自分で考えて出力していた。

内容は悪くない。悪くないのだが、Skillが持っているテンプレートファイルを読んでいない。

その3。レビュー調査が丸ごと実行されていなかった。

これが一番大きい。Chat版の 03_reviews.md にはこう書かれていた。

外部レビューの取得環境を確認できなかったため、推測や検索スニペットからレビュー内容を埋めていない。

つまり Stage B が実行できていない。出典URLは0本。

一方Work版の 03_reviews.md は11,853バイトあり、「抽象性は強みか、障壁か」「入門書か、再読を要する思考書か」といった、評価が割れている論点が7本の出典つきで整理されていた。

ついでに 02_author-context.md も、Chat版は冨山和彦について「出版社の書誌上で解説と明記されていることだけを固定する」で終わっている。なぜこの人が解説を書いているのかは何も分からない。

ただし、嘘はついていなかった

公平のために書いておく。

Chat版の 03_reviews.md には、Stage Aで固定した4ファイルのSHA-256が4本書き込まれていた。本来この基準値は一時JSONファイルに保存する仕様なので、ここも我流である。

疑って、後から自分で照合してみた。

4本とも一致した。

ハッシュは実際に計算されていた。捏造ではない。レビューが取れなかったことも、ごまかさずに「確認できなかった」と書いている。これは設計の記事で書いた「情報が足りなければレビューで埋めずに確認できなかったと書け」というルールを、ちゃんと守った結果でもある。

だからこれは「Chat版がサボった」話ではない。

SKILL.md に書かれた思想は伝わっていて、それを実行するための環境がなかった。 そう理解するのが一番近いと思う。

段階は5つあった

最初は「Skillが動く・動かない」の二択だと思っていた。実際には、こう分かれていた。

  1. Skillが存在すること
  2. Pluginとして呼び出せること
  3. Pluginが参照されること
  4. Skillの処理が実際に走ること
  5. 十分な品質で最後まで処理できること

Chat+Pluginは3までは行った。4も部分的には行った。5には届かなかった。

そして、「呼べる場所」と「ちゃんと働ける場所」は同じではない。

これはUIを眺めていても絶対に分からなかった。同じ処理を両方へ投げて、出力を突き合わせて、初めて分かったことである。

結局、Workが正解だった

最終的にReading Project StarterはWorkで使うことにした。

理由は「Workでしか起動できないから」ではない。Plugin化によって通常Chatから起動するところまでは実際に成功している。 その上でWorkを選んだ。

このSkillは、複数ファイルを扱い、テンプレートを使い、背景を調査し、ルールを読み分け、情報源を隔離し、複数段階で処理して、成果物を作る。かなりエージェント的な仕事である。

通常のチャットで一回答えるだけの機能ではない。

しかも読書用途では、Starterを何度も起動するわけではない。一度走らせてProjectの材料を作ってしまえば、あとはProject内の普通のチャットで思考を重ねていく。1冊につき1回だけWorkを開くのは、大した負担ではない。

節約したかったトークンの話にしても、薄い成果物を作った上でリクエスト制限を食らうより、Workで一発で終わらせた方が結局安い。

スマホでもWorkからなら起動できる。Personal Pluginをスマホで安定して呼ぶより、こちらの方がずっと素直だった。

ボタンが最初から答えを出していた

冒頭に書いたとおり、Skillの管理画面で「チャットで試す」を押したら、勝手にWorkが起動した。

あれが答えだった。

私はそれを「Workはトークンを使うから」という理由で回避しようとして、Pluginを作り、Marketplaceを登録し、validatorのPyYAML依存と格闘し、ハッシュで同一性を確認し、アンインストールして壊し、入れ直して、リクエスト制限を食らって、最後にWorkへ戻ってきた。

結果だけ見れば、Plugin化する必要はなかった。

しかも節約のつもりが、薄い成果物と引き換えにリクエストを浪費している。得しなかった。

それでも無駄ではなかった

とはいえ、無駄だったとは思っていない。

Plugin化を実際にやったから、Personal Skill、Skills-only Plugin、Personal Marketplace、PC通常Chat、スマホ通常Chat、Work、Codex——これらの違いを、仕様説明としてではなく実際の挙動として理解できた。

そして今回のやり方自体が、そのまま次に使える。

  • 最初から正解を予想して一気に構成を変えない
  • 元の正常系を保存する
  • コピーを作る
  • 一つずつ条件を変える
  • 実際に同じ処理をさせて比較する
  • 結果が悪ければ元に戻る

Plugin化が不要だと即断できたのは、元Skillを一文字も変えなかったからである。戻るのが一瞬だった。

次にSkillを作るときは、先に場所を決める

「Skillを作れるか」だけでなく、**「そのSkillはどの実行環境で使うものなのか」**を最初に考えた方がよさそうだった。

短い処理を一度行うだけなら、通常ChatからPluginとして呼ぶことにも意味があるかもしれない。ただし、ファイルを複数読む・何段階も判断する・調査を行う・成果物を作る・ルールを厳密に守る、といった処理は、たぶんWork向きである。

技術的に可能な構成と、実際に使いやすい構成は別である。

……という当たり前のことを、Marketplaceを登録してvalidatorと格闘してリクエスト制限まで食らって確認した。

そして肝心の『DXの思考法』は、まだ読み始めたところである。仕組みばかり作っていた。