スキルシステム
ルーティングとアクティベーションの仕組みと、利用可能なスキルの全カタログ
スキルは Minara Agent の機能単位です。各スキルには、プロンプトフラグメント、ツールのホワイトリスト、そしてルーターが「いつ関連するか」を判断するためのメタデータ群が含まれています。スキルは発見と playbook の入口です。起動すると、そのドメインのツールが表に出て、それらを使うためのガイダンス(いつどのツールを使うか、あるワークフローの背後にある方法論、その土台となる領域理論)が読み込まれます。これはツールの認可ゲートではありません。通常のセッションでは登録済みのツールはすべて直接呼び出せます。スキルのロードは、適切なツールを見つけて playbook を読むのを助けるだけです。Agent が必要に応じてロードするプラグインとお考えください。
MCP を使わない理由 Minara は、コア機能に独自のスキル・ツールレジストリを使用しており、MCP は採用していません。金融ツールには、呼び出しごとのパーミッションティア、型付きスキーマ、そして MCP の仕様ではカバーできない資金移動の確認ゲートが必要なためです。外部プロバイダーは引き続き MCP サーバー経由で統合されます。詳しくは Custom MCP をご覧ください。
このページでは、ルーティングとアクティベーションの仕組みと、Agent が起動できるすべてのスキルのカタログを説明します。
実際の動作例: 機能 の各ページには、起動されるスキルへの参照が含まれています。スキルのインストール では、外部スキルをベンダリングするユーザー向けの手順を説明しています。
3 つのレイヤー
上の図は、決定論的な L0 ルーター、非決定論的な LLM アクティベーションステップ、決定論的なツール呼び出し層から成るルーティングパイプラインを示しています。
L0 ルーターは決定論的です。同じ入力は常に同じカタログを生成します。LLM の activate_skills 呼び出しだけが非決定論的なステップです。ツール呼び出し層(呼び出しごとのパーミッションティアと資金移動の確認)は再び決定論的で、スキルが起動されるときではなくツールが呼び出されるときに実行されます。つまり、パイプラインの両端は LLM なしでテスト可能です。これは意図的な設計上の選択です。
L0 ルーティング: 決定論的プレフィルター
apps/agent/src/skills/router.ts の buildRoutedCatalog() は、TurnRoutingContext を受け取り、登録済みの全スキルにスコアを付けます。
| シグナル | スコア |
|---|---|
| ユーザーメッセージのキーワードヒット | +30 ずつ、上限 +60 |
| ライフサイクルステージの一致 | +20 |
| アセットクラスの一致 | +15 |
別のヒットからの co_activate | +10 |
| シグナルソースの一致(cron ターン) | +25 |
| フォールバック(優先度タイブレーカー) | 100 - priority |
| ネガティブキーワードヒット | −∞ |
conditions の不一致 | −∞ |
-∞ のスコアになったスキルはカタログから完全に除外され、LLM には表示されません。conditions はグレースフルデグラデーションの調整ノブです。
conditions: {
requires_env: ["GLASSNODE_API_KEY"], // skill hidden without key
requires_tools: ["glassnode_metric"], // skill hidden without tool
requires_toolsets: ["documents"],
fallback_for_tools:["web_extract"], // only surface when web_extract absent
platforms: ["darwin", "linux"], // hide on Windows
}出力される RoutedCatalogEntry[] には、スキルがスコアを得た理由(例: ["kw:buy", "stage:decide"])が含まれています。レジストリの buildCatalogFor() は、これをカタログブロック内のインラインヒントとして LLM 向けにレンダリングします。
アクティベーション: メイン LLM が判断する
ベースのシステムプロンプトは常に、1 つのメタツールを公開しています。
activate_skills(ids: string[], confirmed?: boolean)LLM はルーティング済みカタログを読み込み、リクエストに合致するスキルを選択して activate_skills(["minara.core", "memory-personal"]) を呼び出します。ツールハンドラーは SkillSession.activate() を呼び出し、それらのスキルの playbook とツールヒントをプロンプトにロードします。アクティベーションがユーザーに確認を求めることはなく、リスクゲートも実行しません。安全性の強制はすべてツール呼び出し層にあります(下記参照)。
仕組みとしては、ロード済みのセットは直近の activate_skills 呼び出しで渡した内容そのものなので、新たな呼び出しは直前のセットを置き換えます。これによりプロンプトサイズが有界に保たれます。これはツールゲートではありません。ベースラインのツール群(activate_skills、get_price、search_tokens、memory_*、todo など、apps/agent/src/skills/session.ts の DEFAULT_ALWAYS_INCLUDE_TOOLS セット)はスキルが何も起動していなくても毎ターン呼び出せ、メインセッションでは他の登録済みツールも tool_invoke で直接到達できます。アクティベーションは発見と playbook のテキストに関するもので、認可ではありません。
常時アクティブなスキルはありません。アイデンティティ、安全性の不変条件、言語ポリシー、markdown のワイヤープロトコルは、キャッシュされたシステムプロンプトスケルトン(apps/agent/src/core/system-prompt-skeleton.ts)にあり、毎ターンのプレフィックスに焼き込まれます。
安全ゲートが実際にある場所
スキルのアクティベーションは何も確認しません。資金移動と高リスクのゲートはツール呼び出し層、apps/agent/src/tools/_security/tier-gate.ts にあり、各ツールの permissionTier をキーにします。
| ティア | 挙動 |
|---|---|
READ_ONLY | 即座に実行 |
CONFIRM_ONCE | 初回使用時に確認し、以降はセッション中記憶する |
ALWAYS_CONFIRM | 毎回確認。自律的な呼び出しには保存済みの許可が必要 |
MANUAL_ONLY | 明示的な承認が必要。自律的な呼び出しは拒否される |
ゲートはスキルではなくツールをキーにしているため、ツールがどう発見されたかに関わらず成立します。侵害されたツール出力が activate_skills 呼び出しをエコーしても資金を動かせません。アクティベーションは playbook のテキストをロードするだけで、実際のトレードツールは完全な引数コンテキストとともにティアゲートに到達します。hook チェーンの詳細は Agent Loop ページで説明します(Agent ループ を参照)。
ライフサイクルステージ
ルーターはユーザーメッセージからライフサイクルステージを推定します。
| ステージ | トリガーとなる表現 |
|---|---|
discover | "what's trending"、"show me"、"price of" |
evaluate | "should I"、"analyze"、"compare"、"risk" |
decide | "buy"、"sell"、"long"、"short"、"swap" |
manage | "close"、"stop loss"、"my positions" |
ステージはルーティングに使われ(ステージの一致はスキルのカタログスコアを高めます)、ツール呼び出し層にコンテキストを与えます(discover ターンでの自律的なソースは、ティアゲートが実行する内容を厳しくします)。ステージはどのスキルが起動できるかをもはや制限しません。トレードの境界はツールティアが守るため、無害に見える質問にトレード呼び出しを紛れ込ませても、実行時に確認ゲートに到達します。
シグナル: cron と Webhook のターン
cron の実行や Webhook の配信は、SignalContext を構築します。
{
source: "cron",
signal_id: "btc_drop_5pct",
asset: { symbol: "BTC", asset_class: "crypto_major" },
severity: "warn",
preload_skills: ["market.watch", "memory.alerts"],
suggested_stages: ["evaluate"],
trace_id: "t_abc123",
}preload_skills は、LLM が activate_skills を呼び出すのを待たずに、指定した ID を起動するようルーターへのヒントとして機能します。プリロードは playbook のテキストをロードするだけで、ツール呼び出し層のティアゲートを迂回しません。そのため自律的な cron や Webhook のターンも実行時には制約されます。cron ソースから MANUAL_ONLY ツールを呼び出すと、そのまま拒否されます。セッション実行環境の placement(Preferences computer.backend)がチャットのシェル / ファイル / execute_code を固定します。モデル側の呼び出しごとの environment 上書きはありません。trace_id は WorkflowInstance、SkillAuditRecord、ツール実行ログを横断して引き継がれるため、「14:03 の BTC アラートが何をしたか」は SQL クエリ 1 本で追跡できます。
優れたスキルを書くために
ビルトインスキルから蓄積された具体的なガイダンスです。
- プロンプトフラグメントは 800 token(約 3 KB)以内に収めてください。 長いプロンプトはキャッシュ可能なカタログブロックを圧迫し、すべてのターンを遅くします。
descriptionは具体的に(80 字以内)。LLM はスキルをdescriptionで選択します。プロンプト本文はアクティベーション後にしか参照されません。「Perps: open, close, monitor positions on Hyperliquid」は良い例です。「Trading stuff」は不十分です。- 常時アクティブなスキルはありません。 毎ターン実行すべき内容(アイデンティティ、安全性、markdown プロトコル)は、スキルではなく
core/system-prompt-skeleton.tsに属します。 - スキルではなく各ツールの
permissionTierを正確に設定してください。 リスクはスキルではなくツールにあります。確認を 1 回省くために資金移動ツールを低いティアにタグ付けしないでください。レビューで指摘されます。 - 外部プロバイダーには必ず
conditions.requires_envを宣言してください。 キーがない開発マシンでは、レジストリがスキルを自動的に非表示にします。これが正しい動作です。 tool_namesは最小限に。 スキルが実際に使うツールだけを列挙してください。20 個のツールを持つスキルは、たいてい 2 つのスキルが 1 つのふりをしています。
参考実装(SKILL.md パッケージ):
- ツール中心のスキル:
minara-perps/ - プロンプト中心のスキル:
deep-research/ - 方法論レンズのスキル:
analysis/
外部スキル
apps/agent/src/skills/external/ には、ベンダリングされたサードパーティの SKILL.md パッケージが格納されています。minara skills add <git-url> で追加する際の処理は次のとおりです。
- リポジトリを
apps/agent/src/skills/external/<id>/にクローンします。 - ライセンスを検出し、
.minara-skill.jsonに記録します。 - プロプライエタリライセンスのコンテンツは追加を拒否します(過去の事例: Anthropic のオフィススキル)。
- 起動時に
buildExternalDomainSkills()を通じて、SKILL.md フロントマターからDomainSkillを構築します。
外部スキルは完全に第一級市民として扱われます。ビルトインスキルと同じレジストリとルーターを経由し、そのツールは同じツール呼び出しのティアゲートに到達します。別のコードパスは存在しません。
スキルカタログ
すべての組み込みスキルと外部スキルの完全なカタログはリファレンスに あります。各スキルの SKILL.md から自動生成されるため、コードと乖離 することがありません。
同じ機能が両方の形式で存在する場合は、組み込みスキルを優先します。 バイナリに同梱され、CI で型チェックされ、社内ツールレジストリを直接 呼び出します。組み込みが必要なプロバイダーをカバーしていない場合や、 リリースを待たずに上流の SKILL.md 更新を取り込みたい場合は、外部スキルを使います。
スキルシステムは、Minara Agent の資金安全モデルがもっとも可視化される場所です。資金を動かすスキルを追加する場合は、コードを書き始める前に、パイプライン全体(L0 スコアリング、LLM のアクティベーション意図、そして確認フローを実行するツール呼び出しのティアゲート)を確認してください。設計上のミスはここで見つけるほうが、誤ったトレードの後に修正するよりもはるかにコストが低くなります。