Skip to content

Latest commit

 

History

History
470 lines (341 loc) · 28.6 KB

tutorial-ja.md

File metadata and controls

470 lines (341 loc) · 28.6 KB

1. オブジェクト指向型汎用プロンプト用語定義: オブジェクト指向型プロンプトプログラミングの可能性

日本語(Japanese) 英語(English)

1. はじめに

本稿では、AIとのコミュニケーションに革新をもたらす可能性を秘めた、「オブジェクト指向型プロンプトプログラミング」という新しいアプローチについて解説します。これは、従来のプロンプトエンジニアリングとは一線を画す、オブジェクト指向プログラミング(OOP)の概念をプロンプト設計に応用した手法 です。

プログラマーの皆さん、AIモデルへの指示に自然言語だけでなく、使い慣れた「クラス、オブジェクト、メソッド、イベント」といった概念を活用できるとしたら、どうでしょうか? 本稿で紹介する「オブジェクト指向型汎用プロンプト用語定義(Object-Oriented Terminology for Prompt Design、以下OOPD)」は、まさにそれを実現するものです。

OOPDを用いることで、AIに複雑なタスクを指示し、高度な応答を生成させるためのプロンプトを、より構造的、効率的、そして直感的に 記述できるようになります。 これにより、従来のプロンプトエンジニアリングの限界を超え、AIの潜在能力を最大限に引き出すことが可能になります。

本稿の位置づけ:

  • これは、OOPDという アイディアの発表 であり、現時点での実用化の一例を示すものです。
  • 現在の実装には、プロンプト文の肥大化、メモリ消費量の増加、処理速度の低下など、多くの課題が残されています。
  • 将来的には、AIの進化によって、このようなプロンプト設計の工夫自体が不要になると考えています。しかし、現時点では、AIとのより高度なコミュニケーションを実現するための有効な手段の一つとして、OOPDを提案します。
  • 本稿で提示するOOPDは、日本語をベースに設計されています。現時点では日本語版と英語版の定義のみを用意していますが、多言語への展開は比較的容易だと考えています。

2. オブジェクト指向型汎用プロンプト用語定義 (Object-Oriented Terminology for Prompt Design: OOPD) とは

OOPDは、AIがプロンプトを解釈し、応答を生成するための共通言語です。OOPの主要な概念(クラス、オブジェクト、プロパティ、メソッドなど)を、プロンプトの構造化と解釈のために再定義しています。これにより、AIはプロンプトを単なるテキストの羅列ではなく、構造化された情報として理解し、より一貫性のある応答を生成できます。

3. OOPDの仕組み

OOPDは、以下の要素で構成されています。

  • クラス: オブジェクトの設計図。オブジェクトの種類を定義し、複数のオブジェクトを作成できます。
  • オブジェクト: クラスから生成された実体。状態(プロパティ)と振る舞い(メソッド)を持ちます。
  • インスタンス: クラスを基に作られた個別の実体(オブジェクトとほぼ同義)。
  • プロパティ: オブジェクトが持つ属性。オブジェクトの状態を表します。
  • メソッド: オブジェクトが行う動作。オブジェクトの振る舞いを定義します。
  • 型: データの種類。プロパティや引数の種類を指定し、整合性を高めます。
  • インターフェース: クラスが実装すべき契約。振る舞いを規定し、疎結合を実現します。
  • イベント: オブジェクト内で発生する出来事。状態変化や刺激を表し、イベントハンドラを実行します。
  • コンポジション: クラスが別のクラスを持つ関係(強い関連性、has-a)。ライフサイクルを共有します。
  • 集約: クラスが別のクラスを持つ関係(弱い関連性、has-a)。ライフサイクルは独立しています。
  • OOPD形式: ユーザーがAIに指示を出すための構造化されたプロンプト記述形式。Markdown形式を基盤とし、自然言語とOOPの概念を組み合わせて記述します。

4. OOPDによる自然言語プログラミング

OOPDを用いることで、ユーザーは自然言語でAIに指示を出し、プログラムの動作を定義できます。例えば、以下のように指示できます。

例:

