AI自動化は長いプロンプトより変数設計|壊れにくい業務テンプレートの作り方

採用通知、問い合わせ返信、請求書確認を題材に、固定文、入力変数、選択肢、条件分岐、出力schema、例外、停止、承認、監査ログを分け、AI自動化をテスト可能にする方法を解説します。

AIへ業務を任せるとき、最初に作りがちなのが「事情を全部詰め込んだ一枚の長いプロンプト」です。最初の数件は動いても、対象が増えると宛名が抜け、選考段階を取り違え、問い合わせの緊急度を見落とし、請求書の不一致を文章で丸めます。問題は文章力だけではありません。毎回変わる値、選べる値、分岐条件、止める条件、出力の形が一つの文章へ混ざっていることが原因です。

壊れにくくする要点は、プロンプトを長くすることではなく、次の九つを別々に設計することです。

  1. 固定文
  2. 入力変数
  3. 選択肢
  4. 条件分岐
  5. 出力schema
  6. 例外
  7. 停止
  8. 承認
  9. 監査ログ

この記事では、採用通知、問い合わせ返信、請求書確認という三つの架空業務を、壊れやすい一枚プロンプトから、入力と出力を機械的に検査できるテンプレートへ直します。AIが良い文章を作れるかだけでなく、「必要な値がそろったか」「許可された選択肢か」「人の承認前に外部動作へ進んでいないか」をテストできる形にします。

関連する基礎は、AI自動化の静かな失敗を見抜く方法AI自動化の成果と価格を考えるガイド毎日の作業を自動で回す型にもつながります。実装前の安全境界はAIコーディングのプロンプトインジェクション対策とAI開発で秘密を漏らさない方法を先に確認してください。

読み方の最短ルート

目的最初に読む場所
まず設計したい九つの箱へ分ける
具体例から選びたいBefore-After十二例
安全な運用まで確認したい停止と承認を状態機械として考える

需要の証拠と、数字の読み方

このテーマを選ぶ直接の手掛かりは、指定された内部調査メモの自己申告です。そのメモには、採用通知80件を処理する際、選考段階を変数にせず一枚の指示文で進めて失敗し、変数設計後に作業時間が4時間から40分になった、と記録されています。これは第三者監査を通った実測でも、一般化できる効果保証でもありません。本稿では「現場が、文章の追加ではなく変数設計を必要としている」という需要仮説の材料としてだけ扱います。80件、4時間、40分は内部メモ作成者の自己申告値であり、本稿の再現試験結果ではありません。

外部にも、反復業務と個別化を両立したい需要を示す資料があります。Zapierの2021年調査では、調査対象の中小企業従業者の94%が反復的で時間のかかる仕事を行うと回答し、データ入力、文書管理、請求書管理、データの転記が例示されました。LinkedInは、採用メッセージの個別化とAI支援に関する自社製品データを公開しています。Anthropic Economic Indexは、Claude利用における自動化と補助の利用形態を分類して報告しています。

資料ここから読み取れる需要読み取ってはいけないこと
指定された内部調査メモ採用通知の段階を変数化したい現場課題があるすべての会社で同じ時間になる
Zapierの調査反復、転記、請求書管理を減らしたい回答者がいる日本企業全体の比率である
LinkedInの製品データ個別化した採用連絡を規模化したい需要があるAI文面なら必ず採用成果が上がる
Anthropic Economic IndexAI利用を自動化と人との協働に分けて観測できる個別業務の成功率が保証される

需要証拠の公式URLは次の三本です。

数字を引用するときは「誰が、どの対象について、いつ、何を測ったか」を添えます。自社メモ、製品提供会社の利用データ、公的なリスク管理資料は証拠の種類が違います。同じ表へ並べても、強さを同一視しません。

一枚プロンプトが壊れる理由

一枚プロンプトは、手順書、入力データ、判断基準、出力形式、実行命令を一つの文章へ押し込みます。人は前後関係から補えますが、テストは「どの値が必須か」を抽出しにくくなります。

たとえば次の指示です。

候補者へ感じの良い採用通知を書いてください。
書類なら面接案内、一次面接なら結果、最終なら採用条件を入れ、
急ぎなら期限も伝えて、会社らしく丁寧にしてください。
情報が足りなければ自然に補って、そのまま送れる文にしてください。

この文章には、少なくとも六つの未定義があります。

  • 「候補者」は誰か
  • 選考段階は何か
  • 結果の選択肢は何か
  • 「急ぎ」の判定条件は何か
  • 補ってよい情報と、作ってはいけない情報は何か
  • 「そのまま送れる」が下書き作成か実送信か

