1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PoCのfail-fast入門:省略していいコード / してはいけないコード

1
Posted at

「PoCでも本番と同じエラー処理を入れるべき?」
「雑に書いていいって言うけど、どこまで?」
AIのPoC開発で、この判断に悩んだ話と今後は迷わないためのルールをまとめます。


結論:PoCの品質目標は「落ちない」ではなく「早く学ぶ」

保守開発(運用)の目標は、だいたいこうなっています。

  • 例外を握ってでもサービス継続
  • リトライ、フォールバック、監視、復旧手順
  • 変更しても壊れない(堅牢性と保守性)

一方、PoCの目標はこうです。

  • 仮説が正しいか最短で白黒つける
  • ダメなら 早く壊れて原因が見えるほうが得
  • 成果物は「コード」より 学び(意思決定できる材料)

この目的の違いが “fail-fast” の正体です。


よくある誤解:fail-fast = エラー処理ゼロ、ではない

fail-fast は「握りつぶさない」ですが、何も考えずに雑に書くことではありません。

PoCでやるべきはむしろ逆で、

  • 前提(契約)を明文化する
  • 前提違反が起きたら 即落ちる
  • 落ちたら 原因・入力・設定が追える(観測できる)

つまり「壊れ方の設計」です。


迷ったらこれ:エラー処理の“境界”を3つに分ける

PoCで苦しいのは「全部に薄くエラー処理を塗る」ことです。
代わりに、境界で考えます。

境界A:PoCのコア(仮説検証ロジック)

  • 原則:握らない
  • 変な値は落とす(assert / raise
  • ここにリトライや復旧ロジックを入れない

境界B:入口(CLI / APIハンドラ / デモ実行)

  • 原則:最小限だけ握る
  • 目的:隠すためじゃなく「失敗を説明可能にする」
  • 例:入力不足は 400、設定不足は起動失敗、など

境界C:外部I/O(LLM API、DB、ファイル、Webhook)

  • 原則:今回の仮説に関係するものだけ処理する
  • 例:コスト/レート制限を検証するPoCなら429対処は価値がある
    機能検証PoCなら落としてOK

決定木:例外を“握っていい”のはどんなとき?

次の質問で Yes が1つでもあるなら、そこはエラー処理を“投資対象”にしてOKです。

  1. そのエラーは 今回の仮説に関係する?
  2. 握らないと 学びが得られない?(原因が特定できない、再現できない)
  3. 握らないと 危険?(課金暴走、機密漏えい、データ破壊)
  4. デモ相手に見せる必要があり、落ち方が説明不能になる?

全部Noなら、落としてOK(fail-fast)。


省略していいコード(PoCの目的に関係ないなら)

PoCで「ちゃんとしたくなる」けど、目的に関係ないなら後回しでOKなやつです。

  • 複雑なリトライ(指数バックオフ、サーキットブレーカー)
  • フォールバック(別モデル切替、代替経路)
  • 例外クラスの階層設計、エラーコード体系の作り込み
  • 本番同等の入力バリデーションの網羅
  • 永続化の堅牢化(トランザクション、リカバリ設計)
  • 監視/アラート/SLO/オンコール手順
  • DI/抽象化しすぎた設計(早すぎる綺麗さ)

省略していい = “やらない”ではなく、今やらないです。


してはいけない(PoCでも省略しない)コード

AI PoCは、ここを省略すると「動いたけど結論が出ない」「事故る」になりがちです。

1) 再現性(最低限)

  • モデル名 / 主要パラメータ(temperature等)
  • プロンプト(バージョン)
  • 入力データ(版数、サンプル)

2) 観測性(最低限)

  • 入力、出力
  • 失敗時の例外(握りつぶさない)
  • 可能ならリクエストID(LLM APIのrequest_idなど)

3) “結果が無意味になる”入力の排除

  • 空文字、null、フォーマット崩れ
    → ここはPoCでも弾かないと、検証結果が汚れます

4) 事故防止(AI PoCの必須)

  • 機密データを外部へ送らない
  • 課金暴走を防ぐ(上限、件数制限、ログで可視化)
  • 破壊的操作(削除/更新)をPoCでやらない or 明示ガード

NG例:try/exceptで握りつぶして“動いたことにする”

PoCで一番まずいのは、「失敗してるのに成功っぽく見える」ことです。

def call_llm(prompt: str) -> str:
    try:
        return client.generate(prompt)  # 失敗するかもしれない
    except Exception:
        return "{}"  # とりあえず空JSON返しとく(←最悪)
  • 失敗が成功に見える
  • どの入力で壊れたか分からない
  • 検証結果が汚れる(“なんかうまくいった気がする”)

OK例:PoCコアは fail-fast(前提違反は落とす)

例:LLMにJSONを返させるPoC(コアは握らない)

import json

def build_prompt(user_text: str) -> str:
    assert user_text.strip(), "user_text must be non-empty"
    return (
        "Return JSON only.\n"
        f'Input: "{user_text}"\n'
        'Output schema: {"summary": string, "labels": [string]}\n'
    )

def parse_llm_json(text: str) -> dict:
    obj = json.loads(text)  # 壊れてたら例外で落ちてOK
    assert isinstance(obj.get("summary"), str), "summary must be str"
    assert isinstance(obj.get("labels"), list), "labels must be list"
    return obj

ポイント:

  • assert は「前提(契約)」を明文化するため
  • 失敗したら落とす(=原因が見える)
  • PoCの学びの速度が上がる

入口だけ最小限握る(“説明可能”にする)

コアは落ちてOK。でも入口は「何が起きたか」を残すだけやる。

import traceback

def main() -> int:
    try:
        run_poc()
        return 0
    except Exception:
        traceback.print_exc()  # 調査に必要な情報を残す
        return 1

if __name__ == "__main__":
    raise SystemExit(main())

入口で握るのは「隠すため」ではなく 観測のため


AI PoCあるある:どこまで扱うべきエラー?

  • 429 / rate limit

    • 仮説が「スループット/コスト」なら扱う(投資対象)
    • 仮説が「機能」なら落としてOK(後回し)
  • JSON崩れ

    • 仮説が「構造化抽出」なら扱う(出力検査+再試行など)
    • 仮説が「UIモック」なら落としてOK
  • データ品質(空欄/欠損)

    • 結果が無意味になるならPoCでも弾く(省略しない)

まとめ:PoCのエラー処理は「事故防止」と「学びの速度」

  • コアは握らず落としてOK(fail-fast)
  • 入口は“説明可能”にするために最小限握る
  • 外部I/Oは「仮説に関係するなら」投資する
  • PoCで守るべきは稼働率より 再現性・観測性・事故防止

コピペ用チェックリスト

  • このPoCの仮説は1文で言える
  • 成功基準 / 中止基準(timebox)がある
  • コアは例外を握らない(fail-fast)
  • 入口で例外が観測できる(ログ/入力/設定)
  • モデル名/プロンプト/主要パラメータ/データ版数が残る
  • 機密/課金/破壊的操作の事故だけは防いでいる
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?