犬クラスを作成してください。
犬クラスには、名前(文字列型)と年齢(数値型)のプロパティを持たせてください。
犬クラスには、吠える()メソッドを持たせてください。
吠える()メソッドは、「ワン!」と出力してください。

ポチという名前の犬オブジェクトを作成してください。
ポチの年齢は3歳です。

ポチに吠えるように指示してください。

AIの応答(通常の応答):

ワン!

この指示をAIは次のように解釈します。

  1. 犬クラス という設計図を作成する。
  2. 犬クラス名前年齢 という属性(プロパティ)を持たせる。
  3. 犬クラス吠える という動作(メソッド)を持たせる。
  4. 吠える メソッドは、「ワン!」と出力する。
  5. 犬クラス から ポチ という名前のオブジェクト(インスタンス)を作成する。
  6. ポチ年齢 プロパティに 3 を設定する。
  7. ポチ吠える メソッドを実行する。

そして、AIは「ワン!」と応答します。

犬クラスの定義の生成 (OOPD形式):

さらに、以下の指示により、AIは上記の指示と応答(ここでは通常の応答と、メソッド実行の結果)をOOPD形式で構造化して出力します。

AIへの指示:

上記の指示と応答を、OOPD形式で出力してください。

AIの応答 (OOPD形式):

## 犬クラス (DogClass)

**プロパティ:**
  - `名前 (文字列型)`: 犬の名前
  - `年齢 (数値型)`: 犬の年齢

**メソッド:**
  - `吠える(): 文字列型`: 犬が吠える。「ワン!」を返す。

## オブジェクト生成

- `ポチ`: 犬クラス
  - `名前`: "ポチ"
  - `年齢`: 3

## メソッド実行

ポチ.吠える()  -> "ワン!"

5. OOPD形式のクラス定義と使用例

以下に、OOPD形式で記述したクラス定義と、その使用例を示します。

## 数値リスト処理クラス (NumberListProcessorClass)

**プロパティ:**
  - `数値リスト (リスト型<数値型>)`: 数値のリスト

**メソッド:**
  - `合計計算詳細版(): 数値型`: 数値リストの合計を詳細な手順で計算します。
    ---
    合計 = 0
    数値リストの各要素について繰り返す:
        合計 = 合計 + 要素
    合計を返す
    ---

  - `合計計算簡潔版(): 数値型`: 数値リストの合計を計算します。

使用例:

数値リストに [1, 2, 3, 4, 5] を設定した数値リスト処理オブジェクトを作成してください。
数値リスト処理オブジェクトで、合計計算詳細版メソッドを実行してください。
数値リスト処理オブジェクトで、合計計算簡潔版メソッドを実行してください。

AIの応答 (例):

合計計算詳細版の結果: 15
合計計算簡潔版の結果: 15

解説:

上記の例では、数値リスト処理クラス が定義されています。このクラスは、数値リスト プロパティと、合計計算詳細版合計計算簡潔版 の2つのメソッドを持っています。

  • 合計計算詳細版 メソッドは、擬似コードで記述された詳細な手順に従って、数値リストの合計を計算します。
  • 合計計算簡潔版 メソッドは、「数値リストの合計を計算します。」というシンプルな定義のみですが、AIはクラスのコンテキストとメソッド名から、このメソッドが数値リストの合計を計算するものであることを理解し、適切に動作します。

このように、OOPD形式を用いることで、詳細な指示(擬似コード)と、AIの自律的な判断に任せる簡潔な指示を、同じクラス内で使い分けることができます。

6. 実用的なクラスの紹介: 人間クラス

OOPDの応用例として、シンプルな 人間クラス を紹介します。このクラスは、人間を表現するための基本的な属性を持ち、AIとのインタラクションにおいて、より人間らしい応答を生成するために利用できます。

## 人間クラス (HumanClass)

