前回の記事(Zenn)では、エージェントに人格と学習力を持たせた話を書きました。会話をひとりの Shelly として続ける、スキルを自分で直す、承認のデフォルトをもう一段閉じる。
v8.0.0 が「エージェントに人格を持たせた」だとすれば、v8.1.0 は「Shelly が ChatGPT とスマホのあいだの橋になった」リリースです。今回も全部は書きません。骨だけ書きます。
まず動画を2本
ChatGPT に頼んだら、スマホが自分で Google マップを操作した

右下は ClosePaw のビューア(4倍速)。動画(72秒)を見る
ChatGPT から一言で、毎日勝手に論文を要約して Obsidian に保存するエージェントを登録した

右上の時計は実時刻。動画(45秒)を見る
どちらも Galaxy Z Fold6 の分割画面で、左が ChatGPT アプリ、右が Shelly です。PC は使っていません。
ChatGPT が Shelly のターミナルを叩けるようになった
ChatGPT アプリには Codex のリモート操作があります。手元のマシンで codex remote-control を動かしておくと、ChatGPT からそのマシンでコマンドを実行できる。普通は PC でやる話です。
Shelly は Codex をネイティブに同梱しているので、そのホストをスマホの中で立てられます。shelly codex pair --background でペアリングすると、ChatGPT アプリから見たら「スマホが一台のマシン」になる。ChatGPT が打ったコマンドは、Shelly の JNI PTY の上でそのまま動きます。
ここまでは「スマホでシェルが叩ける」だけの話です。面白くなるのは、その先です。
ClosePaw に、スマホ操作を渡す
画面の操作は Shelly ではやりません。ClosePaw という、AI がスマホの画面を見ながらタップして操作するアプリに任せます。
shelly closepaw --wait "Google マップで下北沢の古着屋を探して、評価の高い2軒を Tokyo Vintage リストに保存して"
ChatGPT がこれを打つと、Shelly は ClosePaw にタスクを渡します。ClosePaw は Shizuku の仮想ディスプレイ、つまりスマホの「裏の画面」で Google マップを操作する。前面の ChatGPT と Shelly はそのまま使えます。
Shelly 用に ClosePaw をフォークして、Shelly の署名にピン留めした版を作りました。Shelly からの依頼だけは ClosePaw の確認ダイアログを出さず、ClosePaw の画面も開かずに裏で走ります。
承認は、スマホを持っている人だけ
ここが一番時間を使ったところです。
ChatGPT からスマホを操作できる、ということは、ChatGPT(外部の AI)が依頼から実行まで一人で完結できてしまう、ということでもあります。読んだ Web ページに「ついでにこれも実行しろ」と仕込まれていたら、人が一度も見ないままスマホが動く。
なので、ClosePaw への引き渡しは必ずスマホ側で一回承認を挟みます。
- 通知の「Approve」(画面ロックの解除が必要)
- Shelly のチャットに
approve 1a2b3c4dと打つ
ChatGPT からは承認できません。ターミナルから承認ファイルを書いても通りません(承認の nonce はプロセスのメモリにしか置いていない)。ChatGPT に「承認していいですか?」と聞かせて「はい」と返す形も考えましたが、その「はい」を最終的に打つのは ChatGPT 自身なので、やめました。
通知から承認しても Shelly が全画面にならないようにもしました。分割画面のまま、通知の Approve を押せば裏で走り出します。
結果が ChatGPT に返ってくる
最初の版では、ClosePaw が作業を終えても、ChatGPT は「承認待ちです」で止まったままでした。ClosePaw の結果を Shelly に返す経路がなかったからです。デモを撮ってみて、結果が見えないと全く感動しないことに気づきました。
v8.1.0 では、ClosePaw が作業を終えると、結果の要約を Shelly に送り返します。
- 送り元が本物の ClosePaw 変種か(署名のピン留め、PendingIntent の作成元、API 34+ なら送信元パッケージ)
- Shelly が実際に出した依頼か(依頼ごとの 128bit nonce、一回限り)
を全部確かめたものだけを受け取ります。shelly closepaw --wait は承認と完了まで待って、その結果を表示する。ChatGPT はそれを読んで「KLD TOKYO と NUIR VINTAGE SHIBUYA を保存しました」と答えます。結果の文章はデータとして扱い、制御文字や双方向制御文字は取り除いています。
ChatGPT からエージェントを登録する
もう一本の動画はこちらです。
shelly agent add "Every day at 16:27, collect the latest AI research papers from arXiv and Hugging Face, pick 3 notable ones and summarize them. Write the summaries in English."
ChatGPT がこれを打つと、Shelly のチャットに登録案が出ます。Shelly で一回確認すれば、あとは毎日 16:27 に、ChatGPT も人のタップも無しで Shelly が起きて、Perplexity で調べて、出典付きのノートを Obsidian に書きます。
ChatGPT は「頼む」担当、ClosePaw は「画面を動かす」担当、Shelly は「スマホの中で毎日働く」担当。この分担がやっと形になりました。
デモを撮って見つかったもの
撮影は 8 テイクくらいかかりました。そのたびに直したものがあります。
- 「パープレで」と指名しても、登録した時点で「自動」に上書きされ、予約実行では毎回キーワードで選び直されていた。指名したツールを保存し、予約実行でも守るようにした
- 英語で頼んだのに、要約が日本語で返ってきた。ユーザーの記憶やプロフィールの言語に引っ張られていた。タスク文の言語を最優先にした
- 前回のやり方を「スキル」として使い回すと、追加の指示(「英語で」)が落ちることがあった
- 承認できない下書きに通知の Approve が出ていて、押しても黙って何も起きなかった。予約時刻を過ぎてから承認すると、初回が黙って翌日になっていた。どちらも見えるようにした
- ClosePaw のモデルは gpt-4.1-mini だと「3軒保存して」で迷子になった。gpt-4.1 にして、件数を2軒にした
撮影の途中で、裏の画面を見せるための目のマークを押したら LINE が開いて、トーク一覧が映ったこともあります。その録画は消しました。
補足: リリース署名を変えた
v8.0.2 までのリリース APK は、React Native / Expo のテンプレートに入っている公開の debug 鍵で署名されていました。誰でも「Shelly の更新」に見える APK を作れた、ということです。
v8.1.0 からは非公開のリリース鍵で署名しています。APK Signature Scheme v3 の鍵ローテーションで、Android 9 以降はアンインストール無しでその場で更新でき、データもそのまま残ります。鍵ローテーションの途中で INSTALL_FAILED_DUPLICATE_PERMISSION に当たって lineage を作り直した話は、DEFERRED.md に残してあります。
試す
- APK: GitHub Releases(v8.1.0)
- ClosePaw の Shelly 用変種: https://github.com/RYOITABASHI/closepaw/releases
- License: GPLv3
この記事は Zenn にも投稿しています: https://zenn.dev/ryoitabashi/articles/a1d3962cb96a5c