自然な文章が生成されても、業務として正しいとは限りません。テスト可能な設計では、文章の自然さを検査する前に、入力の完全性、分岐の一意性、出力項目、停止状態を検査します。

混ざっている要素一枚プロンプトで起きる問題分離後の検査
固定文と入力値会社方針まで案件ごとに書き換わる固定文の版番号を照合
自由記述と選択肢「合格」「通過」「次へ」が別値になるenumで許可値を限定
条件分岐と文体指示どの条件が発火したか分からない分岐IDを出力
出力内容と実行命令下書き作成と送信が連続するactionをdraft_onlyに固定
例外と補完指示足りない値をAIが推測するmissing_fieldsへ列挙
承認と成功表示未承認でも完了に見えるapproval_statusを必須化
ログと本文個人情報を過剰に保存するID、版、判定だけを記録

九つの箱へ分ける

1. 固定文

固定文は、案件が変わっても変えない文章と規則です。会社名表記、敬語の基準、禁止表現、下書きであること、推測禁止、送信禁止などを置きます。固定文には版番号を付けます。文章を直したら版を上げ、どの案件がどの版で作られたかログから追えるようにします。

2. 入力変数

入力変数は、案件ごとに変わる値です。candidate_namestageticket_idinvoice_totalのように一つの意味へ一つの名前を与えます。氏名とメールアドレスを一つの文字列へまとめず、別フィールドにします。この記事の例では実在値を使わず、架空応募者ATKT-DEMO-001のような架空値だけを使います。

3. 選択肢

自由記述である必要がない値は、選択肢へします。採用結果ならpassrejecthold、問い合わせ種別ならgeneralbillingcomplaint、請求書判定ならmatchedmismatchneeds_reviewなどです。JSON Schemaではenumで表現できます。

4. 条件分岐

条件分岐は「どの入力なら、どの固定文と必須項目を使うか」です。分岐は自然言語だけでなく、判定表へします。複数条件に同時該当した場合の優先順位も必要です。安全側の原則は、緊急、個人情報、金額不一致、判断不能を通常処理より先に判定することです。

5. 出力schema

schemaは出力の形を定義する設計図です。本文だけでなく、状態、使用した分岐、欠けた項目、承認要否、次の安全な行動を別フィールドへします。OpenAIのStructured Outputs公式資料は、指定したJSON Schemaへの準拠を目的とする機能を説明しています。一方、通常のJSON modeは有効なJSONを作るためのもので、特定schemaへの準拠までは保証しないと明記されています。AnthropicのStructured outputsもJSON Schemaを使いますが、両社とも対応するJSON Schemaには制限があるため、実際のAPIへ移す際は採用モデルと最新仕様を再確認します。

6. 例外

例外は「通常の分岐では処理できないが、入力を捨ててはいけない状態」です。必須値の欠落、選択肢外の値、矛盾、添付未取得、重複候補、読み取り不能を分類します。例外をエラー文だけにせず、exception_codemissing_fieldsで構造化します。

7. 停止

停止は、外部動作へ進まない状態です。個人情報の取り違え、未確定の採否、苦情や法的主張、請求額不一致、重複候補、承認なしを停止条件にします。「止まったら失敗」ではなく、「危険な推測をせず、人へ渡せたら設計どおり」です。

8. 承認

承認は、人が何を確認したかを記録する境界です。承認者が本文を読んだのか、宛先を確認したのか、金額を確認したのかを分けます。この記事のテンプレートは下書き生成までで、メール送信や会計登録は含みません。approval_statusapprovedでも、別システムの実行権限が自動で生える設計にはしません。

9. 監査ログ

監査ログは、入力全文を永久保存する場所ではありません。業務ID、テンプレート版、schema版、分岐ID、結果状態、例外コード、承認状態、処理時刻、追跡IDを中心にします。秘密、本文、添付、不要な個人情報を重ねて保存しません。AIコーディングのコスト台帳で扱う利用記録と同様に、「後から説明するために必要な最小項目」を決めます。

テンプレートの共通骨格

三業務に共通する内部テンプレートは次の形です。これは説明用であり、外部APIへ送る実行コードではありません。

[固定文]
目的: 入力済みの確定情報から、承認前の業務下書きを作る。
禁止: 不足情報の推測、実在データの混入、外部送信、採否決定、会計確定。
出力: 指定schemaに一致する一件のJSON。

[入力変数]
record_id
workflow_type
template_version
各業務の変数

[選択肢]
workflow_type = recruitment_notice | inquiry_reply | invoice_check
action = draft_only

[条件分岐]
停止条件を先に評価する。
通常条件は停止条件に該当しない場合だけ評価する。

[例外]
不足、矛盾、選択肢外、重複、読み取り不能をコード化する。

