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>
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)})
# シンプルなプラグイン例:すべての 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_call | LLM 呼び出し前 | コンテキストの記録、Prompt の変更 |
| post_llm_call | LLM 呼び出し後 | 応答の記録、統計分析 |
| 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"}
# カスタムツールの登録——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
openclaw export --format hermes > openclaw-config.json
# Hermes にインポート
hermes import --from openclaw openclaw-config.json
# 移行結果を検証
hermes doctor
主要概念の対照
| 概念 | OpenClaw | Hermes |
|---|---|---|
| エージェント定義 | 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 # ログ内の機密情報を自動マスキング(デフォルトで有効)
# 本番環境の推奨セキュリティ設定
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# 明示的なホワイトリスト
# 本番環境のアクセス制御設定
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
# 補助タスクは独立したモデルを使用し、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
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 新規スキル)
hermes update
# → コード更新(12 コミット)
# → スキル同期:
# default(最新)
# coder(+2 新規スキル)
# assistant(+2 新規スキル)
その他の拡張ユーザーが変更したスキルは決して上書きされません。更新では組み込みスキルの新規追加と変更部分のみが同期されます。