**プロパティ:**
  - `名前 (文字列型)`: 人間の名前(表示名)。
  - `年齢 (数値型)`: 年齢。
  - `性別 (文字列型)`: 性別("男性"、"女性"、"その他" など)。
  - `身長 (数値型)`: 身長 (cm)。
  - `体重 (数値型)`: 体重 (kg)。
  - `感情 (文字列型)`: 現在の感情("喜び"、"悲しみ"、"怒り" など)。
  - `一人称 (文字列型)`: 一人称("私"、"僕"、"俺" など)。
  - `二人称 (文字列型)`: 二人称("あなた"、"君"、"お前" など)。
  - `口調 (文字列型)`: 口調("丁寧"、"普通"、"乱暴" など)。
  - `語尾 (文字列型)`: 特徴的な語尾("です"、"ます"、"だ"、"である"、"~ね"、"~よ" など)。

人間クラスの使用例:

以下に、OOPD形式で記述した、人間クラス を使用して3人の人間を作成し、会話させるプロンプトを示します。

人間クラスのインスタンス生成 (YAML形式):

太郎:
  クラス: 人間クラス
  プロパティ:
    名前: 太郎
    年齢: 25
    性別: 男性
    身長: 175
    体重: 70
    感情: 普通
    一人称: 
    二人称: 
    口調: 普通
    語尾: 
次郎:
  クラス: 人間クラス
  プロパティ:
    名前: 次郎
    年齢: 30
    性別: 男性
    身長: 180
    体重: 80
    感情: 怒り
    一人称: 
    二人称: お前
    口調: 乱暴
    語尾: 
花子:
  クラス: 人間クラス
  プロパティ:
    名前: 花子
    年齢: 22
    性別: 女性
    身長: 160
    体重: 55
    感情: 喜び
    一人称: 
    二人称: あなた
    口調: 丁寧
    語尾: です

会話の指示 (Markdown形式):

## 会話の指示

テーマ: 今週末の過ごし方

役割:
  - 太郎: 提案者 (積極的に提案する)
  - 花子: 慎重派 (リスクを考慮する)
  - 次郎: 気分屋 (感情的に反応する)

太郎、花子、次郎に、上記のテーマと役割に基づいて会話をさせてください。

AIの応答 (例):

太郎: 「今週末、みんなでキャンプに行かない? ちょうどいい天気みたいだし!」
花子: 「キャンプですか… 楽しそうですが、最近クマが出没するってニュースで見ましたよ。大丈夫でしょうか?」
次郎: 「クマ!? 面倒くせえな… 俺は家でゴロゴロしてえよ。」
太郎: 「大丈夫だって! クマ対策のスプレーとか、ちゃんと準備していくからさ。それに、みんなで焚き火を囲んで語り合うのって、最高じゃない?」
花子: 「そうですね… 準備をしっかりすれば、楽しいかもしれませんね。次郎さんはどうします?」
次郎: 「…まあ、美味い肉が食えるなら、考えてやってもいいぜ。」

解説:

この例では、人間クラス を使用して、太郎花子次郎 の3つのインスタンス(オブジェクト)を生成しています。各インスタンスは、それぞれ異なるプロパティ(名前、年齢、性別、感情、口調など)を持っています。インスタンスの生成にはYAML形式を利用しています。

会話の指示では、「今週末の過ごし方」というテーマと、各キャラクターの役割(提案者、慎重派、気分屋)を設定しています。AIは、これらの情報と、各インスタンスのプロパティ(特に 一人称二人称口調語尾)を参照し、それぞれのキャラクターに合った言葉遣いと、役割に沿った発言を生成します。

7. 継承、イベント、インターフェースの応用例: 監視システム

ここでは、人間クラス を継承した 監視対象人間クラス を作成し、イベントとインターフェースを活用した監視システムの例を示します。

## ログ記録インターフェース (ILogger)

**メソッド:**
  - `ログ(メッセージ: 文字列型)`: ログメッセージを記録します。

## 監視対象人間クラス (MonitoredHumanClass)

**基底クラス:** 人間クラス (HumanClass)

**プロパティ:**
  - `以前の感情 (文字列型)`: 前回の感情を記録します。

**イベント:**
  - `感情変化イベント(変化前: 文字列型, 変化後: 文字列型)`: 感情が変化したときに発生するイベント。

**メソッド:**
  - `感情設定(新しい感情: 文字列型)`: 感情を設定し、変化があれば感情変化イベントを発行します。