[承認]
出力は常に人の確認待ちとし、送信や確定を行わない。
変更する人変更頻度代表的なテスト
固定文業務責任者低い禁止事項と版番号が残る
入力変数案件データ提供者毎件型、必須、形式
選択肢業務責任者低い許可値以外を拒否
条件分岐業務責任者と検品者中程度境界値と優先順位
出力schema実装担当者低いschema validation
例外、停止業務責任者中程度危険入力で停止
承認権限を持つ人毎件承認前に実行されない
監査ログ管理担当者毎件ID、版、判定を追える

Before-After十二例

以下はすべて架空データです。Beforeは壊れやすい一枚プロンプト、Afterは変数、選択肢、分岐、停止を分けた形です。

例1: 採用通知の選考段階

Before:

架空応募者Aさんへ次の選考案内を書いてください。状況に合わせて面接情報も入れてください。

After:

workflow_type: recruitment_notice
application_id: APP-DEMO-001
candidate_name: 架空応募者A
stage: document_screening
decision: pass
next_action: first_interview
interview_slot_status: not_set
action: draft_only

分岐はstage=document_screeningかつdecision=passです。ただし面接日時が未設定なので、日時を創作せず「日程は別途調整」とするか、人へ確認待ちにします。

例2: 採用通知の採否

Before:

面接内容を見て、良さそうなら前向きな結果通知を作ってください。

After:

application_id: APP-DEMO-002
decision_source: human_confirmed
decision: hold
allowed_decisions: [pass, reject, hold]
action: draft_only

AIは面接内容から採否を決めません。decision_sourcehuman_confirmedでなければstopを返します。

例3: 採用通知の回答期限

Before:

なるべく早く返事をもらえるよう、適切な期限を書いてください。

After:

reply_deadline: null
deadline_source: missing
on_missing_deadline: stop

「なるべく早く」を日付へ変換しません。期限が必須の通知なら停止し、missing_fieldsreply_deadlineを入れます。

例4: 採用通知の宛先

Before:

応募者へ送れる状態にして、メールも送ってください。

After:

recipient_display_name: 架空応募者D
recipient_address: [email protected]
action: draft_only
approval_required: true
send_permission: false

.invalidは説明用の架空ドメインです。出力は下書きだけに固定し、送信権限を持たせません。

例5: 問い合わせの分類

Before:

お客様の問い合わせを読んで、普通の質問なら丁寧に返信してください。

After:

ticket_id: TKT-DEMO-001
category: billing
category_source: supplied
allowed_categories: [general, billing, complaint, security, legal]
action: draft_only

自由分類ではなく許可値を使います。securitylegalcomplaintは通常返信より停止を優先します。

例6: 問い合わせの緊急語

Before:

急ぎそうなら急ぎで返してください。

After:

urgency: high
urgency_reason_code: service_unavailable
reply_mode: human_review
auto_send: false

緊急度は速度だけを変える値ではありません。高緊急度なら、AIが即送信するのではなく担当者へ優先表示します。

例7: 問い合わせの不明点

Before:

情報が足りなければ、もっともありそうな内容で自然に補ってください。

After:

missing_fields:
  - contract_id
exception_code: REQUIRED_INPUT_MISSING
status: needs_input

不足を文章で隠さず、欠けた項目を列挙します。返信案は「確認に必要な情報を尋ねる下書き」に限定できます。

例8: 問い合わせの個人情報

Before:

過去の顧客情報も探して、相手に合った返事を作ってください。

After:

customer_reference: CUST-DEMO-008
personal_data_access: prohibited
provided_context_only: true
action: draft_only

別システムを探索しません。入力として明示された架空文脈だけを使います。

例9: 請求書の合計

Before:

請求書を見て、だいたい合っていれば確認済みにしてください。

After:

invoice_id: INV-DEMO-001
subtotal: 10000
tax: 1000
total: 11000
calculated_total: 11000
currency: JPY

「だいたい」を使わず、入力値と計算値を別に持ちます。一致しても会計確定ではなく、機械検算が一致した状態です。

例10: 請求書の不一致

Before:

少し違っても誤差として処理し、承認依頼を作ってください。

After:

invoice_id: INV-DEMO-002
stated_total: 11000
calculated_total: 10900
match_status: mismatch
exception_code: TOTAL_MISMATCH
status: stopped

許容差が正式に定義されていない限り、差額を勝手に許容しません。

例11: 請求書の重複

Before:

同じような請求書があっても新しい方を登録してください。

After:

vendor_id: VENDOR-DEMO-01
invoice_number: DEMO-2026-007
duplicate_candidate: true
existing_record_id: INV-DEMO-OLD-007
status: stopped

