1. ホーム
  2. テックブログ
  3. AIの出力をシステムに組み込む
No.02
2026.9.11 AI活用 設計

【生成AI】デモは動くのに本番で壊れる|AIの出力をシステムに組み込むときのコツ

こんにちは! ボンドバンドで自社サービスの開発をしているエンジニアです。 生成AIを業務システムに組み込む案件、増えてきましたよね。

検証は、だいたい順調に始まります。手元でプロンプトを試すと、いい感じの回答が返ってくる。 「お、これいけるな」と。

ところが実装してユーザーに触ってもらうと、急に雲行きが怪しくなるんですよね。 今回は、そのギャップをどう埋めるかの話です。

「手元では動いたのに」あるある

実際に起きたのは、こんなことでした。

  • JSON で返すよう指示したのに、前後に「はい、承知しました。」が付いてパース失敗
  • 9割は正しい形なのに、たまに項目名が変わる・配列が文字列になる
  • 入力に書いていない経歴や数値が、しれっと文章に混ざる
  • 同じ入力なのに毎回結果が違うので、テストが書けない

どれも「AI の精度が悪い」と言いたくなるんですが、実は組み込み方の設計でかなり減らせます。 順番に見ていきましょう。

コツ① 出力の形は「お願い」じゃなく「制約」で固定する

まずやめたほうがいいのが、プロンプトの文章で「JSON で返してください」とお願いすること。 お願いは、わりと破られます。

主要な LLM の API には、出力を JSON Schema に従わせる仕組み(構造化出力や、スキーマを厳密に適用するツール定義)があります。 これを使えば形は保証されます。使わない手はないです。

たとえば、経歴情報から自己PR文の候補を作る機能ならこんな感じ。

{
  "type": "object",
  "properties": {
    "summary": {
      "type": "string",
      "description": "200文字以内の自己PR本文。入力に無い経歴は書かない"
    },
    "strengths": {
      "type": "array",
      "items": { "type": "string" },
      "minItems": 2,
      "maxItems": 4,
      "description": "強みの要約。各20文字以内"
    },
    "used_experience_ids": {
      "type": "array",
      "items": { "type": "string" },
      "description": "本文の根拠として使った経歴のID。入力に含まれるIDのみ"
    }
  },
  "required": ["summary", "strengths", "used_experience_ids"],
  "additionalProperties": false
}

ポイントは2つです。

  • additionalProperties: falserequired は必ず書く。省くと勝手にキーが増えたり必須項目が欠けたりします
  • description を「人向けのメモ」じゃなくAI への指示として書く。文字数制限とか「入力に無い経歴は書かない」とかは、プロンプト本文よりスキーマの説明に書いたほうが守られやすいです

コツ② 壊れた出力が来る前提で組む

構造化出力を使っても、API のエラーやタイムアウト、稀な変な値はゼロになりません。 受け取る側でも必ず検証します。

// 1) スキーマで検証 → 2) 業務ルールで検証 → 3) だめなら1回だけ再試行
const result = await callModel(prompt, schema);

const parsed = validateSchema(result);          // 型・必須項目
if (!parsed.ok) return retryOnce(prompt, schema);

// 入力に存在しないIDを参照していないか(ここが業務ルールの検証)
const known = new Set(input.experiences.map((e) => e.id));
const unknown = parsed.value.used_experience_ids.filter((id) => !known.has(id));
if (unknown.length > 0) return retryOnce(prompt, schema);

if (parsed.value.summary.length > 200) return retryOnce(prompt, schema);

return parsed.value;

再試行は回数を決めて必ず打ち切ること。無限にリトライすると、障害のときに費用と待ち時間だけがひたすら伸びます。

ここ、大事です

最後は「AI 機能が使えないだけで、本来の業務は続けられる」状態に落とすこと。自己PR文の自動生成が失敗しても、手入力で保存できれば業務は止まりません。ここが抜けていると、外部 API の不調がそのままサービス停止になります。

コツ③ 嘘を業務データに混ぜない

「ハルシネーションを起こさないようにする」は、正直むずかしいです。目指すところを変えましょう。 間違いが業務データとして確定しないこと、これなら設計でなんとかできます。

材料はこっちから渡す

AI の記憶に頼らせない。参照してほしい情報(登録済みの経歴、マスタの用語、社内規定)は、全部プロンプトに材料として入れます。 「知ってることを書いて」から「渡した材料の範囲で書いて」に変えるだけで、事実の捏造はかなり減ります。

根拠も一緒に返させる

