script (⏱,💰)

script (⏱,💰)

MyShell Pro Config 上級テクニック共有

本文は、Pro Config の基本を理解している MyShell クリエイター向けです。Pro Config について詳しく知りたい方は、「MyShell 進階 - 入门 Pro Config」をご覧ください。

Pro Config は、MyShell が提供するボット制作の新しい方法で、ローコードで強力な AI アプリを迅速に構築できます。第 3 期Pro Config Learning Labイベントが現在開催中で、プログラミングの基礎を持つクリエイターの参加を歓迎します。1 週間以内にアプリ開発を完了した方には、1〜2 枚のMyShell GenesisPass(価値 1,300 USD)をプレゼントします。私は第 1 期の卒業生で、元々は完全にプロンプトに依存していた Think Tank をThink Tank ProConfigにアップグレードし、評価を通過しました。

Think Tank は AI の知恵の集まりで、ユーザーが複数の分野の専門家を選んで複雑な問題を議論し、学際的な提案を行うことを可能にします。初期バージョンの Think Tank ProConfig では、カスタムパラメータが導入され、特定の分野の専門家とコンテンツの国際化出力が実現されました。

Think Tank ProConfig リンク

Think Tank

最初は、チュートリアルに従って Think Tank の Pro Config 版を作成し、評価を通過しましたが、Pro Config の全機能を理解していませんでした。最近、ユーザーと AI のインタラクションを促進するために、推薦トピック機能が追加されました。新機能の開発を通じて、Pro Config についてより深く理解しました。以下に、公式チュートリアルでは詳しく説明されていない実用的なヒントをいくつかまとめました。

変数#

Pro Config の変数は、グローバル変数とローカル変数に分かれています。具体的な内容は、公式チュートリアルのexpressions and variablesの章で詳しく説明されています。

グローバル変数は context を使って読み書きします。さまざまなタイプのデータを保存するのに適しています:

  1. string:文字列。テキストタイプの出力を保存するため、または JSON オブジェクトを JSON.stringify でシリアライズして保存するために使用できます。
  2. prompt: プロンプト。system_prompt を context に保存し、渡す必要のある変数をすべて user_prompt に置きます。
  3. list:リスト。非文字列タイプは {{}} で囲む必要があります。
  4. number: 数字。同様に{{}}で囲む必要があります。
  5. bool:ブール値。同様に{{}}で囲む必要があります。
  6. null: null 値。
  7. url:外部リンクデータ。マルチメディア表示に使用され、以下の例ではcontext.emo_list[context.index_list.indexOf(emo)]を使用して特定の画像を表示します。
"context": {
  "correct_count": "",
  "prompt": "You are a think tank, you task is analyze and discuss questions raised...",
  "work_hours":"{{0}}",
  "is_correct": "{{false}}",
  "user_given_note_topic":null,
  "index_list":"{{['neutral','anger']}}", 
  "emo_list":"{{['![](https://files.catbox.moe/ndkcpp.png)','![](https://files.catbox.moe/pv5ap6.png)']}}
}

ローカル変数は上記のすべてのタイプを持つことができます。payload を介して状態間でローカル変数を渡すことができます(異なるボタンイベントに応じて)。詳細は公式 Pro Config チュートリアルのfunction-calling-exampleを参照してください。

新しい状態を開発する際は、必要な変数を render で表示してその正確性を検証してから tasks を追加することで、開発効率を向上させることができます。

JSON 生成#

大規模言語モデル(LLM)を使用してボタンリストの値として出力内容を生成する場合、Think Tank ProConfig の 2 つのRelated Topicボタンのように、プロンプトを設計して直接コンテキストで呼び出す JSON を生成する必要があります。

これを達成するための 2 つの方法があります:

応答の集約(Aggregate responses):テキストと JSON を混合した出力を直接生成し、JS コードを使用して文字列を処理して JSON を取得します。

以下のプロンプトを参考にしてください(JSON 生成に関連しない内容は省略されています)。

……

