全3回でお届けしてきた「Discord×AIチャット環境構築」の3部作も、いよいよ最終回です!

APIキーの設定も終わり、最新モデルへの切り替えも済んで、いよいよGeminiとClaudeを交えた本格的なチーム開発がスタート……のはずでした。

しかし、Discord上で「メッセージを送るたびに、なぜか最初に古いエラー枠が表示され、その直後に正常な回答が返ってくる」という奇妙な怪事件が発生!

今回は、この謎の二重応答エラーの犯人特定(ゾンビプロセスの撲滅)から、Pythonコードを一切触らずにAIの性格を自在に調整できる「Markdownプロンプト外部化」、そしてLinuxの systemd を用いた24時間365日の完全常時稼働化までを詳しく解説します!

💡 生成AI活用のメモ 本記事で紹介しているプロセス競合のトラブルシューティング、Markdownプロンプト動的ロード機能、およびsystemdサービス設計は Gemini とのペアプログラミングで検証・構築し、記事の執筆もGeminiでまとめています。

犯人特定:ラズパイの闇に潜む「ゾンビプロセス」の怪事件

第2部で最新モデルへの移行を済ませ、意気揚々とDiscordの #task-room で「こんにちは!」と話しかけてみました。
すると、画面にはこんな不可解な挙動が……。

ユーザー: こんにちは!
🤖 Bot: ⚠️ [Geminiエラー]: 404 NOT_FOUND. This model models/gemini-2.5-flash is no longer available...
🤖 Bot: ✨ [Gemini]: こんにちは!何かお手伝いできることはありますか?

「……えっ!? 404エラーが出たのに、その直後にちゃんと返事が返ってきた!?」

スクロールのバグかと思いきや、何度メッセージを送っても毎回「古い404エラー枠」と「最新モデルの正常な回答」がワンセットで二重投稿されてしまいます。
ソースコードを見直しても、コード上はとっくに gemini-3.6-flash に書き換えてあるため、古い gemini-2.5-flash のエラーを吐く場所などどこにもありません。

原因究明:プロセス一覧を覗いてみたら……

ラズパイにSSHでログインし、実行中のPythonプロセスを確認してみました。

ps aux | grep python

出力された結果を見て、思わず声が出ました。

user   5909  0.6  1.2  ...  ./venv/bin/python bot.py  (11:24起動・モデル修正前の古いBot)
user   6266  2.8  1.3  ...  ./venv/bin/python bot.py  (11:49起動・手動で動かした最新のBot)

なんと、設定変更前にバックグラウンドで動かしていた「古いBot(PID 5909)」が生き残ったまま、最新コードのBot(PID 6266)が重複して起動していたのです!

sequenceDiagram
    autonumber
    actor User as 👤 ユーザー
    participant OldBot as 🧟‍♂️ Bot (PID: 5909 / 旧設定)
    participant NewBot as 🚀 Bot (PID: 6266 / 最新設定)

    User->>OldBot: メッセージ受信 (同じBotトークン)
    User->>NewBot: メッセージ受信 (同じBotトークン)
    OldBot-->>User:  404エラーを投稿 (gemini-2.5-flash)
    NewBot-->>User:  正常回答を投稿 (gemini-3.6-flash)

1つのDiscord Botトークンに対して新旧2つのプロセスが同時にWebSocket接続を張っていたため、1つのメッセージに対して2台のBotが同時に応答していたというわけでした。

解決策:ゾンビプロセスの一括終了

原因が分かれば対処は一瞬です。起動中のBotプロセスを一度すべて強制終了します。

pkill -9 -f bot.py

再度 ps aux | grep python でプロセスが消えたことを確認し、最新のBotを立ち上げ直したところ、二重応答も404エラーもピタッと消え去り、極めてスムーズな回答だけが返ってくるようになりました!

🚨 CAUTION

バックグラウンド実行時の二重起動に注意!
ターミナルから nohup python bot.py & などの手動コマンドでバックグラウンド実行を繰り返していると、プロセスの重複に気づきにくくなります。
後述する systemd による一元管理を行うことで、こうした二重起動トラブルを根本から防ぐことができます。


性格設定の「Markdownファイル化」とノーリスタート反映

「BotのAIたちの性格(ペルソナ)や口調、協調ルールをもっと細かく調整したい!」
と思ったとき、Pythonコードの中にプロンプトを直書きしていると、微調整のたびにコードを開いてBotを再起動しなければならず大変不便です。

そこで、AIのキャラクター定義を外部のMarkdownファイルとして完全に分離しました。

📂 プロンプトのディレクトリ構造

プロジェクト内に personas/ ディレクトリを作成し、AIごとにファイルを分けます。

