AIエージェントに商品問い合わせを渡す前に、原稿を3つへ分けた見本

「PDFだけを買えますか」という短い問い合わせは、返信文を書くには十分に見えます。けれど、質問文の中には商品の提供物も販売条件もありません。PDFがあるか。単品で売るか。返金条件を決めたか。AIエージェントへ返信の下書きを任せるなら、問い合わせだけを渡しても商品案内にはなりません。
以前の見本では、振る舞いのルールと商品説明を分けることと、問い合わせCSVから渡す列を絞ることを扱いました。今回の焦点は別です。架空の「読書ログNotionテンプレート」を使い、AIへ渡す前の原稿を商品事実・文体ルール・購入者の文面の3つに分けます。未決定の条件は空欄ではなく未設定と書き、購入者の文面は指示ではなくデータとして扱います。モデルへの送信や購入者への返信はしていません。
問い合わせの文章へ、商品の約束を混ぜない
問い合わせ返信は、次の3種類の原稿からできています。
[商品事実]
商品名、提供物、未設定の条件
│
├── 人が確認する境界
│
▼
[文体ルール] ─────────┐
敬語、避ける表現 │
├──> [AIの返信下書き] ───> 人が送信を決める
[問い合わせ本文] ─────┘
顧客名、質問
商品事実には、売ると決めた物だけを書きます。架空の商品なら「Notionテンプレート本体」と「導入ガイドPDF」です。まだ決めていない返金条件を、もっともらしい販売文として足しません。
文体ルールには、です・ます調や避ける言葉を書きます。これは事実を増やす場所ではありません。購入者の質問は、質問として残します。たとえば「PDFだけを購入できますか」は、単品販売が可能だという事実を含みません。
この分け方は、返信を滑らかにするためというより、確認の入口を作るためです。返金条件のような購入判断に関わる項目が未設定なら、AIに穴埋めさせず、人へ戻すべきです。
なぜ空欄ではなく「未設定」か
商品事実のメモに「返金条件」を書かずに進めると、欠けた項目は、下書きを読む人にも欠けているのか、単に見落としたのかが分かりません。
そこで、今回はあえて返金条件: 未設定と残しました。これは販売条件を決めたという意味ではありません。「この項目について、返信で断定してはいけない」と読める印です。
未設定の情報を空欄にするより、未設定だと分かる値を置く方を選びました。空欄を見るAIやレビューする人は、値を埋めたくなります。未設定という文字があれば、回答を保留する理由を商品ファイルからたどれます。
一時ディレクトリで返金条件の値を読み分ける
ここでは実在の顧客情報も販売条件も使いません。空の一時ディレクトリに、商品事実、文体、問い合わせをそれぞれ作ります。次のスクリプトは、product-facts.txtの返金条件:行を実際に読みます。値が空欄ならFAIL、未設定ならHOLD(人へ戻す)、値があればOKとし、終了コードも変えます。
# check_reply_context.py
from pathlib import Path
import sys
pairs = [
("FACTS", "product-facts.txt"),
("STYLE", "reply-style.txt"),
("INQUIRY", "inquiry.txt"),
]
for label, name in pairs:
path = Path(name)
if not path.exists():
print(f"{label}: missing")
print("GATE=FAIL context_files=0")
raise SystemExit(2)
print(f"{label}: lines={len(path.read_text(encoding='utf-8').splitlines())}")
refund = None
for line in Path("product-facts.txt").read_text(encoding="utf-8").splitlines():
if line.startswith("返金条件:"):
refund = line.split(":", 1)[1].strip()
break
if refund is None:
print("REVIEW: product-facts.txt missing refund line")
print("GATE=FAIL context_files=3")
raise SystemExit(2)
if refund == "":
print("REVIEW: product-facts.txt refund=空欄")
print("GATE=FAIL hand_back_to_human=1")
raise SystemExit(1)
if refund == "未設定":
print("REVIEW: product-facts.txt contains refund=未設定")
print("GATE=HOLD hand_back_to_human=1")
raise SystemExit(2)
print(f"REVIEW: product-facts.txt contains refund={refund}")
print("GATE=OK context_files=3")
raise SystemExit(0)
まず、返金条件を空欄にした版です。
mkdir -p "${TMPDIR:-/tmp}/reply-context-proof"
cd "${TMPDIR:-/tmp}/reply-context-proof"
printf '%s\n' '商品名: 読書ログNotionテンプレート' '提供物: Notionテンプレート本体、導入ガイドPDF' '返金条件:' > product-facts.txt
printf '%s\n' '文体: です・ます調' '避ける表現: 最短、必ず、保証' > reply-style.txt
printf '%s\n' '顧客名: 山田花子' '質問: PDFだけを購入できますか' > inquiry.txt
python3 check_reply_context.py
echo $?
実行結果です。終了コードは1でした。
FACTS: lines=3
STYLE: lines=2
INQUIRY: lines=2
REVIEW: product-facts.txt refund=空欄
GATE=FAIL hand_back_to_human=1
1
次に、同じ3ファイルで返金条件だけを未設定へ書き換えます。
printf '%s\n' '商品名: 読書ログNotionテンプレート' '提供物: Notionテンプレート本体、導入ガイドPDF' '返金条件: 未設定' > product-facts.txt
python3 check_reply_context.py
echo $?
実行結果です。終了コードは2でした。
FACTS: lines=3
STYLE: lines=2
INQUIRY: lines=2
REVIEW: product-facts.txt contains refund=未設定
GATE=HOLD hand_back_to_human=1
2
FAILは行の欠落や空欄です。HOLDは、未設定だと読める値が残っているので、返信を確定せず人へ戻す合図です。どちらも販売や返信の可否そのものを判定しません。確認できたのは、返金条件の書き方が空欄と未設定で別の出口になることと、3つの役割を別ファイルに置いたことです。実際の返信を作る前に、商品事実を人の手で更新します。返信案を読む工程も必要です。
購入者の文面をデータとして分ける
商品事実を渡さずに問い合わせ文だけから返信させると、AIは提供物や条件を推測しやすくなります。反対に、販売ページ全体、過去の顧客メール、内部メモを一度に渡せば、必要のない個人情報や古い案内まで混ざり得ます。
OWASPは、LLMアプリケーションで指示とデータを明確に分ける構造を勧めています。購入者の文章を、商品ルールや運用指示と同じ塊として扱わないことは、返信品質だけでなく、入力に含まれる指示を過信しないための基本にもなります。同時に、ラベルを付けるだけでは境界の強制にはなりません。ファイルを分けても、渡す内容と更新手順を人が決めなければ効果は続きません。
小さな個人ビジネスでは、まず次の境界で足ります。
- 商品事実は、現在有効な提供物と条件だけにする
- 文体ルールには、商品の仕様や価格を書かない
- 購入者の文面は、指示ではなく問い合わせデータとして扱う
- 未設定の条件が質問されたら、返信を確定せず人へ戻す
NISTのAI Risk Management Frameworkは、AIの設計、利用、評価へ信頼性の考慮を組み込むための枠組みです。ここで作った3ファイルは、その枠組みを満たす証明ではありません。どの人が何を決めるかを曖昧にしないための、小さな出発点にはなります。
この見本で扱わなかったこと
この見本は、AIが正しい返信を作るかを比べていません。顧客名は合成データであり、実際の注文、返金、価格、配送、販売実績は使っていません。
また、3ファイルに分けても、古い商品事実を渡せば古い案内になります。PDF単品の販売可否を決めたら、商品事実を更新し、その更新をレビューします。ファイルを分けることは、条件を決める作業そのものではありません。
次に実運用へ進めるなら、商品ごとに「AIへ渡してよい商品事実」と「人だけが決める条件」を1枚の短い表にします。返信が便利かどうかより前に、間違えたくない約束を確認できる形にしておくことが先です。
用語
| 用語 | この見本での意味 |
|---|---|
| 商品事実 | 商品名、提供物、決定済みの販売条件のように、案内の根拠になる情報です。 |
| 文体ルール | 敬語や避ける表現など、返信の書き方だけを定める情報です。 |
| 問い合わせ本文 | 購入者が送った名前や質問であり、商品条件そのものではありません。 |
| 未設定 | 条件が決まっておらず、AIが断定してはいけない状態です。 |
| 返信下書き | AIが作った案であり、そのまま送信を許可するものではありません。 |


