生成AIのガードレールとは、モデルの前後に置いて、入力と出力を決めた基準で検査する層のことです。 モデル自体を作り変えるのではなく、アプリ側のコードで「通す・直す・止める・やり直す」を決めます。

この記事では、検査を置く場所を入力・出力・ツール実行の3か所に分け、リスクごとに「どこで・何を使って」検査するかを一覧にしました。後半では、マスク処理・スキーマ検証・再試行と代替応答までをつないだPythonのコードを、実行結果と一緒に載せています。プロンプトインジェクションへの対策と、JSONを出力させる方式の比較は範囲が広いため、ここではそれ以外の検査項目と全体の設計に絞ります。

確認環境:Ubuntu 24.04 / Python 3.11.15 / jsonschema 4.26.0 / Mermaid 12.1.0(流れ図の描画を確認)。確認日 2026-10-06。コードはモデルを呼び出さず、決まった文字列を返す代役の関数で検査の動きを確かめています。

この記事の結論

  • ガードレールはモデルの前後に置く検査の層。プロンプトの書き方とは別に、アプリのコードとして用意する。
  • 検査の場所は入力・出力・ツール実行の3か所。リスクごとに、どこで受け止めるかを先に決める。
  • 手段はルールベース検査 → 分類モデル → 別モデルによる判定の順に、速いものから並べる。
  • 不合格のときの動きは直す・やり直す・代替応答を返すの3つ。再試行の回数には上限を付ける。

ガードレールの対策一覧(リスク別の早見表)

リスク 起きること 検査する場所 主な実装手段 不合格のときの動き
個人情報の混入 メールアドレスや電話番号がモデルへ送られる、または回答に出る 入力・出力 正規表現でのマスク、固有表現を見つける分類モデル 置き換えて通す
話題の逸脱 用途と関係のない質問に答えてしまう 入力 キーワードの許可リスト、話題の分類モデル モデルを呼ばずに案内文を返す
形式崩れ JSONが壊れる、必須項目が欠ける、余分な項目が付く 出力 JSONの読み込み、JSON Schemaでの検証 理由を添えて再試行
根拠の無い回答 渡していない資料や、資料に無い内容を答える 出力 出典IDの照合、引用文の照合、別モデルによる判定 再試行し、合格しなければ「分からない」と返す
過剰な長さ 入力が長すぎて費用が増える、回答が画面に収まらない 入力・出力 文字数・トークン数の上限、最大出力トークンの指定 入力は受け付けず案内、出力は再試行
有害表現 攻撃的な言葉や不適切な内容が回答に入る 入力・出力 語のリスト、有害表現の分類モデル、別モデルによる判定 代替応答を返す
ツールの誤った呼び出し 許可していない操作、範囲外の引数で実行される ツール実行 ツールの許可リスト、引数のスキーマ検証、人の承認 実行せず理由を返す

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「生成AIのガードレールとは?入力・出力の検証設計と対策一覧」

ガードレールを置く3か所

flowchart LR
    U[利用者の入力] --> I[入力の検査]
    I -->|通す| M[モデル]
    I -->|止める| G[案内文]
    M --> O[出力の検査]
    O -->|合格| A[回答]
    O -->|不合格| R{再試行の上限内か}
    R -->|はい| M
    R -->|いいえ| F[代替応答]
    M -. ツール呼び出し .-> T[ツール実行の検査]
    T -->|許可| X[ツール]
    X -. 結果 .-> M
場所 役割 検査の例 ここで止める利点
入力 モデルへ渡す前に整える・止める 長さの上限、個人情報のマスク、話題の判定 モデルを呼ばないので速く、費用もかからない
出力 利用者や後続の処理へ渡す前に確かめる 形式、長さ、出典の照合、使わない語 画面や後続のプログラムに渡る内容をそろえられる
ツール実行 モデルが選んだ操作を実行する前に確かめる 許可リスト、引数の型と範囲、人の承認 データの変更や外部への送信を、実行の手前で止められる

OWASPが公開している「Top 10 for LLM Applications 2025」には、機微な情報の開示(LLM02:2025)、出力の不適切な取り扱い(LLM05:2025)、過剰な権限(LLM06:2025)、誤情報(LLM09:2025)、際限のない消費(LLM10:2025)が並んでいます。上の3か所は、この5項目をそれぞれ受け止める位置に対応します。