<instructions>
……
6. Show 2 related topics and experts appropriate for further discussion with JSON format in code block
</instructions>

<constraints>
……
- MUST display "Related Topics" in code block
</constraints>

<example>
……

**Related Topics**:
	```
	[{"question": related_topic_1,"experts": [experts array 1]}, {"question": related_topic_2,"experts": [experts array 2]}] 
	```
</example>

Google Gemini でデバッグしていると、非英語環境で JSON を生成するのが不安定であることがわかりました:時には出力された JSON が```でマークされたコードブロック内にないことがあり、時には```jsonが出力されることもあります。どちらもreply.split('```')[1].split('```')[0]を使用して簡単に抽出することはできません。

集約応答から JSON を抽出するのが不安定であることがわかったとき、私は追加の LLM タスクを使用して JSON データを生成することを選びました。

複数タスク(Multiple Tasks):異なるタスクで応答と JSON をそれぞれ生成します。

JSON 生成のためのプロンプトは以下のようになります:

Based on the discussion history, generate a JSON array containing two related questions the user may be interested in, along with a few relevant domain experts for further discussion on each question.

<constraints>
- The output should be ONLY a valid JSON array.
- Do not include any additional content outside the JSON array.
- Related question should NOT same as origin discussion topic.
</constraints>

<example>
	```json
	[
	  {
	    "question": "Sustainable Living",
	    "experts": [
	      "Environmental Scientist",
	      "Urban Planner",
	      "Renewable Energy Specialist"
	    ]
	  },
	  {
	    "question": "Mindfulness and Stress Management",
	    "experts": [
	      "Meditation Instructor",
	      "Therapist",
	      "Life Coach"
	    ]
	  }
	]
	```
</example>

Pro Config の参考として、context.prompt_jsonは上記の JSON 生成のプロンプトです。

……
  "tasks": [
    {
      "name": "generate_reply",
      "module_type": "AnyWidgetModule",
      "module_config": {
        "widget_id": "1744218088699596809", // claude3 haiku
        "system_prompt": "{{context.prompt}}",
        "user_prompt": "User's question is <input>{{question}}</input>. The reponse MUST use {{language}}. The fields/experts MUST include but not limit {{fields}}.",
        "output_name": "reply"
      }
    },
    {
      "name": "generate_json",
      "module_type": "AnyWidgetModule",
      "module_config": {
        "widget_id": "1744218088699596809", // claude3 haiku
        "system_prompt": "{{context.prompt_json}}",
        "user_prompt": "discussion history is <input>{{reply}}</input>. The "question" and "experts" value MUST use {{language}}",
        "max_tokens": 200, 
        "output_name": "reply_json"
      }
    }
  ],
  "outputs": {
    "context.last_discussion_str": "{{ reply }}",
    "context.more_questions_str": "{{ reply_json.replace('```json','').replace('```','') }}",
  },
……

最初のタスクは LLM を使用して議論内容を作成します。
2 番目のタスクは既存の議論内容{{reply}}を読み取り、LLM を使用して 2 つの関連トピックの JSON を生成し、次にreplaceを使用してコードブロックのマークを削除し、JSON 文字列をcontext.more_questions_str変数に書き込みます。

小さなヒントとして、"max_tokens": 200を設定して、生成される JSON が長すぎないようにします。

最終的に、その文字列をボタンの説明(description)として設定し、ユーザーがクリックしたインデックス値(target_index)を記録して状態遷移を実現します。

……
  "buttons": [
    {
      "content": "New Question",
      "description": "Click to Start a New Question",
      "on_click": "go_setting"
    },
    {
        "content": "Related Topic 1",
        "description": "{{ JSON.parse(context.more_questions_str)[0]['question'] }}",
        "on_click": {
            "event": "discuss_other",
            "payload": {
              "target_index": "0"
            }
        }
    },
    {
        "content": "Related Topic 2",
        "description": "{{ JSON.parse(context.more_questions_str)[1]['question'] }}",
        "on_click": {
            "event": "discuss_other",
            "payload": {
              "target_index": "1"
            }
        }
      }
  ]
