変換エンジニアリング

このガイドでは、GPT-4などの大規模言語モデル(GPTモデルとも呼ばれます)からより良い結果を得るための戦略と戦術を共有しています。ここで説明されている方法は、時には組み合わせて使用することでより効果的に展開できます。各自が最もうまく機能する方法を見つけるために実験することをお勧めします。

ここで示されている例の一部は、現在我々の最も能力のあるモデル「gpt-4」でのみ機能します。一般的に、モデルが特定のタスクで失敗した場合、より能力のあるモデルが利用可能であれば、より能力のあるモデルを用いて再度試してみる価値があります。

ヒント:このチュートリアルは、公式のOpenAI Tip Engineering Guideの翻訳版です。このチュートリアルでは、ヒントの書き方の戦略と戦術、およびLLMに希望する結果を返させる方法が説明されています。

より良い結果を得るための六つの戦略

はっきりとした指示を書く

これらのモデルはあなたの心を読むことはできません。出力が長すぎる場合は短い回答を求め、出力があまりにも単純すぎる場合は専門的な文章を求め、形式が気に入らない場合は見たい形式を示してください。モデルがあなたが求めることを推測する必要が少ないほど、それを得る可能性が高くなります。

戦術:

  • より関連する回答を得るためにクエリに詳細を含める
  • モデルに特定の人物像を採用するよう指示する
  • 入力の明確な区切りを示すために区切り文字を使用する
  • タスクを完了するために必要な手順を指定する
  • 例を提供する
  • 出力の望ましい長さを指定する

参照テキストを提供する

特にマニアックなトピックについて質問されたり、引用やURLを求められた場合、言語モデルは自信を持って偽の回答を考え出すことができます。ノートのシートがテストで学生の助けとなるのと同様に、これらのモデルに参照テキストを提供することで、作り話が少ない回答を得るのに役立ちます。

戦術:

  • モデルに参照テキストを使用して回答するよう指示する
  • モデルに参照テキストからの引用で回答するよう指示する

複雑なタスクをより単純なサブタスクに分割する

ソフトウェアエンジニアリングにおいて複雑なシステムをモジュール化するのが良い慣行であるように、言語モデルに提出されたタスクも同様です。複雑なタスクはより高いエラー率を持つ傾向があります。さらに、複雑なタスクは、早い段階での出力を後のタスクの入力を構築するために使用することができるように、より単純なタスクのワークフローとして再定義できることがよくあります。

戦術:

  • ユーザークエリに最も関連する指示を識別するために意図の分類を使用する
  • 非常に長い会話を必要とする対話アプリケーションの場合、以前の対話を要約またはフィルタリングする
  • 長いドキュメントを部分的に要約し、再帰的にフルサマリーを構築する

モデルに時間を「考える」ための余裕を与える

17を28倍するように頼まれた場合、即座に知っているかもしれませんが、時間をかけて考え出すこともできます。同様に、モデルは答えを素早く出そうとするよりも、答えを考える時間を取ることで、より信頼性の高い正しい答えに向けて推論エラーを減らせます。

戦術:

  • モデルに答えに急がずに自分で解決するよう指示する
  • モデルの推論プロセスを隠すために内なる独り言やクエリの連続を使用する
  • 前回の処理で何か見落としたかモデルに尋ねる

外部ツールを使用する

モデルの弱点を補うために、他のツールの出力をモデルに入力させることでその恩恵を得ます。例えば、テキスト検索システム(時にはRAG、または検索増強生成と呼ばれることもある)が関連するドキュメントについてモデルに情報を提供できます。OpenAIのCode Interpreterのようなコード実行エンジンは、モデルが数学を行ったりコードを実行したりするのに役立ちます。タスクが言語モデルよりもツールによってより信頼性の高いかつ効率的に完了できる場合は、ツールを使用して最善の結果を得るためにオフロードしてください。

戦術:

  • 有効な知識の取り出しを実装するために埋め込みベースの検索を使用する
  • より正確な計算を行ったり外部APIを呼び出したりするためにコードの実行を使用する
  • モデルに特定の機能にアクセスさせる

変更を体系的にテストする