似た手段との違い:システムプロンプト・ルール・分類モデル・別モデル判定

ガードレールとして使える手段は4つあります。システムプロンプトでの指示はモデルへのお願いで、残りの3つはモデルの外で行う検査という点が大きな違いです。

手段 仕組み 速度 すり抜けやすさ 向く検査
システムプロンプトでの指示 「〜には答えない」「JSONだけを返す」とモデルに伝える 追加の時間なし 高い(従うかどうかはモデル次第) 口調、答える範囲の基本方針
ルールベース検査 正規表現、文字数、スキーマ、許可リストで機械的に判定 とても速い(下の計測で1件あたり数十マイクロ秒) 形が決まったものは低い、言い換えには弱い 形式、長さ、決まった形の個人情報、ツールの引数
分類モデル 文を「有害/無害」「対象/対象外」などに分ける小さなモデル 速い 中くらい(学習した範囲に強い) 有害表現、話題の判定、固有表現
別モデルによる判定 もう1つのモデルに「この回答は資料に沿っているか」と採点させる 遅い(モデル呼び出しが1回増える) 低め(意味まで見られる)、ただし判定自体も揺れる 根拠の有無、文脈に合うか、トーン

どれを使うかの判断基準

条件 選ぶもの
形が決まっている(JSON、文字数、メールアドレス、ID) ルールベース検査
言い換えが多く、語のリストでは拾いきれない 分類モデル
意味を読まないと判定できない(資料と回答の食い違いなど) 別モデルによる判定
応答までの時間を延ばしたくない ルールベース検査を必ず通し、重い検査は対象を絞る
データの変更や外部送信を伴う ツール実行の検査に加えて人の承認
方針を伝えたいだけで、守られなくても影響が小さい システムプロンプトでの指示

速い検査を前に、重い検査を後ろに置くと、ほとんどの入力は最初の段で判定が終わります。システムプロンプトでの指示は残しつつ、守られなかった場合に受け止める検査を外側に用意する、という組み合わせが基本です。

正規表現で個人情報をマスクする

入力と出力の両方で使えるマスク処理です。メールアドレス・電話番号・郵便番号を [MAIL] のような印に置き換え、置き換えた件数も返します。

# mask.py
import re
import unicodedata

# 検査の順番が大事:長くて形がはっきりしたものから先に置き換える
PATTERNS = [
    ("MAIL", re.compile(r"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}")),
    ("TEL", re.compile(r"(?<!\d)0\d{1,4}-\d{1,4}-\d{4}(?!\d)")),
    ("TEL", re.compile(r"(?<!\d)0[789]0\d{8}(?!\d)")),
    ("ZIP", re.compile(r"(?<!\d)\d{3}-\d{4}(?!\d)")),
]


# NFKC では半角ハイフンにならない横棒を、数字の直後にある場合だけそろえる
DASHES = re.compile(r"(?<=\d)[ー‐−–—―](?=\d)")


def mask(text: str) -> tuple[str, dict[str, int]]:
    """個人情報らしい文字列を [種類] に置き換え、置き換えた件数も返す"""
    text = unicodedata.normalize("NFKC", text)  # 全角の数字や記号を半角にそろえる
    text = DASHES.sub("-", text)
    counts: dict[str, int] = {}
    for label, pattern in PATTERNS:
        text, n = pattern.subn(f"[{label}]", text)
        if n:
            counts[label] = counts.get(label, 0) + n
    return text, counts


if __name__ == "__main__":
    samples = [
        "山田太郎です。連絡は taro.yamada@example.com か 090-0000-0000 へ。",
        "住所は〒100-0000、電話は03-0000-0000です。",
        "携帯は09000000000、注文番号は 2026-1006-0001 です。",
        "電話は 03ー0000ー0000 または 03−0000−0000 です。",
        "備品の貸出期間を教えてください。",
    ]
    for s in samples:
        masked, counts = mask(s)
        print(masked)
        print("   ->", counts)
$ python3 mask.py
山田太郎です。連絡は [MAIL] か [TEL] へ。
   -> {'MAIL': 1, 'TEL': 1}
住所は〒[ZIP]、電話は[TEL]です。
   -> {'TEL': 1, 'ZIP': 1}
携帯は[TEL]、注文番号は 2026-1006-0001 です。
   -> {'TEL': 1}