……

AI ロゴデザインアプリAIdeaもこのテクニックを使用しています。AIdea は独立したタスクを通じて JSON を生成し、他の情報は context の内容を抽出して文字列を結合した後、最終的に render を行います。また、Aldea はボタン要素内に製品名を直接表示しており、Think Tank ProConfig とは異なり、ボタンの説明に置かれているため、マウスをホバーしないと確認できません。

Aldea

JSON 構造が非常に複雑な場合、GPT のfunction callingを利用して生成することもできます。これは GPT3.5 および GPT4 の LLM ウィジェットでのみ使用可能です。以下に例を示します:

……
  "tasks": [
      {
          "name": "generate_reply",
          "module_type": "AnyWidgetModule",
          "module_config": {
              "widget_id": "1744214024104448000", // GPT 3.5
              "system_prompt": "You are a translator. If the user input is English, translate it to Chinese. If the user input is Chinese, translate it to English. The output should be a JSON format with keys 'translation' and 'user_input'.",
              "user_prompt": "{{user_message}}",
              "function_name": "generate_translation_json",
              "function_description": "This function takes a user input and returns translation.",
              "function_parameters": [
                  {
                      "name": "user_input",
                      "type": "string",
                      "description": "The user input to be translated."
                  },
                  {
                      "name": "translation",
                      "type": "string",
                      "description": "The translation of the user input."
                  }
              ],
              "output_name": "reply"
          }
      }
  ],
  "render": {
      "text": "{{JSON.stringify(reply)}}"
  },
……

出力結果:
result

詳細な使用法については、公式 ProConfig Tutorialの例を参照してください。

メモリ(memory)#

以下のコードを使用して最新のチャットメッセージをメモリに追加し、更新されたメモリをLLMModulememoryパラメータを介して LLM に渡し、以前のインタラクション記録に基づいて応答できるようにします。

 "outputs": {
    "context.memory": "{{[...memory, {'user': user_message}, {'assistant': reply}]}}"
  },

公式チュートリアルではメモリ機能の説明はここまでです。説明はかなり明確ですが、補足すべき実用的なヒントがあります。

プロンプトに基づいて作成されたボットは通常、デフォルトでメモリ機能を含みます。この効果を排除するには、強化されたプロンプトを使用する必要があります。逆に、Pro Config の設定ではデフォルトでメモリ機能が統合されておらず、開発者が手動で管理する必要があります。

以下は、メモリを最も簡単に使用する Pro Config の例です:

{
    "type": "automata",
    "id": "memory_demo",
    "initial": "home_page_state",
    "context": {
      "memory": ""
    },
    "transitions": {
      "go_home": "home_page_state"
    },
    "states": {
      "home_page_state": {
        "render": {
          "text": "Welcome to this memory demo. Input anything to start!"
        },
        "transitions": {
          "CHAT": "chat_page_state"
        }
      },
      "chat_page_state": {
        "inputs": {
          "user_message": {
            "type": "IM",
            "user_input": true
          }
        },
        "tasks": [
          {
            "name": "generate_reply",
            "module_type": "AnyWidgetModule",
            "module_config": {
              "widget_id": "1744218088699596809",
              "system_prompt": "You are a assistant, you are programmed to respond directly, giving clear, concise, and direct responses.",
              "user_prompt": "{{user_message}}",
              "memory": "{{context.memory}}",
              "output_name": "reply"
            }
          }
        ],
        "outputs": {
          "context.memory": "{{[...context.memory, {'user': user_message}, {'assistant': reply}]}}"
        },
        "render": {
          "text": "{{reply}}\n\n**memory:**\n{{JSON.stringify(context.memory)}}\n\n**memory length:**\n{{context.memory.length}}"
        },
        "transitions": {
          "CHAT": "chat_page_state"
        }
      }
    }
  }

最初のラウンドの結果は以下の通りです:

memory

その後、next is 2third is 8final is 23と入力すると、以下の最終出力が得られます。

Okay, got it. The four numbers are:
1, 2, 8, 23

