MINARA

カスタムエージェント

システムプロンプト + スキル + ツール + リスク上限 + トリガーをまとめた再利用可能なバンドル。CLI / REPL / HTTP / ワークフロー / cron から実行可能

🟢 構成可能: カスタムエージェントはレシピであり、別ランタイムではありません。 REPL セッションと同じエージェントループ、同じスキルレジストリ、 同じ資金確認ゲート上で動作します。

カスタムエージェント (Custom Agent) は次をまとめた保存済みバンドルです。

  • system_prompt (エージェントが実行時に従う指示)
  • skill_ids のサブセット (ランナーが起動する DomainSkill)
  • tool_names + tool_sets のサブセット (ランナーが公開するツール)
  • risk_tier_max の上限 (1 = 読み取り専用、4 = 手動のみ)。Web UI ウィザードでは「読み取り専用 / 資金移動なし / 資金移動可」の 3 択として提示され、最後の「資金移動可」は tier 3 (確認付き現物取引: swap、buy、sell) か tier 4 (永続・出金・autopilot を含む全資金操作) を選べます。定時・イベント実行のエージェントは資金移動ができず、資金移動は毎回確認が必要です。
  • discovery_mode (ランナーが自己拡張できる積極性)
  • triggers リスト (manual / cron / event)
  • 自由形式の metadata

このバンドルは SQLite の agent_definitions テーブルに永続化されます。 実行経路は次のいずれかです。REPL /agents run、CLI minara agents run、 HTTP POST /v1/agents/:id/runs、Web UI の Run ドロワー、 ワークフローステップ agent_turn { agent_id }、cron / event トリガー。

カスタムエージェントは概念的に Anthropic の Managed Agents API ではなく Claude Code subagents に近い存在です。メインエージェントと同じプロセス内で ローカル実行され、同じスキルカタログを共有し、同じ安全境界を継承します。 サンドボックス化されたサードパーティランタイムではありません。

カスタムエージェントのフロー:保存された定義がトリガーで起動し、ランタイムがリスク上限を制限し、資金確認ゲートの内側で共有エージェントループ上を実行し、自律実行の終了時に通知します

なぜオペレーターは欲しがるのか

  • 再利用: 繰り返し発生するタスクを一度だけエンコードします。 「ETH 朝刊」「ポートフォリオ週次レビュー」「オンチェーン流入ウォッチャー」など、 それぞれを名前付きエージェントとして登録し、ワンクリックで起動できます。
  • 限定されたツール面: リサーチ用エージェントには読み取り専用スキルだけで十分です (swap_tokens は不要)。財務エージェントには Hyperliquid 永続先物だけが必要です。 スキルセットが小さいほど、システムプロンプトはタイトに、無関係なツール呼び出しは少なく、 1 ターンあたりのトークンコストは低くなります。
  • トリガー: cron: "0 9 * * *" を付けたエージェントはオペレーター操作なしで 毎朝動きます。event: { event_name: "price.alert" } を付けたエージェントは イベントバスがマッチするイベントを発行したときに起動します。
  • ワークフローから合成可能: 複数ステップのワークフローからは、 リサーチプロンプトをインライン化する代わりに agent_turn { agent_id: "research-bot" } で参照できます。 ワークフロー作者がフローを持ち、エージェントが推論を持ちます。
  • 共有可能: ~/.minara/agents/ に JSON ファイルを置けば、 次回起動時にローダーが拾い上げます。research-bot をチームメイトに エクスポートすると、相手のインスタンスは source: "file:..." として読み込みます。

3 つの探索モード

discovery_mode は、実行時にランナーが skill_idstool_names をどう扱うかを制御します。

新規エージェントの既定は free_discovery です。メインアシスタントと同じく、 エージェントは必要なスキルを自分で発見するため、Web UI ウィザードで事前に 選ぶ必要はありません。ツールは選択したスキルと risk_tier_max の上限から 決まるため、tool_namestool_setsdiscovery_skill_pool は JSON ファイルローダーまたは HTTP API で設定する高度なフィールドであり、 ウィザードでは公開されません。