新旧の判断をAIへ委ねず、人が原本と受領経路を確認します。

例12: 三業務共通の完了判定

Before:

問題なければ成功と返してください。

After:

status: needs_approval
schema_valid: true
business_checks_passed: true
approval_status: pending
external_action_executed: false

schemaに合ったこと、業務チェックを通ったこと、人の承認、外部実行を別々に表します。「成功」という一語でまとめません。

業務別の分岐表

採用通知

優先条件状態作るもの人が確認すること
1採否が人により未確定stopped不足項目一覧採否そのもの
2宛名、求人名、段階の欠落needs_input不足項目一覧正しい応募記録
3条件、報酬、勤務地の矛盾stopped矛盾一覧正式条件
4次の行動または期限の欠落needs_input確認待ち票日程と期限
5必須値がそろいschema適合needs_approval通知下書き宛先、本文、条件

採用通知では、AIが採否を決めないことが最重要です。入力は人が確定した事実だけにし、下書きの個別化と整形へ役割を限定します。権限の境界設計はClaude Codeの権限設定で扱う考え方とも共通します。

問い合わせ返信

優先条件状態作るもの人が確認すること
1セキュリティ、法的主張、重大な苦情stopped要点と引継ぎ票担当部署と回答方針
2本人確認が必要stopped必要確認項目正規の本人確認手順
3原文や添付が不足needs_input不足一覧取得元と完全性
4一般、請求、操作質問needs_approval返信下書き事実、約束、期限
5分類不能needs_review分類候補と根拠正しい分類

返信を自動送信せず下書きに留めれば、誤った約束、返金確約、法的評価、秘密の混入を人が止められます。実行結果の取りこぼしを監視する方法はWebhookの二重処理を防ぐ方法も参考になります。

請求書確認

優先条件状態作るもの人が確認すること
1原本を取得できないstopped取得失敗票正しい原本
2取引先と請求番号の重複候補stopped重複比較票同一請求か
3小計、税、合計が不一致stopped差分票正式金額と税区分
4通貨、日付、番号の欠落needs_input不足一覧原本と契約
5検算一致、必須値ありneeds_approval確認票計上と支払の可否

金額が一致しても、支払承認や会計登録は別の権限です。AIの出力は確認票までに留めます。

出力schema六例

以下はJSON Schema Draft 2020-12を意識した学習用の例です。JSON Schema公式サイトは、2020-12を現行仕様として案内しています。ただしOpenAIとAnthropicのStructured Outputsは標準JSON Schemaの全機能ではなく制限された範囲を扱うため、このまま任意のモデルへ投入できるという意味ではありません。実装時は利用先の対応キーワードを再確認し、ローカルのvalidatorでも検査します。

Schema例1: 共通結果

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "record_id": { "type": "string", "minLength": 1 },
    "workflow_type": {
      "type": "string",
      "enum": ["recruitment_notice", "inquiry_reply", "invoice_check"]
    },
    "status": {
      "type": "string",
      "enum": ["needs_input", "needs_review", "needs_approval", "stopped"]
    },
    "external_action_executed": { "const": false }
  },
  "required": ["record_id", "workflow_type", "status", "external_action_executed"],
  "additionalProperties": false
}

external_action_executedを常にfalseとし、このテンプレートの責任範囲が下書き生成までだと表します。

Schema例2: 採用通知の入力

{
  "type": "object",
  "properties": {
    "application_id": { "type": "string", "pattern": "^APP-DEMO-[0-9]{3}$" },
    "candidate_name": { "type": "string", "minLength": 1 },
    "job_title": { "type": "string", "minLength": 1 },
    "stage": {
      "type": "string",
      "enum": ["document_screening", "first_interview", "final_interview"]
    },
    "decision": { "type": "string", "enum": ["pass", "reject", "hold"] },
    "decision_source": { "const": "human_confirmed" }
  },
  "required": [
    "application_id",
    "candidate_name",
    "job_title",
    "stage",
    "decision",
    "decision_source"
  ],
  "additionalProperties": false
}

説明用のため、応募IDを架空形式に限定しています。実在の応募者データをこの記事のテストへ入れません。

Schema例3: 問い合わせ返信の結果

{
  "type": "object",
  "properties": {
    "ticket_id": { "type": "string" },
    "category": {
      "type": "string",
      "enum": ["general", "billing", "complaint", "security", "legal"]
    },
    "urgency": { "type": "string", "enum": ["normal", "high"] },
    "summary": { "type": "string" },
    "draft_body": { "type": ["string", "null"] },
    "approval_required": { "const": true },
    "stop_reason": { "type": ["string", "null"] }
  },
  "required": [
    "ticket_id",
    "category",
    "urgency",
    "summary",
    "draft_body",
    "approval_required",
    "stop_reason"
  ],
  "additionalProperties": false
}

