6.3 KiB
English | 日本語
Architecture Overview
MAESTRO は、ユーザーが投げたタスクを LLM 駆動のワークフロー(Piece)で実行する エージェントオーケストレーターである。コントリビュータ向けのコードマップは ../AGENTS.md も参照。
実行フロー
UI (POST /api/local/tasks)
→ bridge/server.ts (Express API)
→ Repository (SQLite: jobs テーブルに enqueue)
→ Worker.poll() が queued ジョブを取得
→ piece-classifier.ts: LLM がタスクを分類し Piece を選択
→ piece-runner.ts: pieces/*.yaml を読み、movements を順に実行
→ agent-loop.ts: 1 movement の ReAct ループ (LLM ↔ tool calls)
├─ 中間遷移: transition ツール
└─ 終了: complete ツール (success / aborted / needs_user_input)
→ ジョブ完了: DB 更新 + 進捗コメント。成果物は workspace/output/
- API 受付 —
bridge/server.tsがタスクを受け、Repository経由でjobsテーブルにqueuedで登録する。 - ワーカー —
worker.tsが DB をポーリングし、自分のprofiles/task_classesに合致するジョブを取得(複数ワーカーが並走)。 - 分類 —
piece-classifier.tsがタスク本文と全 Piece の description を LLM に渡し、最適な Piece を選ぶ。 - Piece 実行 —
piece-runner.tsが Piece の movements を順に回す。verify movement のフィードバックは次の execute に引き継がれ、transition.lessonsで movement 間の教訓が蓄積される。 - ReAct ループ —
agent-loop.tsが 1 movement 内で LLM とツールを往復させる。ContextManagerが LLM のusageからトークン使用量を追跡し、閾値(70/85/95%)で warn / prompt / force_transition を発火する。
Piece と Movement
- Piece =
pieces/*.yaml。movements配列で構成。 - 各 Movement は
allowed_tools(LLM に提示するツール)、edit(Write/Edit 可否)、rules(遷移条件)を持つ。allowed_tools外のツールは LLM から見えない。 - 遷移: 中間ホップは
transition(rules[].nextに列挙した宛先のみ選択可)、終了はcomplete。complete.resultがユーザーに見える唯一の最終出力。 default_nextはエンジン内部の sentinel(コンテキスト溢れ時の強制遷移、ASK 上限時のフォールバック)。- Progressive pressure: 同一 movement への連続訪問が増えると警告を注入し、閾値超過で ABORT。
ツールランタイム
ツールは src/engine/tools/*.ts のモジュール群。tools/index.ts が動的にロードし dispatch する。各ツールは 1 行の description(毎 LLM 呼び出しに乗るため簡潔に)を持ち、詳細手順は docs/tools/<name>.md(ReadToolDoc で取得)に置く。主なモジュールは ../AGENTS.md の一覧を参照。
Read 系ツールは並列実行される。Write/Edit は movement の edit: true のときのみ提示され、書き込みは主に workspace/output/ に限られる。
Bash サンドボックス
エージェントの Bash 実行は、利用可能なら bwrap サンドボックスで隔離する:
- ファイルシステム: タスクの workspace のみ rw bind、
/usr等は ro、他タスクの workspace やホスト/homeは不可視。 - 環境変数:
--clearenv+ 最小 allowlist のみ注入(シークレット env はサンドボックス内から見えない)。 - ネットワーク:
--unshare-netで遮断(外向き通信は SSRF ガード付きの WebFetch/MCP に集約)。 - 各 Bash コールは独立したサンドボックス(揮発
/tmp・毎回新名前空間)。永続するのは workspace のみ。
safety.bash_sandbox でモードを選ぶ(auto/always/off)。bwrap 不在時は hardened フォールバック(コマンド許可リスト + パススコープ検査 + env スクラブ付き exec)になる。実行時 pip/npm install は全モードで拒否され、Python パッケージは runtime/python-requirements.txt からプリベイクされる。詳細は operations/bash-sandbox-provisioning.md。
ワークスペース構造(ジョブ実行時)
{worktree_dir}/local/{taskId}/
input/ アップロード・DownloadFile の保存先
output/ 成果物(Write/Edit が許可される主な場所)
logs/ activity.log / 各種履歴
subtasks/ SpawnSubTask の結果
skills/ ReadSkill で materialize されたスキルファイル
データベース
SQLite(better-sqlite3)。db/schema.sql が初期スキーマ。追加カラムは db/migrate.ts で
PRAGMA table_info → 存在チェック → ALTER TABLE ADD COLUMN のパターンで冪等に適用する
(バージョン管理テーブルは使わない)。主なテーブル: jobs / local_tasks /
local_task_comments / audit_log ほか。
ジョブのライフサイクル
queued → dispatching → running → succeeded / failed / waiting_human(ASK 回答待ち)/ waiting_subtasks(並列サブタスク待ち)。失敗時は retry で再 queued(最大 retry.max_attempts 回)。
オプションのサブシステム
- LLM Gateway(
src/gateway/) — MAESTRO 自身を OpenAI 互換 LLM プロキシとして公開(仮想キー・予算・Prometheus メトリクス)。複数 GPU/チーム共有向け。env/接続種別がAAO_*/aao_gatewayの歴史的接頭辞を使う。 - MCP — Model Context Protocol サーバー連携(
MCP_ENCRYPTION_KEY必須)。 - Reflection — ジョブ完了ごとにユーザーメモリを LLM が自動更新(既定 OFF、revert 可)。
- 認証 — Passport による Google/Gitea OAuth(任意)。
private/org/publicの可視性モデル。 - スケジューラ — cron 式の定期タスク。
フロントエンド
React + Vite + TailwindCSS + @tanstack/react-query。ui/src/App.tsx がルート。2 カラム(list + detail)レイアウトで、タスク一覧・スケジュール・設定・スキル/Piece 管理を扱う。