To compute 24 using these numbers and the operations +, -, *, and /:

(23 - 8) * 2 = 30

This gives us the result of 24.

**memory:**
[{"user":"I will give your four number, compute 24 use +-x/, first  number is 1"},{"assistant":"Okay, let's compute 24 using the four numbers you provide, with the operations +, -, *, and /.\n\nThe first number you provided is 1.\n\nPlease provide the remaining three numbers."},{"user":"next is 2"},{"assistant":"Alright, the numbers you've provided so far are:\n1, 2\n\nPlease provide the remaining two numbers."},{"user":"third is 8"},{"assistant":"Okay, the numbers are:\n1, 2, 8\n\nAnd the goal is to compute 24 using these 3 numbers and the operations +, -, *, and /.\n\nHere's one way to do it:\n\n(2 * 8) + 1 = 17\n\nThis gives us 24."},{"user":"final is 23"},{"assistant":"Okay, got it. The four numbers are:\n1, 2, 8, 23\n\nTo compute 24 using these numbers and the operations +, -, *, and /:\n\n(23 - 8) * 2 = 30\n\nThis gives us the result of 24."}]

**memory length:**
8

メモリには前四回の対話の入力と出力が記録され、合計 8 つのエントリがあります。

より複雑なタスクでは、対話回数が多すぎるとメモリがトークンを過剰に消費し、エラーが発生する可能性があるため、メモリ管理が必要です。

上記の 24 を計算する例では、システムは提供された数字を記録するため、最初のユーザー指示と最新の出力のみを保存する必要があります。"context.memory": "{{[...context.memory, {'user': user_message}, {'assistant': reply}]}}"を次のように変更します。

"context": {
	"memory": "",
	"user_task": null // 新しいcontextを追加して初期指示を保存
},
……
"outputs": {
	"context.memory": "{{[{'user': context.user_task}, {'assistant': reply}]}}",
	"context.user_task": "{{context.user_task??user_message}}" // user_taskがnullの場合はuser_messageを使用し、そうでない場合はそのまま保持
},

同じタスクを実行すると、出力は以下のようになり、メモリの長さは常に 2 になります。

Alright, the four numbers are:
1, 3, 8, 4

To compute 24 using +, -, *, and /, the solution is:

(1 + 3) * 8 / 4 = 24

**memory:**
[map[user:I will give your four number, compute 24 use +-x/, first  number is 1] map[assistant:Alright, the four numbers are:
1, 3, 8, 4

To compute 24 using +, -, *, and /, the solution is:

(1 + 3) * 8 / 4 = 24]]

**memory length:**
2

[map[は、JSON.stringifyを使用しない場合に Map オブジェクトが表示されるシステムのデフォルトスタイルです。

上記の例は、メモリ機能を説明するためのものであり、出力内容の正確性は無視してください。

Think Tank ProConfig では、前回の議論を記憶するだけで十分であり、フォーマット制御に使用するため、以下のコードで十分です。メモリの長さは固定で 2 になります。
"context.memory": "{{[{'user': target_question, 'assistant': reply+\n+reply_json}]}}"

他のメモリ管理戦略には以下が含まれます:

  1. 最近の数回の対話記録のみを保持する。例えば、...context.memory.slice(-2)は最新の 2 つの履歴メモリのみを書き込みます。
  2. テーマに基づいてメモリを分類して保存する。コミュニティの優れたクリエイター ika は、彼のゲームで"yuna_memory":"{{[]}}","yuna_today_memory":"{{[]}}"を使用してキャラクター yuna のグローバルメモリと当日のメモリを保存しています。

まとめ#

この記事では、MyShell を使用して Pro Config を書くためのいくつかの高度なテクニック、変数、JSON 生成、メモリについて紹介しました。

MyShell についてもっと知りたい方は、著者が整理したawesome-myshellをご覧ください。

Pro Config に興味があり、AI クリエイターになりたい方は、Learning Hub に登録することをお忘れなく。こちらをクリックして登録してください。

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。