停止時はdraft_bodynullにできます。本文がないことと処理失敗を混同せず、stop_reasonを残します。

Schema例4: 請求書確認

{
  "type": "object",
  "properties": {
    "invoice_id": { "type": "string" },
    "currency": { "type": "string", "enum": ["JPY"] },
    "subtotal": { "type": "integer", "minimum": 0 },
    "tax": { "type": "integer", "minimum": 0 },
    "stated_total": { "type": "integer", "minimum": 0 },
    "calculated_total": { "type": "integer", "minimum": 0 },
    "match_status": {
      "type": "string",
      "enum": ["matched", "mismatch", "needs_review"]
    },
    "accounting_posted": { "const": false }
  },
  "required": [
    "invoice_id",
    "currency",
    "subtotal",
    "tax",
    "stated_total",
    "calculated_total",
    "match_status",
    "accounting_posted"
  ],
  "additionalProperties": false
}

schemaは型を確認できますが、subtotal + tax = calculated_totalのような業務計算をすべてschemaだけで表す必要はありません。計算関数のテストと分けます。

Schema例5: 例外

{
  "type": "object",
  "properties": {
    "exception_code": {
      "type": "string",
      "enum": [
        "REQUIRED_INPUT_MISSING",
        "VALUE_OUT_OF_RANGE",
        "VALUE_CONFLICT",
        "DUPLICATE_CANDIDATE",
        "SOURCE_UNAVAILABLE",
        "HUMAN_DECISION_REQUIRED"
      ]
    },
    "missing_fields": {
      "type": "array",
      "items": { "type": "string" },
      "uniqueItems": true
    },
    "safe_next_action": {
      "type": "string",
      "enum": ["request_input", "human_review", "keep_stopped"]
    },
    "retry_allowed": { "type": "boolean" }
  },
  "required": [
    "exception_code",
    "missing_fields",
    "safe_next_action",
    "retry_allowed"
  ],
  "additionalProperties": false
}

例外コードを固定すると、件数集計と再発分析ができます。生のエラーメッセージだけを集計軸にしません。

Schema例6: 監査ログ

{
  "type": "object",
  "properties": {
    "trace_id": { "type": "string", "minLength": 1 },
    "record_id": { "type": "string", "minLength": 1 },
    "template_version": { "type": "string", "pattern": "^v[0-9]+\\.[0-9]+$" },
    "schema_version": { "type": "string", "pattern": "^v[0-9]+\\.[0-9]+$" },
    "branch_id": { "type": "string", "minLength": 1 },
    "result_status": {
      "type": "string",
      "enum": ["needs_input", "needs_review", "needs_approval", "stopped"]
    },
    "approval_status": {
      "type": "string",
      "enum": ["not_required", "pending", "approved", "rejected"]
    },
    "logged_at": { "type": "string", "format": "date-time" },
    "contains_secret": { "const": false }
  },
  "required": [
    "trace_id",
    "record_id",
    "template_version",
    "schema_version",
    "branch_id",
    "result_status",
    "approval_status",
    "logged_at",
    "contains_secret"
  ],
  "additionalProperties": false
}

schemaへ氏名やメール本文を入れず、追跡に必要な識別子と判定を中心にします。ログの保管期間、アクセス権、削除方法は実際の組織方針で別途決めます。

Structured Outputsとtool schemaを混同しない

Structured Outputsとtool schemaは似ていますが、責任が違います。

仕組み主な目的形を拘束する対象外部動作との関係
JSON SchemaJSONデータの構造と制約を記述データそれ自体は実行しない
Structured Outputsモデルの応答をschemaへ合わせる最終応答それ自体は送信や登録をしない
Tool schemaツールへ渡す引数の形を定義ツール入力実行主体と権限設計が別途必要
業務validator型以外の業務ルールを検査入力と出力不一致時に停止できる
承認ゲート人の確認を要求外部動作直前の状態承認なしで進めない

OpenAIのfunction calling公式資料は、strict modeのschema要件を満たさない場合にリクエストが拒否されること、非strictではbest-effortになり得ることを説明しています。Anthropicのtool定義ではinput_schemaを指定し、input_examplesを使う場合は例がschemaに適合していなければエラーになります。

ここで重要なのは、schemaに合う引数が作れたことと、そのツールを実行してよいことは別だという点です。send_emailの引数が完全でも、送信承認がなければ呼び出しません。この記事ではtoolを定義する場合も、実行可能な送信toolではなく、create_draft_recordのようなローカル下書き作成までに留める想定です。

