大半の AI エージェントは 一度に一ターンだ。こちらが打つ、向こうが返す、向こうが待つ。ループを回しているのはこちら。エージェントはただの関数呼び出しに過ぎない。
Hermes Agent もこのモードを持っている——むしろ既定だ。だが /goal という別のモードも積んでいる。ここでは反転して、ループを回すのはエージェント側になる。目標と成功基準を一度設定すれば、エージェントは提案・実行・自己評価・再試行を回し続け、別の judge LLM が「基準を満たした」と認めるまで走る。v0.14.0(2026 年 5 月 16 日)が /subgoal を追加して、走行中のループに新しい基準を後付けで重ねられるようになった——再起動なしで(#25449)。
この記事では、中で何が起きているのか、それが正しい道具なのはいつか、逆に間違った道具になる失敗モードはどこか、を見ていく。
既定モード(対比のために)
Hermes のチャットセッションは「ユーザのメッセージごとに一ターン」だ。エージェントはあなたのメッセージを読み、必要ならツールを呼び、応答を返す。仕事が終わっていなければ、こちらがつついて回す:「続けて」「もう一回」「X はどう」。外側のループはあなたが回している。
探索的な作業ならこれで十分だ——「このコードを説明して」「メモを下書きして」「バグを見つけて」。各ステップでエージェントを止め、こちらが舵を切り直したい類の仕事。
成功条件が具体的で、そこへ至る道筋が反復的な仕事には、これは向かない。「このモジュールを pytest が通るまでリファクタする」は、各ターンを手で運転すると 30 ターンの作業だ。/goal なら一行で済む。
/goal が実際にやっていること
/goal Make all tests in tests/api/ pass. Don't change the test assertions. Done when pytest exits 0.
これを送ると、3 つのことが起きる:
- 1.目標テキストが worker のターゲット prompt になる。 その後の各ターンで、worker モデルは目標と現在のベストアテンプトを含むシステムメッセージを受け取る。
- 2.各 worker ターンの後で、独立した「judge」LLM 呼び出しが走る。 judge は目標と現在の状態、提案された完了版を見る。返ってくるのは「done」(ループ終了)か「続け、足りていないのはここだ」のどちらか。
- 3.judge が done と言うまでループは続く——あるいは
/stopで止める、あるいは設定された反復上限に当たる。
judge が要だ。worker と同じ LLM 呼び出しではないし、worker の思考連鎖を見ていない——目標と現在の状態だけを見る。この分離が /goal を機能させる:自分の答えが正しいと既に信じ込んでいる worker は、judge として下手だ。コンテキストなしで呼ばれた新鮮な LLM 呼び出しの方が、ずっと向いている。
このパターンは Hermes のコードベース内部では「Ralph loop」と呼ばれている。標準的な擬似コード while not done: do(work); ralph = judge(work) に由来する名前だ。v0.14.0 の /subgoal 拡張は、走行中のループに新しい judge 基準をユーザが注入できるようにしたもの。
/subgoal——走行中の基準追加
モジュールをリファクタする /goal を起動した。3 ループ目で気付く——リファクタを進める一方で、各関数の循環的複雑度を 10 以下に保ちたい、と。ループを止めて作り直したくはない。
/subgoal Each function must have cyclomatic complexity <= 10.
judge が次に走るとき、その新しい制約を勘案する。現在のベストアテンプトが新条件を落とせば、ループは続く。通れば、ループは抜ける。
これはリリースノートの 1 行 bullet 上では小さく見える機能だ——「アクティブな /goal にユーザ追加の基準を後付け」——だが、ループを実際に使ってみると荷重を担うことが分かる。本物の目標は、エージェントが働くのを横で見ているうちに精緻化される。/subgoal がないと、精緻化の手段は /stop +再定義+再 /goal しかなく、走行中の状態が丸ごと消える。
実例
テストが通るまでリファクタ
/goal Refactor src/api/users.py so the User class follows the new naming convention in src/conventions.md. Don't break any existing tests. Done when:
1. pytest exits 0
2. The User class matches the convention rules in conventions.md
worker がリファクタを試し、judge が両条件を確認する。両方が緑になればループ終了。
UI を反復で詰める
/goal Make the button on /pricing more prominent. Done when:
1. The button is the largest interactive element above the fold on desktop
2. It uses the primary brand color (#FF5A50)
3. Existing Lighthouse accessibility score doesn't drop
worker が CSS を編集し、judge が browser ツールでスクリーンショットを撮って確認する。こちらが横で見守らずに大量の反復が回る。
バグを掴む
/goal Find the cause of the intermittent test failure in tests/auth/test_session.py::test_logout_clears_cookie. Done when you produce a minimal failing repro and a one-paragraph explanation.
ここで judge が見ているのは、成果物の両方が揃っているか——最小再現と一段落の説明——どちらかだけが揃っても通さない。最初の下書きの説明が曖昧すぎれば、/subgoal で「説明は対応する request/response の往復に言及すること」のような制約を後足しできる。
使うべきでないケース
/goal が間違った道具になるのは、次のような仕事のとき:
- •成功条件がぼやけている。 「もっとエレガントにして」——judge が安定した採点を返せず、ループは振動するか盲判で通すかになる。ここはターン単位で行く。
- •作業の経過を見ながら介入したい。 各イテレーションは judge が発火する前に完了まで走る——だから per-turn の可視性は得られない。途中レビューが要るなら、ターン単位か
/handoffを使う。 - •コストが速度より重要。 各ループは worker 呼び出し + judge 呼び出しだ。10 イテレーションの目標は 20 LLM 呼び出し分の金。リファクタには見合うが、「この変数の名前何にしよう」には浪費。
- •成功基準を真剣に考えていない。 ゴミ基準 → ゴミループ。
/goalは具体性に報いる仕様で、曖昧があればエージェントはそこを突いてくる。
/handoff との合わせ技
v0.14.0 は /handoff も出した——コンテキストを失わずに、走っているセッションをモデル間で移送する(#23395)。この 2 つは合わせて使える:走っている /goal が速いモデルでは解けない壁に当たったとき、深推論モデルへセッションごと引き渡す。judge は同じ基準で採点を続け、worker だけが強くなる。
/sessions(#20805)も同様に組み合わさる——/goal を一時中断して別のセッションを覗き、後で戻ってくる。ループの状態は checkpoint されている。
エージェントスタックの中の位置
自律性が低い方から高い方へ、エージェントの作業形態は 3 種類:
- 1.ターン単位 —— あなたが運転し、エージェントが応答する。会話的。
- 2.
/goal—— あなたが基準を定め、エージェントが基準到達まで回す。境界付きの自律。 - 3.Cron 実行 —— エージェントがスケジュールに従って無人で走り、結果はメッセージングプラットフォームへ配信される。時間方向に境界なしの自律。
/goal はその真ん中だ。元々は「ずっと見張る」か「専用スクリプトを書く」かしかなかった種類の仕事に対する、ちょうどよい解像度。v0.14.0 の /subgoal がループを走行中に操舵可能にしたことが、これを「面白い機能」から「日常の道具」に変えた。