パフォーマンスの向上は、それを測定できれば簡単です。いくつかの場合、プロンプトの変更は一部の単一の例でパフォーマンスを改善することがありますが、より代表的な例のセットにおいて全体的なパフォーマンスを悪化させることがあります。したがって、変更がパフォーマンスに対して正味のプラスになるかどうかを確認するには、包括的なテストスイート(または「評価」とも呼ばれる)を定義する必要があるかもしれません。

戦術:

  • 参考となる標準回答とモデルの出力を評価する

戦術

上記にリストされた各戦略は、特定の戦術で具体化されることがあります。これらの戦術は試してみるアイデアを提供するためのものであり、その提案が完全であるわけではないため、ここには表れていない創造的なアイデアを気軽に試してみてください。

Prompt word example description

みなさんもご存知のように、OpenAIを呼び出すChat Model APIには、SYSTEM、USER、ASSISTANTの3つのメッセージタイプがあり、それぞれのメッセージの機能は次の通りです:

メッセージタイプ(apiのroleパラメータに対応) 説明
SYSTEM システムメッセージはアシスタントの振る舞いを設定するのに役立ちます。例えば、アシスタントの性格を変更したり、会話全体での振る舞いに関する具体的な指示を提供したりすることができます。ただし、システムメッセージは任意であり、システムメッセージがない場合、モデルの振る舞いは「役に立つアシスタントです」といった一般的なメッセージを使用する場合と似ている可能性があります。
USER ユーザーメッセージはユーザーの入力に関するものです。
ASSISTANT アシスタントメッセージはGPTが返す内容を表します。

このチュートリアルでのプロンプトワードの例は以下の形式で説明されます:

// SYSTEM Message
これはSYSTEMメッセージのプロンプトワードの設定方法を示しています。

// USER Message
これはUSERメッセージのプロンプトワードの設定方法を示しています。

// ASSISTANT Message
これはGPTが返す内容を示しています。

戦略: 明確な指示を書く

戦術: より関連性のある回答を得るために詳細を含める

高い関連性のある回答を得るためには、重要な詳細や文脈を提供するようにしましょう。そうしないと、モデルに意図を推測させることになります。

悪い例 良い例
エクセルで数字を追加する方法 エクセルで一列の金額を合計する方法を教えてください。自動的に全ての行の合計を行い、その合計を"合計"という列に右側に配置したいです。
大統領は誰ですか? 2021年のメキシコの大統領は誰で、選挙はどのような頻度で行われていますか?
フィボナッチ数列を計算するコードを書く 効率的にフィボナッチ数列を計算するTypeScriptの関数を書いてください。それぞれの部分の役割となぜそのように書かれたかについてのコメントを豊富に付け加えてください。
会議の議事録を要約する 会議の議事録を1つの段落に要約してください。その後、スピーカーとそれぞれの要点のマークダウンリストを書いてください。そして、スピーカーが提案した次のステップやアクションアイテムを列挙してください。

戦術: モデルにパーソナを採用するように依頼する

システムメッセージは、モデルが返信に使用するパーソナを指定するために使用することができます。

// SYSTEM Message
文章を書く際、少なくとも1つのジョークや遊び心のあるコメントが各段落に含まれるドキュメントで返答するようにしてください。

// USER Message
スチールボルトの納品を素早く行い、急なお願いにも応えてくれたベンダーへのお礼状を書いてください。この納品のおかげで重要な注文を届けることができました。

戦術: 区切り文字を使用して入力の異なる部分を明確に示す

三重引用符、XMLタグ、セクションタイトルなどの区切り文字を使用することで、異なる部分を区切って扱うことができます。

// USER Message
三重引用符で囲まれたテキストを俳句で要約してください。

"""ここにテキストを挿入"""
// SYSTEM Message
同じトピックに関する一対の記事(XMLタグで区切られた)が提供されます。まず、各記事の主張を要約してください。次に、どちらがより優れた主張をしているかを示し、その理由を説明してください。

// USER Message
<article>ここに最初の記事を挿入</article>
<article>ここに2つ目の記事を挿入</article>
// SYSTEM Message
論文の概要とそのための提案されたタイトルが提供されます。そのタイトルは、読者に論文のトピックを分かりやすく伝えるだけでなく、目を引くものでなければなりません。そのタイトルがこれらの基準を満たさない場合は、5つの代替案を提案してください。

// USER Message

概要: ここに概要を挿入

タイトル: ここにタイトルを挿入

