AI開発

AIエージェントに渡すJSONスキーマを先に決める理由

株式会社Atsumell|6分で読めます
AIエージェントのJSONスキーマ設計を示す図

AIエージェントが途中で崩れるのは、会話が雑だからではない。入力と出力の形がゆるいままだからだ。

自然文は便利だ。だが、業務システムに入れると、どこまでが入力で、どこまでが解釈で、どこからが確定なのかが曖昧になる。そこで効くのが、JSONスキーマを先に決めるやり方だ。

この話は AIエージェントの状態管理を先に決めるべき理由 と近い。状態が「今どこか」の話なら、スキーマは「何を受け取り、何を返すか」の話だ。片方だけ整えても、もう片方が曖昧だと壊れる。

自然文は便利だが、境界がゆるい

自然文の強さは、柔らかく伝えられることにある。たとえば「この案件のフォローをお願い」と一言で頼める。人間同士なら、文脈を補ってくれるから通じる。

だがAIエージェントになると、その柔らかさが逆に不安定さになる。

  • どの案件を指しているのか
  • どの顧客を対象にするのか
  • どの期限を使うのか
  • どの操作まで許されているのか

この4つが毎回揺れると、AIは同じ依頼でも別の解釈をしてしまう。結局、後ろで人間が確認し直すことになる。

だから、入口と出口は型で固定した方がいい。依頼は自然文で受けてもいいが、内部ではJSONに落とす。結果も自由作文ではなく、決まった項目で返す。この切り替えがあるだけで、現場のブレはかなり減る。

OpenAIの Structured Outputs は、その考え方をかなり素直に支えている。出力をJSONスキーマに合わせる。つまり、モデルの気分ではなく、アプリの都合に合わせて返してもらう。

JSONスキーマは会話の合意書

スキーマの役割は、モデルを縛ることではない。人間とモデルが「この形でやりとりする」と合意することだ。

たとえば、問い合わせ対応エージェントならこんな項目で十分かもしれない。

フィールド役割
`caseId`対象案件を一意に指す`C-1024`
`summary`要点を短くまとめる`見積もり依頼あり`
`riskLevel`危険度を分類する`low / medium / high`
`nextAction`次にやることを固定する`replyDraft`
`needsApproval`人間承認が必要か示す`true`

こうしておくと、後段の処理が安定する。CRMに書き込むのか、Slackに戻すのか、メール下書きにするのかが機械的に分かれるからだ。

逆に、項目がないまま自由文を受け取ると、毎回パースのための例外処理が増える。AIの賢さで吸収するより、最初から形を決めた方が速い。

これは AIエージェント要件定義は評価設計から ともつながる。評価したいなら、比較できる項目が要る。比較できる項目があるなら、スキーマに落とすのが一番早い。

どの項目を固定すべきか

スキーマ設計で迷ったら、次の3種類に分けると考えやすい。

  1. 識別子

`caseId` や `dealId` のような、一意に対象を指す項目。ここが曖昧だと、別案件を触る事故が起きる。

  1. 判断結果

`riskLevel`、`priority`、`needsApproval` のような、後段の意思決定に使う項目。ここは列挙型に寄せると強い。

  1. 次アクション

`replyDraft`、`createTask`、`askHuman` のような、次に何をするかを示す項目。実装はこの値で分岐させる。

OpenAIの Safety in building agents でも、構造化された出力でデータフローを絞る考え方が示されている。自由入力のまま外部システムに流すと、どこで何が起きたか追いにくい。型があると、ログも追跡しやすい。

MCPの ResourcesTools を分けて考えるのも同じ発想だ。読むものと、実行するものは分けた方が安全だし、責任分界もはっきりする。

構造化出力が効く場面

Structured Outputs が本当に効くのは、モデルの返答を後段で使う時だ。

たとえば、営業フォローのエージェントであれば、次のような流れになる。

  1. 入力を受け取る
  2. 対象案件を特定する
  3. 危険度を判定する
  4. 下書きを作る
  5. JSONで返す
  6. アプリが次の操作を決める

この形にすると、アプリ側は `needsApproval=true` なら止める、`nextAction=createTask` ならタスクを作る、といった制御がしやすい。自由文のままだと、「それっぽい文章」は返ってきても、機械はどう扱えばいいか分からない。

LangGraphの StateGraphcheckpointing も、同じく型と途中経過を重視している。状態を保存し、再開できるから、失敗しても壊れにくい。

つまり、スキーマは単なるデータ定義ではない。AIとアプリの約束事だ。

スキーマは小さく、でも厳しく

スキーマ設計でやりがちな失敗は、最初から項目を増やしすぎることだ。

ありがちなのは、最初の設計で何でもかんでも載せてしまうことだ。顧客情報、部署情報、感情、例外、承認者、履歴、根拠、補足説明。気持ちはわかる。将来必要になりそうだからだ。

だが、項目が増えるほど、モデルは迷う。人間も迷う。テストも重くなる。結局、使われないフィールドが増えるだけになりがちだ。

最初は5つ前後でいい。

  • 対象を指すID
  • 要点
  • リスク
  • 次アクション
  • 承認要否

ここに絞って、実運用で足りないものだけを足す。スキーマは広げるより、絞ってから増やす方が失敗しにくい。

この考え方は、状態管理の記事とも繋がる。状態は途中経過、スキーマは入出力契約。どちらも「AIに何を任せて、何を任せないか」を先に決めるための道具だ。

AIエージェントを入れるとき、いちばん大事なのはモデルの中身ではない。境界を決めることだ。境界が決まれば、後は改善しやすい。境界がないままでは、何を直したのかも分からない。

参考


関連記事

#AIエージェント#JSONスキーマ#Structured Outputs#要件定義#AI開発

AI仕様書エディタKakusillに興味がありますか?

無料トライアルで、AIと開発する体験をすぐにお試しいただけます。

お問い合わせ