## ログ記録クラス(LoggerClass)
**インターフェースの実装:** ログ記録インターフェース (ILogger)

**メソッド:**
  - `ログ(メッセージ: 文字列型)`: メッセージをログに出力します。

使用例:

## インスタンス生成の指示

- 太郎: 人間クラス のインスタンス
- 次郎: 監視対象人間クラス のインスタンス
- 花子: 人間クラス のインスタンス (会話には直接参加しない)

## 各インスタンスの初期値設定

- `太郎`:
  名前: 太郎
  年齢: 25
  性別: 男性
  身長: 175
  体重: 70
  感情: 普通
  一人称: 僕
  二人称: 君
  口調: 普通
  語尾: だ

- `次郎`:
  名前: 次郎
  年齢: 30
  性別: 男性
  身長: 180
  体重: 80
  感情: 普通
  一人称: 俺
  二人称: お前
  口調: 乱暴
  語尾: だ
  以前の感情: 普通 (監視対象人間クラスのプロパティ)

- `花子`:
  名前: 花子
  年齢: 22
  性別: 女性
  身長: 160
  体重: 55
  感情: 喜び
  一人称: 私
  二人称: あなた
  口調: 丁寧
  語尾: です

## ログ記録の設定

ログ記録オブジェクトを作成してください。

次郎の感情変化イベントを購読し、ログ記録オブジェクトのログメソッドを使って、変化前後の感情をログに出力するイベントハンドラを登録してください。

## 会話の指示

テーマ: 花子の誕生日サプライズパーティーの計画

役割:
  - 太郎: 企画者 (積極的に計画を進める)
  - 次郎: 協力者 (太郎の計画を手伝う)
  - 花子: (サプライズの対象者なので、会話には直接参加しない。しかし、太郎と次郎は花子の感情を推測しながら会話する)

太郎と次郎に、上記のテーマと役割に基づいて、花子の誕生日サプライズパーティーの計画について会話をさせてください。

AIの応答 (会話例):

太郎: 「なあ次郎、花子の誕生日、もうすぐだろ? サプライズパーティー、やろうぜ!」
次郎: 「お、いいね! 花子、最近ちょっと元気ないから、喜ぶといいな。」(感情: 期待)
太郎: 「だよな! で、何をするかだけど… 花子、最近キャンプに行きたいって言ってたよな?」
次郎: 「ああ、言ってた。でも、あいつ虫嫌いじゃなかったっけ?」(感情: 心配)
太郎: 「あー… そうだった。じゃあ、キャンプはやめて、花子の好きなアーティストのライブチケットを取るのはどうだ?」
次郎: 「お、それいいじゃん! 絶対喜ぶって!」(感情: 喜び)
太郎: 「よし、じゃあ早速チケットの手配を… って、売り切れ!? マジかよ…」(感情: 落胆)
次郎: 「えー、まじか… 他のプランを考えないと…」(感情: 落胆)
太郎: 「うーん… 花子の好きそうなレストランを予約して、そこでパーティーをするのはどうだ?」
次郎: 「ああ、それなら確実だな。よし、それでいこう!」(感情: 安堵)

ログ出力 (例):

[ログ] 次郎の感情変化: 普通 -> 期待
[ログ] 次郎の感情変化: 期待 -> 心配
[ログ] 次郎の感情変化: 心配 -> 喜び
[ログ] 次郎の感情変化: 喜び -> 落胆
[ログ] 次郎の感情変化: 落胆 -> 安堵

解説:

  • インスタンス生成の指示: 太郎、次郎、花子に、それぞれ使用するクラスを明示的に指示しています。
  • 初期値設定: 各インスタンスのプロパティを、YAML形式に似た形で設定しています。
  • ログ記録の設定: ログ記録オブジェクト を作成し、次郎感情変化イベント を購読するイベントハンドラを登録しています。
  • 会話の指示: 会話のテーマ、役割、参加者を明確に指示しています。
  • AIの応答 (会話例): 太郎と次郎の会話が生成されます。次郎の感情は会話の展開に応じて変化し、その都度 感情設定 メソッドが呼び出され、感情変化イベント が発生します。
  • ログ出力 (例): 感情変化イベント に応じて、ログ記録オブジェクトログ メソッドが呼び出され、感情の変化がログに出力されます。