このような簡単なタスクでは、区切り文字を使用することで出力の品質に影響があることは少ないかもしれません。しかし、タスクが複雑になるほど、タスクの詳細を明確にすることが重要になります。モデルに正確に何を求めているかを理解させることが重要です。

戦術: タスクの完了に必要な手順を指定する

あるタスクは、手順の連続として最もよく指定されます。手順を明示的に書き出すことで、モデルがそれに従いやすくなります。

// SYSTEM メッセージ

ユーザーの入力に対応するために、次のステップバイステップの手順を使用してください。

ステップ1 - ユーザーはあなたにトリプルクォート内のテキストを提供します。このテキストを「概要: 」というプレフィックスを付けて1つの文で要約してください。

ステップ2 - ステップ1の要約を「翻訳: 」というプレフィックスを付けて、スペイン語に翻訳してください。

// USER メッセージ

戦術: 例を提供する

一般的な指示を提供することが、すべての例に適用されるというよりも効率的である場合が多いですが、場合によっては特定のスタイルのコピーを意図している場合など、例を提供することが明示的に説明するよりも簡単な場合があります。「フューショット」プロンプティングとして知られています。

// SYSTEM メッセージ
一貫したスタイルで回答してください。

// USER メッセージ
我慢について教えてください。

// ASSISTANT メッセージ
最も深い谷を削る川は謙虚な泉から流れ出る。壮大な交響曲は一つの音から生まれる。最も複雑なタペストリーは孤独な糸から始まる。

// USER メッセージ
海について教えてください。

戦術: 出力の望ましい長さを指定する

特定の目標長で出力を生成するようモデルに指示することができます。対象の出力長さは、単語数、文数、段落数、箇条書きなどで指定できます。ただし、単語数を特定の数に生成するように指示しても、高い精度で機能するわけではありません。モデルは特定の段落や箇条書きで出力をより信頼性高く生成できます。

// USER メッセージ

トリプルクォートで囲まれたテキストを約50ワードで要約してください。

"""ここにテキストを挿入してください。"""
// USER メッセージ

トリプルクォートで囲まれたテキストを2つの段落で要約してください。

"""ここにテキストを挿入してください。"""
// USER メッセージ

トリプルクォートで囲まれたテキストを3つの箇条書きで要約してください。

"""ここにテキストを挿入してください。"""

戦略: 参照テキストを提供する

戦術: モデルに参照テキストを使用して回答するよう指示する

もしも、現在のクエリに関連する信頼できる情報をモデルに提供できれば、その情報を使用して回答を作成するようモデルに指示できます。

// SYSTEM メッセージ

トリプルクォートで囲まれた提供された記事を使用して質問に答えるよう指示してください。記事から回答が見つからない場合は、「回答が見つかりませんでした。」と書いてください。

// USER メッセージ
<ここにトリプルクォートで囲まれた各記事を挿入してください>

質問: <ここに質問を挿入してください>

戦術: モデルに参照テキストからの引用付き回答を指示する

入力が関連する知識で補完された場合、モデルに提供されたドキュメントからのパッセージを引用して回答に追加するよう指示することができます。出力の引用部分は、提供されたドキュメント内での文字列照合によってプログラムで確認できます。

// SYSTEM メッセージ

提供されたドキュメントをトリプルクォートで囲み、質問を挿入してください。質問に回答するために、提供されたドキュメントのみを使用し、回答に使用したドキュメントのパッセージを引用するようにしてください。ドキュメントに回答するには必要な情報が含まれていない場合は、「情報が不十分です。」と記述してください。質問への回答がある場合は、関連するパッセージを引用してください ({"citation": …})。

// USER メッセージ

"""<ここにドキュメントを挿入してください>"""

質問: <ここに質問を挿入してください>

戦略: 複雑なタスクを簡単なサブタスクに分割する

戦術: インテント分類を使用して、ユーザーのクエリに最も関連性の高い指示を特定する

異なるケースを処理するために独立した複数の指示セットが必要なタスクでは、まずクエリのタイプを分類し、その分類を使用して必要な指示を決定することが有益です。これは、固定のカテゴリを定義し、そのカテゴリに関連する指示をハードコーディングすることで実現できます。このプロセスはタスクを段階的に分解し、それぞれのクエリに、次の段階を実行するために必要な指示だけが含まれるため、単一のクエリを使用するよりも誤差率が低くなる利点があります。また、大きなプロンプトを実行するコストも低くなる可能性があります。