電話は [TEL] または [TEL] です。
   -> {'TEL': 2}
備品の貸出期間を教えてください。
   -> {}

コードの中で効いている点は3つです。

工夫 入れなかった場合の動き(実行して確認)
unicodedata.normalize("NFKC", ...) で全角を半角にそろえる 「03-0000-0000」は置き換え0件で素通りする
数字にはさまれた横棒(ー、‐、−など)を半角ハイフンにそろえる NFKCをかけても「03ー0000ー0000」「03−0000−0000」の横棒はそのまま残り、電話番号の型に合わない
(?<!\d) と (?!\d) で前後が数字でないことを確かめる 郵便番号の型だけだと、注文番号「2026-1006-0001」が「2[ZIP]-0001」に書き換わる

正規表現で拾えるのは形が決まったものです。氏名や住所の文章部分は形が一定でないため、固有表現を見つける分類モデルと組み合わせます。

スキーマ検証・再試行・代替応答までをつなぐ

次は全体の流れです。題材は架空の「社内の備品予約システムの問い合わせ窓口」で、回答は answer(120字以内)と sources(根拠にした資料のID)を持つJSONで受け取る想定です。

# guard.py
import json
import re

from jsonschema import Draft202012Validator

from mask import mask

# ---- 設定(題材:社内の備品予約システムの問い合わせ窓口) ----
MAX_INPUT_CHARS = 500
MAX_ANSWER_CHARS = 120
MAX_RETRY = 2
TOPIC_WORDS = ["備品", "予約", "貸出", "返却", "延長", "プロジェクター", "会議室"]
BLOCK_WORDS = ["ばか", "無能"]
FALLBACK = {
    "answer": "申し訳ありません。この質問には自動でお答えできませんでした。総務窓口へおつなぎします。",
    "sources": [],
    "fallback": True,
}
ANSWER_SCHEMA = {
    "type": "object",
    "properties": {
        "answer": {"type": "string", "minLength": 1, "maxLength": MAX_ANSWER_CHARS},
        "sources": {
            "type": "array",
            "items": {"type": "string", "pattern": "^DOC-[0-9]{3}$"},
            "minItems": 1,
        },
    },
    "required": ["answer", "sources"],
    "additionalProperties": False,
}
VALIDATOR = Draft202012Validator(ANSWER_SCHEMA)
DOCS = {
    "DOC-001": "プロジェクターの貸出期間は最長7日。延長は1回まで。",
    "DOC-002": "返却は総務カウンターで平日9時から17時まで受け付ける。",
}


# ---- 入力の検査 ----
def check_input(text: str) -> tuple[str | None, list[str]]:
    """通すなら (マスク済みの文, 記録)、止めるなら (None, 記録) を返す"""
    notes = []
    if len(text) > MAX_INPUT_CHARS:
        return None, [f"入力が長すぎる({len(text)}字 > {MAX_INPUT_CHARS}字)"]
    masked, counts = mask(text)
    if counts:
        notes.append(f"個人情報らしい文字列をマスク {counts}")
    if not any(w in masked for w in TOPIC_WORDS):
        return None, notes + ["対象外の話題"]
    return masked, notes


# ---- 出力の検査 ----
def check_output(raw: str) -> tuple[dict | None, list[str]]:
    """問題が無ければ (辞書, [])、あれば (None, 理由の一覧) を返す"""
    try:
        data = json.loads(raw)
    except json.JSONDecodeError as e:
        return None, [f"JSONとして読めない: {e.msg}"]
    errors = [
        f"{'/'.join(map(str, e.path)) or '(全体)'}: {e.message}"
        for e in VALIDATOR.iter_errors(data)
    ]
    if errors:
        return None, errors
    unknown = [s for s in data["sources"] if s not in DOCS]
    if unknown:
        errors.append(f"渡していない資料を根拠にしている: {unknown}")
    hit = [w for w in BLOCK_WORDS if w in data["answer"]]
    if hit:
        errors.append(f"使わない語が入っている: {hit}")
    if errors:
        return None, errors
    data["answer"], _ = mask(data["answer"])  # 出力側でも念のためマスク
    return data, []


