2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Shelly v8.1.0 —— ChatGPTからスマホを動かす橋になった

2
Posted at

前回の記事(Zenn)では、エージェントに人格と学習力を持たせた話を書きました。会話をひとりの Shelly として続ける、スキルを自分で直す、承認のデフォルトをもう一段閉じる。

v8.0.0 が「エージェントに人格を持たせた」だとすれば、v8.1.0 は「Shelly が ChatGPT とスマホのあいだの橋になった」リリースです。今回も全部は書きません。骨だけ書きます。


まず動画を2本

ChatGPT に頼んだら、スマホが自分で Google マップを操作した

ClosePaw が裏の画面で Google マップを操作する
右下は ClosePaw のビューア(4倍速)。動画(72秒)を見る

ChatGPT から一言で、毎日勝手に論文を要約して Obsidian に保存するエージェントを登録した

16:27 に Shelly が自分で動き、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 に残してあります。

試す

この記事は Zenn にも投稿しています: https://zenn.dev/ryoitabashi/articles/a1d3962cb96a5c

2
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?