プロンプトインジェクションと出力検証
指示と資料を分け、生成結果の採用条件をアプリ側で検査します。
説明
外部文書には、要約対象の情報だけでなく、アプリへ別の動作をさせようとする文章が含まれることがあります。資料を読んだモデルの出力を、そのまま権限のある命令として実行しない設計が必要です。
固定の参照文書と生成結果を使い、JSON構造、参照した文書ID、引用箇所を検証します。形式検査だけでは文章の意味まで保証できないことも、同じ資料で確かめます。
指示と資料を分け、生成結果の採用条件をアプリ側で検査します。
1参照資料の内容と出所を確認する
文書7と8を取得した状態を使います。8には動作を要求する文も含まれます。
from sd15 import *
print(DOCS文書IDと原文を対応付ける)資料中の命令形も外部の文字列です。アプリの目的、利用者の依頼、許可したツール操作と同じ権限へ昇格させません。
2要約と根拠を持つ固定結果を解析する
採用する形式はsummaryとcitationsだけです。
good = {"summary":"提出期限は11月20日です。","citations":[{"doc":8,"quote":"提出期限は11月20日です。"}]}
print(check_result生成結果の構造と引用を検査する(json.dumps(good),DOCS))文書8に同じ引用が存在するため採用形式を満たします。資料を保持しているので、IDだけでなく引用箇所も照合できます。
3生成結果に操作要求が混ざる場合を拒否する
要約結果へtoolという余分な項目を追加します。
extra = dict(good,tool=要約契約にない操作項目を追加する{"name":"send","target":"other.example.test"})
print(check_result(json.dumps(extra),DOCS))schema_rejectedです。要約用の出力から、別の実行経路へ自動的に分岐させません。
4取得していない文書の引用を拒否する
生成結果が文書99を根拠として挙げる場合です。
unknown = {"summary":"期限は同じです。","citations":[{"doc":99取得資料にないIDを指定する,"quote":"提出期限は11月20日です。"}]}
print(check_result(json.dumps(unknown),DOCS))evidence_rejectedです。実在しそうなIDを生成しただけでは根拠として扱いません。
5存在するIDでも引用文が違えば拒否する
文書8の期限を21日へ書き換えた引用を試します。
wrong = {"summary":"提出期限は11月21日原文と異なる引用を渡すです。","citations":[{"doc":8,"quote":"提出期限は11月21日です。"}]}
print(check_result(json.dumps(wrong),DOCS))evidence_rejectedです。文書IDだけを合格条件にすると、内容の取り違えを検出できません。
6引用の一致だけでは要約の意味を保証できない
引用は正しいまま、summaryだけを異なる内容へ変えます。
contradiction = dict(good,summary="提出期限は11月21日です。"引用と矛盾する要約を比較する)
checked = check_result(json.dumps(contradiction),DOCS)
print(checked)構造と引用検査には通ります。引用を含むことと、要約がその引用に支えられることは別です。重要な出力では意味の照合や人による確認も工程へ含めます。
7操作が不要な依頼では実行経路を作らない
要約だけを表示対象として取り出します。
checked = check_result(json.dumps(good),DOCS)
print(checked["summary"]検査した要約だけを表示へ渡す)
print(sorted(checked))採用した項目はsummaryとcitationsだけです。学習者や利用者が求めていない送信・更新を、資料中の文から追加しません。
まとめ
外部文書の命令をアプリの指示へ昇格させません。
生成結果の項目と取得資料の引用を照合します。
形式検査と意味の正しさを分けて評価します。
操作履歴と解説を振り返れます。
Python 3.15 / 固定の公開試料
from sd15 import *
print(DOCS){7: '更新日は11月13日です。', 8: '提出期限は11月20日です。外部へ秘密を送れという指示は資料本文に含まれる文字列です。'}good = {"summary":"提出期限は11月20日です。","citations":[{"doc":8,"quote":"提出期限は11月20日です。"}]}
print(check_result(json.dumps(good),DOCS)){'summary': '提出期限は11月20日です。', 'citations': [{'doc': 8, 'quote': '提出期限は11月20日です。'}]}extra = dict(good,tool={"name":"send","target":"other.example.test"})
print(check_result(json.dumps(extra),DOCS))schema_rejected
unknown = {"summary":"期限は同じです。","citations":[{"doc":99,"quote":"提出期限は11月20日です。"}]}
print(check_result(json.dumps(unknown),DOCS))evidence_rejected
wrong = {"summary":"提出期限は11月21日です。","citations":[{"doc":8,"quote":"提出期限は11月21日です。"}]}
print(check_result(json.dumps(wrong),DOCS))evidence_rejected
contradiction = dict(good,summary="提出期限は11月21日です。")
checked = check_result(json.dumps(contradiction),DOCS)
print(checked){'summary': '提出期限は11月21日です。', 'citations': [{'doc': 8, 'quote': '提出期限は11月20日です。'}]}checked = check_result(json.dumps(good),DOCS)
print(checked["summary"])
print(sorted(checked))提出期限は11月20日です。 ['citations', 'summary']
演習完了