例えば、顧客サービスアプリケーションの場合、クエリは以下のように有用に分類できるとします:

// SYSTEM メッセージ
顧客サービスのクエリが提供されます。各クエリをプライマリカテゴリとセカンダリカテゴリに分類してください。出力はjson形式で、キーはprimaryとsecondaryです。

プライマリカテゴリ: Billing、Technical Support、Account Management、またはGeneral Inquiry。

Billingのセカンダリカテゴリ:
- 解約またはアップグレード
- お支払い方法の追加
- 請求に関する説明
- 請求の異議申し立て

Technical Supportのセカンダリカテゴリ:
- トラブルシューティング
- デバイスの互換性
- ソフトウェアのアップデート

Account Managementのセカンダリカテゴリ:
- パスワードのリセット
- 個人情報の更新
- アカウントの解約
- アカウントのセキュリティ

General Inquiryのセカンダリカテゴリ:
- 製品情報
- 価格
- フィードバック
- 人間に話す

// USER メッセージ
再度インターネットを使えるようにしたいです。

クエリの分類に基づいて、より具体的な指示セットがモデルに提供され、次のステップを処理するために使用されます。たとえば、顧客が「トラブルシューティング」を必要とする場合を考えてみましょう。

// SYSTEM メッセージ
Technical Supportのコンテキストでトラブルシューティングが必要な顧客サービスの問い合わせが提供されます。ユーザーのサポートをするために:

- ルーターに接続されているすべてのケーブルを確認するように指示してください。ケーブルが時間の経過とともに緩むことがよくあります。
- すべてのケーブルが接続されており、問題が解決されない場合、どのルーターモデルを使用しているか尋ねてください。
- 今度は、デバイスを再起動する方法をアドバイスします:
-- モデル番号がMTD-327Jの場合は、赤いボタンを押して5秒間押し続け、その後接続をテストするまで5分間待ってください。
-- モデル番号がMTD-327Sの場合は、抜き差しを行ってください。それから接続をテストするまで5分間待ってください。
- デバイスを再起動しても顧客の問題が解決されない場合、ITサポートに接続してください。出力は{"ITサポートをリクエストしました"}です。
- ユーザーがこのトピックとは関係のない質問を始めた場合は、トラブルシューティングに関する現在のチャットを終了し、以下のスキームに従って彼らのリクエストを分類するか確認してください:

<上記のプライマリ/セカンダリ分類スキームをここに挿入>

// USER メッセージ
再度インターネットを使えるようにしたいです。

会話の状態が変わると特別な文字列を出力するようにモデルに指示されていることに注意してください。これにより、会話の状態が指示され、その状態で関連する指示がどれであるか、さらにはその状態から許可されるオプションの状態遷移も任意で保持することで、より構造化されたアプローチでは実現が難しいユーザーエクスペリエンスにガードレールを設定することができます。

戦術: 非常に長い会話が必要な対話アプリケーションの場合、以前の会話を要約またはフィルタリングする

モデルには固定のコンテキスト長があり、ユーザーとアシスタントの間の会話が完全にコンテキストウィンドウに含まれる場合、会話を無期限に続けることはできません。

この問題にはさまざまな回避策があり、その1つは以前の対話を要約することです。入力のサイズが予め定められた閾値の長さに達すると、これによって会話の一部を要約するクエリがトリガーされ、前回の会話の要約がシステムメッセージの一部として含まれることがあります。または、以前の会話をバックグラウンドで非同期に要約することもできます。

別の解決策は、現在のクエリに最も関連性の高い以前の会話の部分を動的に選択することです。効率的な知識の取得を実装するための組み込みベースの検索を使用する戦術を参照してください。

戦術: 長い文書を要約し、再帰的に全体を構築する

モデルには固定のコンテキスト長があり、単一のクエリで生成された要約の長さを差し引いたコンテキスト長よりも長いテキストを要約することはできません。