テストの作り方

テストは「良い文章になったか」だけでは足りません。最初に決定的な検査を置き、その後で人が表現を見ます。

入力テスト

  • 必須フィールドを一つずつ欠落させる
  • enumへ許可外の値を入れる
  • 数字を文字列にする
  • 日付形式を崩す
  • 同じ業務IDを二回入れる
  • 相互に矛盾する値を入れる
  • 実在情報ではなく架空値だけを使う

分岐テスト

  • 通常条件へ一つだけ該当する
  • 停止条件へ一つだけ該当する
  • 通常条件と停止条件へ同時該当する
  • 複数の停止条件へ同時該当する
  • どの条件にも該当しない
  • 境界となる値の直前、同値、直後を入れる

出力テスト

  • JSONとして解析できる
  • schemaへ適合する
  • 必須項目が空文字でない
  • 許可されない追加項目がない
  • external_action_executedが常にfalse
  • 停止時に本文や実行指示が出ない
  • 監査ログに秘密や不要な個人情報がない

人の検品

  • 入力事実と本文が一致する
  • AIが事実を補っていない
  • 宛先、条件、金額、期限が正しい
  • 相手に約束していない内容がない
  • 丁寧さが過剰で意味を曖昧にしていない
  • 停止理由と次の行動が理解できる

AI生成コードの検品チェックリスト回帰テストの手順はコード向けの記事ですが、「変更前に合格例と失敗例を固定し、変更後に同じ検査を回す」という考え方は業務テンプレートにも使えます。

合格ケースだけでなく失敗ケースを資産にする

最初のテストセットは、各業務で次のように作れます。件数は学習用の構成例であり、業界標準ではありません。

業務通常ケース欠落ケース矛盾ケース停止ケース重複ケース
採用通知段階、採否、期限が確定期限なし段階と次行動が不一致採否未確定応募ID重複
問い合わせ一般質問で事実がそろう契約IDなし分類と本文が矛盾法的主張を含むticket_id重複
請求書金額検算が一致請求番号なし合計不一致原本なし取引先と番号が重複

障害が起きたら、その入力を個人情報を除いた最小の架空再現例へ変換し、テストへ追加します。実在の応募者メールや請求書を丸ごと保存してはいけません。どの条件で壊れたかを再現できる架空ケースへ落とします。

テンプレート変更時は、全ケースへ同じ版を適用し、以前の合格ケースが壊れていないか確認します。これが回帰テストです。schemaの変更だけでなく、固定文の変更でも実施します。

停止と承認を状態機械として考える

状態を文章でなく有限の選択肢にすると、次に何ができるかを制御しやすくなります。

received
  -> validating
  -> needs_input
  -> stopped
  -> needs_review
  -> needs_approval
  -> archived_draft

この記事の範囲ではsentpostedpaidを持ちません。メール送信、会計登録、支払、公開を行わないからです。別システムが外部動作を担当する場合も、承認記録と実行権限は分けます。

現在状態許可する操作禁止する操作次へ進む条件
received入力の保存、ID付与下書き確定、送信検査開始
validatingschema検査、業務検査不足値の推測検査結果
needs_input不足一覧の提示勝手な補完正式入力の追加
stopped理由と証拠の記録自動再開、外部実行人の判断と修正
needs_review候補と根拠の提示判断の確定担当者の選択
needs_approval下書き表示送信、支払、公開権限者の確認
archived_draft履歴参照外部実行新しい明示依頼

NIST AI RMFのCoreは、AIリスク管理をGovern、Map、Measure、Manageの四機能で整理し、AIシステムは導入前と運用中にテストされるべきだと説明しています。これは特定のテンプレートを義務づけるものではありませんが、役割、文脈、測定、対応を分ける本稿の設計と整合します。NISTのPlaybookは任意利用の補助資料であり、全項目を順番に実施するチェックリストではない点にも注意します。

IPAのAIセーフティ評価観点ガイドは、人間中心、安全性、公平性、プライバシー保護、セキュリティ確保、透明性を重要要素として示し、検証可能性などの評価観点を説明しています。だから監査ログは「全部保存」ではなく、説明と検証に必要な項目を、プライバシーと安全を守る範囲で記録します。

監査ログの最小設計

監査ログの目的は、後から次の質問へ答えることです。

  • どの業務IDを処理したか
  • どのテンプレート版とschema版を使ったか
  • どの分岐を通ったか
  • なぜ停止したか
  • 誰の承認待ちか
  • 外部動作を実行していないか
