ブログに戻る

AI入門ガイド

プロンプト内のすべてのドキュメントにラベルを付けてモデルが混同しないようにする

貼り付けた各テキストに名前と役割を与える方法。ビフォー/アフターのプロンプトと、Pythonとcurlで動作するチャット補完リクエスト付き。

投稿者: CheapTokens Team公開日 読了時間 7 分

カバー:2つのドキュメントがあるプロンプト。それぞれがソース名付きの独自のタグで囲まれている
このページの内容
  1. ただ貼り付けると何が問題か
  2. 各テキストに名前と役割を与える
  3. 実際のリクエストとして送信する
  4. ラベルのコスト
  5. より大きなテキストの山に対する習慣

2つのテキストを1つのメッセージに貼り付けて、モデルに比較を依頼しましたか?どちらがどちらかを指定しなければ、モデルは推測するしかありません。修正は簡単です。各テキストに名前と役割を与え、それぞれを独自のタグで囲むだけです。Anthropicのプロンプティングガイド(2026年10月31日確認の更新ページ)は、コンテンツの種類ごとにタグを付けることを推奨しています。そうすればモデルが、何が指示で、何が背景で、何が入力かを誤解しません。以下にビフォー/アフターのプロンプトと、CheapTokens APIに送信できる実際のチャット補完リクエストを示します。

ただ貼り付けると何が問題か#

最も単純なケースを考えましょう。サプライヤーが新しい商品説明を送ってきて、ショップページのものと何が変わったかを知りたいとします。「何が変わりましたか?」の下に両方を貼り付けて送信します。あなたには順序が明らかです。しかしモデルにとっては、間に何もない2つのテキストブロックであり、質問にはどちらが古いかが書かれていません。正しく推測することもありますが、新しいテキストを古いものと呼び、変更点を逆方向に並べたリストを、自信満々の口調で返してくることもあります。

同じ罠は日常業務にも潜んでいます:

  • 契約書の2つのバージョンがあり、相手側が何を変えたかを尋ねる;
  • 3つの会議メモがあり、どの決定が互いに矛盾するかを尋ねる;
  • スタイルサンプルと下書き:どちらを模倣し、どちらを書き直すのか?
  • エラーログとコードを一緒に貼り付けて、「これを修正して」と尋ねる。

いずれの場合も、モデルはテキストごとに2つのものが必要です:名前(それが何で、どこから来たか)と役割(それで何をしてほしいか)です。

各テキストに名前と役割を与える#

3つの小さなステップ:

  1. 各テキストを独自のタグに入れます。Anthropicのガイドは、<documents>ラッパーを使い、テキストごとに1つの<document index="1">、その中に名前用の<source>とテキスト自体用の<document_content>を入れることを提案しています。
  2. タグの外側の指示で、それぞれが何であるかを述べます:「ドキュメント1は当店の古いテキストです。ドキュメント2はサプライヤーからの新しいテキストです。」
  3. 同じ言葉で質問します。「変更されたすべての事実を古い -> 新しいとしてリストしてください」と言えば、指し示すべき古いものと新しいものができます。

以下はボトルの例のビフォー/アフターです:

比較する

同じリクエストのビフォーとアフター

ビフォー

text
What changed?

Steel water bottle, 500 ml. Keeps drinks cold for 12 hours. Dishwasher safe.

Steel water bottle, 750 ml. Keeps drinks cold for 24 hours. Hand wash only.

アフター

text
Document 1 is the OLD text from our shop. Document 2 is the NEW text from the supplier. List every fact that changed, one per line, as old -> new.

<documents>
<document index="1">
<source>old description (current shop page)</source>
<document_content>
Steel water bottle, 500 ml. Keeps drinks cold for 12 hours. Dishwasher safe.
</document_content>
</document>
<document index="2">
<source>new description (from the supplier)</source>
<document_content>
Steel water bottle, 750 ml. Keeps drinks cold for 24 hours. Hand wash only.
</document_content>
</document>
</documents>
指示が各ドキュメントを名指しし、各テキストが独自のタグに入っているプロンプト
指示が各ドキュメントを説明し、タグがテキストを分離している

ラベルは数トークンのコストがかかりますが、推測を排除します。AnthropicはこれをClaudeモデル向けに書きましたが、ラベルはプレーンテキストなので、同じレイアウトを別のチャットモデルに送っても問題ありません。

実際のリクエストとして送信する#

以下は「アフター」プロンプトをAPI呼び出しにしたものです。アドレスはhttps://api.cheaptokens.dev/v1、APIはOpenAI互換で、モデルはdeepseek-ai/DeepSeek-V4-Flash-0731です。モデルIDはCheapTokensのドキュメントから取得してください。プロバイダー間で名前が異なります。DeepSeek-V4-Flashは380Kのコンテキストウィンドウと最大32,768の出力トークンを持ち、長いテキストを大量に扱う余裕があります。キーは環境変数から取得し、コードには決して書きません。

2つのツールでの同じリクエスト

Python

python
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.cheaptokens.dev/v1",
    api_key=os.environ["CHEAPTOKENS_API_KEY"],
)