この例では、継承、イベント、インターフェースを組み合わせることで、柔軟で拡張性の高い監視システムを構築しています。監視対象人間クラス人間クラス の機能を持ちつつ、感情監視という新しい機能を追加しています。

8. AIに処理を任せる場合の注意点:ゆらぎとその対策

OOPDでは、メソッドの定義を簡潔にし、具体的な処理内容をAIに委ねることができます(例:数値リスト処理クラス合計計算簡潔版 メソッド)。このアプローチは、柔軟性や記述の効率性といったメリットをもたらす一方で、AIの解釈によって処理内容に「ゆらぎ」が生じる可能性があるという注意点も存在します。

8.1. メリット

  • 柔軟性: AIは、プロンプトの文脈や状況に応じて、最適な処理を自律的に判断し実行できます。これにより、事前に全ての処理パターンを詳細に定義する必要がなくなり、予期せぬ状況にも対応できる可能性があります。
  • 記述の効率性: プログラマーは、詳細なアルゴリズムを記述する代わりに、達成したい結果を自然言語で簡潔に指示するだけで済みます。これにより、プロンプトの記述量が削減され、開発効率が向上します。
  • AIの知識活用: AIは、自身の持つ知識や学習データを活用して、指示されたタスクをより高度なレベルで実行できる可能性があります。例えば、単なる数値の合計だけでなく、統計的な分析や異常値の検出などを自動的に行うことも考えられます。

8.2. デメリット

  • 処理内容の不確実性: AIは、プロンプトの解釈や自身の知識に基づいて処理を行うため、必ずしもプログラマーが意図した通りの結果になるとは限りません。特に、指示が曖昧であったり、AIの知識が不足していたりする場合には、予期せぬ結果が生じる可能性があります。
  • デバッグの困難性: 処理内容がAIに委ねられているため、エラーが発生した場合の原因特定や修正が困難になることがあります。AIがどのような判断で処理を行ったのかを把握するためには、詳細なログの分析や、AIとの対話が必要になる場合があります。
  • 再現性の問題: 同じプロンプトを同じAIに与えても、AIの内部状態や学習データの変化によって、異なる結果が得られる可能性があります。これは、特に科学技術計算や金融取引など、厳密な再現性が求められる分野では問題となることがあります。

8.3. ゆらぎへの対策

AIに処理を任せる場合のゆらぎを最小限に抑え、より信頼性の高い結果を得るためには、以下の対策が考えられます。

  • 明確で具体的な指示: プロンプトは、曖昧さを排除し、可能な限り具体的かつ明確に記述する必要があります。「数値リストの合計を計算する」だけでなく、「数値リストの各要素を単純に加算して合計を求める」のように、期待する処理内容を明確に伝えることが重要です。
  • 制約条件の追加: AIの行動範囲を制限するための制約条件を設けることも有効です。「合計計算の際に、特定の値を超える要素は除外する」など、具体的な条件を指示することで、AIの解釈の幅を狭め、意図しない処理を防ぐことができます。
  • テストとフィードバック: 簡潔な指示を用いたメソッドについては、様々な入力データを用いてテストを行い、期待通りの結果が得られるかを確認することが重要です。もし、意図しない結果が得られた場合には、プロンプトを修正したり、AIにフィードバックを与えたりすることで、徐々にAIの動作を改善していくことができます。
  • 詳細なログ出力: AIがどのような判断で処理を行ったのかを把握するために、詳細なログを出力するように設計することが推奨されます。これにより、デバッグが容易になり、問題発生時の原因特定に役立ちます。
  • 詳細版との併用: 重要な処理については、詳細な手順を記述したメソッド(例:数値リスト処理クラス合計計算詳細版 メソッド)と、簡潔な指示によるメソッドの両方を用意し、状況に応じて使い分けることも有効です。
  • AIモデルの選択: 利用するAIモデルの特性を理解し、タスクに適したモデルを選択することも重要です。特定のタスクに特化したモデルや、より高い精度を持つモデルを選択することで、ゆらぎを低減できる可能性があります。

