Guardrails AIは、LLMに渡す入力とLLMが返した出力を「バリデーター」と呼ぶ検査部品で調べ、不合格のときに例外・修正・再生成のどれを行うかまでコードで決めるPython製のOSSです。社内RAGやチャットボットで、回答に個人情報が混ざっていないか、決めた形式のJSONになっているか、業務上の禁止事項に触れていないかを、返す前に機械的に止める用途で使われます。この記事では、2026年8月14日公開の0.11.0を前提に、公開PyPIへ移ったバリデーターの入れ方、最小のコード、on_failの8つの動作、Pydanticでの構造化出力の検証、日本語で効かないバリデーターの補い方、採用を見送る場面までを実装者向けに整理します。
まとめ:Guardrails AIは入出力の検査と不合格時の処理をPythonで書くための土台
Guardrails AIの中心はGuardというオブジェクトです。正規表現の一致、文字数、選択肢、個人情報の検出といったバリデーターをGuardに積み、LLMの呼び出しをGuardで包むと、入力側と出力側で検査が走ります。
先に押さえる点は3つあります。0.11.0からバリデーターはpip install guardrails-ai-<名前>で入れる形に変わり、従来のguardrails hub installは非推奨になったこと。不合格時の動きは既定で何もしないnoopなので、止めたい検査には明示的にexceptionなどを指定すること。個人情報や有害表現を検出する既製のバリデーターは英語前提の実装が多く、日本語では自作が要ることです。
アプリ本体がPythonで、形式や業務ルールの検査をコードとして管理したいチームなら採用してよい道具です。日本語の有害表現や脱獄の検知が主目的なら、日本語対応をうたう専用サービスを先に検討します。
Guardrails AIとは:GuardとバリデーターでLLMの入出力を検査するOSS
Guardrails AIはGitHubのguardrails-ai/guardrailsでApache 2.0ライセンスのもと公開されており、2026年11月2日時点のスター数は約7,600です。READMEは役割を2つに分けて説明しています。入出力のGuardでリスクを検出して抑えること、LLMから構造化データを生成させることです。AIガードレール全体の設計の中での位置づけはAIガードレールの入力・出力を検査する実装層の設計で扱っています。
最新は0.11.0、Python 3.10以上3.14未満で動くライブラリ
PyPIのguardrails-aiのページによると、最新版は2026年8月14日公開の0.11.0で、対応するPythonは3.10以上3.14未満です。0.10.0は2026年4月3日、0.10.2は6月4日に出ており、半年ほどで3つの系列が進みました。3.14の環境ではインストールできないため、CIのPythonの版も合わせておきます。
依存関係も、導入する前に確認しておく対象です。0.11.0は必須の依存にlitellm(1.82.5以上2.0未満)・openai・langchain-core・OpenTelemetry関連を含みます。LiteLLMは2026年10月に配布工程の侵害が起きた部品なので、lockファイルで版を固定し、LiteLLMの1.107.0侵害の影響確認に挙げた版を避けているか確かめてから入れます。
検査の単位はバリデーター、入力用と出力用のGuardに積んで使う
バリデーターは「1つの観点で値を調べ、合格か不合格かを返す部品」です。公式が配布するものに、正規表現の一致を見るRegexMatch、長さを見るValidLength、選択肢を見るValidChoices、個人情報を見るDetectPII、有害表現を見るToxicLanguage、競合他社名を見るCompetitorCheckなどがあり、Guardrails Hubで一覧できます。
1つのGuardに複数のバリデーターを積めます。use()のon引数で、ユーザーの入力(messages)を調べるのか、LLMの出力を調べるのかを分けます。既定は出力側です。
インストールから最初の検証まで:pip・configure・Guard.validate
ここからは、問い合わせ窓口のRAGが返す回答を検査する場面を例に、最初の検証を通すまでを追います。コードは公式のREADME・notebook・ソースの記法に沿って組んだもので、手元での実行結果ではありません。
0.11.0からバリデーターはPyPIの公開パッケージとして入れる
0.11.0の大きな変更は、公式バリデーターの配布先です。プルリクエスト#1548で、トークンが必要だった専用の配布サーバーpypi.guardrailsai.comから公開PyPIへ移り、guardrails hub系のCLIは非推奨の警告を出すようになりました。公式の移行ガイドによる書き換えは次のとおりです。
# 0.10系まで(専用サーバーから入れる・トークン必須)
guardrails hub install hub://guardrails/detect_pii
from guardrails.hub import DetectPII
# 0.11.0から(公開PyPIから入れる・トークン不要)
pip install guardrails-ai-detect-pii
from guardrails_ai.detect_pii import DetectPII
旧来の書き方もいまは動きます。ただし移行ガイドは、hub CLIとguardrails.hubからの読み込みを次のメジャーリリースで削除すると明記しています。日本語の解説記事の多くは旧来のguardrails hub installのままなので、新しく書くコードを揃える先は0.11.0の形式です。名前の下線はハイフンに変わり、detect_piiはguardrails-ai-detect-piiになります。
guardrails configureで聞かれる匿名メトリクスとリモート推論の2項目
READMEの手順では、インストール後にguardrails configureを実行します。ここで聞かれる2つの質問は、社内データを扱う環境では答えを決めてから進めます。0.11.0のconfigureコマンドのソースでは、匿名メトリクスの送信とリモート推論の利用が、どちらも既定で「有効」と定められているためです。
python -m venv .venv
source .venv/bin/activate
pip install "guardrails-ai==0.11.0"
pip install guardrails-ai-regex-match guardrails-ai-valid-length guardrails-ai-detect-pii
# 匿名メトリクスを送らず、バリデーターの推論を手元で行う
# --token "" はAPIキーの入力待ちを飛ばす指定(CIで止まらないようにする)
guardrails configure --disable-metrics --disable-remote-inferencing --token ""
リモート推論は、DetectPIIやToxicLanguageのようにモデルを使うバリデーターの推論を、Guardrails AI側のエンドポイントで行う仕組みです。検査対象の文章が社外へ送られることになるため、社内文書を扱うRAGでは--disable-remote-inferencingを選びます。設定はホームディレクトリの.guardrailsrcに保存されるので、CIでは同じコマンドをジョブの先頭で流しておきます。
Guard().useとvalidateで正規表現と文字数の検査を通す最小コード
LLMをまだつながず、文字列に対して検査だけを走らせるのがvalidate()です。決めたルールが期待どおりに合否を出すかを、ここで先に確かめます。
from guardrails import Guard, OnFailAction
from guardrails_ai.regex_match import RegexMatch
from guardrails_ai.valid_length import ValidLength
# 回答は「受付番号 R-数字8桁」を必ず含み、400字以内とする
guard = Guard().use(
RegexMatch(regex=r"R-\d{8}", match_type="search", on_fail=OnFailAction.EXCEPTION),
ValidLength(min=1, max=400, on_fail=OnFailAction.EXCEPTION),
)
guard.validate("受付番号 R-20261102 で承りました。") # 合格
try:
guard.validate("承りました。") # 受付番号が無いので不合格
except Exception as e:
print(e)
戻り値はValidationOutcomeで、合否はvalidation_passed、検査後の値はvalidated_output、LLMの生の出力はraw_llm_outputで読めます。exceptionを指定した検査は、不合格になると例外として呼び出し元へ上がります。
LLM呼び出しへの組み込み:model指定・on_failの8動作・構造化出力
検査のルールが固まったら、LLMの呼び出しそのものをGuardで包みます。入力の検査はLLMを呼ぶ前、出力の検査は返ってきた直後に走ります。
guard(model=…, messages=…)で入力と出力の両方を検査する
LLMの使い方を説明する公式ページのとおり、Guardは内部でLiteLLMを使い、modelにOpenAI・Anthropic・Azure OpenAI・Geminiなどのモデル名を書けば呼び分けられます。LiteLLMを通したくない場合は、文字列を返す自作の関数を第1引数に渡します。
from guardrails import Guard
from guardrails_ai.detect_pii import DetectPII
from guardrails_ai.valid_length import ValidLength
guard = (
Guard()
# 入力:メールアドレスや電話番号が含まれていたらLLMを呼ばずに止める
.use(DetectPII(pii_entities=["EMAIL_ADDRESS", "PHONE_NUMBER"], on_fail="exception"), on="messages")
# 出力:長すぎる回答は1回だけ作り直させる
.use(ValidLength(min=1, max=400, on_fail="reask"))
)
result = guard(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": "社内規程のQ&Aに400字以内で答えてください。"},
{"role": "user", "content": "出張旅費の精算期限は?"},
],
num_reasks=1,
)
print(result.validation_passed, result.validated_output)
APIキーはOPENAI_API_KEYなどの環境変数で渡します。呼び出しの履歴はguard.history.lastに残り、再生成の回数はiterationsの数から読み取れます。
on_failの8種類と既定のnoop、reaskは既定で1回まで
不合格のときの動きは、Guardではなくバリデーターごとに指定します。0.11.0のOnFailActionの定義には8つの値があり、エラーと修復を説明する公式ページが各動作を説明しています。
| 値 | 不合格のときの動き | 向く検査 |
|---|---|---|
| exception | 例外を送出する | 入力の個人情報、必須項目の欠落 |
| reask | 失敗理由を添えてLLMに作り直させる | 長さ・形式の不一致 |
| fix | バリデーターが用意した修正値に置き換える | 個人情報の伏せ字化、大文字小文字 |
| fix_reask | 修正して再検査し、だめなら作り直させる | 修正だけでは通りにくい形式 |
| filter | 不合格の項目だけを取り除く(構造化データのみ) | 任意項目の値の誤り |
| refrain | 出力全体を返さずNoneを返す | 返すと事故になる出力 |
| noop | 記録だけして値はそのまま通す(既定) | 導入初期の観測 |
| custom | 自作の関数に値と失敗結果を渡す | 定型の謝罪文への差し替え |
実務で先に決めるのは、既定がnoopだという点です。on_failの使い方の公式notebookも、指定しなければnoopになると書いています。止めたつもりの検査が、実は記録だけで素通りしていた、という事故はここから起きます。
reaskで作り直す回数の上限は、Guardの呼び出しごとにnum_reasksで指定する値です。guard.pyではnum_reasksを指定しないと1回に設定され、作り直すたびにLLMの呼び出しが1回増えます。応答時間と料金の上限から逆算して、0〜2回の範囲で明示しておきます。
Pydanticモデルで構造化出力を検証し、項目ごとにバリデーターを付ける
LLMにJSONを返させたい場合は、PydanticのBaseModelで形を定義し、Guard.for_pydantic()でGuardを作ります。構造化データの公式notebookと同じく、Fieldのvalidatorsに項目ごとの検査を書けます。
from pydantic import BaseModel, Field
from guardrails import Guard
from guardrails_ai.valid_choices import ValidChoices
from guardrails_ai.valid_length import ValidLength
class Ticket(BaseModel):
category: str = Field(
description="問い合わせの分類",
validators=[ValidChoices(choices=["請求", "契約", "障害", "その他"], on_fail="reask")],
)
summary: str = Field(
description="要約(80字以内)",
validators=[ValidLength(min=1, max=80, on_fail="fix")],
)
guard = Guard.for_pydantic(output_class=Ticket)
result = guard(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "先月の請求額が二重に引き落とされています。"}],
)
print(result.validated_output) # 例:{"category": "請求", "summary": "..."}
形式そのものの保証は、各社APIのJSON Schema指定のほうが強力です。OpenAIやBedrockの構造化出力で形を固め、Guardrails AIでは「分類が決めた4値か」「要約が80字以内か」のような中身の規則を見る、という分担が扱いやすくなります。API側の仕組みはLLM構造化出力のJSON Schemaでの実装にまとめています。
日本語の入力と出力で使うときの落とし穴と、自作バリデーターでの補い方
既製のバリデーターをそのまま日本語の文章に掛けると、エラーは出ないのに何も検出しない状態になりやすい点に注意が要ります。ソースを読むと理由が分かります。
DetectPII・ToxicLanguageの英語前提と日本語検出の制約
公開PyPIの配布元であるDetectPIIのソースは、Microsoft Presidioの解析をlanguage="en"で呼んでいます。Presidioの言語対応の説明は、既定の構成では英語の認識器とモデルしか持たないこと、日本語入力でよく出る全角の英数字は英数字のパターンに一致しないことを書いています。人名・住所の検出は日本語では期待できません。
ToxicLanguageのソースも同様で、既定のモデルはDetoxifyのunbiased-small、文の分割はNLTKのsent_tokenizeです。DetoxifyのREADMEによると多言語モデルでさえ対応は英語・フランス語・スペイン語など7言語で、日本語は含みません。日本語のPII検出を別の手段で測った結果はOpenAI Privacy Filterの日本語PII検出の実測が参考になります。
register_validatorで日本の電話番号とマイナンバーを伏せる自作例
日本固有の規則は、カスタムバリデーターの公式ページと公式notebookの形で自作します。Validatorを継承し、_validateで合否を返すだけです。
import re
import unicodedata
from typing import Any, Dict
from guardrails import Guard
from guardrails.validator_base import (
ErrorSpan, FailResult, PassResult, ValidationResult, Validator, register_validator,
)
PATTERNS = {
"電話番号": re.compile(r"0\d{1,4}-?\d{1,4}-?\d{4}"),
"マイナンバー候補": re.compile(r"(?<!\d)\d{4} ?\d{4} ?\d{4}(?!\d)"),
}
@register_validator(name="custom/jp_pii", data_type="string")
class JapanesePII(Validator):
def _validate(self, value: Any, metadata: Dict[str, Any]) -> ValidationResult:
text = unicodedata.normalize("NFKC", value) # 全角数字を半角にそろえる
spans, masked = [], text
for label, pattern in PATTERNS.items():
for m in pattern.finditer(text):
spans.append(ErrorSpan(start=m.start(), end=m.end(), reason=label))
masked = pattern.sub("***", masked)
if not spans:
return PassResult()
return FailResult(error_message="日本の個人情報らしき値を含みます", fix_value=masked, error_spans=spans)
guard = Guard().use(JapanesePII(on_fail="fix"))
print(guard.validate("担当の携帯は090-1234-5678です").validated_output)
正規表現による検出では、桁数が同じ別の番号も検出対象です。誤検出を許容できる出力側の伏せ字化(fix)から始め、入力を止める(exception)運用は、実際の問い合わせログで誤検出率を測ってから切り替えます。人名や住所まで見たい場合は、日本語モデルを入れたPresidioを呼ぶバリデーターを同じ形で書きます。
Guardrails AIを採用する条件と見送る場面、他のガードレールとの使い分け
LLMのガードレールは、検査をどこに書くかで道具が分かれます。Guardrails AIはPythonのコード、NeMo Guardrailsは設定ファイルと対話フロー、Bedrock Guardrailsはクラウドの管理画面とAPIが基本の置き場所です。
採用する条件:Python製アプリで形式と業務ルールの検査をコードで持つ
採用してよいのは、アプリ本体がPythonで、検査の規則を開発者がコードとして書き、テストとレビューの対象にしたいチームです。「受付番号を必ず含む」「分類は決めた4値」「金額は0以上」のような、業務の仕様から機械的に決まる規則は、Guardrails AIの得意分野です。
導入の順番も決めておきます。最初に入れるのは、形式と長さの検査をexceptionかreaskで、個人情報の伏せ字化をfixで付ける構成です。モデルを使う検査は、日本語での検出率を自社データで測ってから足します。回答の検査層まで含めてRAGを作りたい、既存のチャットボットに後から検査を入れたい、という案件はRAG構築支援としてご相談いただけます。
見送る場面:日本語の有害表現検知が主目的の場合と、Python以外の基盤
見送るのは2つの場面です。1つ目は、日本語の暴言・差別表現・脱獄の検知が導入の主目的である場合です。前の章で見たとおり既製のバリデーターは英語前提で、日本語の分類モデルを自前で用意しない限り検出の質が出ません。日本語の項目を持つ専用サービスを使うほうが早く届きます。
2つ目は、アプリがJavaやGoで書かれ、Pythonの実行環境を持ち込みたくない場合です。guardrails startで検査をREST APIのサーバーとして立てる方法もありますが、Flaskのサーバーを1つ運用する手間が増えます。クラウドのマネージドなガードレールのほうが運用は軽くなります。
ガードレール4製品の比較:規則を書く場所と日本語対応による選定基準
4つとも入力と出力を検査できますが、規則の書き方と日本語への対応が違います。
| 道具 | 規則を書く場所 | 得意なこと | 日本語 |
|---|---|---|---|
| Guardrails AI | Pythonのコード | 形式・業務ルールの検査と再生成 | 既製は英語前提、自作で補う |
| NeMo Guardrails | YAMLとColang | 対話の流れの制御と話題の制限 | LLM判定なら日本語で書ける |
| Bedrock Guardrails | AWSの管理画面とAPI | 有害表現・PII・根拠確認の一括適用 | 機能ごとに対応言語を要確認 |
| chakoshi | SaaSの管理画面とAPI | 日本語の不適切表現の検知 | 日本語特化 |
組み合わせる構成もよくあります。日本語の有害表現はchakoshiやBedrock Guardrailsで止め、業務固有の形式と規則はGuardrails AIのコードで見る、という分担です。それぞれの詳細はNeMo Guardrailsの設定例と0.24の変更点、Amazon Bedrock Guardrailsを日本語で効かせる設定、chakoshiのポリシーとAPIの使い方で扱っています。
よくある質問
Guardrails AIを使い始める前に確認されることの多い質問をまとめました。
Guardrails AIは無料で使えますか?
ライブラリ本体と公式バリデーターはApache 2.0のOSSで、商用のシステムでも無料で使えます。0.11.0からは公式バリデーターも公開PyPIから入れられ、トークンの登録は不要になりました。費用が発生するのは、Guardで包んだLLMのAPI料金と、reaskで作り直したぶんの追加呼び出しです。ProvenanceLLMのように検査の中でLLMを呼ぶバリデーターを使う場合は、その呼び出しの料金もかかります。
Guardrails AIとNeMo Guardrailsの違いは何ですか?
開発元と規則の書き方が違う別の製品です。Guardrails AIはGuardrails AI社のPythonライブラリで、検査をバリデーターとしてコードに書きます。NeMo GuardrailsはNVIDIAのOSSで、対話の流れや話題の制限を記述するのはYAMLの設定とColangという言語です。NeMo Guardrails側にはGuardrails AIのバリデーターを呼び出す統合もあり、両者を併用する構成も取れます。
guardrails hub installが非推奨と表示されるのはなぜですか?
0.11.0で、公式バリデーターの配布先が専用サーバーから公開PyPIへ移ったためです。guardrails hub install hub://guardrails/detect_piiはいまも動き、内部でguardrails-ai-detect-piiを入れたうえで非推奨の警告を出します。移行ガイドは次のメジャーリリースでhub CLIとfrom guardrails.hub import ...を削除するとしているため、pip installとfrom guardrails_ai.detect_pii import DetectPIIの形に書き換えておきます。
Guardrails AIでハルシネーションを防げますか?
形式の誤りや決めた規則からの逸脱は止められますが、事実の誤りを完全に防ぐことはできません。根拠の文書と回答を照らすProvenanceLLMのようなバリデーターもありますが、判定には別のLLMや埋め込みモデルを使うため、判定自体が誤ることがあります。RAGの検索精度の改善、回答に出典を付ける設計、人による確認との組み合わせが必要です。対策の全体像はAIハルシネーション対策の実装と運用で扱っています。
Guardrails AIはOpenAI以外のモデルでも使えますか?
使えます。Guardは内部でLiteLLMを使うため、modelにclaude-で始まるAnthropicのモデル名やazure/デプロイ名、gemini/モデル名を書けば呼び分けられ、公式ページは100を超えるLLMに対応するとしています。社内で動かすモデルなど対応外のものを使う方法は、メッセージを受け取って文字列を返す関数を自作し、guard()の第1引数に渡す形です。validate()だけを使うなら、LLMを呼ばずに既存の出力を検査することもできます。
関連記事
- ハルシネーション(AI)とは?意味・語源・発生率と原因・種類を実例で解説:出力の検査で防ぎたい誤答の種類と原因の整理です。
- プロンプトインジェクションとは?攻撃例・種類と対策をOWASP LLM01とコードで解説【2026年】:入力側の検査で止めたい攻撃の具体例です。
- RAG構築の手順とは?データ整備から精度向上・本番運用までの進め方:検査層をRAG全体のどこに置くかを決める前提の工程です。
- DeepEvalとは:pytest形式でLLM出力を採点する使い方、指標の選び方とCIへの組み込み【4.3系・2026年11月】:本番で止める検査と、リリース前に採点する評価の役割分担です。
- LiteLLMとは?複数LLMを1つのAPIで呼ぶProxyの構築手順とフォールバック・予算設定【2026年10月】:Guardが内部で使うLLM呼び出し層の仕組みです。