old = "Steel water bottle, 500 ml. Keeps drinks cold for 12 hours. Dishwasher safe."
new = "Steel water bottle, 750 ml. Keeps drinks cold for 24 hours. Hand wash only."

prompt = f"""Document 1 is the OLD text from our shop. Document 2 is the NEW text from the supplier. List every fact that changed, one per line, as old -> new.

<documents>
<document index="1">
<source>old description (current shop page)</source>
<document_content>
{old}
</document_content>
</document>
<document index="2">
<source>new description (from the supplier)</source>
<document_content>
{new}
</document_content>
</document>
</documents>"""

response = client.chat.completions.create(
    model="deepseek-ai/DeepSeek-V4-Flash-0731",
    messages=[{"role": "user", "content": prompt}],
    max_tokens=300,
)
print(response.choices[0].message.content)
print(response.usage)

curl

bash
curl https://api.cheaptokens.dev/v1/chat/completions \
  -H "Authorization: Bearer $CHEAPTOKENS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "deepseek-ai/DeepSeek-V4-Flash-0731",
    "max_tokens": 300,
    "messages": [{
      "role": "user",
      "content": "Document 1 is the OLD text from our shop. Document 2 is the NEW text from the supplier. List every fact that changed, one per line, as old -> new.\n\n<documents>\n<document index=\"1\">\n<source>old description (current shop page)</source>\n<document_content>\nSteel water bottle, 500 ml. Keeps drinks cold for 12 hours. Dishwasher safe.\n</document_content>\n</document>\n<document index=\"2\">\n<source>new description (from the supplier)</source>\n<document_content>\nSteel water bottle, 750 ml. Keeps drinks cold for 24 hours. Hand wash only.\n</document_content>\n</document>\n</documents>"
    }]
  }'

返信はchoices[0].message.contentのプレーンテキストで、隣のusageがトークンを数えます。良い回答は3つの変更をリストします:500 ml -> 750 ml、12時間 -> 24時間、食洗機対応 -> 手洗いのみ。矢印が逆方向なら、モデルはラベルを見失っています。指示がタグと同じ名前でドキュメントを呼んでいるか確認してください。

ラベルのコスト#

タグはテキストであり、テキストは課金されます。チームリーダーがそれぞれ約2,000トークンの会議メモを3つ入力し、どの決定が矛盾するかを尋ねるとします。3つのメモ:3 × 2,000 = 6,000トークン。指示とタグに約150トークン(仮定)を加えると、リクエストは入力6,150トークン、出力300トークンになります。DeepSeek-V4-Flashでは、この1回のリクエストのコストは$0.00012で、タグ自体はメモに比べて誤差です。以下は同じリクエストを1,000回送信した場合で、OpenRouterも並べています:

モデル リクエストあたり 1,000 リクエスト OpenRouter、1,000 リクエスト
GLM-5.3-Flash $0.00014 $0.135 $0.231
DeepSeek-V4-Flash $0.00012 $0.122 $0.473
MiniMax-M2.7 $0.00035 $0.353 $4.23

リクエストあたり 6,150 入力トークンと 300 出力トークン。100万トークンあたりの価格は現行のもので、当社の料金体系に合わせて変動します。OpenRouter 列は同じワークロードの参考価格を示しています。

6,150トークンすべてが380Kウィンドウに余裕を持って収まります(コンテキストウィンドウとは)。入力と出力を合わせた合計で数えると、リクエストはOpenRouterより安くなります。入力と出力は異なるレートで課金され、入力トークンと出力トークンがその理由を説明しています。すべてのモデルの現在の数値は料金ページにあります。

より大きなテキストの山に対する習慣#

テキストが2つ以上になると、番号だけでは不十分です。それぞれに独自の名前が必要です。下の図は例のレイアウトを示しています:最初に質問を含む指示、次に各ドキュメントを独自のタグで囲みます。

フロー:指示と質問、ドキュメント1(古い)、ドキュメント2(新しい)
指示と質問、次にラベル付きの各ドキュメント:例のプロンプトのレイアウト
  • 番号だけでなく内容で名前を付けます。回答がそれを引用して返す場合、<source>contract v2, sent by the client</source>はdocument 2より優れています。
  • 指示はタグの外側に置き、貼り付けたテキスト内の行が命令と解釈されないようにします。
  • 1つのテキストに1つのタグ。長いファイルでも1つのタグ、2つのファイルなら2つです。
  • 質問で名前を再利用します:「monday-notesのどの決定がwednesday-notesと矛盾しますか?」
  • 例にも役割を与えます。「ドキュメント1はスタイルサンプルです:事実ではなく口調をコピーしてください。ドキュメント2は書き直す下書きです。」
自分で試す試してみましょう:エラーログとそれを生成したコードが1つのプロンプトにあります。それぞれに何を追加しますか?答えを表示

名前と役割です。ログには<source>error log from the last run</source>と「これは症状です、編集しないでください」。コードには<source>app.py</source>と「これは修正するものです」。そしてそれらの名前で修正を依頼します。

プロンプトの残りの基本(目標、コンテキスト、形式)については、良いプロンプトの書き方を参照してください。