ご存知のように、大規模な言語モデルにタスクを実行させる必要がある場合、その実行をガイドするプロンプトを入力する必要がある。簡単なタスクであれば、自然言語で明確に記述することができます。例えば、「以下を簡体字中国語に翻訳してください」、「以下の要約を生成してください」などです。
しかし、モデルに特定のJSON形式を生成させるような複雑なタスクや、タスクに複数の分岐があり、各分岐が複数のサブタスクを実行する必要があり、サブタスクが相互に関連しているような場合には、自然言語による記述では不十分である。
議題
この先を読む前に、2つの示唆に富む質問を試してみてほしい:
- 複数の長い文章があり、それぞれを80文字以内の短い文章に分割し、長い文章と短い文章の対応を明確に記述したJSON形式に出力する必要がある。
例えば、こうだ:
[ { "long": "これは長い文章なので、短い文章に分割する必要があります。", "short": [ [ { "short": [ "これは分割が必要な長い文章です。", "short": [ "This is a long sentence that needs to be split", "short": [ "This is a long sentence", "that needs to be split", "into shorter sentences. "これは長い文です", "分割する必要があります", "短い文に". これは長い文章で、短い文章に分割する必要がある。] }, { "short". }, { "long": "another long sentence that should be split into shorter sentences.", "short": [ "that needs to be split", "into shorter sentences." ] }, { "short": [ "別の長い文章", "分割すべき文章", "short": [ "that should be split", "short": [ "Another long sentence", "that should be split", "short". 「より短い文に。 ] } ]
- 元の字幕付きテキストには、台詞の情報しかありませんが、そこから章、話者を抽出し、章と段落ごとに台詞をリストアップする必要があります。複数の話し手がいる場合は、同じ話し手が連続して話す場合ではなく、それぞれの台詞の前に話し手を付ける必要がある。(これは、私自身がビデオスクリプトを整理するために使用しているGPTです。 ビデオスクリプト照合GPT)
入力例:
だから、イーロン・マスクの言葉を引用するが、気にしないでほしい。 申し訳ない。 しかし、彼はこれがプライバシーとセキュリティのモデルであることに同意していない。 彼はこの統合を "不気味なスパイウェア "と呼んだ。それに対するあなたの反応は? 気にしない? それが彼の意見だ。 明らかに、私はそうは思わない。 我々もだ ミラ、来てくれてありがとう お忙しいでしょう。 ミラに聞きたいことはたくさんありますが、20分しかありません。 そこで、まずいくつかの期待事項を設定したいと思います。 最近のニュースやミラがCTOとして担当している分野など、いくつかのトピックに焦点を当てたいと思います。 うまくいけば、これらのトピックのいくつかに飛び込むことができるでしょう。 最初の質問は、あなたが今、非常に多忙であること、そしてニュースにおける攻撃、良いものも悪いものもありますが、あなたは約6年前に入社されました。 当時は非常に異なる組織でした。 あなたは比較的目立たず、あまり知られていませんでした。 仕事に集中できていた頃が懐かしいですか? 今でも仕事に完全に取り組んでいると言える。 ただ、その仕事は進化していて、研究だけではありません。 研究も進歩している。 この技術をいかに有益で安全な形で世に送り出すかということでもあり、使命は変わらない。 技術に携わり、製品を開発している私たちにとっては、少し異例に思えるかもしれませんが、これには多くの人々の関心が集まっています。 でもね、私たちがやっていることの重要性を考えれば、このような注目はとても必要なことだし、ポジティブなことなんだ。
出力例:
### はじめに **司会者 イーロン・マスクの言葉を引用します。申し訳ありませんが、彼はこれがプライバシーとセキュリティのモデルであることに同意していません。彼はこの統合を "不気味なスパイウェア "と呼びました。それに対するあなたの反応は? **ミラ それが彼の意見です。もちろん、私はそうは思いません。私たちもそうは思いません。 ### 歓迎と紹介 **ホスト ミラ、お集まりいただきありがとうございます。お忙しいとは思います。質問もたくさんあるのですが、20分しかありません。まずはご期待いただきたいと思います。最近のニュースや、あなたがCTOとして担当している分野など、いくつかのトピックに焦点を当てたいと思います。これらのトピックのいくつかに飛び込めることを願っています。 ##キャリアレビュー **ホスト 最初の質問は、あなたが今、非常に忙しいという事実と、良いことも悪いことも含めてニュースに出ている攻撃についてですが、あなたは約6年前にこの会社に入社されました。当時は非常に異なる組織でした。あなたは比較的地味で、あまり知られていませんでした。仕事に全力を注いでいた頃が懐かしいですか? **ミラ 私たちは今でも仕事に全力を注いでいると言えるでしょう。ただ、仕事が進化し、研究だけではなくなったということです。研究が大きく進歩したからです。また、この技術をいかに有益かつ安全な方法で世に送り出すかということでもある。ですから、使命は変わりませんし、研究もかなり進み、仕事の領域も広がっています。この技術に取り組み、製品を開発している私たちにとっては、少し異常に感じるかもしれません。しかし、私たちがやっていることの重要性を考えれば、このような注目は非常に必要なことであり、ポジティブなことであることに気づかなければならない。
プロンプトの真髄
プロンプトのテクニックの書き方に関する記事をネットでたくさん読んだり、プロンプトのテンプレートをたくさん覚えたりしているかもしれないが、プロンプトの本質とは何だろうか?なぜプロンプトが必要なのか?
プロンプトは、基本的に自然言語で記述されたLLMへの制御命令であり、LLMがこちらの要求を理解し、必要に応じて入力を希望する出力に変えることを可能にする。
例えば、よく使われる数発技法は、LLMに例題を通してこちらの要求を理解させ、そのサンプルを参照してこちらの望む結果を出力させるというものです。例えば、CoT(Chain of Thought)とは、タスクを人為的に分解し、実行プロセスを限定することで、LLMが拡散しすぎたり、重要なステップをスキップしたりすることなく、こちらが指定したプロセスやステップに従うことができ、より良い結果を得ることができるようにすることである。
私たちが学生だった頃、先生が数学の定理について話すときには、その定理の意味を理解できるような例を示さなければならなかったのと同じように、私たちが実験をするときには、先生は実験の手順を教えてくれなければならなかった。たとえ私たちが実験の原理を理解していなくても、手順通りに実験を行えば、多かれ少なかれ同じ結果を得ることができる。
プロンプトの結果が最適でないことがあるのはなぜですか?
これは、LLMが我々の要求を正確に理解できないためであり、一方ではLLMの指示を理解し従う能力によって、他方では我々のプロンプトの説明の明確さと正確さによって制限される。
LLMの出力を正確に制御し、擬似コードを用いてその実行ロジックを定義する方法
プロンプトは基本的にLLMの制御命令であるため、従来の自然言語による記述に限定されることなく、LLMの出力を正確に制御し、その実行ロジックを定義するために擬似コードを使用してプロンプトを記述することができる。
疑似コードとは何か?
擬似コードの歴史は古く、自然言語とプログラミング言語の中間のような記述方法で、アルゴリズムを記述するための形式的な記述方法です。様々なアルゴリズムの本や論文では、擬似コードの記述をよく見かけますが、言語に詳しくなくても、擬似コードを通してアルゴリズムの実行の流れを理解することができます。
では、LLMは擬似コードをどの程度理解しているのだろうか?実際、LLMの擬似コードに対する理解度は非常に高く、LLMは大量の高品質なコードで訓練を受けており、擬似コードの意味を容易に理解することができます。
プロンプトの擬似コードの書き方は?
疑似コードは、プログラマーにとっては非常に馴染み深いものであり、プログラマーでなくても、いくつかの基本的なルールを覚えておくだけで、簡単な疑似コードを書くことができる。いくつかの例を挙げよう:
- 例えば、入力や中間結果を特定の記号で表す。
- 文字列、数値、配列など、データの型を定義するために使用される。
- 特定のサブタスクの実行ロジックを定義する関数
- ループや条件判定など、プログラムの実行プロセスを制御するために使われる制御フロー。
- if-else文は、条件Aが満たされればタスクAを実行し、そうでなければタスクBを実行する。
- 配列の各要素に対してタスクを実行するforループ。
- whileループでは、Aという条件が満たされると、Bというタスクが連続して実行される。
では、前の2つのリフレクション・クエスチョンを例にして、擬似コードのプロンプトを書いてみましょう。
特定のJSONフォーマットを出力する疑似コード
希望するJSONフォーマットは、TypeScriptの型定義に似た擬似コードで明確に記述できる:
文章は1行以内(80字以内、英単語10語以内)に分割してください。 例えば、句読点、「and」、「that」、「where」、「what」、「when」、「who」、「which」、「or」などは可能であれば分割してください。分割するための句読点や単語は残しておくこと。 単語や句読点を追加したり削除したりしないでください。 入力は文字列の配列である。 出力はオブジェクトの有効な json 配列で、各オブジェクトには文とそのセグメントが含まれます。 配列
字幕スクリプトを擬似コードで整理する
字幕付きテキストを照合するタスクは比較的複雑である。 このタスクを達成するためのプログラムを書くことを想像すると、章を抽出し、話者を抽出し、最後に章と話者に従ってダイアログを照合するなど、多くのステップがあるかもしれない。擬似コードを使えば、このタスクをいくつかのサブタスクに分解することができる。具体的なコードを書く必要はなく、サブタスクの実行ロジックを明確に記述すればよい。そして、これらのサブタスクを段階的に実行し、最後に結果出力を統合する。
のような変数を使うことができる。 件名
そしてスピーカー
そして章立て
そしてパラグラフ
その他
出力時には、Forループを使って章や段落を繰り返し、If-else文を使って発言者の名前を出力する必要があるかどうかを判断することもできる。
あなたの仕事は、読みやすくするためにビデオトランスクリプトを再編成し、複数人の対話のために話者を認識することです。 以下は、それを行う方法についての擬似コードです。以下はその擬似コードです。
def extract_subject(transcript): #トランスクリプトのサブジェクトを探し、文字列として返す。 # トランスクリプトからサブジェクトを見つけ、文字列として返す。 def extract_chapters(transcript): # トランスクリプト内の章を探し、文字列のリストとして返す。 def extract_chapters(transcript): 文字列のリストとして返す。 def extract_speakers(transcript): #トランスクリプト内の話者を見つけ、文字列のリストとして返す。 def extract_speakers(transcript): #トランスクリプト内の話者を見つけ、文字列のリストとして返す。 def find_paragraphs_and_speakers_in_chapter(chapter): # 段落を探し、文字列のリストとして返す。 def extract_speakers(transcript). def find_paragraphs_and_speakers_in_chapter(chapter). #章内の段落と話者を探し、タプルのリストとして返す。 #各タプルは話者とその段落を含む。 #章内の段落と話者を見つけ、タプルのリストとして返す。 def format_transcript(transcript): #主語、テキスト、単語を取り出す。 #主語、話者、章を抽出し、それらを表示する。 件名 = extract_subject(transcript) print("Subject:", subject) スピーカー = extract_speakers(transcript) print("Speakers:", speakers) chapters = extract_chapters(transcript) print("Chapters:", chapters) #トランスクリプトをフォーマットする formatted_transcript = f "# {subject}n" for chapter in chapters. formatted_transcript += f "## {chapter}n}n" for chapter in chapters. paragraphs_and_speakers = find_paragraphs_and_speakers_in_chapter(chapter) for speaker, paragraphs in paragraphs_and_speakers. #複数の発言者がいる場合、各段落の前に発言者の名前を表示する if speakers.size() > 1. formatted_transcript += f"{発言者}:" formatted_transcript += f"{発言者}:" for paragraphs in paragraphs: formatted_transcript += f"{発言者}: formatted_transcript += f" {paragraph}n" formatted_transcript += "\nân" return formatted_transcript print(format_transcript($user_input))
どうなるか見てみよう:
このプロンプトで生成したGPTを使うこともできます:転写組織GPT
擬似コードでChatGPTに複数の画像を同時に描画させる
私も最近、台湾のネットユーザーである尹祥志先生から、非常に興味深い言葉の使い方を学んだ。擬似コードでChatGPTに複数の画像を一度に描画させる.
さて、もしあなたが チャットGPT 一度に複数の画像を生成したい場合は、擬似コードを使って複数の画像を生成するタスクを複数のサブタスクに分割し、複数のサブタスクを一度に実行し、最終的に結果出力を統合することができます。
ここに図を描くための擬似コードがあります。擬似コードのロジックに従って、DALL-Eで図を描いてください: images_prompts = [ { style: "Kawaii"、 prompt: "かわいい犬を描いてください"、 aspectRatio: "Wide" }, { style: "リアル系", prompt: "リアルな犬を描いてください", aspectRatio: "ワイド" }, { prompt: "リアルな犬を描いてください", aspectRatio: "正方形 アスペクト比: "正方形" } ] images_prompts.forEach((image_prompt))=>{」を実行します。 print("Generating image with style: " + image_prompt.style + " and prompt: " + image_prompt.prompt + " and aspect ratio: " + image_prompt.aspectRatio) image_generation(image_prompt.style, image_prompt.prompt, image_prompt.aspectRatio); })
概要
上記の例から、自然言語による記述に限定するのではなく、擬似コードを使用することで、LLMの出力結果をより正確に制御し、その実行ロジックを定義できることがわかります。複雑なタスクや複数の分岐を持つタスクに遭遇し、各分岐が複数のサブタスクを実行する必要があり、サブタスクが互いに関連している場合、擬似コードを使用してプロンプトを記述する方がより明確で正確です。
プロンプトを書くとき、プロンプトは基本的に自然言語で記述されたLLMへの制御命令であり、LLMが私たちの望むことを理解し、必要に応じて入力を期待する出力に変えることを可能にするものであることを覚えておいてください。プロンプトを記述する形式としては、例えば数ショット、CoT、擬似コードなど、様々な形式に柔軟に対応することができます。
他の例もある: