
[Guidance#1]GPT-4による多段階の推論を試す
Microsoft社が出したGuidanceについて、利用方法をまとめます。
今回はGPT-4を利用した、多段階の推論をしたいというケースを取り上げてみたいと思います。
ゴールを「チキンカレーのレシピを改良したい」とし、
1.まず改良案を洗い出してもらう
2.それぞれの改良案の良いところ/悪いところを生成してベストな選択肢を定義してもらう
3.ベスト改良案の計画について生成してもらう
以下のColabで試せます。
プログラムを定義
全体のコードはこちらになります。guidance('''…''')部分で、まとめて他段階の推論を行なっています。
import os
os.environ['OPENAI_API_KEY'] = "your-openai-api-key"
!pip install guidance
import guidance
import re
# ここでは GPT-4 を使用しますが、gpt-3.5-turbo も利用可能です
guidance.llm = guidance.llms.OpenAI("gpt-4")
# Best=Xを抽出しそのオプション内容を返す関数(Guidance Program内で呼び出す)
def parse_best(prosandcons, options):
best = int(re.findall(r'Best=(\d+)', prosandcons)[0])
return options[best]
create_plan = guidance('''
{{#system~}}
あなたは料理のエキスパートです。
{{~/system}}
{{! 五つの改良案を生成します }}
{{#block hidden=True}}
{{#user~}}
私は{{goal}}です。
改良案を一つ提案してもらえますか?
提案は非常に短く、最大でも一行です。
{{~/user}}
{{#assistant~}}
{{gen 'options' n=5 temperature=1.0 max_tokens=500}}
{{~/assistant}}
{{/block}}
{{! 各改良案の利点と欠点を生成し、最良の改良案を選びます }}
{{#block hidden=True}}
{{#user~}}
私は{{goal}}です。
以下の各改良案の利点と欠点についてコメントし、最良の改良案を選んでいただけますか?
---{{#each options}}
改良案{{@index}}: {{this}}{{/each}}
---
各改良案について非常に簡潔に説明してください(利点は一行、欠点は一行)、そしてBest=Xという形で最良の改良案を教えてください、Xは最良の改良案の番号です。
{{~/user}}
{{#assistant~}}
{{gen 'prosandcons' temperature=0.0 max_tokens=500}}
{{~/assistant}}
{{/block}}
{{! 選択された改良案を達成するための計画を生成します }}
{{#user~}}
私は{{goal}}です。
以下が私の計画です:
{{parse_best prosandcons options}}
この計画について詳しく説明して、最良の達成方法を教えてください。
{{~/user}}
{{#assistant~}}
{{gen 'plan' max_tokens=500}}
{{~/assistant}}''')
out = create_plan(
goal='チキンカレーのレシピを改良したい',
parse_best=parse_best,
echo=True
)
guidance programの文法
guidanceの見通しをよくするため、文法について簡単に解説していきます。
{{ }}を使って変数の呼び出しや関数の実行、論理制御などを行います
{{#role_tag~}} {{~/role_tag}}
これで囲われている部分が指定したロールのメッセージ部分になります。Chat.Completion型のAPIを利用する場合、このロールタグを用いる必要があります
{{#system~}} {{~/system}}
{{#user~}} {{~/user}}
{{#assistant~}} {{~/assistant}}
{{! xxxxx }}
コメントを意味します。プロンプトとしては含まれず実行時に除外されていそうです。
{{~! xxxx }}という形でもコメントは書けるようです。違いはよく分かりません。
{{gen 'xxx' n=5 temperature=1.0 max_tokens=500}}
LLMへの推論部分となります。この{{gen …}}の箇所に該当する生成文字列が'xxx'という変数に格納されます。
`n=`で何回生成するかを指定できます。複数生成した文字列は配列のように呼び出すことができます。今回のユースケースではoptionsで5つ選択肢を指定して、それを後続部分のeachでそれぞれ呼び出しています。
Chat.Completion型の場合は、ロールタグの中に単独で{{gen …}}を指定しないとエラーが出てしまいます。{{#assistant~}} {{gen 'xxx' n=5 temperature=1.0 max_tokens=500}} {{~/assistant}}のように利用します。
{{#block hidden=True}} {{/block}}
このブロックで囲われた部分は、後続の推論時にプロンプトとして含まれない(隠される)ようになっています。前準備のプロセスを含ませたくない場合などに有用なイメージです。
今回のユースケースでは、複数生成した選択肢を全て前提情報として含ませるのではなく、最良の選択肢のみを抽出して利用するようにしています。
Colabで実際に動かしてライブストリーミングの挙動を見ると理解ができると思います。
{{parse_best prosandcons options}}
カスタム関数parse_bestを呼び出すこともできます。以降に続くprosandcons optionsは引数です。
{{parse_best}}で指定した部分は、戻り値に差し変わった形でプロンプトが作成されます。
出力結果
ライブストリーミングで見ると、以下のような3段階の出力結果が出てきます。各ステップはいきなり出力内容が書き変わるので、最初は少し混乱しますが、正常です。



また生成した各種変数はKey-Valueのように呼び出すことが可能です。
# 生成された変数はこのように呼び出すことができます
print(f"Goal: {out['goal']}")
print("\n----------\n")
print(f"Options: {out['options']}")
print("\n----------\n")
print(f"Pros and Cons: {out['prosandcons']}")
print("\n----------\n")
print(f"Plan: {out['plan']}")
Goal: チキンカレーのレシピ
----------
Options: ['オリーブオイルの代わりにココナッツオイルを使用し、風味とコクをアップさせてみてください。', '具材にチキンだけでなく、フルーツ(りんごやマンゴー)を加えることで、風味豊かな甘さを追加。', 'クリーミーな風味と濃厚さを出すためにココナッツミルクを追加する。', '豆乳を使用してクリーミーな食感を追加します。', 'レーズンとアーモンドスライスを加えて、フルーティーでナッツ味をプラスしましょう。']
----------
Pros and Cons: 改良案0: 利点: ココナッツオイルは風味とコクをアップさせる。 欠点: オリーブオイルの健康効果が失われる。 改良案1: 利点: フルーツを加えることで風味豊かな甘さが追加される。 欠点: 甘さが好みでない人には不向き。 改良案2: 利点: ココナッツミルクでクリーミーな風味と濃厚さが出る。 欠点: カロリーが増える。 改良案3: 利点: 豆乳でクリーミーな食感が追加される。 欠点: 豆乳の風味が好みでない人には不向き。 改良案4: 利点: レーズンとアーモンドスライスでフルーティーでナッツ味がプラスされる。 欠点: アレルギーを持つ人には不向き。 Best=2 ココナッツミルクを追加することで、クリーミーな風味と濃厚さが出て、チキンカレーの味がより豊かになります。ただし、カロリーが増えることに注意してください。
----------
Plan: チキンカレーのレシピを改良し、クリーミーで濃厚な風味を出すためにココナッツミルクを追加する方法について説明します。 まず、以下の材料を用意してください。 - 鶏肉(好みの部位):500g - 玉ねぎ:1個 - にんにく:2片 - 生姜:1かけ - トマト:2個 - カレーパウダー:大さじ2 - ターメリックパウダー:小さじ1 - コリアンダーパウダー:小さじ1 - クミンパウダー:小さじ1 - ガラムマサラ:小さじ1 - 塩:適量 - 水:カップ1 - ココナッツミルク:カップ1 - 油:大さじ2 - シナモンスティック:1本 - カルダモン:2粒 - クローブ:2粒 - ベイリーフ:1枚 - 唐辛子:1本(お好みで) - ショウガのみじん切り:小さじ1 - パクチー:適量(お好みで) 手順: 1. 鶏肉を一口大に切り、塩とターメリックパウダーをまぶしておきます。 2. 玉ねぎ、にんにく、生姜をみじん切りにし、トマトは角切りにします。 3. 中火で熱したフライパンに油を入れ、シナモンスティック、カルダモン、クローブ、ベイリーフを加えて香
ぜひ試してみて下さい!