constrained

ハードなホワイトリストです。ランナーは宣言された skill_ids を厳密に起動し、 宣言された tool_names (および tool_sets の合併との交差) のみを公開します。 activate_skills メタツールは無効化されるため、LLM はターン中の自己拡張を行えません。

本番の信頼性を取りたい場合はこちらを選んでください。エージェントは毎回同じ形状で 走ります。レビューしやすく、テストしやすく、予算化しやすい構成です。

scenario_aware

後方互換のために残されており、現在の挙動は constrained と完全に同じです。 プロンプトごとにスキルをプリロードしていたシナリオ分類器は廃止されたため、 このモードは宣言された skill_ids だけを実行し、activate_skills は無効です。 既存のエージェントは値を保持しますが、新規エージェントは constrained を 選んでください。

free_discovery (既定)

宣言されたシードセットを起点に、LLM がターン中に activate_skills を 呼んでスキルを追加できます。 discovery_skill_pool の glob パターン (空 / 未指定ならカタログ全体) と risk_tier_max によって制限されます。

慎重に使ってください。エージェントに解空間としてカタログ全体を渡す形になり、 オープンエンドなリサーチには強力ですが、狭く反復的なジョブには脆くなります。

3 モード共通の安全不変条件

  • risk_tier_max は upsert 時だけでなく、トリガー時 にもランナーで強制されます。 たとえ DB を直接 UPDATE agent_definitions SET risk_tier_max = 4 で書き換えても、 cron / event / autopilot のトリガーでは実効上限が 2 にクランプされます。
  • 資金確認ゲートはエージェント実行のコンテキストを参照します。 テスト実行では、環境変数 MINARA_SKIP_FUND_CONFIRM=1 が 設定されていても 2 段階確認を強制します。
  • アーカイブ済みエージェントは fail-closed です。実行中の agent_turn ステップが アーカイブ済みエージェントを参照している場合、保存済みのスナップショットに対して 実行を継続しますが、アーカイブ済み id への新規実行は即座に失敗します。

トリガー

各エージェントには triggers リストがあります。v1 では 4 種類を提供します。

種類形状発火条件
manual{ kind: "manual" }UI で Run をクリック / /agents run を入力 / POST /v1/agents/:id/runs
cron{ kind: "cron", expr: "0 9 * * *", timezone?: "UTC" }TriggerManager の tick が cron 式を跨ぐ
event{ kind: "event", filter: { event_name: "price.alert", payload_match?: {...} } }イベントバスがマッチするイベントを発行
once{ kind: "once", fire_at: 1717430400000 }実時刻が fire_at (unix ミリ秒) に達した時。一度だけ発火し、その後エージェントは自分をアーカイブします

安全ルール: 既定では manual 以外のトリガーは upsert 時点で risk_tier_max ≤ 2 を強制するため、定時 / イベントエージェントは資金を 移動できません。エージェントは自律的な資金移動を選択できます (allow_autonomous_fund_moves: true。同じ書き込みに confirm_autonomous_fund_moves: true が必要)。これにより非 manual の上限が ≤ 3 (確認付き現物取引) まで上がります。tier 4 (永続・出金・autopilot) は 常に手動トリガーが必要で、発火時には人がループに入ります。上限を超える 書き込みはストアが明確なエラーで拒否します。

once エージェントはリマインダーの実装そのものです。一度だけ発火し、その後 アーカイブされて二度と発火しません。発火済みのリマインダーを復元しても再生は されません。再スケジュール (新しい fire_at を設定) するか、手動で実行して ください。繰り返しのリマインダーには cron トリガーを使います。

通知

実行が終わると、Minara は 2 つの方法で知らせます。

アプリ内通知センター。 右上のベルが未読数と最近のエージェント実行の一覧を 表示し、各項目はその実行へのリンクになっています。常時オンでリアルタイムに 更新され、既読にしたりクリアしたりできる短い履歴を保持します。

