自定義 Agent
系統提示詞、技能、工具、風險上限和觸發器的可保存組合,可通過 CLI、REPL、HTTP、Workflow 和 cron 運行
🟢 可配置:自定義 Agent 是一個配方,不是獨立的運行時。 它運行在同一個 agent 循環、同一個技能註冊表、同一個資金確認閘門上, 與 REPL 會話完全一致。
自定義 Agent (Custom Agent) 是一份保存好的組合:
- 一段
system_prompt(Agent 運行時的指令) - 一份
skill_ids子集(runner 激活哪些 DomainSkill) - 一份
tool_names+tool_sets子集(runner 暴露哪些工具) - 一個
risk_tier_max上限(1 只讀 → 4 僅手動)。Web UI 嚮導把它呈現為三檔 :: 只讀、不動資金、可動資金 :: 其中"可動資金"再分 tier 3(確認制現貨:swap、buy、sell)或 tier 4(全部資金操作,含永續、提現、autopilot)。定時和事件觸發的 agent 無法動用資金,且每次資金操作仍需確認。 - 一個
discovery_mode(runner 自我擴展的激進程度) - 一組
triggers(manual、cron、event) - 自由形式的
metadata
這份組合持久化到 SQLite 的 agent_definitions 表。
你可以從 REPL /agents run、CLI minara agents run、HTTP
POST /v1/agents/:id/runs、Web UI 的 Run 抽屜、workflow 步驟
(agent_turn { agent_id }),或 cron / event 觸發器運行它。
自定義 Agent 在概念上更接近 Claude Code subagents, 而不是 Anthropic 的 Managed Agents API。它們在與主 agent 相同的 進程內本地執行,共享同一份技能目錄,繼承同一組安全邊界。 它們不是沙箱化的第三方運行時。
運維者為什麼想要它
- 複用:把一個高頻任務編碼一次。"每日 ETH 早報"、 "每週組合復盤"、"鏈上流入監控",每一個都是命名 Agent, 一鍵啟動。
- 限定工具面:研究型 Agent 只需要只讀技能(不需要
swap_tokens)。 財庫型 Agent 只需要 Hyperliquid 永續。 技能集越小,系統提示詞越緊湊、無關工具調用越少、每輪 token 成本越低。 - 觸發器:掛上
cron: "0 9 * * *"的 Agent 每天早晨自動運行, 無需運維干預。掛上event: { event_name: "price.alert" }的 Agent 在事件總線發佈匹配事件時觸發。 - 可被 Workflow 編排:多步 workflow 可以引用
agent_turn { agent_id: "research-bot" }, 不必把研究提示詞內聯進去。Workflow 作者擁有流程, Agent 擁有推理。 - 可分享:把一個 JSON 文件丟進
~/.minara/agents/, 下次啟動時 loader 會拾起。把你的research-bot導出給隊友, 對方實例加載後source: "file:..."。
三種 discovery 模式
discovery_mode 控制 runner 在執行時如何對待 skill_ids 和 tool_names。
新建 agent 默認 free_discovery:和主助手一樣,agent 自行發現所需技能,
Web UI 嚮導無需你預先勾選。工具由所選技能加上 risk_tier_max 上限決定,
因此 tool_names、tool_sets、discovery_skill_pool 是高級字段,只能通過
JSON 文件加載或 HTTP API 設置,不在嚮導裡暴露。
constrained
硬白名單。Runner 完全按照聲明的 skill_ids 激活,
完全按照聲明的 tool_names(與 tool_sets 的並集取交集)暴露工具。
activate_skills 元工具被禁用,LLM 無法在中途自我擴展。
生產可靠性場景請選這個。Agent 每次都按同樣的形狀運行。 易於審閱、易於測試、易於做預算。
scenario_aware
為向後兼容保留,當前行為與 constrained 完全一致。
原先按提示詞預加載技能的場景分類器已下線,因此該模式只運行聲明的
skill_ids,activate_skills 禁用。已有 agent 保留此值;新建 agent
請選 constrained。
free_discovery(默認)
從聲明的種子集合起步,LLM 可以在中途調用 activate_skills 加技能。
受 discovery_skill_pool glob 模式(為空 / 缺失則全目錄)約束,
受 risk_tier_max 鉗制。
請節制使用。它把整個技能目錄作為解空間交給 Agent, 對開放式研究很強,對窄而重複的任務卻脆弱。
三種模式都遵守的安全不變量
risk_tier_max在 觸發時 由 runner 強制執行, 不只是在 upsert 時。就算你直接在 DB 裡UPDATE agent_definitions SET risk_tier_max = 4,cron / event / autopilot 觸發依然會 把有效上限鉗到 2。- 資金確認門會讀取 Agent 運行的上下文。測試運行強制走兩步確認,
哪怕環境裡設置了
MINARA_SKIP_FUND_CONFIRM=1。 - 歸檔 Agent 走 fail-closed。任何在飛的
agent_turn步驟 若引用了已歸檔的 Agent,繼續按已保存的 snapshot 運行; 而新提交的運行如果對應 Agent 已歸檔,立即失敗。
觸發器
每個 Agent 有一組 triggers。v1 支持四種類型。
| 類型 | 形狀 | 何時觸發 |
|---|---|---|
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 毫秒)。只觸發一次,隨後 Agent 自動歸檔 |
安全規則:默認情況下,任何非 manual 的觸發器在 upsert 時強制
risk_tier_max ≤ 2,因此定時 / 事件 agent 無法動用資金。agent 可以選擇開啟
自主資金操作(allow_autonomous_fund_moves: true,且同一次寫入需帶
confirm_autonomous_fund_moves: true),這會把非 manual 的上限抬到
≤ 3(確認制現貨交易)。tier 4(永續、提現、autopilot)始終需要手動觸發,
確保它們觸發時人在環裡。超出上限的寫入會被 store 以清晰錯誤拒絕。
once Agent 就是提醒的實現方式。它只觸發一次,然後歸檔,不再觸發。恢復一個
已觸發的提醒不會重放它。請重新排期(設置新的 fire_at)或手動運行。要做週期
提醒,改用 cron 觸發器。
通知
一次運行結束後,Minara 有兩種方式告訴你。
站內通知中心。 右上角的鈴鐺會顯示未讀數和最近的 Agent 運行列表,每條都 鏈接到對應的那次運行。它一直開著、實時更新,並保留一小段可標記已讀或清空的 歷史。
瀏覽器通知。 在 設置 → 通用 裡(或鈴鐺上的快捷開關)打開「瀏覽器通知」, 當 Minara 標籤頁在後臺或被最小化時,就能收到一條系統桌面通知。當你正看著 Minara 標籤頁時,提醒會改為以站內消息的形式出現。瀏覽器首次會詢問權限。一旦 你關閉標籤頁或退出瀏覽器就收不到了,並且頁面需要安全上下文(HTTPS),localhost 例外。
哪些運行會通知。 Agent 自己發起的運行會通知:定時(cron)、事件(event)、
一次性提醒、以及 workflow 步驟。你自己發起的運行不會通知(Run 按鈕、
/agents run、聊天對話),因為你已經在看著它了。測試運行永遠不通知。
按 Agent 控制。 每個 Agent 都有一個「站內通知」設置。可以為話癆 Agent 關掉, 或只在運行失敗時通知。新建的 Agent 默認開啟。
引用 Agent 的 Workflow
Workflow 的 agent_turn 步驟有兩種形態:
// 推荐:按 id 引用已有的自定义 Agent
{ "kind": "agent_turn", "agent_id": "research-bot",
"input": { "ticker": "ETH" } }
// 旧式回退:inline goal,引擎临时拉起一个一次性 Agent,
// 不带任何 scoped 的技能 / 工具子集
{ "kind": "agent_turn", "goal": "summarize recent ETH news" }何時用 agent_turn { agent_id } 而非 tool_call
需要推理、多工具探索、自然語言輸出時用 agent_turn:
研究、起草、分類、總結。
輸入已知、動作確定的單步操作用 tool_call:
一次 swap、一次 transfer、一次餘額查詢、一次價格抓取。
工具調用更快、更便宜,且不必讓一輪 LLM 重複 confirm 上下文,
繼續沿用既有的資金確認閘門。
一個"先做空 ETH,再寫策略復盤"的 workflow 拆成兩步:
執行用 tool_call { tool: "open_perps_position" },
復盤用 agent_turn { agent_id: "strategy-note" }。
本地自動化技能會自動遵守這套矩陣。
它會暴露自定義 Agent 目錄,把"起草"/"研究"/"總結"意圖路由到
agent_turn,把資金動作意圖路由到 tool_call。
CLI
minara agents 子命令暴露完整生命週期。
| 動作 | 形式 | 用途 |
|---|---|---|
list | minara agents list [--archived] | 列出每一個已註冊的 Agent |
get | minara agents get <id> | 以 JSON 形式打印完整 definition |
create | minara agents create --from <file.json> | 從 JSON 文件插入 |
update | minara agents update <id> --from <patch.json> | PATCH;實質改動時遞增 version |
archive | minara agents archive <id> | 軟刪除;卸載所掛的觸發器 |
run | minara agents run <id> [--input "..."] [--test] | 啟動一次 ad-hoc 運行;事件流到 stdout |
export | minara agents export <id> | 打印 JSON,方便管道寫入文件 |
import | minara agents import [--from <file.json>] | export 的逆操作;缺 --from 時讀 stdin |
run 同步打開一個事件流,直到 workflow 完成或失敗,
然後打印最終的 __adhoc__ 輸出 payload。可直接餵給 cron / shell 腳本。
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 | 列出每一個已註冊的 Agent |
/agents create | 交互式 collectArgs 流程:名字 → 系統提示詞 → 技能挑選 |
/agents run [<id>] [<input>...] | 運行一個 Agent;缺 <id> 時彈出實時選擇器 |
/agents archive [<id>] | 歸檔;缺 <id> 時彈出實時選擇器;y/N 確認 |
/agents create 流程走標準的
collectArgs
模式:必填字段一字段一字段地提示;校驗失敗時只重問壞字段;
連續三次空回答取消。
Web UI
Web UI 在 AUTOMATE 導航組下的 /agents 路由列出自定義 Agent
(和 Workflows、Autopilot 並列)。請打開 Web UI 的 /agents。
- 列表頁:每個 Agent 一張卡,含名字、風險上限、discovery 模式、 觸發器摘要,以及每卡的 Run / Edit / Archive 動作。 Import 按鈕接收 JSON 文件上傳,New 按鈕打開向導。
- 嚮導(3 步):第 1 步挑模板(researcher / treasury sentinel / drafting)或"空白"。第 2 步起名、寫系統提示詞、挑技能(只有 硬白名單模式才顯示選擇器)。第 3 步選 discovery 模式、風險上限、觸發器類型, 安全鉗制規則就地顯示。
- 詳情頁:Overview / Definition / History 三個 tab。
Definition tab 顯示當前 JSON;PATCH 編輯會原子地遞增
version。 - Run 抽屜:從列表卡或詳情頁打開。內嵌 SSE 事件流顯示
workflow:started→workflow:step事件 → 終態workflow:completed/workflow:failed。Run as test (?test=1) 是 一個 checkbox;測試運行在環境變量配了 skip 的情況下,依然會彈出資金確認 modal。
REST 端點
HTTP gateway 為非 CLI 集成暴露同一組接口。
| 方法 | 路徑 | 用途 |
|---|---|---|
GET | /v1/agents | 列出 definition(?archived=true 僅返回已歸檔) |
POST | /v1/agents | 創建:body 是一個 AgentDefinitionInput |
GET | /v1/agents/:id | 拿最新 definition |
PATCH | /v1/agents/:id | 更新;body 是部分 AgentUpdatePatch |
DELETE | /v1/agents/:id | 歸檔(軟刪除,可恢復) |
POST | /v1/agents/:id/restore | 恢復已歸檔的 agent(重新掛載觸發器) |
DELETE | /v1/agents/:id/permanent | 永久刪除(不可逆;運行歷史保留) |
POST | /v1/agents/:id/runs | 啟動 ad-hoc 運行;加 ?test=1 進入測試模式 |
GET | /v1/agents/:id/runs | 列出歷史運行(workflow 實例歷史) |
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
# 启动一次 ad-hoc 测试运行
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 觸發 Agent 適合用
risk_tier_max: 1(只讀)。 定時 agent 默認上限為 tier 2,開啟allow_autonomous_fund_moves後為 tier 3。超出該上限的寫入會在 upsert 時被拒。 discovery_mode: "constrained"意味著 runner 不會在中途調用activate_skills。技能 / 工具面就是聲明的樣子。tool_sets: ["market_data"]把該集合裡的每個工具疊加進tool_names白名單。Runner 取並集。
包含 agent_turn { agent_id } 的 Workflow 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 }}"
}
}
]
}Workflow 作者編排流程;research-bot 擁有推理。
第 2 步首次執行時,engine 把 Agent definition 快照寫入
workflow_instances.agent_def_snapshot。
之後對 research-bot 的 PATCH 不影響這個在飛實例。
新提交的運行才拿到新版本。
基於 JSON 文件的分享
Agent loader 在啟動時掃描 ~/.minara/agents/
(或 $MINARA_DATA_DIR/agents/)。每一個能解析成 AgentDefinition
的 *.json 文件,都會落入 store,source: "file:<绝对路径>"。
文件來源行是 PATCH-locked 的:REST 和 CLI 的更新會被以清晰錯誤拒絕。 請在磁盤上改文件,然後重啟 agent(或調用 loader 同步端點)以拾起改動。 這保證文件始終是來源真相,磁盤與 DB 之間不會悄悄漂移。
刪除文件會在下一次同步時歸檔對應行,所以刪文件不會破壞已經 為該 Agent 做過快照的 workflow。
安全姿態(彙總)
- Runtime 風險鉗制:非 manual 觸發器(cron、event、autopilot)
會把
effective_risk_tier_max鉗到 2,開啟allow_autonomous_fund_moves後鉗到 3。鉗制在 AgentRunner 裡、LLM 一輪開始之前、觸發源解析之後立即執行。 tier 4 工具在註冊表門處對自主來源始終被攔截。 - 上下文感知的資金確認:每一次資金移動工具調用都路由經過資金確認門。
測試運行時,無論
MINARA_SKIP_FUND_CONFIRM怎麼配, 確認門都強制走兩步確認。測試運行不會悄悄動錢。 - 歸檔 Agent fail-closed:對已歸檔 Agent 的手動運行立即失敗。
掛在已歸檔 Agent 上的 cron 觸發器連續 skip 三次後,
自動停用觸發器。在飛的
agent_turn步驟按已保存的 snapshot 繼續。 歸檔只對未來生效。 - Snapshot 隔離:通過
agent_id引用 Agent 的 workflow 實例, 在首次執行時把完整 definition 做成 snapshot。 之後對源 Agent 的 PATCH 或 ARCHIVE,對任何在飛實例都沒有影響。 - 審計日誌:每一次運行都向審計日誌寫入請求的風險 tier、
生效(鉗制後的)風險 tier、觸發源,以及被丟掉的技能 / 工具列表。
Web UI 在 History tab 暴露這些;CLI 可以通過
minara agents get <id>加一次 instance 查詢拿到。