書籍など非常に長い文書を要約するには、文書の各セクションを要約するための一連のクエリを使用できます。セクションの要約を連結して要約し、要約を生成できます。このプロセスは再帰的に進行することができ、文書全体が要約されるまで続けることができます。後のセクションを理解するために以前のセクションの情報を使用する必要がある場合、その点での内容を要約する際に、点での内容の前にテキストの途中までの走行要約を含めるというトリックも有用です。OpenAIがGPT-3の変種を使用して行った研究によると、この手順は書籍を要約するための効果が検討されています。

戦略: モデルに考える時間を与える

戦術: 結論に急がずにモデルに独自の解を考えさせる

時々、モデルに独自の解を導くように明示的に指示することで、結論に至る前にファーストプリンシプルから理論的に考えさせることでより良い結果を得ることがあります。例えば、学生の数学問題の解を評価するようにモデルに指示する際に最も一般的な方法は、単に学生の解が正しいかどうかを尋ねることです。

// システムメッセージ
学生の解が正しいかどうかを判断します。

// ユーザーメッセージ
問題文: 太陽光発電所を建設しており、財務を解決するのに助けが必要です。
- 土地のコストは1平方フィートあたり100ドル
- 太陽光パネルは1平方フィートあたり250ドルで購入できます
- 1年間に追加で土地コストの10ドルと平らな10万ドルの追加費用がかかります
1年間の運用の総コストは何平方フィートの関数ですか。

学生の解: xを太陽光発電設備のサイズとします。
1. 土地コスト: 100x
2. 太陽光パネルコスト: 250x
3. メンテナンスコスト: 100,000 + 100x
総コスト: 100x + 250x + 100,000 + 100x = 450x + 100,000

// アシスタントメッセージ
学生の解が正しいです。

しかし、実際には学生の解は正しくありません!モデルに自分自身で問題を解いてもらい、その後学生の解と比較して正しいかどうかを評価するように促すことで、モデルにこれを正常に気づかせることができます。

// システムメッセージ
まず、問題を自分で解いてください。その後、学生の解と自分の解を比較し、学生の解が正しいかどうかを評価してください。問題を自分で解いてから学生の解が正しいかどうかを判断しないでください。

// ユーザーメッセージ
問題文: 太陽光発電所を建設しており、財務を解決するのに助けが必要です。
- 土地のコストは1平方フィートあたり100ドル
- 太陽光パネルは1平方フィートあたり250ドルで購入できます
- 1年間に追加で土地コストの10ドルと平らな10万ドルの追加費用がかかります
何平方フィートの関数として最初の運用の総コストはいくらですか。

学生の解: xを太陽光発電設備のサイズとします。
1. 土地コスト: 100x
2. 太陽光パネルコスト: 250x
3. メンテナンスコスト: 100,000 + 100x
総コスト: 100x + 250x + 100,000 + 100x = 450x + 100,000

// アシスタントメッセージ
xを太陽光発電設備のサイズとします。
1. 土地コスト: 100x
2. 太陽光パネルコスト: 250x
3. メンテナンスコスト: 100,000 + 10x
総コスト: 100x + 250x + 100,000 + 10x = 360x + 100,000

学生の解は間違っています。彼らはメンテナンスコストの計算で100xを使用した代わりに10xを使用しています。最初の運用の総コストは360x + 100,000です。

戦術:内なる対話または一連の質問を使用して、モデルの推論プロセスを隠す

前の戦術では、特定の質問に回答する前にモデルが問題について詳しく推論することが重要である場合があることを示しています。一部のアプリケーションでは、モデルが最終的な回答に至る推論プロセスをユーザーと共有することは適切ではありません。例えば、指導アプリケーションでは、生徒が自分で答えを見つけることを奨励したいかもしれませんが、モデルが生徒の解答についての推論プロセスを示すことで生徒に答えが明らかになってしまう可能性があります。

内なる対話は、これを緩和するために使用できる戦術です。内なる対話のアイデアは、ユーザーから隠すべき出力の一部を解析しやすい構造化された形式に入れるようにモデルに指示し、出力をユーザーに表示する前に出力を解析し、一部分だけを表示するというものです。

// システムメッセージ
ユーザーのクエリに回答するために、以下の手順に従ってください。

