nikkie-ftnextの日記

イベントレポートや読書メモを発信

「ChatGPT Prompt Engineering for Developers」Summarizing 素振りの記

はじめに

こぉ↑ひぃ↓かぁぷ→ のぞいたら♪1 nikkieです。

先日視聴し終えた「ChatGPT Prompt Engineering for Developers」。

その中から要約(Summarizing)についてサンプルコードを元に素振りしたログを残します。

目次

Summarizing

Andrew Ng先生と、OpenAIのIsa Fulfordさんによる講座「ChatGPT Prompt Engineering for Developers」。

LLMsで何ができるかの見通しをつかめる、非常にオススメの講座です。

何ができるかの1つが、要約(Summarizing)。
https://learn.deeplearning.ai/chatgpt-prompt-eng/lesson/4/summarizing

LLMsに要約をお願いするプロンプトについて具体的なテクニックが知られちゃいます!

  • DeepLearning.AIの講座の環境ではJupyter Notebookが動きます
    • 順にセルを実行していくと、なんとOPENAI_API_KEYが設定されて、OpenAIのAPIが叩けます2
    • 私は手元のPCの環境で動かしました
  • ChatGPT(gpt-3.5-turbo)に要約をお願いします

手元の環境

なお環境変数OPENAI_API_KEYさえあればopenaiライブラリは動くので、私はexportだけして使っています。

英語の商品レビューを要約

以下の商品レビューを要約します。
※サンプルコードは一続き(改行をエスケープして折っている)ですが、見やすさのために文ごとに改行しています。これによりAPIの出力は多少異なります

prod_review = """\
Got this panda plush toy for my daughter's birthday, who loves it and takes it everywhere.
It's soft and super cute, and its face has a friendly look.
It's a bit small for what I paid though.
I think there might be other options that are bigger for the same price.
It arrived a day earlier than expected, so I got to play with it myself before I gave it to her."""

基本となる要約プロンプトはこちら

prompt = f"""\
Your task is to generate a short summary of a product review from an ecommerce site.

Summarize the review below, delimited by triple backticks.

Review: ```{prod_review}```"""

triple backticksは、delimiterを使うという「明確で具体的な指示を与える」ための戦術(tactic)の1つです。

次のように要約してくれます。

% python summarizing.py
This panda plush toy is soft, cute, and has a friendly face. The reviewer's daughter loves it and takes it everywhere. However, the toy is a bit small for the price paid, and there may be bigger options available for the same price. The toy arrived a day earlier than expected.

このプロンプトを少しずつ次々と変えていきます。

  • 語数の制約を付ける
  • 要約する観点を指定する
    • 商品の配送について
      • 「shipping departmentにフィードバックを与えるために要約してください」
    • 商品の価格について
      • 「pricing departmentに(以下略)」
  • summarizeの代わりにextractという語を使う
    • すごく端的に抜き出されることがある!
    • extract + shipping department向け
    • extract + pricing department向け
  • 複数のレビューの要約
    • 1つのレビューと同様のプロンプトを反復するだけ

仮説: 観点を指定してLLMsに読んでもらえるのではないか

要約って万人にとっての正解があるって思っていたんですよね。
ですが、「Summarizing」での例を見て別の可能性を考えるようになりました。

示された例では、商品の配送についての要約、商品の価格についての要約と、観点を指定した要約がされます。
要約を読みたい人の文脈によって、正解の要約が変わるんじゃないかな〜と考え始めています。
なので、静的な1通りの要約ではなく、何回かLLMsとやり取りして複数パターンの要約を元に理解を深めていく共同作業としての要約、それがありえるかもしれません。

この仮説を検証するためにこのブログのタイトルを使います3
https://gist.github.com/ftnext/f80038bcc749d75b54cb9f2e1a073d22

ブログタイトル一覧要約の自作ライブラリ(v0.0.1)の_build_summarize_prompt_textメソッドを置き換えていきます
https://github.com/ftnext/recent-state-summarizer/blob/v0.0.1/recent_state_summarizer/summarize.py#L26-L33

特に観点を指定しない要約

def _build_summarize_prompt_text(titles_as_list: str) -> str:
    return f"""\
3つのバッククォートで囲まれた以下は、同一人物が最近書いたブログ記事のタイトルの一覧です。
それを読み、この人物が最近何をやっているかを詳しく教えてください。
応答は文ごとに改行して区切ってください。

\`\`\`
{titles_as_list}
\`\`\`
"""

Markdownのコードブロック記法と競合しないようにバッククォートの前にバックスラッシュを入れました)

