作成日: 2026-03-06
更新日: 2026-03-13
ステータス: Draft(定義正本)
本書は Butler Layer の思想・目的・責務分離・運用規約を定義する正本である。
実装詳細は別紙の実装仕様書群に委譲する。
頭脳チーム (Brain Team): 要件定義・方針決定・最終判定を行う高性能LLM群執事チーム (Butler Team): 定形実行・情報収集・記録を行う低コストLLM群オーケストレーター (Butler Orchestrator): 執事実行の制御面(契約検証、ポリシー、承認、実行、記録)を担うPythonサービス判断ゲート (Routing Gate): Orchestrator内でQwenが担うパターンマッチ・振り分け機能タスク契約 (Task Contract): 頭脳から執事へ渡す機械可読な依頼仕様結果契約 (Result Contract): 執事から頭脳へ返す機械可読な結果仕様協調トランザクション (Collaboration Transaction): 頭脳の要求投入から執事の結果返却までの1往復協調セッション (Collaboration Session): 複数の協調トランザクションで構成される作業単位タスクインスタンス (Task Instance): 協調トランザクション内で実行される具体タスク実行計画 (Execution Plan): 執事が採用した手順列(SOP由来または暫定手順)承認イベント (Approval Event): HITLで承認/却下が確定したイベント検証フェーズ (Verification Phase): success criteria の達成判定を行う工程エスカレーション (Escalation): 執事が解決不能事項を頭脳へ差し戻す動作失敗分類 (Failure Class): need_input / blocked / failed の分類規約SOP: Standard Operating Procedure。再利用可能な実行手順Intent × Target: SOP識別のための固定意図と可変対象の組証跡 (Evidence): 実行コマンド、主要出力、エラー断片などの監査可能データHITL: Human-in-the-loop。重要操作の人間承認ゲートIntentドメイン: Butlerが担当する運用タスクの範囲(後述)AI主体開発では、探索系作業(ドキュメント検索、ログ収集、状態確認)がトークン消費の大半を占める。
その結果、設計判断を行う高性能LLMのコンテキストが圧迫される。
加えて、BrainのトークンはContextLimitに達しやすく、プランを上げる余裕がない環境では特に深刻である。
Butler Layer はこの問題を、役割分離と運用プロトコルで解決する。
高性能LLM群(Claude Code / Codex)。
主責務は「方針決定」「要件定義」「最終判断」。
Butler Orchestrator(Pythonサービス)+ Qwen(ローカルLLM)。
主責務は「定形実行」「情報収集」「証跡記録」。
Butler Orchestratorは決定論的なPythonサービスとして実装する。
Qwenは「判断ゲート」と「自律エージェント」の2つの役割で動作する。
Butler Orchestrator(Pythonサービス・状態機械)
├─ SOP Resolver(DBクエリ)
├─ Policy Engine(ifコード)
├─ Approval Gate(待機ループ)
├─ Execution Backend Selector
├─ Execution Backend(LocalBackend など。subprocess / mcp_call 実行を担当)
├─ Recorder(SQLite書き込み)
├─ Qwen呼び出し(判断が必要な特定ポイントのみ)
├─ Agent Backend Selector
└─ Agent Backend(QwenAgentBackend など。delegation_mode="agent" の自律ループを担当)
補足:
ExecutionBackend 抽象を導入し、既存の executor.py は LocalExecutionBackend から呼ばれるWindmillExecutionBackend を追加し、Windmill の async flow run endpoint と job polling endpoint を使う実接続を入れたAgentBackend 抽象に LangGraphAgentBackend を追加し、環境変数 BUTLER_AGENT_BACKEND=langgraph で QwenAgentBackend と切り替えられるf/butler/execute_task_steps とし、repo 内の実装入口は windmill/flows/execute_task_steps.py で管理するcmd / check / wait / mcp_call に対応し、mcp_call は context.mcp_servers に渡された URL / token で MCP サーバーへ直接 HTTP 接続するBUTLER_EXECUTION_BACKEND はフォールバックとして使うtarget.service=docker でも Windmill backend を選択できるようにし、Docker Compose ベースの長時間運用タスクを Windmill へ逃がせるようにするWindmillBackend 実接続を追加しやすくなるknown_only モード(SOP登録済みのIntentのみ実行):
Qwenがやること(パターンマッチと振り分けのみ):
agent モード(delegation_mode: "agent" 指定時):
Agent Executor は backend selector 経由で AgentBackend を選び、
現在は QwenAgentBackend が Qwen(Ollama ローカルLLM)の自律ループを実行する:
instruction を受け取るimplicit_scope に "local" を含めると local__list_files / local__read_file / local__markdown_to_html / local__record_md_to_trilium ツールが利用可能になる(ローカルファイル参照・変換・Trilium登録)AgentBackend 層に _verify_key_outputs / _preserve_agent_failure_summary を置き、ループ完了後に intent が要求するツール呼び出しを検証する。未実施なら summary を信じず FAILED にするLangGraphAgentBackend は ChatOllama + LangGraph prebuilt agent で同じツール群を実行し、key_outputs を Qwen backend と同じフォーマットで残すbutler__cancel_task を呼ぶと threading.Event 経由でループを安全に中断できるQwenがやらないこと(いずれのモードでも):
単なる接続では協調は成立しない。
協調はタスク契約・結果契約・状態遷移の合意で成立する。
SOPは Intent(固定語彙)と Target(可変属性)の組で管理する。
これによりタスク定義の爆発を防ぐ。
破壊的/不可逆操作は承認ゲートを通す。
執事は「勝手に進めない」。ただし承認はBrain経由で行い、Butlerが人間に直接話しかけることはしない。
最初から全自動を目指さない。
単一Intentから開始し、成功した運用のみSOP化する。
実行結果は要約ではなく証跡中心で返す。
頭脳は証跡に基づいて可否判断する。
Brainは運用系タスク(Intentドメインに該当するもの)をBrain自身が実行可能な場合でもButlerに委任する。
Butlerが未知の場合は手順を教えてSOP化させる。
効率より委任を優先する。これは以下の2つの理由による:
BrainはTask Contractを1回投入したら、あとはOrchestratorが自律的に動く(fire and forget)。
OrchestratorがBrainを起こすのは need_input・escalation・最終結果返却のときだけ。
Orchestratorの内部でQwenを何回呼ぼうとBrainのトークンは消費しない。
以下のIntentに該当するタスクはButlerの仕事とする。
Brainはこれらを自分で実行せず、必ずButlerに委任する。
| Intent | 説明 |
|---|---|
bootstrap_context |
プロジェクト情報・コンテキストの収集 |
collect_logs |
ログ・状態情報の収集 |
triage |
障害・失敗事象の一次切り分け |
deploy |
サービスのデプロイ |
restart |
サービスの再起動 |
health_check |
ヘルスチェック・状態確認 |
commit_push |
git commit / push |
record_to_trilium |
Triliumへの作業記録 |
read_from_trilium |
Triliumからの情報取得 |
update_sop |
SOPの修正・更新 |
このリストは運用の中で拡張される。追加は本書のマイナーバージョンアップで行う。
Brain Team (Claude/Codex)
-> Task Contract (MCP tool: butler__submit_task)
Butler Orchestrator (Pythonサービス)
-> SOP Resolver
-> Policy / Approval Gate
-> Execution Backend Selector
-> Execution Backend
-> Recorder
-> Qwen (判断ゲート)
Resources
-> MCP / CLI tools
-> SQLite (machine state)
-> Trilium (human docs, optional)
Brain↔Butler の通信はMCPプロトコルで行う。Butler OrchestratorはMCPサーバーとして動作する。
補足:
butler__submit_task が同期返却するか非同期受領 (RECEIVED) にするかは main.py の固定 intent 一覧ではなく、butler__reload だけで反映できるButler MCP サーバーは fastmcp.exe run butler/main.py として stdio transport で起動される。
Claude Code のセッションごとに1プロセスが spawn されるが、セッション終了時にプロセスが残存(ゾンビ化)する問題が確認された。
複数のゾンビプロセスが同一 SQLite を掴むと UNIQUE constraint エラーや接続障害が発生する。
対策として以下を main.py に実装している:
| 機構 | 説明 |
|---|---|
PID ファイル (butler.pid) |
起動時に書き込み、終了時に削除。既存 PID が生存中なら警告ログを出力 |
atexit ハンドラ |
正常終了時に PID ファイルを削除 |
SIGTERM / SIGINT ハンドラ |
シグナル受信時にクリーンアップしてからプロセス終了 |
| SQLite WAL モード | PRAGMA journal_mode=WAL で複数接続の読み書き競合を緩和 |
| SQLite busy_timeout | PRAGMA busy_timeout=30000 + connect(timeout=30) でロック待ちを許容 |
注意: PID ファイルは「検出と警告」のみで、既存プロセスを自動 kill はしない(安全側に倒す設計)。
ゾンビが残った場合は手動で taskkill /F /IM fastmcp.exe を実行する。
vX.Y を採用X: 互換性を崩す定義変更Y: 互換性を保つ追記/明確化本システムの最上位目的は Brainのトークン消費を低レベル作業から切り離し、高次判断へ集中させること である。
「動くこと」は前提条件であり、合格判定は以下のKPIで行う。
>= 95%0件teach_if_unknown -> NEED_INPUT -> teach -> DONE): >= 90%>= 30% を目安>= 20% 削減ButlerLayer_契約通信仕様書_v0.3.mdButlerLayer_実行SOP仕様書_v0.3.mdButlerLayer_データ運用仕様書_v0.3.mdButlerLayer_Brain動作原則_v0.1.mdButlerLayer_アーキテクチャ定義書_v0.2.md本書を Butler Layer の概念定義の正本とする。