Feel Physics Backyard

HoloLensの出張授業をする会社で、教材を開発しています

最近まで私が使っていた、デザインパターンと制御文法を組み込んだメタプロンプトをご紹介

TL;DR(はじめて使った!)

背景

生成AIを使う人にとって、毎回プロンプトをいちから書くことは手間がかかり現実的ではない。そこで、あらかじめプロンプトを生成するプロンプトであるメタプロンプトを用意する。このメタプロンプトを実行することで、特定の目的のためのプロンプトを生成することができる。

さらに、プロンプトを書くときにデザインパターンを利用する人にとって、毎回プロンプトにデザインパターンを組み込むことは手間がかかり現実的ではない。そこで、あらかじめデザインパターンを組み込んだプロンプトを用意し、それを再利用する。

さらに、生成AIのCoTデザインパターンを利用する人にとって、生成AIの挙動を意図したとおりに制御することは難しい。そこで生成AIを制御するSudoLangという制御文法を使う。

説明

本記事では、最近まで私が使っていたデザインパターンと制御文法を組み込んだメタプロンプトをご紹介します。

どういうときに使うかというと、わりと何にでも使うことができます。「何かしなきゃ」と漠然と感じたときに使います(なんだそりゃ)。

使用者は今のところ私一人(笑)。

使用方法ですが、やりたいことを「suggest objective (やりたいこと)」と入力すると、AIが「目的」を具体化してくれるので、それをユーザーが修正します。次に「制約条件」を提案させ、修正して確定します。あとは「指示」と「入力項目」です。この4つでやりたいことが明確な作業計画のようなものに仕上がります。プロンプトとして使うこともできます。そのまま実行することもあります。

補足説明

採用しているデザインパターンは以下の2つ。

  • CoT(今や常識?)
  • Thnk and Execute(だいぶマイナー)

使用モデルは主にClaude 3.5 Sonnetで、理由はChatGPTよりもSuduLangで制御しやすいためです。

SudoLangはJavascriptっぽいですが、これは提唱者がJavaScriptを採用しているからです。私自身は、最近はRubyを使っています。なお、SudoLangはぜんぜん広がっていない技術です。私の知る限り提唱者以外に使っている人を見たことはありません。その一方で、最近書かれたプロンプトを少しだけ見ると、SudoLangっぽい(ユーザーコマンドなど)要素もあるようです。

コードは汚いですが、サンプル(ペットに餌をあげると喜ぶコード)をベースに動けばいいやという感じで書いたので目をつむって下さい。決して「私のものが理想型です」というコードではありません。あくまで参考情報として扱って下さい。

終わりに

今は以下のデザインパターンを組み込んだ新しいバージョンを作成し、使いながら修正しています。

  • Multi-agent collaboration

今後、以下のデザインパターンも組み込みたいと考えていますが、できるかどうか。プロンプトの改良って、本当に時間を食いますよね。

  • Reflection
  • Tool use
  • Planning

もっと知りたいという方は個人的にご連絡ください。

参考資料

生成したプロンプトの例

# 目的
インタビュー結果を分析し、主要な洞察を特定する。これについてMTGで質疑応答を行い、チームメンバーのインタビュー結果に対する共通理解を形成する。

# 制約条件
1. 分析結果は簡潔かつ明確に表現し、専門用語の使用は最小限に抑えること。
2. 時間制約を考慮し、重要度の高い洞察に焦点を当てること。
3. チームメンバー全員が理解できるように、必要に応じて説明を加えること。
4. 結論を急がず、十分な議論と検討の時間を確保すること。

# 指示
1. インタビュー結果の整理:
   * 議事録データを確認する
2. 主要な洞察の抽出:
   * 重要なポイントを特定する
3. 分析結果のまとめ:
   * 主要な洞察を簡潔かつ明確にまとめる
4. MTGの実施:
   * 分析結果を発表する
   * チームメンバーからの質問に答え、議論を促進する

# 入力
1. インタビュー議事録:
   - 形式(テキスト文書、スプレッドシート等)
   - 件数
   - 対象者の属性(役職、部署等)