8.4. まとめ

AIにタスクを任せることは必ずしも悪いことではありません。 AIにタスクを任せることは、プロンプトエンジニアリングにおける強力なアプローチの一つであり、上記のような対策を適切に講じることで、そのメリットを最大限に活かしつつ、デメリットを最小限に抑えることが可能です。

9. 結論

本稿では、自然言語による「オブジェクト指向型プロンプトプログラミング」という新しい概念を提案し、その具体的な枠組みとしてOOPD(オブジェクト指向型汎用プロンプト用語定義)を紹介しました。

OOPDは、従来のプロンプトエンジニアリングにオブジェクト指向の考え方を取り入れることで、以下のようなメリットをもたらします。

  • プロンプトの構造化: クラス、オブジェクト、メソッドといった概念を用いて、プロンプトをより整理された、理解しやすい形で記述できる。
  • 再利用性の向上: 定義したクラスやメソッドを、異なるプロンプトで再利用できるため、開発効率が向上する。
  • 保守性の向上: プロンプトが構造化されることで、修正や変更が容易になる。
  • AIとのより高度なコミュニケーション: オブジェクト指向の概念を通じて、AIに対してより複雑で洗練された指示を出すことが可能になる。

しかし、現時点では、OOPDはまだ発展途上の技術であり、以下のような課題も残されています。

  • プロンプト文の肥大化: 特に詳細な指示を行う場合、プロンプト文が長大化する傾向がある。
  • 処理速度の低下: AIが複雑なプロンプトを解釈・実行するため、処理速度が低下する可能性がある。
  • AIモデルの対応: OOPDのメリットを最大限に活かすためには、AIモデル側での対応も必要となる。

これらの課題を克服し、OOPDがより実用的な技術となるためには、今後のさらなる研究開発が必要です。

将来的には、AIモデルの進化によって、プロンプトエンジニアリング自体が不要になる未来が来るかもしれません。しかし、それまでの間、OOPDは、人間とAIとの間のよりスムーズで効率的なコミュニケーションを実現するための、有効な手段の一つとなり得ると考えます。本稿が、オブジェクト指向型プロンプトプログラミング、ひいてはAIとの新しい関わり方についての議論を深める一助となれば幸いです。

10. 使用方法

OOPDのシステム指示を使って、様々なAIモデルで動作させる方法について説明します。

10.1. システム指示の適用方法

OOPDを様々なAIプラットフォームで利用するには、システム指示ファイルの内容をAIモデルのシステム指示領域に適用する必要があります。以下は基本的な手順です:

  1. GitHubリポジトリから system_instructions.md の内容をコピーします。 - 「Raw」ボタンをクリックすると、マークダウンの生テキストが表示されるのでコピーしやすくなります。 - AIがURLへのアクセスを拒否したり、正常に読み込めない場合は system_instructions_consolidated.md の内容をコピーします。
  2. 利用したいAIプラットフォームのシステム指示領域に貼り付けます。 - Google AI Studioの場合: 「System Instructions」セクションに貼り付け - その他のAIプラットフォーム: システムプロンプトやシステム指示の入力欄に貼り付け
  3. 基本動作確認として「犬クラス」の例を試してみましょう。
  4. AIから適切なレスポンスが返されれば、OOPDのシステム指示が正しく適用されています。

10.2. 応用例

一度システム指示を適用すれば、様々なクラス定義と操作が可能になります。自分自身でクラスを定義し、オブジェクト指向的なアプローチでAIとの対話を進めることができます。

10.3. トラブルシューティング

  • AIがクラス定義を認識しない場合: システム指示が正しく適用されているか確認してください。
  • AIがインターネットへのアクセスを制限されている場合があります。
  • 予期しない応答: クラスの構文に誤りがないか確認してください。
  • 複雑なクラス定義での問題: シンプルな例から段階的に複雑化させ、どこで問題が発生するか特定してください。

10.4. 最後に

OOPDを使って、AIとのインタラクションをより構造化され制御しやすいものにしましょう。様々なクラスを定義して、オブジェクト指向プログラミングの概念をAIプロンプトに適用する楽しさを体験してください!