Hermes は、完全な言語サーバーをバックグラウンドのサブプロセスとして実行し、それらのセマンティック診断結果を write_file と patch で使用される post-write リント・チェックに提供します。エージェントがファイルを編集すると、構文エラーだけでなく、型エラー、未定義の名前、インポートの欠落、(言語サーバが検出する) プロジェクト全体のセマンティックな問題 など、編集によって発生したエラーを正確に確認できます。
Hermes エージェント☤ 入門 : 機能 – コア : 言語サーバー・プロトコル (LSP)
作成 : Masashi Okumura (@classcat.com)
作成日時 : 07/29/2026
バージョン : Hermes Agent v0.19.0 (2026.7.20) — The Quicksilver Release
* 本記事は hermes-agent.nousresearch.com/docs の以下のページを参考にしています :
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。

Hermes エージェント☤ 入門 : 機能 – コア : 言語サーバー・プロトコル (LSP)
Hermes は、完全な言語サーバー – pyright, gopls, rust-analyzer, typescript-language-server, clangd, 更に ~20 – をバックグラウンドのサブプロセスとして実行し、それらのセマンティック診断結果を write_file と patch で使用される post-write リント・チェックに提供します。エージェントがファイルを編集すると、構文エラーだけでなく、型エラー、未定義の名前、インポートの欠落、(言語サーバが検出する) プロジェクト全体のセマンティックな問題 など、編集によって発生したエラーを正確に確認できます。
これは、最高水準のコーディングエージェントが使用するのと同じアーキテクチャです。Hermes は自己完結型で提供されます: エディタホストは不要で、プラグインのインストールも不要、別途デーモンの管理も必要ありません。
When LSP runs
LSP は Git ワークスペースが検出 された場合のみ有効化されます。LSPは Git ワークスペースの検出に基づいて動作します。エージェントの作業ディレクトリ (または編集中のファイル) が git リポジトリ内にある場合、LSP はそのワークスペースに対して実行されます。どちらも git リポジトリ内にない場合、LSP は休止状態 (dormant) になります – これは、現在の作業ディレクトリ (cwd) がユーザーのホームディレクトリであり、診断対象のプロジェクトが存在しないような、メッセージング・ゲートウェイのために役立ちます。
チェックは段階的に行われます: まずプロセス内で構文チェック (数マイクロ秒) が行われ、構文に問題がなければ次に LSP 診断が行われます。不安定な言語サーバーや言語サーバーが存在しない場合でも、書き込み処理が中断されることはありません – LSP の障害発生時には、構文のみの結果に警告なしにフォールバックします。
具体的には、write_file または patch が正常に実行されるたびに、以下の処理が行われます :
- Hermes は、ファイルの現在の診断情報のベースラインを取得・記録します。
- 書き込みを実行します。
- 言語サーバーに再度問い合わせを行い、ベースラインに既に存在する診断情報を除外し、新しい診断情報のみを表示します。
The agent sees output like:
{
"bytes_written": 42,
"dirs_created": false,
"lint": {"status": "ok", "output": ""},
"lsp_diagnostics": "LSP diagnostics introduced by this edit:\n\nERROR [42:5] Cannot find name 'foo' [reportUndefinedVariable] (Pyright)\nERROR [50:1] Argument of type \"str\" is not assignable to \"int\" [reportArgumentType] (Pyright)\n "
}
lint フィールドには構文チェックの結果 (ast.parse、json.loads などを介したマイクロ秒単位のプロセス内解析) が格納されます; lsp_diagnostics フィールドには実際の言語サーバーからの意味診断情報が格納されます。2 つのチャネル、独立した信号です – エージェントは、構文的にクリーンなファイルで意味的な問題がある場合、`lint: ok` と入力済みの lsp_diagnostics として認識します。
サポートされる言語
| 言語 | サーバ | 自動インストール |
|---|---|---|
| Python | pyright-langserver | npm |
| TypeScript / JavaScript / JSX / TSX | typescript-language-server | npm |
| Vue | @vue/language-server | npm |
| Svelte | svelte-language-server | npm |
| Astro | @astrojs/language-server | npm |
| Go | gopls | go install |
| Rust | rust-analyzer | 手動 (rustup) |
| C / C++ | clangd | 手動 (LLVM) |
| Bash / Zsh | bash-language-server | npm |
| YAML | yaml-language-server | npm |
| Lua | lua-language-server | 手動 (GitHub releases) |
| PHP | intelephense | npm |
| OCaml | ocaml-lsp | 手動 (opam) |
| Dockerfile | dockerfile-language-server-nodejs | npm |
| Terraform | terraform-ls | 手動 |
| Dart | dart language-server | 手動 (dart sdk) |
| Haskell | haskell-language-server | 手動 (ghcup) |
| Julia | julia + LanguageServer.jl | 手動 |
| Clojure | clojure-lsp | 手動 |
| Nix | nixd | 手動 |
| Zig | zls | 手動 |
| Gleam | gleam lsp | 手動 (gleam install) |
| Elixir | elixir-ls | 手動 |
| Prisma | prisma language-server | 手動 |
| Kotlin | kotlin-language-server | 手動 |
| Java | jdtls | 手動 |
| PowerShell | PowerShellEditorServices (pwsh host) | 手動 (release zip) |
「手動」のエントリについては、その言語に適したツールチェーン・マネージャ (rustup、ghcup、opam、brew 等) を使用してサーバーをインストールしてください。Hermes は PATH または <HERMES_HOME>/lsp/bin/ にあるバイナリを自動的に検出します。
CLI
hermes lsp status # service state + per-server install status
hermes lsp list # registry, optionally --installed-only
hermes lsp install # eagerly install one server
hermes lsp install-all # try every server with a known recipe
hermes lsp restart # tear down running clients
hermes lsp which # print resolved binary path
出力例
% hermes lsp list pyright [installed ] .py,.pyi typescript [missing ] .ts,.tsx,.js,.jsx,.mjs,.cjs,.mts,.cts vue-language-server [missing ] .vue svelte-language-server [missing ] .svelte astro-language-server [missing ] .astro gopls [missing ] .go rust-analyzer [manual-only] .rs clangd [installed ] .c,.cpp,.cc,.cxx,.h,.hh,.hpp,.hxx bash-language-server [missing ] .sh,.bash,.zsh,.ksh yaml-language-server [missing ] .yaml,.yml lua-language-server [manual-only] .lua intelephense [missing ] .php ocaml-lsp [missing ] .ml,.mli dockerfile-ls [missing ] .dockerfile,Dockerfile terraform-ls [missing ] .tf,.tfvars dart [installed ] .dart haskell-language-server [missing ] .hs,.lhs julia [missing ] .jl clojure-lsp [missing ] .clj,.cljs,.cljc,.edn nixd [missing ] .nix zls [missing ] .zig,.zon gleam [missing ] .gleam elixir-ls [missing ] .ex,.exs prisma [missing ] .prisma kotlin-language-server [missing ] .kt,.kts jdtls [missing ] .java powershell [manual-only] .ps1,.psm1,.psd1
設定
デフォルト設定は通常のセットアップでは問題なく動作します; バイナリが PATH 環境変数にある場合は、何も設定する必要はありません。
# config.yaml
lsp:
# Master toggle. Disabling skips the entire subsystem — no servers
# spawn, no background event loop runs.
enabled: true
# How long to wait for diagnostics after each write.
wait_mode: document # "document" or "full"
# Max seconds to wait for the server to re-check the file after an
# edit. Only *fresh* diagnostics (produced for the post-edit
# content) are ever reported; if the server doesn't finish within
# this budget, the edit reports "no LSP data" rather than stale
# errors from before the edit. Raise this for slow servers on big
# projects (tsserver, rust-analyzer mid-indexing).
wait_timeout: 5.0
# How to handle missing server binaries.
# auto — install via npm/pip/go install into /lsp/bin
# manual — only use binaries already on PATH
install_strategy: auto
# Per-server overrides (all optional).
servers:
pyright:
disabled: false
command: ["/abs/path/to/pyright-langserver", "--stdio"]
env: { PYRIGHT_LOG_LEVEL: "info" }
initialization_options:
python:
analysis:
typeCheckingMode: "strict"
typescript:
disabled: true # skip TS even when its extensions match
サーバーごとのキー
disabled: true— 拡張子がファイルと一致しても、このサーバーを完全にスキップします。command: [bin, ...args]— カスタム・バイナリパスを固定します。自動インストールをバイパスします。env: {KEY: value}— 生成されたプロセスに渡される追加の環境変数。initialization_options: {...}— initialize ハンドシェイクで送信される LSP の initializationOptions ペイロードにマージされます。サーバー固有です; consult the language server’s docs.
インストール場所
install_strategy: auto の場合、Hermes はバイナリを `<HERMES_HOME>/lsp/bin/` にインストールします。NPM パッケージは `<HERMES_HOME>/lsp/node_modules/` にインストールされ、bin シンボリックリンクは 1 つ上の階層に作成されます。Go のバイナリは、GOBIN が staging ディレクトリを指した状態で `go install` でインストールされます。
/usr/local/, ~/.local/, またはその他の共有ディレクトリには何もインストールされません – staging ディレクトリは完全に Hermes が所有しており、プロファイルをリセットすると削除されます。
パフォーマンス特性
LSP サーバーは初回起動時に 遅延起動 (lazy-spawned) されます。.py ファイルが使用されたことのないプロジェクトで Python ファイルを編集すると、pyright が起動します; ほとんどのサーバーでは起動に 1~3 秒かかります (rust-analyzer は、コールドプロジェクトでは10+ 秒かかる場合があります)。同じワークスペース内でのその後の編集では、実行中のサーバーが再利用されます。
LSP レイヤーは、診断情報が出力されない場合、クリーンな書き込みに数ミリ秒を追加します。診断情報が出力される場合、待機時間は wait_timeout 秒となります – 通常、pyright/tsserver の場合は数十ミリ秒、rust-analyzer のインデックス作成中は数秒でサーバーが応答します。
診断機能の実行は、データの最新度 (freshness) に基づいて制御されています: サーバーが現在の編集内容に対して結果を生成した場合 (変更時または変更後に publishDiagnostics がプッシュされた場合、あるいは変更後にプルリクエストが応答された場合) のみ、結果が有効となります。再チェックがまだ行われていない低速なサーバーでは、その編集に対して “no data” という結果になります – 昨日のエラーが現在のエラーとして再報告されることは決してありません。
サーバーは Hermes プロセスの存続期間中、稼働状態を維持します。アイドルタイムアウトによるリーパー (回収機能) は存在しません – 書き込みのたびにサーバーのインデックスを再起動するコストは、デーモンを稼働させ続けるコストよりもはるかに高くなるためです。
無効化
config.yaml で lsp.enabled: false を設定すると、サブシステム全体が無効になります。書き込み後のチェックは、以前のバージョンから変更されていないインプロセス構文チェック (Python の場合は ast.parse、JSON の場合は json.loads 等) にフォールバックします。
レイヤー全体を無効にせずに、単一の言語のみを無効にするには :
lsp:
servers:
rust-analyzer:
disabled: true
以上