AIエージェントに「取り消せる操作」と「取り消せない操作」を区別させる設計 ― 電子帳簿保存法対応から考えるMCPツール設計
なぜこの話をするか
AIエージェントに業務システムを操作させるとき、一番怖いのは「間違って実行してしまった不可逆な操作」です。請求書の発行、契約の確定、送金。便利さと危うさが表裏一体になります。
この記事では、日本の電子帳簿保存法(電帳法)が要求する「発行後は改ざんできない」という制約を、AIエージェント向けのツール設計にどう落とすかを、国産CRM「Knottle」のMCP実装を題材に、実際のツール名と拒否条件のレベルで書きます。
電帳法が要求すること
電子帳簿保存法は、電子的に作成・保存する請求書等について、事後の改ざんを防ぐ仕組みを求めています。実務上よく採られる形は2つです。
- 書類を「発行」した時点で、金額・明細を凍結(ロック)する
- 訂正したい場合は、元の書類を書き換えるのではなく「取消」処理を行い、取消の事実と取消前の内容を記録として残す
この「発行=ロック」「訂正=取消+新規発行」という二段構えは、会計・法務の要求から来たものですが、AIエージェント設計の文脈にそのまま持ち込めます。
状態機械を、そのままツールの割り方にする
Knottleの見積・請求まわりは13個のツールで構成されていて、前進と後退が必ず別ツールになっています。
前進:
create_quote → accept_quote → issue_quote → issue_invoice → record_payment
(下書き) (受注) (見積書発行) (請求書発行) (入金記録)
後退(それぞれ独立したツール):
| 取り消しツール | 拒否する条件 |
|---|---|
unaccept_quote |
— |
unissue_quote |
— |
unissue_invoice |
入金記録が残っていれば拒否 |
unrecord_payment |
— |
delete_quote |
発行済み / 受注中なら拒否(物理削除・復元不可) |
delete_deal |
発行済みまたは受注中の見積が1件でもあれば拒否 |
前進側にも条件があります。record_payment は請求書が未発行なら拒否します。
ポイントは、AIが「請求書を発行して」と言われたときに取れる選択肢が、構造的に一方向しかないことです。金額を間違えて発行してしまっても、静かに上書きすることはできません。訂正するには unissue_invoice という別のツールを明示的に呼ぶ必要があり、しかも入金が記録されていればそれも拒否されます。
「取り消せる」と「取り消せない」の境界を、ツールの粒度と拒否条件で表現する。 これが電帳法対応とAIエージェント設計が交差する場所です。
発行日をクライアントから渡せなくする
もうひとつ、地味ですが効いている判断があります。
見積書・請求書の発行日は、ツールの入力に存在しません。 サーバーが日本時間の当日を必ず打ちます。
AIエージェントは、会話の流れで平気に「じゃあ先月末の日付で発行しておきますね」と言います。悪意ではなく、ユーザーの要望に沿おうとするだけです。しかしバックデートでの発行は、電帳法が防ごうとしているものそのものです。
入力パラメータとして受け取らなければ、AIは指定できません。 プロンプトで禁止するのではなく、インターフェースから消す。AIエージェントに不可逆操作を触らせる場合、「やらないよう指示する」より「できないようにする」方が確実です。
同じ考え方で、明細の消費税率は 0.10 / 0.08 / 0 の3値しか受け付けません。一方で単価は省略可にしてあります(省略すると0)。引合(RFQ)を単価未定のまま取り込めるようにするためで、ここは業務側の要求で意図的に緩めています。何を締めて何を緩めるかは、法制度ではなく業務の形が決めます。
取り消した事実そのものを残す
書き込み系ツールは監査ログに記録されます(読み取り系は記録しません)。そのうえで、破壊的操作と取り消し操作だけは、実行前のスナップショットをログに残します。
| ツール | 残すもの |
|---|---|
delete_quote / unissue_quote / unissue_invoice / unrecord_payment
|
見積番号・金額・明細件数・見積発行日・請求発行日・発行状態・ステージ |
delete_deal |
案件名・見積/活動/タスク/書類の件数 |
delete_person |
氏名・紐づく顧客数 |
見積・請求書は法的に保存義務のある証憑なので、消したこと・発行を取り消したこと自体を後から再構成できる必要があります。 行そのものは上書き・削除されても、直前の姿がログに残ります。
なお監査ログの書き込み失敗は、ツール呼び出しを失敗させません(fire-and-forget)。ログが取れなかったせいで顧客の業務が止まるのは本末転倒だからです。ここは「証跡の完全性」より「業務の継続」を優先した判断で、トレードオフとして自覚的に選んでいます。
AIエージェント設計への一般化
業務システムをAIに触らせるとき、この記事の内容は次の4点に一般化できると思います。
- 不可逆操作と修正操作を、別のツールとして分離する。 同じツールで両方を扱うと、AIは黙って上書きできてしまう
- 拒否条件をサーバー側に置き、AIには結論だけ返す。 「入金済みなので取り消せません」までをサーバーが判断する
- やらせたくない指定は、入力パラメータから消す。 プロンプトの禁止事項より、インターフェースの不在が強い
- 取り消しの事実と、取り消し前の姿を残す。 状態遷移を伴うドメインでは、現在の状態だけでは事故を追えない
電帳法のような法制度要件は、一見AIエージェント設計と無関係に見えます。しかし実際には「不可逆性をどう扱うか」を業界が何十年もかけて整理した成果物なので、安全なツール設計のヒントとして読み替えられる部分がかなり多いというのがこの記事の主旨です。
このような設計で作っている国産のMCP対応CRMがKnottleです。気になった方はこちらからどうぞ: https://knottle.amjt.jp/signup
Discussion