Anthropic Claude のプロンプトガイドの USEFUL HACKS をじっくり見る

## はじめに
[前回](https://qiita.com/mariohcat/items/fb48f6cd500b830050a4) に続いて、今回も Anthropic 社のプロンプトガイドを見ていきます。

今回は USEFUL HACKS というなんかワクワクする章をしっかり読みます。書かれていることを意訳しつつ、日本語で実験しながら進めます。

注：本記事の実験は [Amazon Bedrock](https://aws.amazon.com/jp/blogs/news/amazon-bedrock-launch-seminar-japan/) の Claude v2 を使って行いました。

## USEFUL HACKS

ではドキュメントを見ていきましょう！

### ハルシネーションを防ぐために「わかりません」と Claude に言わせる
学習データにない知識が必要な質問に回答させようとすると、LLM は話をでっち上げることがあります。これがいわゆるハルシネーション（幻覚）と呼ばれるものですが、大抵の場合話をでっち上げるよりも、知らないものは知らないと回答して欲しいのではないでしょうか。

以下に、よくないプロンプトの例を示します。

```text:よくないプロンプト


Human: 今までに記録された最も重いカバの重さはどれくらいですか？

Assistant:
```

以下のように回答されましたが、本当かどうかちょっと怪しいです。

```text
記録されている最も重いカバの重さは約3,500キログラムです。
（後略）
```

次に、以下のように聞いてみます。

```text:良いプロンプトの例


Human: 次の質問には、答えを知っている場合、またはよく知られた推測ができる場合のみ答えてください。そうでなければ、答えがわからないと教えてください。

今までに記録された最も重いカバの重さはどれくらいですか？

Assistant:
```

すると、わからないという回答が返ってきました。

```test
申し訳ありませんが、最も重いカバの正確な重さを知る十分な情報がありません。カバの体重は個体差が大きく、記録された最大体重についての信頼できるデータが限られているため、正確な最大値を答えることは困難です。ご質問の答えがわからないことをご理解ください。
```

### 回答する前に考えさせる

回答に必要な情報を一旦取ってきてから最終回答を考えさせるようなプロンプトが有効なことがあります。

以下の例は、Anthropic Claude が使える Amazon Bedrock について聞いてみた例です。参照情報として [こちらの FAQ](https://aws.amazon.com/jp/bedrock/faqs/) を抜粋しました。

```test:プロンプトの抜粋


Human: 以下の質問に回答してください。
<question>
Amazon Bedrockで使えるFMは何ですか？
</question>
<faq>
Q: モデルをトレーニングして Amazon Bedrock にデプロイすることはできますか?
A: Amazon Bedrock は、基盤モデルへのアクセスに使用できるマネージドサービスです。モデルを微調整して Amazon Bedrock API で使用することができます。
Q: Amazon Bedrock ではどの FM を利用できますか?
A: Amazon Bedrock をご利用のお客様は、現在使用可能な最先端の FM の中からお選びいただけます。これには、Anthropic の Claude、AI21 Labs の Jurassic-2、Stability AI の Stable Diffusion、Cohere の Command and Embed、Meta の Llama 2、Amazon Titan の言語と埋め込みモデルが含まれます。
Q: Amazon Bedrock ではどのような SDK がサポートされていますか?
A: Amazon Bedrock はランタイムサービス用の SDK をサポートしています。iOS と Android SDK のほか、Java、JS、Python、CLI、.NET、Ruby、PHP、Go、CPP のテキスト入力と音声入力の両方をサポートしています。
</faq>
回答するときは、まずユーザーの質問に関連するFAQ内の正確な引用を探して、<thinking></thinking> XMLタグの中に文字通りに書き留めてください。これは関連する内容を書き留めるためのスペースであり、ユーザーには表示されません。関連する引用を抽出し終えたら、質問に答えてください。ユーザーへの回答は<answer></answer> XMLタグの中に入れてください。

Assistant:
```

質問文の表現を少し変えてみたのですが、以下のように正しい QA のペアを持ってきた上で決められたフォーマットで最終回答できました。

```test
<thinking>
Q: Amazon Bedrock ではどの FM を利用できますか?
A: Amazon Bedrock をご利用のお客様は、現在使用可能な最先端の FM の中からお選びいただけます。これには、Anthropic の Claude、AI21 Labs の Jurassic-2、Stability AI の Stable Diffusion、Cohere の Command and Embed、Meta の Llama 2、Amazon Titan の言語と埋め込みモデルが含まれます。
</thinking>
<answer>
Amazon Bedrockで利用できる主なFMは、AnthropicのClaude、AI21 LabsのJurassic-2、Stability AIのStable Diffusion、CohereのCommand and Embed、MetaのLlama 2、Amazon Titanの言語と埋め込みモデルです。
</answer>
```

### 段階的に考えてもらう
複数の小さなサブタスクから構成される複雑なタスクを解いてもらいたい場合は、サブタスクをリストしてあげるのが効果的です。

どんなサブタスクに分解すべきかがわからない場合、そこも Claude に考えさせちゃいましょう。

以下は、ドキュメントによくない例として書かれていたのですが、なんかうまく正解されてしまいました。

```test:よくない例


Human: 太郎さんはりんごを4つ持っています。花子さんはみかんを3つ持っています。太郎さんはりんごを1つ花子さんにあげ、花子さんはお礼にみかんを2つ太郎さんにあげました。その後、太郎さんと花子さんは自分のみかんを1つずつ食べました。太郎さんと花子さんが持っているみかんの数の合計はいくつですか。

ステップバイステップで考えてください。

Assistant:
```

本来は、以下のプロンプトが良い例だそうです。段階的に回答しなさい、という指示はリクエスト部分と分けて書くようにと書かれていました。

以下のプロンプトでも、正しい結果が出力されました。

```test:よくない例


Human: 太郎さんはりんごを4つ持っています。花子さんはみかんを3つ持っています。太郎さんはりんごを1つ花子さんにあげ、花子さんはお礼にみかんを2つ太郎さんにあげました。その後、太郎さんと花子さんは自分のみかんを1つずつ食べました。太郎さんと花子さんが持っているみかんの数の合計はいくつですか。

Assistant: ステップバイステップで考えで良いですか？

Human: はい、そうしてください。

Assistant:
```

上記のように、実際は行われた会話ではないけれど、会話があったていで指示を書くのは Claude に期待する回答をしてもらうために有効です。

偽物の記憶を Claude に埋め込む感じがしてちょっと面白いテクニックだなと思います。

### 複雑なタスクをサブタスクに分割する

複雑なタスクを一気に Claude に解かせようとすると失敗することがあります。あらかじめサブタスクに分割できるようであれば、その情報をプロンプトに入れて Claude を助けることができます。

```test:よくないプロンプト


Human: 「春が日本で一番良い季節である」をテーマにコラムを書きたいです。このテーマに支持するトピック文を3つと、反対するトピック文を3つ用意し、最後に結論を加えてください。

Assistant:
```

以下のような結果になりました。内容としてはそれっぽいですが、エッセイの形にはならなかったです。

```test
はい、テーマ「春が日本で一番良い季節である」に関するコラム文を3つの支持トピックと3つの反対トピック、そして結論を含めて作成します。

支持トピック1:
春はさわやかな季節で、穏やかな気候が心地よい。ゆったりとした気分で外出しやすい。

支持トピック2:
桜の花見は春の景色を華やかに彩る。家族や友人と桜の下でお花見は楽しい思い出になる。

支持トピック3:
春休みは1年で一番長く、リラックスした休暇を取れる季節。旅行に行くには良い時期だ。

反対トピック1:
春の季節風邪が流行る季節でもある。花粉症の人も大変な季節。

反対トピック2:
雨の日が多く、晴れた日があると混雑するので外出は大変。

反対トピック3:
入学、入社、転勤など環境の変化が多い季節。ストレスも高まりがち。

結論:
春にはさまざまな長所と短所がある。しかし、穏やかな気候と美しい桜の景色は、日本ならではの春の魅力だ。気候の変化に体調管理に気をつけつつ、家族や友人とゆったりと楽しむのが一番。春を満喫するには、その長所を大切にすることが大事だ。
```

次に、良いプロンプト例です。

```test:良いプロンプト


Human: 次の手順に従ってください：
1. 「春が日本で一番良い季節である」を支持するトピック文を3つ書く。
2. 「春が日本で一番良い季節である」に反対するトピック文を3つ書く。
3. ステップ1および2から各トピック文を拡張してエッセイを書き、論争を統合する結論を加えてください。エッセイは<essay></essay>タグで囲んでください。

Assistant:
```

おぉ、エッセイっぽい形で出力されました！

```text
<essay>
春は日本で最も良い季節の一つです。花見を楽しむことができます。桜の花が満開になると、公園は美しいピンク色に染まります。友人や家族とピクニックをしたり、お酒を飲んだりして楽しむことができます。また、春は気候が穏やかで過ごしやすい季節です。夏のように暑すぎず、冬のように寒すぎません。適度な気温で野外活動を楽しむことができます。さらに新学期が始まり、新しい出会いや挑戦が待っています。新入生の入学式やクラブ活動の始まりなど、希望に満ちた季節です。

一方で、春が日本で最も良い季節というわけではありません。梅雨の季節が訪れるのも春です。長期間の雨で気分が滅入ってしまうことも。花粉症に悩まされる人も多くいます。また、入学や進学、就職など新しい環境への不安も大きい季節です。気候の変化も大きく、体調を崩しやすい時期でもあります。

春にはいいこともあれば、悪いこともあります。季節ごとに長所と短所があるのは当然です。大切なのは、その季節を最大限に楽しむことだと思います。花見を楽しみ、新しい出会いを大切にする。梅雨の間は雨に負けずに過ごす工夫をする。苦手な面も克服して、春を充実させることができるはずです。季節の変化を楽しみながら、その時々を大切に過ごすのが人生だと思います。
</essay>
```

サブタスクに分割しても期待する結果が得られない場合は、プロンプトを分割して前のプロンプトの結果を次のプロンプトに入れる「プロンプトチェーン」が有効な場合があります。

### プロンプトチェーン
前に実行したタスクの結果を次のプロンプトに入れていく手法はプロンプトチェーンと呼ばれます。

プロンプトチェーンを使うと、長いひとつのプロンプトではなく、より小さい単純なプロンプトを複数繋げて実行することで複雑なタスクを解くことができます。

プロンプトチェーンを使うメリットは以下が挙げられます。

- プロンプトがシンプルになる
- どのサブタスクがうまくいかないかなどのトラブルシューティングがやりやすい
- Claude の出力を段階的に確認できる

#### ドキュメントと引用を使って質問に答える

この例では、Claude にドキュメントと、それに基づいて答えてもらいたい質問を与えます。多くの場合、ドキュメントのテキストと関連する引用の両方を使用して質問に答えるようにプロンプトを書くと、テキストまたは引用だけを使用するよりも期待する出力を得やすくなります。

最初のプロンプトでは、質問に関連する直接のドキュメントの引用を抽出するように指示します。

```test


Human: 以下の<document></document> XMLタグ内にドキュメントがあります。
<document>
Amazon Bedrock では、データの使用方法や暗号化方法を制御しながら FM をプライベートにカスタマイズできます。Amazon Bedrock はベースとなる基盤モデルのコピーを別に作成し、そのモデルのプライベートコピーをトレーニングします。プロンプト、プロンプトを補足するために使用される情報、FM 応答、カスタマイズされた FM などを含むデータは、API 呼び出しが処理されるリージョンにとどまります。
</document>
「Amazon BedrockはFMをカスタマイズできますか？」という質問に関連するテキストを抜粋し、抜粋したテキストを<quotes></quotes> XMLタグで囲んでください。もしこのドキュメント内にこの質問に関連するテキストが見当たらない場合は、「関連するテキストは見つかりません」と回答してください。

Assistant:
```

いい感じに関連するテキストを抜粋してくれました。

```text
<quotes>Amazon Bedrock では、データの使用方法や暗号化方法を制御しながら FM をプライベートにカスタマイズできます。Amazon Bedrock はベースとなる基盤モデルのコピーを別に作成し、そのモデルのプライベートコピーをトレーニングします。</quotes>
```

次に、Claude が出力したテキストの抜粋 (`<quotes></quotes>` XML タグを含む) を別のプロンプトに置き換えることができます。

以下は、ドキュメント、抜粋、質問に対応するプレースホルダに、先ほどのプロンプトで使用したドキュメント、質問と出力された抜粋テキストを手動で埋め込んだものです。


```text


Human: ドキュメントとそのドキュメントからの抜粋を使って、質問「Amazon BedrockはFMをカスタマイズできますか？」に答えてください。
以下の<document></document> XMLタグ内にドキュメントがあります。

<document>
Amazon Bedrock では、データの使用方法や暗号化方法を制御しながら FM をプライベートにカスタマイズできます。Amazon Bedrock はベースとなる基盤モデルのコピーを別に作成し、そのモデルのプライベートコピーをトレーニングします。プロンプト、プロンプトを補足するために使用される情報、FM 応答、カスタマイズされた FM などを含むデータは、API 呼び出しが処理されるリージョンにとどまります。
</document>

これらは質問「Amazon BedrockはFMをカスタマイズできますか？」に最も関連するドキュメントからの直接の引用です：<quotes>Amazon Bedrock では、データの使用方法や暗号化方法を制御しながら FM をプライベートにカスタマイズできます。Amazon Bedrock はベースとなる基盤モデルのコピーを別に作成し、そのモデルのプライベートコピーをトレーニングします。</quotes>

これらを使用して、質問「Amazon BedrockはFMをカスタマイズできますか？」に対して簡潔に回答してください。あなたの回答が正確であり、ドキュメントや抜粋に記載されていない情報を含まないようにしてください。

Assistant:
```

すると、以下のように期待する回答が得られました。

```text
はい、Amazon BedrockではFMをカスタマイズできます。ドキュメントによると、Amazon Bedrockはデータの使用方法や暗号化方法を制御しながら、FMをプライベートにカスタマイズできる機能があります。
```

#### 回答の検証、再確認

プロンプトチェーンは、前のステップの回答を自己チェックするよう指示するのにも適していいます。

[前回の記事のこちら](https://qiita.com/mariohcat/items/fb48f6cd500b830050a4#claude-%E3%81%AB%E8%87%AA%E8%BA%AB%E3%81%AE%E5%87%BA%E5%8A%9B%E3%82%92%E8%A9%95%E4%BE%A1%E3%81%95%E3%81%9B%E3%82%8B) で紹介したテクニックです。

#### タスク並列

マルチステッププロンプトは、並列、連続、それらの組み合わせで実行できます。

ある概念を小学1年生、中学2年生、大学1年生という3つの異なるレベルの相手に説明したいとします。また、説明する際は、まずは対象とする概念の概要を説明してからその詳細を説明する流れにしたいとします。

その場合、次のようなテンプレートが有効です。

```text


Human: この概念について説明してください。: {{CONCEPT}}

{{LEVEL}}の読者のレベルに適した、この概念の概要を3つの文章で書いてください。 

<outline></outline> XMLタグ内で、1行につき1文ずつ、概要の文章だけを回答してください。それ以外のことは何も言わないでください。

Assistant:
```

上記テンプレートを使って、CONCEPTを機械学習とし、LEVELを小学1年生、中学2年生、大学1年生、として実行してみました。
この説明だと小学1年生にはちょっと理解が難しそうですが、Claude がやろうとしていることは理解できますし、期待する動作だと言って良いでしょう。

```text
小学1年生バージョン：
<outline>
機械学習は、コンピューターがデータから学習することです。
コンピューターは、たくさんのデータを解析して、パターンを見つけます。
そして、新しいデータにそのパターンを当てはめて、予測したり分類したりします。
</outline>

中学2年生バージョン：
<outline>
機械学習とは、コンピュータにデータを与えて、そこから規則やパターンを自動的に学習させる技術です。
機械学習を使うと、コンピュータに人間のように考えたり判断したりする能力を持たせることができます。
機械学習は、画像認識や音声認識、自動運転などの様々な分野で活用されています。
</outline>

大学1年生バージョン：
<outline>
機械学習とは、コンピュータに大量のデータを解析させることで、コンピュータに新しい概念を自動的に学習させる技術です。
機械学習のアルゴリズムは、入力されたデータからパターンを見つけ出し、新しいデータに対する予測を行います。
機械学習は、コンピュータに独自に学習させ、人間の支援なしに意思決定できるようにするために用いられます。
</outline>
```

読者レベルごとに得られた3つの OUTLINE それぞれを以下のプロンプトにチェーンさせることで、それぞれのレベルに合わせたフルバージョンの文章を作ることができます。

```text


Human: こちらは文章のアウトラインです。：
{{OUTLINE}}

アウトラインの各文を段落に展開してください。各文をそのまま、対応する段落の最初の文として使用してください。{{LEVEL}}の読者レベルに合わせて書くようにしてください。

Assistant:
```

小学1年生むけのバージョンで上記プロンプトをチェーンさせてみました。指示通り読者レベルに合わせた、3つの段落から成る文章が出力されました。

```text
はい、小学1年生向けにアウトラインを段落に展開します。

機械学習は、コンピューターがデータから学習することです。
コンピューターは、とてもたくさんのデータを調べます。そして、そのデータの中から同じようなパターンを見つけ出します。コンピューターはデータを調べることが大好きなのです。

コンピューターは、たくさんのデータを解析して、パターンを見つけます。
コンピューターは、データの中からいろいろなパターンを見つけます。データには、数字や文字がたくさん書いてあります。コンピューターはその中から、同じようなパターンを探し出すのが上手なのです。

そして、新しいデータにそのパターンを当てはめて、予測したり分類したりします。
コンピューターは、見つけたパターンを使って新しいデータを調べます。新しいデータも同じパターンがあれば、コンピューターはそれを予測したり、データを分類したりすることができるのです。
```

### Claude の理解度を確認する

Claude がプロンプトを理解したかどうかを確認する最善の方法は、Claude 自身に聞いてみることです。

```text


Human: 一つの文を与えるので、その中に「りんご」という単語が何個含まれているかを教えてください。例えば、「私はりんごを食べたい」という文章が与えられた場合、答えは[1]です。なぜなら、「りんご」という単語が文の中に一個だけ含まれているからです。答える前に、何かを推理したり説明したりすることはできますが、最終的な答えだけを括弧の中にこのようにして回答してください。：[1]

指示が理解できましたか？

Assistant:
```

上記指示を理解してくれたようです！

```text
はい、指示は理解できました。文中の「りんご」の数を括弧内に回答するようにします。
```

Claude がプロンプトを理解したことを確認できたら、それを会話履歴としてプロンプトに入れることで、期待する出力を得やすくすることができます。

```text


Human: 一つの文を与えるので、その中に「りんご」という単語が何個含まれているかを教えてください。例えば、「私はりんごを食べたい」という文章が与えられた場合、答えは[1]です。なぜなら、「りんご」という単語が文の中に一個だけ含まれているからです。答える前に、何かを推理したり説明したりすることはできますが、最終的な答えだけを括弧の中にこのようにして回答してください。：[1]

指示が理解できましたか？

Assistant: はい、指示は理解できました。文中の「りんご」の数を括弧内に回答するようにします。

Human: よろしい。では、以下の文章に対して指示を実行してください。

「りんごのパイを焼くためにりんごを一つ使います。残りのりんごは後で使うために取っておきます。」

Assistant:
```

無事、[3]という出力を得ることができました。

### Claude にやり直しさせる

Claude の出力が期待しているものに近いもののちょっと違うなという場合は、もう一度考え直すように指示することができます。

以下のテンプレートでは、PARAGRAPH を前回の実行結果で置き換えて、INSTRUCTIONS を追加の指示で置き換えます。

これを自動化するには、プロンプトチェーンの仕組みを使う必要があります。

```text


Human: 以下に書き直す対象のテキストがあります。
<paragraph>
{{PARAGRAPH}}
</paragraph>

テキストを以下の指示に従って書き直してください：
<instructions>
{{INSTRUCTIONS}}
</instructions>

書き直したテキストを<rewrite></rewrite>タグで囲んでください。

Assistant: <rewrite>
```

## おわりに

USEFUL HACK の章では、Claude に所望の出力をさせる様々な工夫が紹介されていました。架空の会話履歴をプロンプトに埋め込んで、Claude が指示を理解した既成事実を作る的なハックが面白かったです。

次回は、USE CASES の章を見ていきたいと思います。