Skip to content

エージェント概要

Ongrid は マルチエージェント ReAct システム です。ユーザーは常に coordinator(チャット画面の最上位ペルソナ)と対話します。タスクが 専門領域に当てはまるとき(深い根本原因調査、変更を伴うアクションのレビュー、 ネットワーク深掘り)、coordinator は AgentTool 経由でサブ エージェント("worker")へ dispatch します。各 worker は同じグラフ カーネルを フィルター済み tool bag に対して走らせ、最終回答を返し、 coordinator がそれを自分の返信に編み込みます。

このページが地図です。各ペルソナの詳細は個別ページで説明します。

チャットスレッドではなくペルソナ

ペルソナ はエージェントが何をするかを記述したディスク上のファイルです。 正典のレイアウトは Claude Code のエージェントフォーマットと同じ形(snake_case キー)です:

yaml
---
name: specialist-disk
description: 文件系统 / 磁盘容量专家 — du / find / stat / inode / 挂载 / 大文件
when_to_use: |
  When the task is about disk / filesystem health:
    - Disk full / utilization climbing
    - Hunt for large files / large directories
    - inode exhaustion / mount point inspection
tools:
  - query_knowledge
  - host_find_large_files
  - host_du_summary
  - host_stat_file
  - host_bash
  - query_promql
  - get_host_load
permission_mode: read-only
max_turns: 15
---
[markdown body — this becomes the system prompt]

フロントマターの下の本文が SystemPrompt です。同じ name のペルソナ ファイルが 2 つあると衝突し、ローダーが警告をログ出力します。全フィールドは ペルソナフォーマットリファレンス を参照 してください。

ペルソナは manager イメージの ./agents/(コンテナ内では /app/agents/) にあります。Ongrid はイメージに組み込みペルソナを同梱し、マウントされた ディレクトリからユーザー作成ペルソナも読み込みます —— カスタムエージェント を参照。

Coordinator vs worker

観点CoordinatorWorker
ユーザーと対話はい(チャット画面または IM 経由)決してしない —— worker 出力は coordinator へ
Tool bag広い:query_*、AgentTool、redirect スタブ狭い:ペルソナの tools: ホワイトリスト
ペルソナ名default(または組織別オーバーライド)specialist-*incident-investigatorreviewer
spawn 元ランタイム(チャットセッションごとに 1)AgentTool または review_gate デコレーター
spawn できるはい(worker を)いいえ(worker は設計上ネストしない)
セッション長命、永続化spawn ごとに新セッション、1 ターンにスコープ

coordinator の仕事は dispatch + トリアージ + 合成 です。深掘りツールは worker 側にあります。coordinator は LLM がハルシネーションしやすいツール (host_bashget_host_load、…)用の RedirectStub スロットを持ち、そのいずれかが呼ばれるとモデルに AgentTool 経由で 再発行するよう促す redirect メッセージを返します。

AgentTool

coordinator の dispatch プリミティブ。配線名は AgentTool(Claude Code の ツールカタログに合わせて PascalCase)。LLM から見えるスキーマ:

json
{
  "type": "object",
  "properties": {
    "description":   {"type": "string"},
    "subagent_type": {"type": "string"},
    "prompt":        {"type": "string"}
  },
  "required": ["description", "subagent_type", "prompt"]
}
  • description —— SPA タイルが使う 1 行のタスク要約。
  • subagent_type —— ペルソナの name。coordinator のシステムプロンプトに 注入されるカタログが有効な値を列挙します(ペルソナレジストリから reviewerdefault を除いたもの)。
  • prompt —— タスク要綱フル。worker は coordinator のコンテキストを 見ることができません —— 必要な詳細(incident_id、device_id、正確な 言い回し)をすべて詰め込んでください。

呼び出しは coordinator から見て同期 です。worker が completed / failed / killed に到達するまでブロックします。以前のリビジョンには 非同期の background: true フラグがありましたが、弱いモデルがそれを使い、 pending な task_id でユーザーに答えてフォローしないという挙動になりました。 今日このフラグは存在しません(事後分析コメントは agent_tool.go 参照)。非同期の唯一の経路は reviewer で、 それも LLM ではなくデコレーターが駆動します。

重複排除は組み込み

sha256(subagent_type + canonical(prompt)) でキーした 120 秒 LRU が、 2 回目の同一 AgentTool 呼び出しを短絡します。LLM は明示的な「もう dispatch 済み」ヒント付きで前回結果を見ます。coordinator ループのブローアウトを抑制 します(E2E eval D1 では重複排除なしで 240 秒間に 122 ツール呼び出しを観測)。