さっきのスキーマの used_experience_ids がこれです。 本文と一緒に「どの入力を根拠にしたか」を返させて、その ID が実在するかをプログラムで検証する。 実在しない ID を返してきた出力は、内容も怪しいので捨てます。

機械的に判定できる形を1つ持たせておく、これがかなり効きました。

数値と固有名詞は生成させない

金額、日付、型番、取引先名。このへんを文章の中で生成させると、もっともらしい嘘が混ざります。 生成させるのは文章の骨格だけにして、確定値はシステム側でテンプレートに差し込む。 地味ですが、業務システムだとここで差が出ます。

書き込み先を限定する

AI の出力が直接書き込める先は、下書き用のテーブル・カラムだけにします。 確定データへの反映は必ず人の操作を経由させる。 この境界を最初に引いておくと、あとから機能を増やしても壊れにくいです。

設計の勘所

「AI が間違えたとき、誰がいつ気づけるか」を先に決めておく。気づけない場所には組み込まない、という判断も含めて設計だと思っています。

コツ④ 「AIは下書きまで」を画面で担保する

うちが提供しているクラウド経歴書管理サービス「シェアキャリ」にも、AI による自己PR文の作成支援があります。 ここでも AI が作るのはあくまで下書き。編集できる状態で表示して、本人が手を入れて保存して初めて経歴書に反映されます。

画面を作るときに意識しているのはこのあたりです。

  • 生成結果だと見て分かるようにする(そのまま確定できる導線を作らない)
  • 複数案を出して選ばせる。1案だけだと、吟味より受け入れが起きやすいです
  • 生成前の内容にいつでも戻せる
  • 待ち時間があることを、押す前に伝える

「人が最後に見る」は運用ルールで書いても守られません。画面の作りで担保するもの、というのが結論でした。

コツ⑤ 毎回違う出力を、どうテストするか

生成AIを組み込むと、同じ入力でも出力が毎回変わります。期待値と完全一致で比較する、いつものテストが使えません。 うちでは2段構えにしています。

何を見るかいつ動かすか
自動テスト AI 呼び出しをモックして、検証・リトライ・縮退の分岐が正しく動くか CI で毎回
評価セット 代表的な入力を数十件用意して、実際に生成させて、機械判定できる条件(文字数、禁止語、根拠IDの実在)の通過率を見る プロンプト変更時・モデル更新時

コツは、評価セットの合否を人の感覚じゃなく条件で書くことです。 「自然な文章か」は判定できませんが、「200文字以内か」「入力に無い固有名詞が入っていないか」なら自動で判定できます。

これができると、プロンプトを直したときに「前よりよくなった」と数字で言えるようになります。 議論が一気にラクになるので、早めに作っておくのがおすすめです。

あとから効いてくる、待ち時間とコストの話

実装が終わってから効いてくるのがこの2つ。先に手を打っておくといいです。

  • 同期で待たせない。数秒かかる処理を画面遷移の途中に置かない。生成中の状態を持たせて非同期で反映する作りにしておくと、あとがラクです
  • 生成結果は保存して使い回す。同じ入力で何度も生成させない。保存しておけばコストも待ち時間も次からゼロです
  • 利用量の上限を先に決める。1ユーザーあたり1日◯回まで、とか。使われすぎて費用が跳ねると、機能を止める理由になってしまいます
  • プロンプトの固定部分を前に置く。プロンプトキャッシュに対応した API なら、変わらない指示を先頭にまとめるだけで費用が下がります

まとめ

長くなりましたが、やることは要するに「不確実な出力を、確実な仕組みで受け止める」これだけです。

  • 出力の形は、お願いじゃなくスキーマで固定する
  • 壊れた出力と API 障害を前提に、検証・リトライ・縮退を組む
  • 材料を渡して、根拠を返させて、確定値は生成させない
  • AI は下書きまで。確定は人、を画面で担保する
  • 機械判定できる条件で評価セットを作る

モデルの性能はこれからも上がっていきますが、ここに挙げた設計は無駄になりません。 むしろ任せられる範囲が広がるほど、境界の引き方が効いてくると思っています。

書いた人:インフラ・実装担当

自社サービスの開発と、お客様の業務システムへの AI 機能の組み込みをやっています。

自社の業務にAI、どこから入れるか迷っていませんか

株式会社ボンドバンドは、業務システムの開発と AI 活用の支援をしています。 「どの業務なら任せていいの?」の切り分けからご相談いただけます。

お問い合わせはこちら
← テックブログ一覧に戻る