この人物は最近、Pythonのcsvモジュールを使ってCSVファイルを読み込む方法を学んだり、ChatGPTを使って日本語テキストを処理する方法を調べたりしているようです。また、リソースファイルと一緒にパッケージをインストールする方法や、pytest.mark.parametrizeの使い方など、Pythonの様々な機能についても学んでいるようです。さらに、読書ログをつけていて、『機械学習デザインパターン』や『Clean Code』などの書籍を読んでいるようです。最近は、映画『かがみの孤城』の原作小説も読み終え、感動したようです。また、株式会社はてなに入社したようです。

技術観点と技術以外観点でお願いしてみました。
※これは完成版ではなく、試行錯誤中のものを晒しています

技術観点

def _build_summarize_prompt_text(titles_as_list: str) -> str:
    return f"""\
3つのバッククォートで囲まれた以下は、同一人物が最近書いたブログ記事のタイトルの一覧です。
この人物のソフトウェアエンジニアとしての近況を知りたいです。
タイトル一覧を読み、この人物が最近どんな技術を触っているかを詳しく教えてください。
応答は文ごとに改行して区切ってください。

\`\`\`
{titles_as_list}
\`\`\`
"""
この人物は最近、以下の技術に触れているようです。

- Pythonのcsvモジュールを使ったCSVファイルの読み込みや、空行やフィールド数の違いに対する対応方法
- ChatGPTやTikTok APIを使った日本語テキストのトークン化や、Webページの本文取得の実装方法
- 機械学習に関するチュートリアルやデザインパターンの読書
- Pythonのパッケージのリソースファイルとのインストール方法や、csvモジュールのソースコードリーディング
- pytestのパラメータ化や、クリーンアーキテクチャやClean Codeの読書
- 映画や小説の感想、会社のリリースや入社などの個人的な情報

技術以外観点

def _build_summarize_prompt_text(titles_as_list: str) -> str:
    return f"""\
3つのバッククォートで囲まれた以下は、同一人物が最近書いたブログ記事のタイトルの一覧です。
この人物はソフトウェアエンジニアですが、技術以外の近況を知りたいです。
タイトル一覧を読み、この人物が最近どんな趣味をやっているかを詳しく教えてください。
応答は文ごとに改行して区切ってください。

\`\`\`
{titles_as_list}
\`\`\`
"""
この人物は最近、以下の趣味に取り組んでいるようです。

- 『バグハンター2 REBOOT』を遊ぶこと
- #ミノ駆動本の読書
- ChatGPTに関する研究
- 機械学習に関するチュートリアルの写経
- #かがみの孤城の小説や映画の鑑賞
- Pythonのテクニカルなトピックに関する研究

また、株式会社はてなに入社したようです。

ちょっとちんぷんかんぷんなところもありますが、要約(箇条書き)のトピック、変わってますよね!
なので講座で示された観点ごとの要約は、英語だけでなく日本語でも再現するんじゃないかと思います。

なお、temperatureを0に固定しているはずですが、返り値が複数パターンありました(2、3通りの中から返ってくる)。
なんでだろう... なにか見落としているのかもしれません(宿題事項)

(「応答は文ごとに改行して区切ってください。」はかつては効いていたのですが、もう全然効いてないですね...)

終わりに

「ChatGPT Prompt Engineering for Developers」講座のSummarizingで素振りしました。
私が持っていた要約のイメージが少し揺さぶられています。
観点を指定してやり取りを繰り返す共同作業としての要約、もうちょっと可能性を探ってみたい!

英語はきれいに観点に沿って回答していますが、(日本語はカオスな文章を与えたのもあり)今一つに感じます。
テキストの種類を商品レビューに揃えたり、LLMsも英語と日本語で習熟度に違いはありそうなので、より賢くなっていると聞いたGPT-4を試してみたり、アイデアは尽きないです。
もう少し触ってみよう!

P.S. Ng先生、もっとPythonicに書けますよ

複数のレビューについて要約を反復するコードにPython好きすぎる立場から異議あり!!

現状

for i in range(len(reviews)):
    # reviews[i]を参照

提案「それ、enumerateで書くのがPythonicとされてますよ」

for i, review in enumerate(reviews):
    # reviewで参照できる!

項目7 rangeではなくenumerateを使う


  1. ちょw 弾幕やばすぎww https://www.nicovideo.jp/watch/so23335421
  2. さすがOpenAIとのパートナーシップ! 実行環境はどういう仕組みなんでしょう? あとこれ悪用されないのかな?
  3. タイトルからの近況要約に取り組んでいます