Hermes Agent プラグイン開発と本番実践

この章は上級ユーザー向けです:プラグインシステムによる Hermes の拡張方法、OpenClaw からの移行方法、そして Hermes を本番環境にデプロイする際のセキュリティとコストのベストプラクティスを説明します。


プラグイン開発入門

Hermes は 3 種類のプラグインをサポートしています:汎用プラグイン(ツール + Hook)、メモリプロバイダー、コンテキストエンジン。

例

# インストール済みプラグインを対話的に管理
hermes plugins

# コマンドラインで管理
hermes plugins list
hermes plugins install <path>
hermes plugins enable <name>
hermes plugins disable <name>

ダッシュボードでプラグインを管理できます。以下のコマンドで Dashboard(ダッシュボード)を起動します:

hermes dashboard

ブラウザでダッシュボードを開き、左側のプラグインリストを開くと、インストール済みのプラグインを確認できます:

Hook システム

最も一般的なプラグイン機能は Hook です。Agent のライフサイクルの重要なポイントにカスタムロジックを注入します:

例

# ファイルパス:プラグインディレクトリ/logging_plugin.py
# シンプルなプラグイン例:すべての LLM 呼び出しを記録
from hermes.plugins import Plugin, hook

class LoggingPlugin(Plugin):
    name = "logging-plugin"

    @hook("pre_llm_call")
    async def before_call(self, ctx):
        # 毎回の LLM 呼び出し前に実行
        print(f"[LOG] LLM を呼び出します。現在のコンテキスト長:{len(ctx.messages)}")

    @hook("post_llm_call")
    async def after_call(self, ctx, response):
        # 毎回の LLM 呼び出し後に実行
        print(f[LOG] LLM 呼び出し完了。応答長:{len(response.content)})

利用可能な Hook ポイント

Hookトリガータイミング代表的な用途
pre_llm_callLLM 呼び出し前コンテキストの記録、Prompt の変更
post_llm_callLLM 呼び出し後応答の記録、統計分析
pre_tool_callツール呼び出し前(インターセプト/変更可能)権限検証、パラメータフィルタリング
post_tool_callツール呼び出し後結果の監査、ログ記録
on_message_receivedユーザーメッセージ受信時メッセージの前処理、NGワードフィルタリング
on_session_startセッション開始時リソースの初期化、コンテキストの注入
on_session_endセッション終了時リソースのクリーンアップ、要約の生成

カスタムツールの登録

プラグインを通じて Agent に新しいツール機能を追加します:

例

# ファイルパス:プラグインディレクトリ/my_tools.py
# カスタムツールの登録——Agent は組み込みツールと同じように使用できます
from hermes.plugins import Plugin

class MyPlugin(Plugin):
    name = "my-tools"

    def register_tools(self, ctx):
        # カスタムツールを登録すると、Agent のシステムプロンプトに表示されます
        ctx.register_tool(
            name="my_custom_tool",
            description="このツールは何らかの処理を実行します。ユーザーが X を必要とするときに使用します",
            parameters={
                "type": "object",
                "properties": {
                    "input": {
                        "type": "string",
                        "description": "入力パラメータの説明"
                    }
                },
                "required": ["input"]
            },
            handler=self.my_tool_handler
        )

    async def my_tool_handler(self, **kwargs):
        # ツールの実際の実行ロジック
        input_text = kwargs.get("input", "")
        # ... 処理ロジック ...
        return {"result": "done"}

OpenClaw からの移行

OpenClaw を使用している場合、公式がゼロダウンタイム移行ソリューションを提供しています:

例

# OpenClaw 設定をエクスポート
openclaw export --format hermes > openclaw-config.json

# Hermes にインポート
hermes import --from openclaw openclaw-config.json

# 移行結果を検証
hermes doctor

主要概念の対照

概念OpenClawHermes
エージェント定義JSON Agent 設定SOUL.md + config.yaml
ワークフロー手動で記述する YAML フロースキル(SKILL.md)
メモリバックエンド外部データベース組み込み SQLite + プラガブル
スキル/ツールコードプラグインMarkdown スキルファイル
マルチインスタンスマルチプロセス設定Profile システム

本番環境のベストプラクティス

セキュリティチェックリスト

本番デプロイ時の推奨セキュリティ設定:

例

# ファイルパス:~/.hermes/config.yaml
# 本番環境の推奨セキュリティ設定
terminal
:
  backend
: docker          # 必須:Agent コマンド実行環境の分離

approvals
:
  mode
: smart              # 危険なコマンドは承認が必要(または manual の方がより厳格)
  cron_mode
: deny          # スケジュールタスクは危険なコマンドに対してデフォルトで拒否

security
:
  redact_secrets
: true     # ログ内の機密情報を自動マスキング(デフォルトで有効)

環境変数でのアクセス制御:

例

# ファイルパス:~/.hermes/.env
# 本番環境のアクセス制御設定
GATEWAY_ALLOW_ALL_USERS=false           # すべてのユーザーを許可しないこと
TELEGRAM_ALLOWED_USERS=あなたのユーザーID# 明示的なホワイトリスト

Token コスト管理

補助タスクでより安価なモデルを使用し、運用コストを大幅に削減します:

例

# ファイルパス:~/.hermes/config.yaml
# 補助タスクは独立したモデルを使用し、Token 費用を削減
auxiliary
:
  background_review
:
    provider
: openrouter
    model
: google/gemini-3-flash-preview    # メインモデルを使用する必要はありません

  vision
:
    provider
: openrouter
    model
: google/gemini-2.5-flash-preview

  session_search
:
    provider
: openrouter
    model
: google/gemini-3-flash-preview

マルチ Profile ゲートウェイ監視

例

# すべての Profile のゲートウェイステータスを同時に表示
hermes profile list

# すべてのゲートウェイを一括再起動
for profile in coder assistant researcher; do
  $profile gateway restart
done

更新戦略

1つのコマンドでコードとすべての Profile の組み込みスキルを同時に更新します:

例

# コードを一度に更新 + すべての Profile に新しい組み込みスキルを同期
hermes update
# → コード更新(12 コミット)
# → スキル同期:
# default(最新)
# coder(+2 新規スキル)
# assistant(+2 新規スキル)

ユーザーが変更したスキルは決して上書きされません。更新では組み込みスキルの新規追加と変更部分のみが同期されます。

その他の拡張