# ---- 全体の流れ:入力検査 → モデル → 出力検査 → 再試行 → 代替応答 ----
def answer(question: str, call_model) -> dict:
    masked, notes = check_input(question)
    for n in notes:
        print("  [入力]", n)
    if masked is None:
        return {"answer": "備品の予約・貸出・返却についてお尋ねください。", "sources": [], "fallback": True}
    feedback = ""
    for attempt in range(1, MAX_RETRY + 2):
        raw = call_model(masked, feedback)
        data, errors = check_output(raw)
        if data is not None:
            print(f"  [出力] {attempt}回目で合格")
            return data
        print(f"  [出力] {attempt}回目は不合格: {errors}")
        feedback = "前回の出力は次の理由で使えません。直して出力してください。\n" + "\n".join(errors)
    print("  [出力] 再試行の上限に達したので代替応答を返す")
    return FALLBACK


# ---- モデルの代わりに、決まった文字列を順に返す関数(検査の動きを見るための代役) ----
def fake_model(replies: list[str]):
    it = iter(replies)

    def call(question: str, feedback: str) -> str:
        return next(it)

    return call


if __name__ == "__main__":
    cases = [
        ("1. そのまま合格", "プロジェクターの貸出期間は?",
         ['{"answer": "最長7日です。延長は1回までできます。", "sources": ["DOC-001"]}']),
        ("2. 形式崩れ→再試行で合格", "返却はどこでできますか。連絡先は taro@example.com です",
         ['回答:総務カウンターです。',
          '{"answer": "総務カウンターで平日9時から17時まで受け付けます。", "sources": ["DOC-002"]}']),
        ("3. 根拠の無い回答→再試行で合格", "貸出の延長は何回までですか",
         ['{"answer": "延長は3回までできます。", "sources": ["DOC-009"]}',
          '{"answer": "延長は1回までです。", "sources": ["DOC-001"]}']),
        ("4. 3回とも不合格→代替応答", "予約の取り消し方法は?",
         ['{"answer": "", "sources": []}',
          '{"answer": "取り消しできます", "source": "DOC-001"}',
          '{"answer": "' + "予約一覧から取り消せます。" * 12 + '", "sources": ["DOC-001"]}']),
        ("5. 対象外の話題(モデルを呼ばない)", "今日の夕食の献立を考えて", []),
    ]
    for title, q, replies in cases:
        print(f"=== {title}")
        result = answer(q, fake_model(replies))
        print("  =>", json.dumps(result, ensure_ascii=False))
$ python3 guard.py
=== 1. そのまま合格
  [出力] 1回目で合格
  => {"answer": "最長7日です。延長は1回までできます。", "sources": ["DOC-001"]}
=== 2. 形式崩れ→再試行で合格
  [入力] 個人情報らしい文字列をマスク {'MAIL': 1}
  [出力] 1回目は不合格: ['JSONとして読めない: Expecting value']
  [出力] 2回目で合格
  => {"answer": "総務カウンターで平日9時から17時まで受け付けます。", "sources": ["DOC-002"]}
=== 3. 根拠の無い回答→再試行で合格
  [出力] 1回目は不合格: ["渡していない資料を根拠にしている: ['DOC-009']"]
  [出力] 2回目で合格
  => {"answer": "延長は1回までです。", "sources": ["DOC-001"]}
=== 4. 3回とも不合格→代替応答
  [出力] 1回目は不合格: ["answer: '' should be non-empty", 'sources: [] should be non-empty']
  [出力] 2回目は不合格: ["(全体): 'sources' is a required property", "(全体): Additional properties are not allowed ('source' was unexpected)"]
  [出力] 3回目は不合格: ["answer: '予約一覧から取り消せます。予約一覧から取り消せます。…(省略)…予約一覧から取り消せます。' is too long"]
  [出力] 再試行の上限に達したので代替応答を返す
  => {"answer": "申し訳ありません。この質問には自動でお答えできませんでした。総務窓口へおつなぎします。", "sources": [], "fallback": true}
=== 5. 対象外の話題(モデルを呼ばない)
  [入力] 対象外の話題
  => {"answer": "備品の予約・貸出・返却についてお尋ねください。", "sources": [], "fallback": true}

この流れで決めていること