ログ項目残す理由残さない代替情報
trace_id一回の処理を追うなし
record_id元業務と照合する氏名を主キーにしない
template_version使用した固定文を特定固定文全文を毎回複写しない
schema_version検査条件を特定schema全文を毎回複写しない
branch_id判断経路を説明内部推論の逐語を保存しない
exception_code例外を集計生のエラー全文に依存しない
approval_status人の境界を確認承認者の私的メモを残さない
timestamp順序と滞留を調べる不要な端末情報を集めない

入力原文が別の正規システムに存在するなら、ログは参照IDを持ち、本文の複製を避けます。保持期間と削除方法は、利用目的、契約、組織規則、適用法令に合わせて決めます。本稿は法的助言ではありません。

導入を三段階に分ける

段階1: 架空データだけで設計

最初はこの記事のような架空値だけを使います。必須項目、選択肢、分岐表、schema、例外コード、停止条件を作り、validatorで検査します。実在の応募者、顧客、取引先データを使いません。

段階2: 過去データを匿名化した再現テスト

組織の許可と適切な匿名化がある場合に限り、問題の特徴だけを架空ケースへ移します。原文のコピーではなく、「期限欠落」「二重請求候補」のような構造を再現します。秘密や個人情報は入力しません。

段階3: 人の承認付き下書き運用

実運用を検討する場合も、最初は下書き作成までに限定します。入力、出力、停止、承認、ログの件数を照合し、問題があれば手作業へ戻せる状態にします。API契約、データ保持、権限、料金、送信、公開は別途確認が必要です。本稿はそれらを実行していません。

自動化の実測を一定期間続ける考え方は自動化を30日続けた記録、作業の引継ぎはAIコーディングの引継ぎメモも参考になります。

よくある質問

1. 長いプロンプトは全部捨てるべきですか

いいえ。固定文や説明が長く必要な業務もあります。問題は長さではなく、毎回変わる値、選択肢、分岐、出力、停止が文章へ埋もれていることです。固定文として版管理し、変数とschemaを外へ出します。

2. 変数を増やせば必ず正確になりますか

なりません。意味が重なる変数、誰も入力できない変数、判定不能な変数を増やすと運用が複雑になります。一つの変数へ一つの意味を持たせ、実際の業務で取得できる値だけにします。

3. すべての入力を必須にすべきですか

いいえ。下書きに必要な必須値と、あれば個別化できる任意値を分けます。ただし未入力時の扱いを決めます。空欄のまま本文へ差し込む、AIが推測する、という挙動は避けます。

4. enumとは何ですか

許可する選択肢の一覧です。たとえば採用結果をpassrejectholdへ限定します。表記ゆれを減らし、未知の値を例外へ回せます。

5. JSONで出ればschemaは不要ですか

必要です。有効なJSONであることは、必須項目、型、選択肢、追加項目まで正しいことを意味しません。OpenAI公式資料も、JSON modeとschema準拠を目的とするStructured Outputsを区別しています。

6. Structured Outputsならvalidatorは不要ですか

不要とは言えません。提供会社ごとに対応するJSON Schemaの範囲があり、schemaは業務計算や外部データとの一致をすべて検証しません。API側の制約に加え、ローカルのschema検査と業務validatorを使います。

7. OpenAIとAnthropicで同じschemaをそのまま使えますか

共通化できる部分はありますが、そのまま使えるとは限りません。両社の公式資料はJSON Schemaの制限を案内しています。対応キーワード、strictの指定方法、初回のschema処理、互換性を利用時点で確認します。

8. tool schemaが正しければ自動実行してよいですか

いいえ。引数の形が正しいことと、その操作が許可されていることは別です。送信、支払、公開、削除、課金などは、権限と承認を独立して確認します。

9. 情報が一つ足りないだけならAIに補わせてもよいですか

事実として使う値は補わせません。欠落をmissing_fieldsへ出し、人へ確認します。定型のつなぎ言葉を生成することと、日付、金額、採否、契約条件を創作することを区別します。

10. 採用通知でAIに採否を決めさせてもよいですか

この記事の範囲では行いません。採否は人が確定し、AIは確定済み情報から下書きを作るだけです。採用判断へAIを使う場合は、公平性、説明、法務、個人情報、異議申立てなどを含む別の高リスク設計が必要です。

11. 問い合わせ返信は一般質問だけ自動送信できますか

本稿のテンプレートは送信しません。一般質問でも顧客情報、最新の契約、障害、返金、期限が絡む可能性があります。まず下書きと人の確認で実測し、送信を検討するなら別の明示的な権限設計が必要です。

12. 請求金額が一致すれば自動で支払えますか

できません。金額一致は一つの検査結果です。取引先、契約、重複、納品、税区分、承認権限、支払日など別の確認があります。本稿は確認票の下書きまでです。

