🤖

ChatGPT を macOS/iOS の「ショートカット」から呼び出す (※要有料 API)

2023/03/03に公開

概要

macOS/iOS の「ショートカット」アプリでは、HTTP リクエストの送信や JSON の簡単なパースができます。これらの機能を組み合わせることで、ChatGPT の API を手軽に呼び出すことができます。

当然 curl などを利用したシェルスクリプト等でも同様のことができるのですが、「ショートカット」を利用することで以下のような利点があります。

  • ショートカットの豊富な入出力方法を使える
    • スクリーンショットの OCR テキスト認識結果を入力に利用したり、ChatGPT の応答を読み上げさせたりも簡単にできる
  • メニューバーから・Dock から・ショートカットキーからなど、簡単に呼び出す方法を手軽に設定できる
  • iOS でも動作する

クリップボードの中身を ChatGPT のリクエストに投げるショートカットの例

ショートカットを作成し、以下のようにアクションを設定します。結果はクリップボードに保存されます。

例1

  1. URLの内容を取得
    • URL: https://api.openai.com/v1/chat/completions
    • 方法 (method): POST
    • ヘッダ
      • Authorization: Bearer + (半角スペース) の後に ChatGPT の API キーを指定
      • Content-Type: application/json
    • 本文を要求 (request body)
      • model (テキスト): gpt-3.5-turbo
      • messages (配列)
        • 項目1 (辞書)
          • role (テキスト): user
          • content (テキスト): 右クリックして「変数を挿入」→「クリップボード」
  2. アラート (レスポンス確認用。これはお好みで)
  3. 辞書の値を取得
    • URLの内容 内の choices を取得
  4. 辞書の値を取得
    • (アクション (3) で取得した値) 内の message を取得
  5. 辞書の値を取得
    • (アクション (4) で取得した値) 内の content を取得
  6. クリップボードにコピー
    • (アクション (5) で取得した値) をクリップボードにコピー

クリップボードの中身にプロンプト文字列をくっつけた上で ChatGPT のリクエストに投げるショートカットの例

例えば ChatGPT を要約のために頻繁に利用している場合、「以下のテキストを要約して下さい」云々を毎回含めるのは面倒です。ここで テキストを結合 アクションを利用すれば、予め用意しておいたテキストを含めてリクエストに送ることができます。

また、複数のテキストに対して同様のアクションを毎回定義するのは面倒です。これについては ショートカットを実行 アクションを入力 (≒ 引数) 付きで呼び出すことで、一連のアクションを関数のように呼び出すことができます。

ついでに、system としての指示 (ChatGPT の振る舞いを指定するメッセージ) も入力可能にしてみます。

擬似コードで示すと以下のような感じです。

# ショートカットは複数の引数を入力できないため、辞書を入力とする
def callChatGPT(**kwargs):
  # `system` への入力
  system = kwargs["system"]
  # `content` の先頭に入力する指示
  preface = kwargs["preface"]

  response = requests.post(
    "https://api.openai.com/v1/chat/completions",
    headers={...},
    json={
      "model": "gpt-3.5-turbo",
      "messages": [
        {
          "role": "system",
          "content": system
        },
        {
          "role": "user",
          "content": preface + "\n" + clipboard_text
        }
      ]
    }
  )

  to_clipboard(response.json()["choices"][0]["message"]["content"])


def summarize():
  callChatGPT(
    system="あなたは高度な日本語処理システムとして振る舞います。",
    preface="以下のテキストを要約して下さい。"
  )


def translate():
  callChatGPT(
    system="あなたは高度な多言語翻訳システムとして振る舞います。",
    preface="以下のテキストを日本語に翻訳して下さい。"
  )

呼び出される側のショートカットの例

ショートカットは複数の入力を受け取ることはできないため、辞書 (連想配列) を受け取ってそれぞれのキーを取り出すようにします。

アクションの設定例を以下に示します。system に入力する文字列をショートカット入力辞書の system に、user のプロンプト文先頭に入力する文字列を preface に入力させることにします。

例2-1

  1. (次のアクションを定義し、ショートカットの入力 を変数の入力とすると出現します)
  2. 入力から辞書を取得
    • ショートカットの入力 から辞書を取得
  3. 辞書の値を取得
    • (アクション (2) で取得した値) 内の system の値を取得
  4. 辞書の値を取得
    • (アクション (2) で取得した値) 内の preface の値を取得
  5. テキストを結合
    • (アクション (4) で取得した値) と クリップボード改行 で結合
  6. (以下、最初の例とほぼ同様なので省略)

呼び出す側のショートカットの例

呼び出す側は、上記で設定したアクションに沿うように辞書を構築して入力 (≒ 引数) に指定します。

他のプロンプトテンプレートを用意したい場合、ショートカットを複製すると量産が容易になります。

例2-2

  1. 辞書
    • system, preface をそれぞれ設定
  2. ショートカットを実行
    • 入力: (アクション (1) で作成した辞書)

おわりに

本記事では、macOS/iOS の「ショートカット」アプリで ChatGPT の API を呼び出す方法を紹介しました。今回作成したアクションは1回のやりとりで完結するプロンプトが前提ですが、うまいことアクションを組み合わせれば、複数回のやりとりを行うことも可能だと思います。

ショートカットは意外と入出力機能が豊富です。例えば「画面の指定領域を OCR した英語テキストを、OCR の誤認識を修正させながら日本語で翻訳・要約する」などの処理も (多少不正確ながらも) 可能です。アクションとプロンプトを組み合わせれば、「iPhone 上でコピーしたテキストに対して気の利いた返事を書かせる」など、アイディア次第で色々できそうです。

Discussion