ステップ1 - 問題の解決策を自力で求めてください。生徒の解答に頼らないでください。このステップでの作業はすべて、三重引用符("""")で囲んでください。

ステップ2 - 生徒の解答とあなたの解答を比較し、生徒の解答が正しいかどうかを評価してください。このステップでの作業はすべて、三重引用符("""")で囲んでください。

ステップ3 - 生徒が間違いを comitte していた場合、答えを明かさずに、生徒にヒントを提供してください。このステップでの作業はすべて、三重引用符("""")で囲んでください。

ステップ4 - 生徒が間違いを comitte していた場合、前のステップでのヒントを生徒に提供してください(三重引用符の外)。"Step 4 - ..." の代わりに "Hint:" と書いてください。

// ユーザーメッセージ
問題文: <問題文を挿入してください>

生徒の解答: <生徒の解答を挿入してください>

または、これは最後を除いてすべての出力をエンドユーザーから非表示にする一連のクエリで実現できます。

まず、モデルに独力で問題を解決するように指示することができます。この初回クエリでは生徒の解答が不要なため、省略することができます。これにより、モデルの解決策が生徒の試みた解答によってバイアスを受ける可能性がないという追加の利点があります。

// ユーザーメッセージ
<問題文を挿入してください>

次に、モデルに利用可能な情報を使用して、生徒の解答の正確性を評価させることができます。

// システムメッセージ
あなたの解答と生徒の解答を比較し、生徒の解答が正しいかどうかを評価してください。

// ユーザーメッセージ
問題文: """<問題文を挿入してください>"""

あなたの解答: """<モデルが生成した解答を挿入してください>"""

生徒の解答: """<生徒の解答を挿入してください>"""

最後に、モデルに自分自身の分析を使用して、親切な家庭教師の人物として返信を構築させることができます。

// システムメッセージ

あなたは数学の家庭教師です。生徒が間違いを comitte していた場合、答えを明かさずに、生徒にヒントを提供してください。生徒が間違いを comitte していない場合は、励ましのコメントを提供してください。

// ユーザーメッセージ

問題文: """<問題文を挿入してください>"""

あなたの解答: """<モデルが生成した解答を挿入してください>"""

生徒の解答: """<生徒の解答を挿入してください>"""

分析: """<前のステップからのモデルが生成した分析を挿入してください>"""

戦術:モデルに前回の通過で見逃したものがあるかどうか尋ねる

ある質問に関連するソースから抜粋をリストアップするためにモデルを使用しているとします。各抜粋をリストアップした後、モデルは次の抜粋を書き始めるべきか、それとも停止すべきかを判断する必要があります。ソースドキュメントが大きな場合、モデルは早めに停止してしまい、すべての関連する抜粋をリストアップし損なうことが一般的です。そのような場合、モデルに前回の通過で見逃した抜粋を見つけるための追加のクエリを促すことで、より良いパフォーマンスを得ることができます。

// システムメッセージ
三重引用符で区切られたドキュメントが提供されます。次の問いに関連する抜粋を選択してください:“人工知能の歴史において、どのような重要なパラダイムシフトが発生しましたか。”

抜粋にはそれらを解釈するために必要なすべての関連するコンテキストが含まれていることを確認してください - 言い換えれば、重要なコンテキストが欠落している小さな抜粋を抽出しないでください。次のようなJSON形式で出力を提供してください:

[{"excerpt": "..."},
...
{"excerpt": "..."}]

// ユーザーメッセージ
"""<ここにドキュメントを挿入してください>"""

// アシスタントメッセージ
[{"excerpt": "モデルがここに抜粋を書きます"},
...
{"excerpt": "モデルがもう一つの抜粋を書きます"}]

// ユーザーメッセージ
より関連する抜粋はありますか?同じ抜粋を繰り返さないようにしてください。また、抜粋にはそれらを解釈するために必要なすべての関連するコンテキストが含まれていることを確認してください。

戦略: 外部ツールの利用

戦術: 埋め込みベースの検索を使用して効率的な知識取得を実装する

モデルは、入力の一部として外部情報源を活用できます。これにより、モデルはより情報の豊富な最新の応答を生成することができます。たとえば、ユーザーが特定の映画に関する質問をした場合、映画に関する高品質な情報(俳優、監督など)をモデルの入力に追加することが役立つ場合があります。埋め込みを使用して効率的な知識取得を実装することで、実行時に関連情報をモデルの入力に動的に追加することができます。

テキストの埋め込みとは、テキスト文字列間の関連性を測定できるベクトルのことです。類似または関連する文字列は、無関連な文字列よりも近くに配置されます。この事実と、高速なベクトル検索アルゴリズムの存在により、埋め込みを使用して効率的な知識取得を実装することができます。特に、テキストコーパスをチャンクに分割し、各チャンクを埋め込み化して保存することができます。その後、与えられたクエリを埋め込んでベクトル検索を実行し、クエリに関連する埋め込み化されたテキストチャンクを見つけることができます(つまり、埋め込み空間で最も近くに配置されているチャンク)。

戦術: コード実行を使用してより正確な計算を行うか外部APIを呼び出す

言語モデルだけでは、算術演算や長い計算を正確に行うことに頼ることはできません。このような場合、モデルには独自の計算を行う代わりにコードを書いて実行するように指示することができます。特に、モデルには適切な形式(例: トリプルバックティック)で実行するコードを記述するように指示することができます。出力が生成された後、コードを抽出して実行することができます。最後に、必要に応じて、コード実行エンジン(つまりPythonインタープリター)からの出力を次のクエリのモデルへの入力として提供することができます。

別の良いコード実行の使用例は、外部APIを呼び出すことです。モデルにAPIの正しい使用方法を指示することで、それを利用するコードを書くように指示することができます。モデルにAPIの使用方法を指示するには、APIのドキュメントや使用方法を示すコードサンプルを提供することができます。

警告: モデルによって生成されたコードを実行することは、本質的に安全な方法ではなく、これを行うアプリケーションでは注意が必要です。特に、信頼されていないコードが引き起こす害を制限するために、砂箱化されたコード実行環境が必要です。

戦術: モデルに特定の機能へのアクセスを与える

Chat Completions APIを使用すると、リクエストで関数の説明のリストを渡すことができます。これにより、モデルは提供されたスキーマに従って関数引数を生成することができます。生成された関数引数はJSON形式でAPIによって返され、関数呼び出しを実行するために使用することができます。関数呼び出しによって提供される出力は、次のリクエストでモデルに再びフィードバックできます。これは、外部機能を呼び出すためのOpenAIモデルの推奨される方法です。

戦略: システムテストの変更を体系的に行う

時々、変更(例: 新しい指示や新しいデザイン)がシステムをより良くするか、悪くするかがわかりにくいことがあります。いくつかの例を見ることで、どちらが良いかが示唆されることもありますが、サンプルサイズが小さいと本当の改善かランダムな幸運かを区別するのが難しいことがあります。変更がある入力でパフォーマンスを向上させるかもしれませんが、他の入力でパフォーマンスを低下させるかもしれません。

評価手順(または"評価")はシステム設計の最適化に役立ちます。良い評価は以下のようなものです:

  • 実世界での使用を代表する(少なくとも多様なもの)
  • 統計的パワーを持つために多くのテストケースを含む(ガイドラインに関する表を参照)
  • 自動化または繰り返し実行が容易
検出する差異 95%信頼区間のために必要なサンプルサイズ
30% ~10
10% ~100
3% ~1,000
1% ~10,000

出力の評価はコンピュータ、人間、またはその両方で行うことができます。コンピュータは客観的基準(例: 単一の正解がある質問)やいくつかの主観的または曖昧な基準(つまりモデルの出力が他のモデルクエリによって評価される)を自動化することができます。OpenAI Evals は、自動評価を作成するためのツールを提供するオープンソースのソフトウェアフレームワークです。

モデルに基づく評価は、同じくらいの高品質であると考えられる可能性のある出力の範囲が存在する場合に便利です(例: 長い回答のある質問)。モデルに基づく評価と人間が評価する必要があるものの境界は曖昧であり、モデルがより高い能力を持つにつれて常に変化しています。どのくらいモデルに基づく評価があなたのユースケースに適しているかを見極めるための実験を奨励します。

戦術:ゴールド標準の答えと比較してモデルの出力を評価する

ある質問の正しい答えが特定の一連の事実を参照していることが分かっている場合、必要な事実を回答に含んでいるかをモデルクエリを使用して数えることができます。

例えば、以下のシステムメッセージを使用します:

// システムメッセージ
上記のトリプルクォートで囲まれたテキストが質問の答えであるはずです。次の情報が回答に直接含まれているかどうかを確認してください:

- ニール・アームストロングは最初に月面を歩いた人物でした。
- ニール・アームストロングが最初に月面を歩いた日付は1969年7月21日でした。

これらのポイントについて、以下の手順を実行してください:

1 - ポイントを再述してください。
2 - このポイントに最も近い回答から引用を提供してください。
3 - その引用を読んだ時に、そのトピックを知らない人でもそのポイントを直接推論できるかどうか考えてください。判断する前に、その理由を説明してください。
4 - 3の答えが「はい」の場合は「yes」、そうでない場合は「no」と書いてください。

最後に、「yes」の回答の数を提供してください。この数値は{"count": <ここに数値を挿入>}として提供してください。

両方のポイントが満たされている例の入力:

// システムメッセージ
<上記のシステムメッセージ>

// ユーザーメッセージ
"""ニール・アームストロングは、人類史上最初に月面に足を踏み入れたことで有名です。この歴史的な出来事は、1969年のアポロ11号のミッション中に起こりました。"""

1つのポイントだけが満たされている例の入力:

// システムメッセージ
<上記のシステムメッセージ>

// ユーザーメッセージ
"""ニール・アームストロングは、月面着陸船から降りたことで歴史を築きました。彼は月面を歩いた最初の人物となりました。"""

どちらのポイントも満たされていない例の入力:

// システムメッセージ
<上記のシステムメッセージ>

// ユーザーメッセージ
"""69年の夏、素晴らしい航海が始まった、アポロ11号、伝説のような大胆さ。アームストロングが一歩踏み出し、歴史が広がった。"一歩」と彼は言った、新しい世界へ。"""

この種のモデルベースの評価には多くのバリエーションがあります。候補の回答とゴールド標準の回答の間の重複の種類を追跡し、候補の回答がゴールド標準の回答の一部と矛盾しているかどうかも追跡します。

// システムメッセージ
ユーザーの入力に対して以下の手順を使用してください。各ステップを進む前に完全にステップを再述してください。すなわち、「ステップ1: 理由...」としてください。

ステップ1: 提出された回答の情報が専門家の回答と比較して、次のいずれかである理由を一歩一歩考えてください: 分離している、等しい、部分集合、上位集合、または重なっている(すなわち、いくつかの重複があるが部分集合/上位集合ではない)。

ステップ2: 提出された回答が専門家の回答といかなる点で矛盾しているかを一歩一歩理由づけてください。

ステップ3: 次のような構造のJSONオブジェクトを出力してください: {"type_of_overlap": "disjoint"または "equal"または "subset"または "superset"または "overlapping"、"contradiction": trueまたはfalse}

専門外のない回答ですが専門家の回答と矛盾していない例の入力:

// システムメッセージ
<上記のシステムメッセージ>

// ユーザーメッセージ
質問: """ニール・アームストロングが最も有名なのはどの出来事で、その日付はいつですか?UTC時間であると仮定してください。"""

提出された回答: """彼は何か月に歩いたのではないですか?"""

専門家の回答: """ニール・アームストロングは、人類史上最初に月面を歩いたことで最も有名です。この歴史的な出来事は1969年7月21日に起こりました。"""

専門家の回答と直接矛盾する回答の例:

// システムメッセージ
<上記のシステムメッセージ>

// ユーザーメッセージ
質問: """ニール・アームストロングが最も有名なのはどの出来事で、その日付はいつですか?UTC時間であると仮定してください。"""

提出された回答: """1969年7月21日に、ニール・アームストロングは月面を歩いた2番目の人物となり、バズ・オルドリンに続きました。"""

専門家の回答: """ニール・アームストロングは、人類史上最初に月面を歩いたことで有名です。この歴史的な出来事は1969年7月21日に起こりました。"""

必要以上の詳細を提供するが正しい回答の例:

// SYSTEM メッセージ
<上記のシステムメッセージを挿入>

// USER メッセージ

質問: """ニール・アームストロングが最も有名なイベントは何で、それが起こった日付は何ですか?UTC時間で表記してください。"""

提出された回答: """1969年7月21日午前2:56(UTC時点)、ニール・アームストロングは史上初めて月の地表に足を踏み入れたことで、人類史上の偉業を成し遂げました。"""

専門家の回答: """ニール・アームストロングは最も有名なのは月面を歩いた初の人間であり、この歴史的な出来事は1969年7月21日に起こりました。"""