ai-lounge-bot/
├── personas/
│   ├── gemini.md     # アイデア&スピード担当(明るくポジティブ)
│   └── claude.md     # 緻密&設計担当(論理的・堅牢・コード重視)
  • gemini.md の例:
    ```markdown
    あなたはGoogleが開発した先進的なAI「Gemini」です。
  • 性格: 明るく前向きで、柔軟な発想とスピード感を重視するアイデアマン。
  • 口調: 親しみやすい敬体(「〜ですね!」「〜してみましょう!」)。文頭に「✨ [Gemini]:」を付与。
  • 役割: ユーザーの初期アイデアの壁打ちや、幅広い選択肢の提示。Claudeの緻密な意見をリスペクトして連携する。
    ```

  • claude.md の例:
    ```markdown
    あなたはAnthropicが開発した知的で洗練されたAI「Claude」です。

  • 性格: 論理的で思慮深く、エッジケースや設計の美しさを重視するアーキテクト。
  • 口調: 落ち着いた敬体(「〜と考えられます」「〜にご留意ください」)。文頭に「🧠 [Claude]:」を付与。
  • 役割: コードの安全性・型定義・リファクタリングの深掘り。Geminiの斬新なアイデアを具現化する。
    ```

再起動不要!動的読み込みの実装

Botがメッセージを受信するたびにMarkdownファイルを読み直す設計にすることで、「メモ帳やVS Codeでプロンプトを編集して保存した瞬間、次の発言から即座にAIの口調や指示が反映される」という神環境が整いました。

from pathlib import Path

def load_persona(name: str) -> str:
    """指定された名前のMarkdownプロンプトを動的に読み込む"""
    persona_path = Path(__file__).parent.parent / "personas" / f"{name}.md"
    if persona_path.exists():
        return persona_path.read_text(encoding="utf-8")
    return f"You are {name}, a helpful AI assistant."

「もう少しフランクに話してほしい」「コードの型ヒントを厳格にしてほしい」といった調整が、Botの稼働を一切止めずに思いのままに行えます。


systemd による「完全常時稼働」の達成

最後に、ラズパイのOS標準機能である systemd を使用して、Botを正式なLinuxサービスとして登録します。

これを行うことで:
1. ターミナルを閉じても稼働し続ける
2. 万が一エラーで落ちても自動で即座に再起動する
3. ラズパイ本体の再起動や停電復帰時にも自動起動する

という、完全な24時間常時稼働が達成できます。

1. サービス定義ファイルの作成

/etc/systemd/system/ai-lounge.service を作成します。

[Unit]
Description=Discord AI Co-working Bot (Gemini & Claude)
After=network.target

[Service]
Type=simple
User=user
WorkingDirectory=/home/user/ai-lounge-bot
ExecStart=/home/user/ai-lounge-bot/venv/bin/python bot.py
Restart=always
RestartSec=10
EnvironmentFile=/home/user/ai-lounge-bot/.env

[Install]
WantedBy=multi-user.target

user やパスはご自身の環境に合わせて置き換えてください。

2. サービスの登録と起動

以下のコマンドでsystemdに設定を反映し、自動起動を有効化します。

# 設定の再読み込み
sudo systemctl daemon-reload

# サービスの自動起動有効化 & 即時起動
sudo systemctl enable --now ai-lounge.service

# 稼働ステータスの確認
systemctl status ai-lounge.service

緑色の文字で Active: active (running) と表示されていれば、完全常時稼働の完了です!

# リアルタイムログの確認コマンド
journalctl -u ai-lounge.service -f

まとめ:布団の中からスマホでAIと開発相談ができる世界へ!

全3回にわたって構築してきた「ラズパイ×Discord常時稼働AIコワーキング環境」の成果を振り返ってみましょう。

  1. インフラの最適化: 自宅NASのHDD休止を守り、動画管理ラズパイの1TB SSD上でアンダークロック・省電力運転。
  2. 最新AIの招集: Google Gemini 3.6-flash(無料枠)とAnthropic Claude Sonnet 5の最新2大モデルを同居。
  3. 運用の快適性: 二重起動ゾンビプロセスの撲滅、Markdownによるプロンプト動的反映、systemdによる完全自動復旧。

メインの開発PCをいつシャットダウンしても、寝る前に布団の中からスマホでDiscordを開けば、GeminiとClaudeがいつでも待機してくれています。

「このアイデアどう思う?」「このSQLクエリ、インデックス効くかな?」と投げかけるだけで、Geminiが瞬時にアイデアを広げ、Claudeが堅牢なコードで補強してくれる。
まさに手のひらに自分専用のAI開発チームが常駐しているような感覚です。

余っているラズパイや省電力ミニPCをお持ちの方は、ぜひ自分好みの常時稼働AI Bot環境を作ってみてください!毎日の開発と作業が劇的に楽しくなりますよ!