所要時間: 約40分 | 難易度: ★★★★☆
この記事で作るもの
LLMの応答品質をリアルタイムでスコアリングし、基準を下回った場合に自動でプロンプトを修正して再試行、あるいは別モデルへフォールバック(切り替え)を行うPythonスクリプトを構築します。
- 応答の「論理的整合性」と「命令遵守」を自動評価するロジック
- GPT-4oからClaude 3.5 Sonnet、あるいはローカルLLMへ自動で切り替えるパイプライン
- プロンプトの「劣化」を検知するためのログ保存機能
前提知識として、Pythonの基本的な文法と、環境変数の設定方法を理解している必要があります。 必要なものは、OpenAIとAnthropicのAPIキー、そしてPython 3.10以上の実行環境です。
なぜこの方法を選ぶのか
Redditのr/LocalLLaMAなどで議論されている「モデルの知能低下(Intelligence Drop)」は、API背後のモデル更新や量子化、あるいは安全性のための過度なガードレール設置が原因と推測されます。 これを回避するために「一つのモデルを信じる」運用は、現在のAI開発において最もリスクが高い選択です。
従来のように「プロンプトを工夫して終わり」にするのではなく、コード側で「期待する出力が得られたか」を判定するバリデータ(検印機)を実装するのが、実務における正解です。 特定のモデルが「不機嫌(Grumpy)」になった際に、即座に別の推論エンジンへルーティングする動的なパイプラインを構築することで、システム全体の可用性を担保します。
Step 1: 環境を整える
まずは必要なライブラリをインストールします。
今回は構造化データの扱いに長けたinstructorと、複数のAPIを統合管理するライブラリを使用します。
pip install openai anthropic python-dotenv pydantic instructor
instructorはPydanticを使ってLLMの出力をバリデーションするための必須ライブラリです。
「モデルが指示を無視する」問題に対し、型定義によって出力を強制的に矯正する役割を果たします。
⚠️ 落とし穴:
APIライブラリのバージョンが古いと、最新モデル(Claude 3.5やGPT-4o)のトークン計算やストリーミング処理でエラーが出ます。必ずpip install -Uで最新版に更新してください。
Step 2: 基本の設定
APIキーをソースコードに直書きするのは、SIer時代なら即刻クビ案件です。
.envファイルを作成し、そこにキーを記述してpython-dotenvで読み込みます。
import os
from dotenv import load_dotenv
from openai import OpenAI
from anthropic import Anthropic
import instructor
from pydantic import BaseModel, Field, field_validator
# 環境変数の読み込み
load_dotenv()
# クライアントの初期化
# instructor.patch()を使うことで、OpenAIのレスポンスをPydanticモデルで受け取れるようにします
client_openai = instructor.from_openai(OpenAI(api_key=os.environ["OPENAI_API_KEY"]))
client_anthropic = instructor.from_anthropic(Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"]))
ここではinstructorによるパッチ適用が肝です。
これにより、LLMの応答が「文字列」ではなく「検証済みのオブジェクト」として返ってくるため、知能低下による「フォーマット崩れ」をコードレベルで即座に検知できます。
Step 3: 品質評価ロジックの実装
モデルが「指示を無視しているか」を判定するための、評価用データ構造を定義します。
class LLMResponse(BaseModel):
answer: str = Field(..., description="ユーザーへの回答内容")
logic_score: int = Field(..., description="回答の論理的整合性 (1-10)")
instruction_followed: bool = Field(..., description="指示を全て遵守したか")
@field_validator("logic_score")
@classmethod
def check_score(cls, v):
if v < 7:
# スコアが低い場合は意図的にエラーを投げ、リトライを促す設定にする
raise ValueError("論理スコアが低すぎます。再考してください。")
return v
期待される出力
この定義を使うと、モデルが適当な回答を返した場合、Python側でValidationErrorが発生します。
「出力が浅い」「指示を無視している」という曖昧な問題を、プログラムが処理可能な「例外」に変換できるわけです。
Step 4: 実用レベルの自動切替パイプライン
知能低下を感じた際に、自動でモデルを切り替えてリトライする関数を作成します。 私は過去、GPT-4が数式計算を間違え始めた際、この手法でClaude 3 Opusにバイパスさせることで、本番環境のダウンタイムをゼロに抑えました。
def smart_generate(prompt: str):
# まずはメインモデル(GPT-4o)で試行
try:
print("Trying GPT-4o...")
return client_openai.chat.completions.create(
model="gpt-4o",
response_model=LLMResponse,
messages=[{"role": "user", "content": prompt}],
max_retries=2 # instructorが自動でリトライしてくれる
)
except Exception as e:
print(f"GPT-4o failed or quality too low: {e}")
# フォールバックとしてClaude 3.5 Sonnetを使用
print("Falling back to Claude 3.5 Sonnet...")
return client_anthropic.messages.create(
model="claude-3-5-sonnet-20240620",
response_model=LLMResponse,
max_tokens=1024,
messages=[{"role": "user", "content": prompt}]
)
# 実行例
user_input = "2026年時点での分散コンピューティングの課題を、技術的・経済的視点で3000文字程度で分析して。"
final_output = smart_generate(user_input)
print(f"Final Answer: {final_output.answer[:100]}...")
print(f"Score: {final_output.logic_score}")
このコードのポイントは、response_modelに先ほど定義したLLMResponseを渡している点です。
LLMは「自分の回答の質」を客観的に評価するのが苦手ですが、instructorによる強制的な構造化とPydanticのバリデーションを組み合わせることで、低品質な出力を「失敗」としてトラップできます。
よくあるトラブルと解決法
| エラー内容 | 原因 | 解決策 |
|---|---|---|
ValidationError が頻発する | モデルの性能に対して指示が複雑すぎる | System Promptを分割し、1回1タスクに絞る |
RateLimitError | 短時間の過剰なリトライ | 指数バックオフ(待機時間を増やす)処理をtenacity等で実装する |
JSONDecodeError | LLMがJSON以外の余計な文章を出力した | instructorの利用を徹底するか、Promptに「出力はJSONのみ」と明記 |
次のステップ
今回のスクリプトで、知能低下に対する「防御策」は整いました。 次のステップとしては、私の自宅サーバーのようにRTX 4090を積んだ環境で、Llama 3等のローカルLLMをバリデータとして組み込むことをおすすめします。
外部APIの知能低下は、私たちのコントロール外で発生します。
しかし、ローカルLLMなら「昨日の重み」をそのまま保持できるため、APIの挙動がおかしくなった際の「不変の基準点」として機能します。
Ollamaを使ってローカルにエンドポイントを立て、今回作ったsmart_generateの第3の選択肢(最終防衛ライン)として組み込んでみてください。
AIに「仕事」を任せるなら、常に最悪のケースを想定した冗長化設計が不可欠です。
よくある質問
Q1: モデルの切り替えでコストが跳ね上がりませんか?
コストは上がりますが、品質が低い回答を垂れ流して手動で修正する「人件費」の方が遥かに高価です。実務では、まず軽量なモデル(GPT-4o-mini等)で試し、バリデーションに落ちた場合のみ高性能モデルへ昇格させる「カスケード戦略」を推奨します。
Q2: 4090を2枚挿ししていなくてもローカルLLMは動きますか?
8Bクラスのモデルであれば、VRAM 8GB〜12GB程度のミドルエンドGPUでも十分動きます。ただし、知能低下を検知するための「高度な論理推論」をローカルでやらせるなら、最低でも70Bクラスのモデルが必要になり、その場合はVRAM 48GB(4090 2枚分)が現実的なラインになります。
Q3: バリデーション自体が間違っている可能性は?
あります。そのため、Pydanticのlogic_scoreは絶対的な指標ではなく「異常検知」のトリガーとして使います。ログを保存しておき、定期的に人間が「モデルが悪いのか、バリデータが厳しすぎるのか」を評価するフィードバックループを回すのがプロの仕事です。
📦 この記事に関連する商品
GeForce RTX 4090ローカルLLMでの検証や高品質なバリデーションには24GB以上のVRAMが必須です
※アフィリエイトリンクを含みます