ブラウザ通知。 設定 → 一般 (またはベルのクイックトグル) で「ブラウザ通知」を オンにすると、Minara のタブがバックグラウンドや最小化されているときに OS の デスクトップ通知を受け取れます。Minara のタブを見ているときは、代わりにアプリ内 メッセージとして表示されます。ブラウザは初回に許可を尋ねます。タブを閉じたり ブラウザを終了したりすると届かず、ページにはセキュアなコンテキスト (HTTPS) が 必要です。localhost は例外です。

どの実行が通知するか。 エージェントが自分で行う実行が通知します: 定時 (cron)、イベント (event)、一度きりのリマインダー、ワークフローのステップです。 自分で開始した実行 (Run ボタン、/agents run、チャットのターン) は、すでに 見ているので通知しません。テスト実行は通知しません。

エージェントごとの制御。 各エージェントには「アプリ内通知」設定があります。 うるさいエージェントではオフにしたり、失敗時だけ知らせるよう選べます。新しい エージェントは既定でオンです。

エージェントを参照するワークフロー

ワークフローの agent_turn ステップには 2 つの形があります。

// 推奨: 既存のカスタムエージェントを id で参照
{ "kind": "agent_turn", "agent_id": "research-bot",
  "input": { "ticker": "ETH" } }

// レガシーなフォールバック: inline goal。エンジンは scoped な
// スキル / ツールサブセットを持たない一回限りのエージェントを立ち上げます
{ "kind": "agent_turn", "goal": "summarize recent ETH news" }

agent_turn { agent_id }tool_call の使い分け

推論、複数ツール探索、自然言語出力が必要なステップでは agent_turn を選びます。 リサーチ、起草、分類、要約などが該当します。

入力が決まっていて動作が確定している単一ステップでは tool_call を選びます。 1 回のスワップ、送金、残高チェック、価格取得などです。ツール呼び出しは 高速かつ低コストで、既存の資金確認ゲートをそのまま使えるため、 LLM ターンを跨いで確認コンテキストを再構築する必要がありません。

「ETH をショートしてから戦略ノートを書く」というワークフローは 2 ステップに分解します。 実行は tool_call { tool: "open_perps_position" }、 書き起こしは agent_turn { agent_id: "strategy-note" } です。

ローカルオートメーションスキルは、このマトリクスを自動的に守ります。 カスタムエージェントのカタログを公開し、「起草」「リサーチ」「要約」の意図は agent_turn に、資金移動の意図は tool_call にルーティングします。

CLI

minara agents サブコマンドはフルライフサイクルを公開します。

アクション用途
listminara agents list [--archived]登録済みエージェントを一覧
getminara agents get <id>フル定義を JSON で出力
createminara agents create --from <file.json>JSON ファイルから挿入
updateminara agents update <id> --from <patch.json>PATCH。意味のある変更で version を昇格
archiveminara agents archive <id>ソフト削除。アタッチ済みトリガーを解除
runminara agents run <id> [--input "..."] [--test]アドホック実行を起動。イベントを stdout にストリーム
exportminara agents export <id>JSON を出力。ファイルへパイプ可能
importminara agents import [--from <file.json>]export の逆。--from 省略時は stdin を読む

run はワークフローが完了 / 失敗するまで同期的にイベントストリームを開き、 最後に __adhoc__ の出力ペイロードを出します。cron / シェルスクリプトと そのまま連携できます。

minara agents export research-bot > research-bot.json
scp research-bot.json bob@host:~/.minara/agents/
ssh bob@host minara agents list           # research-bot が source=file:... で出現

REPL

/agents スラッシュコマンドが対話版です。

振る舞い
/agents または /agents list登録済みエージェントを一覧
/agents create対話的な collectArgs フロー: 名前 → システムプロンプト → スキル選択
/agents run [<id>] [<input>...]エージェントを実行。<id> 省略時はライブピッカー
/agents archive [<id>]アーカイブ。<id> 省略時はライブピッカー。y/N で確認

/agents create フローは標準の collectArgs パターンに従います。必須フィールドを 1 つずつ尋ね、バリデーションに落ちたら 不正なフィールドだけを再質問し、空回答が 3 回続くとキャンセルされます。