13. 例外が多いのは設計失敗ですか

必ずしもそうではありません。導入初期は、現場の表記ゆれや不足項目が見えるため例外が増えます。例外を隠さず分類し、入力設計を直せるなら有用な観測です。

14. 停止条件は少ない方が効率的ですか

少なければよいわけではありません。影響の大きい誤送信、誤採否、誤支払を防ぐ条件は必要です。一方、何でも停止すると人の負担が増えるため、実測した例外と影響を見て調整します。

15. 監査ログへ入力と出力を全部残すべきですか

いいえ。目的に必要な最小項目を決めます。本文や添付が正規システムにあるなら参照IDを使い、ログへ個人情報や秘密を複製しません。

16. schemaの版はいつ上げますか

必須項目、型、選択肢、意味、分岐へ互換性のない変更をしたときです。説明文だけの変更と構造変更を区別し、どの記録がどの版で作られたか追えるようにします。

17. テンプレート変更後に何を再テストしますか

通常、欠落、矛盾、停止、重複の固定ケースをすべて再実行します。新しい失敗だけでなく、以前通っていたケースが壊れていないかを確認します。

18. 時短効果はどう測りますか

導入前後で、同じ範囲の作業時間、処理件数、例外件数、手戻り、見逃し、承認時間を記録します。内部メモの4時間から40分という自己申告を自社の見込み値として使わず、自分の業務で測ります。

19. 成功率は何%なら公開できますか

一律の基準はありません。業務の影響、テスト母数、失敗の種類、測定期間、除外条件を示さず、一つの率だけを出すべきではありません。本稿は成功率を提示も保証もしません。

20. 最初にどの業務から試すべきですか

外部送信や金銭確定を伴わず、入力と正解を人が確認でき、失敗しても手作業へ戻せる下書き業務から始めます。この記事の三例なら、架空データでの下書き生成とschema検査が入口です。

実務用チェックリスト

設計前

  • 業務の目的と、AIがしないことを一文で固定した
  • 外部送信、支払、公開、採否決定を範囲外にした
  • 実在データではなく架空ケースを用意した
  • 正解を判定できる担当者を決めた

入力

  • 一つの変数へ一つの意味を割り当てた
  • 必須と任意を分けた
  • 自由記述でなく選択肢にできる値をenum化した
  • 欠落時に推測せず停止する
  • IDを氏名や件名だけに依存させない

分岐

  • 停止条件を通常条件より先に評価する
  • 複数条件が重なったときの優先順位がある
  • どの条件にも該当しない場合を定義した
  • 分岐IDを出力とログへ残す

出力

  • 出力schemaに状態、欠落、例外、承認を含めた
  • additionalPropertiesの扱いを決めた
  • schema適合と業務正解を分けて検査する
  • 外部動作が未実行であることを出力する

運用

  • テンプレート版とschema版を記録する
  • 通常、欠落、矛盾、停止、重複のテストがある
  • 承認前に外部動作へ進まない
  • 監査ログへ不要な個人情報や秘密を残さない
  • 手作業へ戻す手順がある

まとめ

一枚の長いプロンプトを、さらに長い一枚へ直しても、構造が混ざったままならテストは難しいままです。固定文、入力変数、選択肢、条件分岐、出力schema、例外、停止、承認、監査ログを分けると、「どこが壊れたか」を項目ごとに確認できます。

採用通知では採否を人の確定値に限定し、問い合わせ返信では重大分類を通常返信より先に止め、請求書確認では金額一致と会計確定を分けます。共通するのは、AIへ外部実行の権限を渡す前に、下書きと検査の層を作ることです。

schemaに合うことは必要ですが、それだけで業務の正しさ、安全、承認を保証しません。schema validation、業務validator、人の検品、停止条件、監査ログを重ねます。時短や成功率は、内部メモや提供会社の数字を自社の保証値へ置き換えず、同じ範囲と条件で自分の業務を測ります。

Sources

以下の公式ページを2026年7月24日に確認しました。製品仕様は変更されるため、実装時に利用するモデル、API版、対応schema、データ保持、料金を再確認してください。

OpenAI公式

Anthropic公式

JSON Schema公式

NIST公式

IPA公式

需要証拠

指定された内部調査メモの80件、4時間、40分は、公式仕様や第三者調査ではなく自己申告の需要材料として本文で区別しました。この記事はその数字の再現性、成功率、費用対効果を保証しません。

続き(結論と実データ)はnoteに置いています

ここでは手順のところまで書きました。実際に出た数字、うまくいかなかった条件、そのまま使える設定ファイルは、 note の記事にまとめてあります。

noteで続きを読む Xをフォローする