システムプロンプトの組み立て方

ComposeSystemPrompt は LLM が受け取るプロンプトを順に組み立てます。

  1. basePrompt —— ランタイムの普遍的な前文。空の場合あり。
  2. agentProfile.SystemPrompt —— ペルソナの markdown 本文。coordinator も持つことがある(ほとんど持つ)、worker は常に持つ。
  3. agentProfile.CriticalReminder —— <critical-reminder>...</critical-reminder> でラップ。これはペルソナ レベルの定数。graph レイヤーが長セッションの attention drift に耐える ため、さらに ターンごとに <system-reminder> として再注入します。
  4. 各アクティブスキルごとに[能力: <name>] ヘッダー + スキルの PromptBody

coordinator はスキルリストの前に追加ブロック —— エージェントカタログbuildAgentCatalog) —— を受け取ります。これは descriptionwhen_to_use の 1 行目を含む 「利用可能な specialist」の markdown 箇条書きです。カタログは意図的に reviewerReviewGate デコレーターのみが spawn 可能)と default(仮想的な最上位ペルソナで、spawn 可能なサブ エージェントとして列挙すると coordinator が自身を再帰的に spawn できて しまう)を除外します。

エージェントレジストリ

AgentRegistry はパース済みペルソナをメモリに保持します。起動時に一度ロードし、Reload() は単一の sync.RWMutex スワップなので、進行中の coordinator ターンが 半分ロードされたレジストリを観測することはありません。

メソッドいつ
Load(root)起動時。<root>/**/*.md を再帰的に walk。
Reload(root, ...)マーケットプレースのインストール/アンインストール。アトミックスワップ。
ByName(name)spawn 時のルックアップ。ミスは (nil, false)
Replace(ag)ユーザーエージェント編集。in-place upsert —— ライブレジストリ、再起動なし。
Remove(name)ユーザーエージェント削除。

ファイルごとのパースエラーは walk を中断せず警告として記録されます (スキルレジストリと同じポリシー)。存在しないエージェントルートは エラーではなく、空のレジストリが返るだけで起動失敗にはなりません。

Reviewer とレビューゲート

reviewer は特殊です:coordinator は spawn できませんReviewGate デコレーターがゲートし、Class"write" または "destructive" の どんなツールも捕捉します。デコレーターは:

  1. 提案ペイロード(actiontargetreasonblast_radiusoperator)を構築。
  2. reviewer ワーカーを spawn(内側ツールから見て同期)。内側ツールの 15 秒タイムアウトとは独立の 60 秒タイムアウトを持つ。
  3. reviewer が Decision: approve を返せば、呼び出しは内側ツールへ 素通り。そうでなければデコレーターは reviewer の理由をラップした ErrReviewRejected を返す。

これがエージェントカタログから reviewer を落とす理由です:デコレーター のみが呼び出します。カタログに置けば coordinator が何もゲートしない アドホックな「レビュー」を dispatch できてしまいます。

完全なステートマシンは Reviewer を参照して ください。

Worker ライフサイクル

Runtime.SpawnWorker のステートマシン:

text
pending  → running  → completed
                   ↘ failed
                   ↘ killed     (StopWorker called while running)
  • worker が実行中でも監査と親 → worker のツリークエリが解決するように、 chat_sessions 行は事前に作成されます。
  • バックグラウンド spawn は長命のランタイム ctx から派生するので、終了する HTTP リクエストが worker を実行中に解体することはありません。同期 spawn は呼び出し元の ctx を継承します。
  • セッション行はパニックを含むすべての終端パスで close (closed_at が立つ)されます —— これがないと孤児行が溜まります (修正前のテスト環境で 161 件溜まりました)。

worker は worker を spawn できませんSpawnWorkerRuntime 上 のみに公開され、 disabledForWorker フィルターが worker の tool bag から AgentTool を剥がします。1 つの coordinator、N 個の並列 worker、それより深いネストなし。

次に

  • Coordinator —— デフォルトペルソナ、3 つの 制御ツール、dispatch するか直接答えるかの判断。
  • Incident investigator —— 0 号 病人までの根本原因、18 ツール予算、F1 eval。
  • Specialists —— compute / disk / network / ops / sre、各々が所有するもの、coordinator がどう選ぶか。
  • Reviewer —— 変更ツールに対する SOP ダブル サインゲート。
  • カスタムエージェント —— 自前ペルソナの作成、 ホットリロード、デバッグ。