決めること このコードでの値 考え方
入力の上限 500字 用途に対して十分な長さにし、超えたらモデルを呼ばない
回答の上限 120字 画面の表示枠に合わせ、スキーマの maxLength で検査
余分な項目 additionalProperties: False で受け付けない 項目名の打ち違い(source)を見つけられる
再試行の回数 最大2回(合計3回まで) 回数に上限が無いと、費用と待ち時間が増え続ける
再試行で伝える内容 不合格の理由の一覧 同じ依頼を繰り返すより、理由を渡すほうが直りやすい
代替応答 人の窓口への案内 合格しない回答を見せるより、次の手段を示す
記録 入力・出力の検査結果を1行ずつ出力 どの検査で何件止まったかを後から数えられる

実際のアプリでは fake_model の部分を各社のAPI呼び出しに置き換え、feedback を次のメッセージとして渡します。

ツール実行の検査:許可リストと引数の検証

モデルがツール(関数)を呼び出す構成では、実行の手前にも検査を置きます。許可リストにあるか、引数がスキーマに合うか、人の承認が要る操作かの3点です。

# tool_guard.py
from jsonschema import Draft202012Validator

# 呼び出してよいツールと、引数のスキーマ、人の承認が要るかどうか
TOOLS = {
    "search_items": {
        "confirm": False,
        "schema": {
            "type": "object",
            "properties": {"keyword": {"type": "string", "minLength": 1, "maxLength": 50}},
            "required": ["keyword"],
            "additionalProperties": False,
        },
    },
    "cancel_reservation": {
        "confirm": True,
        "schema": {
            "type": "object",
            "properties": {"reservation_id": {"type": "integer", "minimum": 1}},
            "required": ["reservation_id"],
            "additionalProperties": False,
        },
    },
}


def check_tool_call(name: str, args: dict, approved: bool = False) -> tuple[bool, str]:
    tool = TOOLS.get(name)
    if tool is None:
        return False, f"許可リストに無いツール: {name}"
    errors = [e.message for e in Draft202012Validator(tool["schema"]).iter_errors(args)]
    if errors:
        return False, "引数がスキーマに合わない: " + " / ".join(errors)
    if tool["confirm"] and not approved:
        return False, "人の承認待ち(変更を伴う操作)"
    return True, "実行してよい"


if __name__ == "__main__":
    calls = [
        ("search_items", {"keyword": "プロジェクター"}, False),
        ("delete_all_items", {}, False),
        ("search_items", {"keyword": "プロジェクター", "limit": 100000}, False),
        ("cancel_reservation", {"reservation_id": "12; 13"}, False),
        ("cancel_reservation", {"reservation_id": 12}, False),
        ("cancel_reservation", {"reservation_id": 12}, True),
    ]
    for name, args, approved in calls:
        ok, reason = check_tool_call(name, args, approved)
        print("OK " if ok else "NG ", name, args, "->", reason)
$ python3 tool_guard.py
OK  search_items {'keyword': 'プロジェクター'} -> 実行してよい
NG  delete_all_items {} -> 許可リストに無いツール: delete_all_items
NG  search_items {'keyword': 'プロジェクター', 'limit': 100000} -> 引数がスキーマに合わない: Additional properties are not allowed ('limit' was unexpected)
NG  cancel_reservation {'reservation_id': '12; 13'} -> 引数がスキーマに合わない: '12; 13' is not of type 'integer'
NG  cancel_reservation {'reservation_id': 12} -> 人の承認待ち(変更を伴う操作)
OK  cancel_reservation {'reservation_id': 12} -> 実行してよい

読み取りだけのツールは自動で通し、データを変えるツールは承認を挟む、という分け方にすると、検査の重さを操作の影響に合わせられます。

根拠の無い回答を減らす検査の段階

上のコードの出典ID照合は、最も軽い検査です。確かめられる範囲は段階ごとに違います。

段階 検査の内容 確かめられること 手段
1 出典IDが渡した資料に含まれるか 存在しない資料を挙げていないこと ルールベース
2 回答に付けた引用文が資料の本文にそのまま含まれるか 引用が資料に実在すること ルールベース(文字列の一致)
3 回答の内容が資料と食い違っていないか 意味のうえで資料に沿っていること 別モデルによる判定

Anthropicのドキュメント「Reduce hallucinations」では、分からないときは分からないと答えてよいと伝えること、資料からの直接の引用を先に取り出させること、主張ごとに引用を付けさせ、裏づけの無い主張は取り下げさせることが挙げられています。段階2の検査は、この「引用を付けさせる」指示と組み合わせて使えます。

