1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Gemma 4:e4b で作るコメント違反監視ボット:ローカル LLM 運用の理想と現実

1
Last updated at Posted at 2026-05-04

概要

ローカルで Gemma 4:e4b を動かし、ステラソラ攻略有志 Wiki のコメントがルールに違反していないか自動判定し、Discord に通知する仕組みを作ってみました。実際に運用してみたところ、クラウドモデル(Gemini 等)との知能差やローカルモデルのルール設定の難しさが見えてきたので、備忘録としてまとめてみました。

私は上記 Wiki の運営関係者ではなく、一閲覧者として「ローカルLLMでどこまで判定できるか」を試した個人的なプロジェクトです。実際にこのボットで投稿を削除したり、公式に導入したりするものではありません。

リポジトリ

プログラムの全容はこちらに置いてあります。

実行環境

自宅の PC 環境で Docker を使って動かしています。

  • OS: Windows 11
  • メモリ: 32GB
  • GPU: GeForce RTX 2070 SUPER
  • コンテナ: Docker Desktop (Ollama / Python)

やったこと

掲示板を定期的にスクレイピングし、取得したコメントを AI に投げて、ルールに基づいた違反判定を行わせるシンプルなツールです。

1. 掲示板のコメントをスクレイピング

Python + BeautifulSoup4 を使用しています。掲示板の各投稿から、本文、投稿者 ID、日時を抽出します。

def comment_iterator(soup: bs4.BeautifulSoup) -> Iterator[Comment]:
  li_list = soup.select('div#body li')
  for li in li_list:
    texts = li.find_all(string=True, recursive=False)
    if not texts: continue
    text = ''.join(texts).strip().replace('\n', '')
    match = re.match(r'^(.+) -- \[(.+)\]', text)
    if not match: continue
    comment = match.group(1)
    date_userid = match.group(2)
    span_date = li.select_one('span[data-mtime]')
    if not span_date: continue
    date = datetime.fromisoformat(span_date['data-mtime'])
    yield Comment(date_userid, comment, 'コメント/雑談掲示板', date)

2. Gemma 4:e4b でルール違反を判定

Ollama 上で Gemma 4:e4b を使用し、コメントが掲示板ルールに違反しているか判定させます。e2b も試してみましたが、精度に難(※)があったので e4b 以上のモデルをお勧めします。

※超明確な違反(「死ね」とかドストレートなコメント)じゃない限り違反と判定してくれませんでした。

2.1. Modelfile

掲示板の具体的なルールを SYSTEM プロンプトに埋め込んだカスタムモデルを作成しました。

FROM gemma4:e4b

PARAMETER temperature 0
PARAMETER num_ctx 4096

SYSTEM """
あなたは「ステラソラ攻略有志 Wiki」の雑談掲示板の管理人です。
後述する**判定プロセス**に従い、判定対象のコメントが **掲示板のルール** に違反するかを判定します。

(中略)

TEMPLATE """{{ .System }}
# 判定対象
以下のコメントを判定してください。
<<<
{{ .Prompt }}
>>>
"""

2.2. ollama-python で API を叩く

レスポンスを安定させるため、JSON フォーマットを指定してリクエストを投げます。

from ollama import Client

client = Client(host='http://ollama:11434')

def post(self, comment: Comment) -> OllamaServiceResponse:
  response = client.generate(
    model='wiki-moderator',
    prompt=comment.comment,
    stream=False,
    format={
      'type': 'object',
      'properties': {
        'is_violation': {'type': 'boolean'},
        'violation_type': {'type': 'string'},
        'violation_description': {'type': 'string'},
      },
      'required': ['is_violation', 'violation_type', 'violation_description'],
    },
    options={
      'temperature': 0,
      'num_ctx': 4096,
    }
  )
  
  response_dict = json.loads(response.response)
  return OllamaServiceResponse(
    is_violation=response_dict['is_violation'],
    violation_type=response_dict['violation_type'],
    violation_description=response_dict['violation_description'],
  )   

3. Discord Webhook で通知

判定結果が is_violation: true の場合のみ、Discord に詳細を投稿します。

def post_to_discord(self, content: str) -> None:
  payload = {'content': content}
  res = requests.post(self.webhook_url, json=payload)
  res.raise_for_status()

実際に動かしてみた結果

とりあえず形にはなり、自動で違反を拾ってくれるようにはなりました。
レスポンス速度もおおよそ2秒前後と問題ありません。
が、精度面に問題があり 「実運用にはもう一工夫必要」 というのが正直な感想です。

1. 用語の理解不足

ゲーム特有の用語や略称を正しく理解できていません。
例えば、 「ハフバ(ハーフアニバーサリー)」 を含むコメントを Gemma に判定させると、以下のような回答が返ってきました。

「『ハフバ』という、ステラソラとは別のゲーム作品名を挙げて言及しているため、他のゲーム作品を引き合いに出す行為(ルール違反)に該当します。」

「ハフバ」というイベント略称を「他作品の名前」と勘違いして、ルール違反とみなしています。

掲示板のルールに加えてゲーム用語を補強する必要がありそうです。

2. 文脈理解の過敏さ

少しでも強い表現があると、過剰に反応する傾向があります。

「(説明を読もう!)」という強い命令口調と、相手を責め立てるような威圧的な口調が認められるため、ルール違反(喧嘩腰な書き込み)に当たります。

掲示板のルールに「~しろよ、~やれよ。等の強い命令口調」という項目があるため、それに忠実すぎた結果、一般的な注意喚起まで違反として拾ってしまいます。
ルールの例外を読ませるのは、このサイズのモデルにはまだ荷が重いのかもしれません。

Gemini との比較

同じプロンプトを Gemini に投げると、これらは完璧にクリアされます。

ハーフアニバーサリーという祝事に対し(云々)

「(説明を読もう!)」という表現は、人によっては「上から目線」「喧嘩腰」と感じる可能性があります。掲示板のルールにある「他者への誹謗中傷・喧嘩腰な書き込み」に抵触するかどうかの瀬戸際ですが、内容自体が正しいアドバイスであるため、これだけで即座に削除されることは稀です。

(後者は過敏すぎる気もしますが、まあ問題なしと判定はしているので良しとします)

このようにスラング、文脈まで汲み取った上でかなり正確に返してくれます。
やはり「知能のベースライン」に差を感じました。

今後の展望

トークン数(コンテキストサイズ)にはまだ余裕があるので、以下の改善で精度向上が狙えそうです。

  • 用語集の埋め込み: 「ハフバ=イベント名」などの定義を SYSTEM プロンプトに追加する
  • 用例の追加: 「こういうのは違反、こういうのはセーフ」という具体例をいくつかプロンプトに含める

さいごに

今回、初めて Gemma 4Ollama を触ってみましたが、環境構築から実装まで 2 日足らずで完了しました。ローカル LLM の開発体験は非常に良く、API 料金やプライバシーを気にせずガシガシ試行錯誤できるのは大きな魅力です。精度面ではクラウドモデルに及びませんが、補助的な「一次検閲ボット」としては十分に可能性を感じるツールになりました。興味がある方はぜひ試してみてください。

1
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?