【登壇資料】 Midosuji Tech 〜意思決定モデルやってみた編〜で「LiteLLMのガードレールにJevを入れてみた」というタイトルで登壇しました! #midosuji_tech

【登壇資料】 Midosuji Tech 〜意思決定モデルやってみた編〜で「LiteLLMのガードレールにJevを入れてみた」というタイトルで登壇しました! #midosuji_tech

Midosuji Tech 〜意思決定モデルやってみた編〜で「LiteLLMのガードレールにJevを入れてみた」というタイトルでLTしました!
2026.11.14

はじめに

こんにちは、スーパーマーケットとAgentCoreが好きなコンサル部の神野です。

2026年10月29日(木)に開催された「クラメソおおさか IT 勉強会 Midosuji Tech 〜意思決定モデルやってみた編〜」で、「LiteLLMのガードレールにJevを入れてみた」というタイトルでLTをしたので資料を共有します!

https://classmethod.connpass.com/event/409980/

登壇資料

こちらが登壇資料となります!

話したこと

ポイントを抜粋して説明します!

やりたかったこと

ポリシーがとても厳しい架空の会社を例にLiteLLM ProxyでLLMに送る中身を検査する「よしなにフィルター」を作りたいと考えていました。

人事や未公表の経営情報まで回答モデルへ送らせない架空の会社で、LiteLLM Proxyがすべての入力を送る前に確かめる

あれ、Bedrock Guardrailsあるからそれ使えば良くない?って思いますよね。
メールアドレスやカード番号のように形が決まった情報なら、LiteLLMの組み込みのフィルターやBedrock Guardrailsでブロックできます。

ただ、困るのは未発表の買収や人事の話のように決まった形がない情報を よしなにブロックするのはGuardrailsだと難しいです。機械的に「買収」というキーワードで照合すると一般的な質問までブロックされ、言い換えた未発表の話はすり抜けてしまいます。

「買収」で照合すると一般的な質問までブロックされ、言い換えた未発表の話は見逃す

Bedrock Guardrailsの拒否トピックでも意味で判定できますが、例外は書かないよう案内されているのと継ぎ足しするのはしんどいですし、アバウトには指示を書けないのでよしなにフィルターを作るのは難しいのです。

Bedrock Guardrailsの拒否トピックと、架空の会社で例外つきでブロックしたいもの

LLMに判定させると毎回待つ

Jevがでる以前はLiteLLMのカスタムガードレールの中でClaude Haikuにポリシーと入力を渡して判定させる方法を試してみました。

https://dev.classmethod.jp/articles/litellm-dynamic-content-filter/

この方法なら例外も文章で書けて意味で判定できます!
ただ違反の理由まで文章で書かせていたので、判定だけで2秒ほどかかります。
入力のたびに2秒待つのは、日常使いだとちょっと気になりますよね・・・

カスタムガードレールの中でClaude Haikuに判定させ、違反の有無と理由をJSONで返させる構成

判定役をJevに置き換える

ブロックかパスかを決めるだけなら理由の文章は要らないので、そこで判定役を意思決定モデルのJevに置き換えてみました!
判定したい条件を英語の質問として書いておき、Jevが返した確率がしきい値以上ならブロックします。

LiteLLM側はカスタムガードレールのクラスをconfig.yamlに登録しておくだけで、すべてのリクエストで判定が動きます。

config.yaml
guardrails:
  - guardrail_name: jev-semantic-filter
    litellm_params:
      guardrail: jev_filter.JevSemanticFilter  # ファイル名.クラス名
      mode: pre_call                           # 回答モデルを呼ぶ前に判定する
      default_on: true                         # すべてのリクエストで動かす

カスタムガードレールの判定役をJevに替え、確率がしきい値以上ならブロックする構成

Claude Haiku 5.5で約1.8秒かかっていた判定は、Jevだと約0.2秒になりました!
早い!
あくまで今回の自分の環境で測った値なので、参考程度に見てください。

Claude Haiku 5.5とJevの判定時間の比較

Jevはどう動くのか

Jevの答え方の形式にはChoice・Score・Noulなどがあります。
今回はブロックするかどうかのYes/Noの判定なので、Yesになる確率を返すNoulを使いました。