Web UI

Web UI は AUTOMATE ナビゲーショングループ配下の /agents に カスタムエージェントを表示します (Workflows と Autopilot と並びます)。 Web UI の /agents をご覧ください。

  • 一覧ページ: 各エージェントを名前、リスク上限、discovery モード、 トリガー概要、カードごとの Run / Edit / Archive アクションを含むカードで表示。 Import ボタンは JSON ファイルアップロードを受け付け、New ボタンはウィザードを開きます。
  • ウィザード (3 ステップ): ステップ 1 はスターターテンプレート選択 (researcher / treasury sentinel / drafting) または「空白」。 ステップ 2 で名前を付け、システムプロンプトを書き、スキルを選択します (ピッカーはハードホワイトリストモードでのみ表示)。ステップ 3 で discovery モード、 リスク上限、トリガー種別を選びます。安全クランプはインラインで表示されます。
  • 詳細ページ: Overview / Definition / History の 3 タブ。 Definition タブはライブ JSON を表示し、PATCH 編集はアトミックに version を昇格させます。
  • Run ドロワー: 一覧カードまたは詳細ページから開きます。 インライン SSE イベントストリームが workflow:startedworkflow:step イベント → 終端の workflow:completed / workflow:failed を表示します。Run as test (?test=1) はチェックボックスで、 テスト実行では env の skip 設定があっても資金確認モーダルが出ます。

REST エンドポイント

HTTP gateway は非 CLI 連携向けに同じ surface を公開します。

メソッドパス用途
GET/v1/agents定義を一覧 (?archived=true でアーカイブ済みのみ)
POST/v1/agents作成。body は AgentDefinitionInput
GET/v1/agents/:id最新定義を取得
PATCH/v1/agents/:id更新。body は部分 AgentUpdatePatch
DELETE/v1/agents/:idアーカイブ (ソフト削除、復元可能)
POST/v1/agents/:id/restoreアーカイブ済みエージェントを復元 (トリガーを再装着)
DELETE/v1/agents/:id/permanent完全削除 (取り消し不可。実行履歴は残る)
POST/v1/agents/:id/runsアドホック実行開始。?test=1 でテストモード
GET/v1/agents/:id/runs実行履歴 (ワークフローインスタンス履歴)
GET/v1/workflows/:id/instances/:iid/events/stream実行中インスタンス向け SSE イベントストリーム

SSE エンドポイントは Web UI の Run ドロワーと同じものです。 イベントを単一の instance_id で透過的にフィルタリングします。

例: curl で作成

curl -X POST http://localhost:8080/v1/agents \
  -H "Authorization: Bearer $GATEWAY_AUTH_TOKEN" \
  -H "Content-Type: application/json" \
  -d @research-bot.json

# アドホックなテスト実行を起動
curl -X POST "http://localhost:8080/v1/agents/research-bot/runs?test=1" \
  -H "Authorization: Bearer $GATEWAY_AUTH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "input": "summarize recent ETH news" }'

AgentDefinition JSON の例

{
  "id": "research-bot",
  "name": "Daily Research Bot",
  "description": "Morning brief: trending tokens, macro context, watchlist signals.",
  "system_prompt": "You are a markets research assistant. Output a 5-bullet brief covering crypto majors, US equities open, and any flagged watchlist alerts. No advice; observation only.",
  "skill_ids": [
    "analysis.market_overview",
    "research.knowledge_base",
    "minara.core"
  ],
  "tool_names": ["get_price", "get_trending", "search_tokens"],
  "tool_sets": ["market_data"],
  "risk_tier_max": 1,
  "discovery_mode": "constrained",
  "triggers": [
    { "kind": "cron", "expr": "0 9 * * *", "timezone": "UTC" }
  ],
  "metadata": {
    "tags": ["research", "daily"],
    "owner": "[email protected]"
  }
}

