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

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が作った案であり、そのまま送信を許可するものではありません。

出典

この記事をシェア