確かめて分かったこと

  • NFKCだけでは横棒がそろわない。 全角の数字と「-」は半角になりましたが、長音記号「ー」やマイナス記号「−」は変わらず、電話番号の型に合いませんでした。数字にはさまれた横棒を別に置き換えると拾えます。
  • 前後の数字を確かめない型は、別の番号を書き換える。 郵便番号の型だけを当てると、注文番号「2026-1006-0001」の途中が [ZIP] になりました。
  • 出典IDの照合は、内容の食い違いまでは見ない。 {"answer": "延長は3回までできます。", "sources": ["DOC-001"]} を check_output に渡すと、資料の記載(1回まで)と違っていても合格しました。意味の検査は段階3の役割です。
  • jsonschemaのエラー文には、不合格になった値がそのまま入る。 長すぎる回答を検査すると、エラー文に回答の全文が含まれました。再試行の依頼や記録に渡す前に、エラー文を一定の長さで切ると扱いやすくなります。
  • ルールベース検査は応答時間にほぼ影響しない。 この環境で1万回ずつ計測した平均は、入力の検査が約6マイクロ秒、出力の検査が約39マイクロ秒でした。
  • 入力で止めた場合はモデルを1度も呼ばない。 対象外の話題の例では、代役の関数に応答を1つも用意していなくても最後まで動きました。

設計するときの確認表

確認項目 決める内容
守る対象 誰に何を見せないか、何を実行させないか
検査の場所 リスクごとに入力・出力・ツール実行のどこで受け止めるか
不合格の動き 直す・再試行・代替応答・人へ引き継ぐ、のどれか
上限 入力の長さ、出力の長さ、再試行の回数、ツール呼び出しの回数
記録 検査名・結果・件数(マスク前の個人情報は記録に残さない)
見直し 止めすぎた例とすり抜けた例を集め、ルールと語のリストを更新する周期
試験 合格する例と不合格になる例を用意し、検査を変えるたびに流す

よくある質問

Q. 生成AIのガードレールとは何ですか? A. モデルの前後に置いて、入力と出力を決めた基準で検査する層です。入力では長さ・個人情報・話題を、出力では形式・長さ・根拠・表現を確かめ、ツールを使う構成では実行の手前にも検査を置きます。

Q. ガードレールとシステムプロンプトの違いは? A. システムプロンプトはモデルへの指示で、ガードレールはモデルの外で行う検査です。指示は守られない場合があるため、守られなかったときに受け止める検査を外側に用意します。

Q. ガードレールとプロンプトインジェクション対策の違いは? A. プロンプトインジェクション対策は、ガードレールが扱うリスクの1つです。ガードレールはそれに加えて、個人情報の混入、形式崩れ、根拠の無い回答、過剰な長さ、有害表現なども対象にします。

Q. 出力がスキーマに合わないときはどうすればよいですか? A. 不合格の理由を添えて再試行し、上限の回数まで合格しなければ代替応答を返します。この記事のコードでは最大2回の再試行のあと、人の窓口へ案内する文を返しています。

Q. ガードレールを入れると応答は遅くなりますか? A. ルールベース検査だけなら、ほぼ変わりません。別モデルによる判定はモデル呼び出しが1回増えるため、対象を絞って使います。

まとめ

  • ガードレールはモデルの前後に置く検査の層で、アプリのコードとして用意する。
  • 置く場所は入力・出力・ツール実行の3か所。リスク別の一覧表で、受け止める場所を先に決める。
  • 手段はルールベース検査・分類モデル・別モデルによる判定。速いものを前に置く。
  • マスク処理はNFKCでの正規化と横棒の統一、前後の数字の確認を入れると取りこぼしと書き換えすぎが減る。
  • 出力はスキーマ検証 → 理由を添えた再試行 → 代替応答の順で扱い、回数に上限を付ける。
  • 出典IDの照合は軽い検査。内容の食い違いは別モデルによる判定で確かめる。

参考・出典

  • OWASP Top 10 for LLM Applications 2025(OWASP GenAI Security Project)https://genai.owasp.org/llm-top-10/
  • Reduce hallucinations(Claude Platform Docs)https://platform.claude.com/docs/en/test-and-evaluate/strengthen-guardrails/reduce-hallucinations

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「生成AIのガードレールとは?入力・出力の検証設計と対策一覧」

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?