注意点:

  • 読み取り専用の市場データのみを参照する cron トリガー付きエージェントには risk_tier_max: 1 (読み取り専用) が適しています。定時エージェントの上限は 既定で tier 2、allow_autonomous_fund_moves を設定すると tier 3 です。 その上限を超えると upsert が拒否されます。
  • discovery_mode: "constrained" は、ランナーがターン中に activate_skills を呼ばないことを意味します。スキル / ツール面は 宣言したとおりになります。
  • tool_sets: ["market_data"] は、そのセット内の全ツールを tool_names ホワイトリストと合わせて追加します。ランナーは合併を取ります。

agent_turn { agent_id } を含むワークフロー JSON

{
  "id": "morning-brief",
  "name": "Morning Brief",
  "version": 1,
  "steps": [
    {
      "id": "step_1",
      "kind": "tool_call",
      "tool": "get_portfolio_snapshot",
      "input": {}
    },
    {
      "id": "step_2",
      "kind": "agent_turn",
      "agent_id": "research-bot",
      "input": {
        "portfolio_summary": "{{ steps.step_1.output }}"
      }
    },
    {
      "id": "step_3",
      "kind": "tool_call",
      "tool": "send_telegram",
      "input": {
        "text": "{{ steps.step_2.output }}"
      }
    }
  ]
}

ワークフロー作者がフローを編成し、research-bot が推論を持ちます。 ステップ 2 が最初に実行されると、エンジンはエージェント定義を workflow_instances.agent_def_snapshot にスナップショットします。 それ以降の research-bot への PATCH は、この実行中インスタンスに 影響しません。新規実行は新バージョンを取得します。

JSON ファイルによる共有

エージェントローダーは起動時に ~/.minara/agents/ (または $MINARA_DATA_DIR/agents/) をスキャンします。AgentDefinition として パースできる *.json ファイルは、source: "file:<絶対パス>" として ストアに登録されます。

ファイル由来の行は PATCH ロック されています。REST / CLI からの更新は 明確なエラーで拒否されます。ディスク上のファイルを編集してから エージェントを再起動 (またはローダー同期エンドポイントを呼ぶ) してください。 これによりファイルが信頼の出所として保たれ、ディスクと DB の間で 静かなドリフトが発生しません。

ファイルを削除すると次回の同期で対応行がアーカイブされます。 そのため、ファイル削除によってそのエージェントを既にスナップショットしている ワークフローが壊れることはありません。

安全姿勢 (まとめ)

  • ランタイムリスククランプ: 非 manual トリガー (cron / event / autopilot) は effective_risk_tier_max を 2 に、allow_autonomous_fund_moves 設定時は 3 に クランプします。クランプは AgentRunner 内、LLM ターン直前、トリガー源の解決後に 実行されます。tier 4 ツールは自律ソースに対してレジストリゲートで常にブロックされます。
  • コンテキストアウェアな資金確認: すべての資金移動ツール呼び出しは 資金確認ゲートを経由します。テスト実行では、ゲートは MINARA_SKIP_FUND_CONFIRM に関係なく 2 段階確認を強制します。 テスト実行で資金が静かに動くことはありません。
  • アーカイブエージェントの fail-closed: アーカイブ済みエージェントへの 手動実行は即座に失敗します。アーカイブ済みエージェントの cron トリガーは 3 回連続でスキップされると自動的に停止されます。実行中の agent_turn ステップは保存済みスナップショットに対して継続します。 アーカイブは未来方向のみの操作です。
  • スナップショット分離: agent_id でエージェントを参照する ワークフローインスタンスは、最初の実行時に定義全体をスナップショットします。 ソースエージェントへの後の PATCH や ARCHIVE は、実行中インスタンスに 影響しません。
  • 監査ログ: 各実行は、要求されたリスク tier、実効 (クランプ済み) リスク tier、トリガー源、ドロップされたスキル / ツールのリストを 監査ログに書き込みます。Web UI は History タブに表示し、CLI は minara agents get <id> の後にインスタンスクエリで取得できます。

handler の契約は Fund-Moving Confirm を、 監査面全体は Audit & Overrides を参照してください。

目次