Jevの答え方の形式。Choiceは選択肢から1つ選び、Scoreは段階で評価し、NoulはYesになる確率を返す

Noulに判定したい会話と質問を渡すと、質問ごとに0〜1の確率が返ってきます。
ポリシーが複数あっても1回のリクエストにまとめて送れます。
ブロックするかどうかはJevが決めるのではなく、返ってきた確率をしきい値と比べて実装側で決めます。

判定の部分はこんな感じです(エラー処理などは省いています)。

jev_filter.py(抜粋)
from typesafe_sdk import AsyncTypeSafeClient, Noul

class JevSemanticFilter(CustomGuardrail):
    async def judge(self, messages, policies):
        # ポリシーごとにNoulの質問を作り、1回のリクエストでまとめて聞く
        questions = {key: Noul(instructions=p.question) for key, p in policies.items()}
        response = await self.client.system_one(
            state={"messages": messages}, questions=questions, model=self.model
        )
        scores = {key: response.answers[key].noul for key in policies}
        # しきい値以上の項目が1つでもあればブロックする
        blocked = [key for key, p in policies.items() if scores[key] >= p.threshold]
        return {"scores": scores, "blocked_policies": blocked}

質問は英語で書いていて、「一般的な相場は除く」のような例外も質問の中に書けます。
ブロックしたい項目を増やしたいときは、JSONに定義を足します。

たとえば社内予算の項目は次のように書いています。

semantic_filter_rules.json(抜粋)
"confidential_business": {
  "description": "未公開の製品・社内予算・売上・契約条件",
  "question": "Does `messages` disclose specific non-public business information, such as an internal project budget, unreleased product plan, internal sales data, or customer contract terms? General questions about typical budgets, industry averages, or explicitly public information do not count.",
  "threshold": 0.8
}

しきい値の0.8はあくまで今回の例で試して決めた値なので、使う場面に合わせて調整が必要です。

ブロックしたい項目ごとに例外つきの英語の質問としきい値をJSONに書く

試しに同じ「予算」という言葉を含む社内予算と一般的な相場の質問を送ると、社内予算だけがブロックされました!
あくまで今回試した入力の範囲ですが、同じ単語を含んでいても意味で分けられていそうです。

社内予算の入力はブロックされ、一般的な開発予算の相場の質問はパスした

今回試したケースでは質問を日本語に訳すと見逃しが増えました。そのため入力が日本語でも質問は英語で書いたほうが安心そうです・・・!

最初の質問に当てはまらない話題(休職や未公表の障害など)はすり抜けたので、ブロックしたい話題に合わせて質問を追加したり調整する必要がありますね・・・!

Jevは速くて精度もぼちぼち良かったです!
ただ、なぜブロックしたのか理由まで知りたいなら従来のLLMのほうが向いているので、理由を書かせるぶん判定は遅くなり、ここはスピードとのトレードオフですね。

AWSで動かすなら

資料の後半では、AWSで動かす場合の構成も紹介しました。1つ目はLiteLLM ProxyをECS on Fargateにデプロイする構成です。

LiteLLM ProxyをECS on Fargateで動かす構成

番外編

2つ目はLiteLLMではなく、大好きなAgentCore GatewayのインターセプターからJevを呼び出す構成です。マネージドに完結したら嬉しいですもんね!

こちらは実際に期待どおりに動くところまで試しました!

AgentCore GatewayのインターセプターでJevに判定させる構成

この構成のサンプルコードはGitHubで公開しています。
サンプルレベルではありますが、興味があればぜひ試してみてください!

https://github.com/yuu551/agentcore-gateway-jev-interceptor

おわりに

参加いただいた皆さん、ありがとうございました!!
このユースケースのように意思決定モデルも使い込んでいきたいですね!!

本記事が少しでも参考になりましたら幸いです!
最後までご覧いただきありがとうございましたー!!


AI白書2026 配布中

クラスメソッドが独自に行なったAI診断調査をもとに、企業のAI活用の現在地を調査レポートとしてまとめました。企業規模別の活用度傾向に加え、規模を超えてAI活用を進める企業に共通する取り組みまで、自社の現在地を捉えるためのヒントにぜひ。

AI白書2026

無料でダウンロードする

この記事をシェアする

AWSのお困り事はクラスメソッドへ

関連記事