ランサーズ(Lancers)エンジニアブログ > Lancers LLM Labs > LLMは思った通りにも書いた通りにも動かない。教えた通りに動くのだ。

LLMは思った通りにも書いた通りにも動かない。教えた通りに動くのだ。

okada.naoki|2023年09月08日
Lancers LLM Labs

こんにちは、Lancers LLM Labsのエンジニアをしている岡田です。

Lancers LLM Labs とは、急速に成長する生成AI・LLMに対応していくために開設された、専門性の高い技術を理解し先端を走る新チームです。

詳しくはこちらをご覧ください。

今回は、私がLLMを扱う上で欠かせないプロンプトに向き合って、分かったことや感じたことを共有したいと思います。

プロンプトの学びの始まり

プロンプトに向き合い始めて、最初にぶつかったのは「プロンプトってどう学ぶ?」という問いでした。LLMが実用的に使えると話題になり、突如現れた「プロンプトエンジニア・デザイン・チューニング」という分野。情報が散逸しており、情報があってもどれを信頼すればよいのか迷います。また、プロンプトでできることとできないことの区別がつかないなどの問題が存在していました。特に、「プロンプトはこう書くと良い」とか「このプロンプトを使えば解決」という話はあるものの、具体的な問題に対する具体的な対応策はなかなか見当たりませんでした。

オススメされたプロンプトを与えたLLMは、確かに期待以上の出力をすることもありますが、逆に期待を下回ることもあります。LLMを直接利用する場合は問題ありませんが、LLMを内部に組み込みたい場合、期待以上でも期待以下でもなく、期待通りに動く制御可能なプロンプトの方が多くのケースで便利です。

プロンプト設計で気づいたポイント

ということで、本章では「このような問題に対してはこう対応する」という観点から、私が学び取ったことを紹介します。

出力形式がバラつく時

決まった出力を求めているのに、「以上が〜」や「理解しました。」など、対話特有の文言が追加されることがよくあります。

一貫性を求める場面でばらつきが生じたときは、具体的な例を提示することで、より期待通りの動きを引き出すことができます。

  • 具体的な例を入れていない
    具体的な例を入れていない
  • 具体的な例を入れる
    具体的な例を入れる

思ったように動かない時

ある動作を期待していたのに、まったく異なる動作をすることもよく遭遇する問題です。

想定していた動きを得られない場合、手順を明確にして具体的に進めることで、期待する動作を実現できることが多いです。

  • 手順を明確化していない
    手順を明確化していない
  • 手順を明確化している
    手順を明確化している

プロンプトをいくら工夫しても上手くいかない時

最後にプロンプトを出来る限り具体化して、これでもかというくらい作り込んだにも関わらず、プロンプトに書いた指示が無視されることがありました。

そのような時は、プロンプトのタスクが過度に複雑になっていないかを確認しましょう。

タスクの実行に余計な情報や、あれもこれもやりたい複雑なタスクは、それをさらに小さなタスクや質問に分解することで、より適切な答えを得られることがあります。

  • 同系統のタスクは可能
    同系統のタスクは可能
  • 別系統のタスクが混ざると失敗する
    別系統のタスクが混ざると失敗する

LLMは教えた通りに動く

ここまでプロンプトを書き換えても、思った通りに動作してくれないことはしばしばあります。

なぜなら、LLMは私たちの期待どおりに動作しているわけではなく、またプロンプトに書かれた指示どおりに動いているわけでもありません。実際には、LLMは「教えられた内容」に基づき、プロンプトに対する適切な回答を出力しているだけなのです。

LLMの動作は、根本的には訓練データに基づいています。出力される内容も訓練データに基づいたものであるため、訓練データで学んだ範囲を超えることはできません。では、具体的にどのようなデータが学習の基盤となっているのでしょうか。

学習データ

ChatGPTの正確な学習データは分かりませんが、前身のInstrumentGPT(ひいてはその前身のGPT-3)の学習データは以下のデータセットが使われています。(参考

  • CommonCrawl(正解中のWebサイトからクロールで収集された大規模なデータセット)
  • Webtext(約百万のウェブページから抽出されたデータセット)の拡張版
  • 2つのインターネットベースの書籍コーパス
  • 英語版ウィキペディア

NLPのタスクから想定

文章の分類や感情分析、文章生成など、NLPの多様なタスクが学習の際のタスクとして設定されている可能性があります。(参考

  • 文章の分類:文章をカテゴリーやポジティブ・ネガティブで分類
  • 文の中の単語分類:品詞や、固有表現の識別
  • 文章内容の生成:入力テキストの補完、文章の穴埋め
  • 文章からの情報抽出:質問と情報が与えられたとき、情報に基づいた質問に対する答えの抽出
  • 文章の変換:文章の翻訳、要約

性能を測るベンチマークから理解

学習データではありませんが、性能を測るベンチマークの結果からどんなこと学んでいるか知ることはできます。(参考1参考2

  • MARC-ja: 文章のポジティブ・ネガティブ分類
  • JSTS: 与えられた文章のペアが類似度を0(相違)〜5(類似)で測定
  • JNLI: 与えられた文章のペアの関係を含意・矛盾 ・中立のどれか推定
  • JSQuAD: 質問に対して与えられた情報から回答を抽出
  • JCommonsenseQA: 常識があるか5択問題で能力を評価

さいごに

私がここで共有している情報は、あくまで私自身の体験や学びに基づくものです。技術は日進月歩で進化しており、今の情報がすぐに古くなることも考えられます。例えば、私が取り上げた問題は、GPT-3.5の状況でのもので、GPT-4で実行すれば問題にならないかもしれません。まだ確立していない技術や知見が多い中、私たちは試行錯誤を重ねていくしかないのです。

それでも、「LLMは思った通りにも書いた通りにも動かない。教えた通りに動くのだ。」という考えを持つことで、プロンプトについて分からないことが多い中、予期せぬ問題に直面したときにも、少しは気軽に取り組むことができるかと思います。

プロンプトの習得は一筋縄ではいきませんが、新たな領域の開拓は特有の喜びをもたらしてくれるはずです。このブログが皆さんの学びの参考となり、一人でも多くの方の支えになれば嬉しいです。