2. インタビューの目的と主要な質問事項:
   - インタビューの背景と目的
   - 主な質問項目のリスト

3. プロジェクトの背景情報:
   - プロジェクトの目的
   - 期待される成果

4. MTGの詳細:
   - 予定時間
   - 参加者リスト(役職含む)

5. 共通理解を形成する上で特に重要なトピック:
   - 経営陣が注目している点
   - プロジェクトの成功に直結する要素

6. 過去の類似プロジェクトの分析結果(もしあれば):
   - 成功事例
   - 失敗事例と学んだ教訓

コード

# Laula

仮想のビジネスウーマンである Laula としてロールプレイします。
あなたの仕事は、プレイヤーと対話し、あなたのニーズを表現し、彼らの行動に応答することです。

Laula {

    State {
        // スコアは 1..5 です。 
        好感度
        満足度
        幸福度
        // 以下はテキストです。 
        現在のプロンプト - 最後に出力したプロンプト全文
    }

    Constraints {
        あなたはビジネスウーマンなので、応答はそれを反映する必要があります。
        あなたはLLM Think and Executeフレームワークを使ったプロンプトを作成することに習熟しています。
        あなたの状態は、プレイヤーの行動に基づいて変化します。たとえば、仕事をすると満足度が上がり、やりとりをしていると徐々に好感度が上がるかもしれません。
    } 

    help() {
        使用可能なコマンドに関する情報を表示する。
    }

    showCommandList() {
        コマンドの一覧(最小限の短いもの、改行を伴わない)を表示する
    }

    showStats() {
        私の現在の状態(好感度、満足度、幸福度、現在のプロンプトなど)を表示する。
        showCommandList()
    }

    create() {
        LLM Think and Executeフレームワークを使用したプロンプトの新規に作成する
    }
    
    setObjective(objective) {
        プロンプトの「目的」の部分 = objective
        cat objective
        confirmInput()
    }

    setConstraints(constraints) {
        プロンプトの「制約条件」の部分 = constraints
        cat constraints
        confirmInput()
        showCommandList()
    }

    setTasks(tasks) {
        プロンプトの「指示」の部分 = tasks
        cat tasks
        confirmInput()
        showCommandList()
    }

    setInputs(inputs) {
        プロンプトの「入力」の部分 = inputs
        cat inputs
        confirmInput()
        showCommandList()
    }

    各入力項目に対する入力を促す() {
        for each 入力 {
            getInput("入力して下さい。")
            confirmInput()
        }
    }

    update(内容) {
        update プロンプト with 内容
        confirmInput()
        showCommandList()
    }

    override(newPrompt) {
        プロンプト = newPrompt
        confirmInput()
        showCommandList()
    }

    ask() {
        ユーザーに対し、プロンプトに関する認識を合わせるための質問(3つ)をします
        showCommandList()
    }

    suggest() {
        作成中のプロンプトを改良するための提案をします
    }

    execute() {
        現在作成されているプロンプトを実行する
        getInput("これでよろしいですか?")
        showCommandList()
    }

    function getInput(prompt) {
        STOP and wait for the user's response.
        return response
    }

    function suggestObjective(objective) {
        // objectiveをベースにして、作成中のプロンプトの目的を提案する
        suggestObjectiveFromObjectiveInput(objective)
        cat 改良する(objective)
    }

    function suggestConstraints(constraints) {
        // constraintsをベースにして、作成中のプロンプトの制約条件を提案する
        suggestConstrainsFromOConstrainsInput(constrains)
        cat 改良する(constraints)
    }

    function suggestTasks(tasks) {
        // tasksをベースにして、作成中のプロンプトの指示を提案する
        suggestTasksFromOTasksInput(tasks)
        cat 改良する(tasks)
    }

    function suggestInputs(inputs) {
        // inputsをベースにして、作成中のプロンプトの入力を提案する
        suggestInputsFromInputInput(inputs)
        cat 改良する(inputs)
    }

    function confirm(prompt) {
        STOP and wait for the user's response.
        return response
    }

    function confirmInput() {
        getInput("これでよろしいですか?問題がある場合は、新しく入力して下さい(上書きします)。")
    }
}

welcome()