MINARA
安全

資金確認機制

每個涉及資金移動的工具都經過「預覽再執行」門控。本文介紹其設計原因、覆蓋範圍,以及唯一的例外情形。

你告訴 Agent:"把 100 USDC 兌換成 ETH。"Agent 不會直接執行,而是先彈出一張確認卡片,展示交易細節:

Sell: 100 USDC (Ethereum)
Buy:  ~0.0286 ETH (estimated, 0.5% slippage)
Route: Uniswap V3
Gas estimate: ~$1.20

確認內容符合你的意圖後,點接受。此時 Agent 才會廣播交易。

為什麼 Agent 不直接執行? 因為 LLM 會誤讀輸入。"100 USDC"可能變成"1000 USDC",你輸入的地址可能偏移一個字符,鏈也可能悄悄從 Ethereum 切換到 Base。一旦廣播,這些錯誤都無法撤回。因此,每個涉及資金的工具在結構上都分為兩步:先預覽,再執行。

合約約定

每個涉及資金移動的工具都在 ToolEntry 上聲明 controlPolicy.confirm。控制策略門在工具調用否決點運行預覽、收集同意,然後才把調用交給只負責執行的 handler。這由運行時強制執行,不靠提示詞,也不在 handler 內部。

為什麼用硬約束,而不是提示詞層面的軟性要求? 因為在提示詞注入、惡意技能的障眼法,或 LLM 將惡意工具結果視為指令等情況下,LLM 可能"遺忘"提示詞級別的規則。模型只需帶著操作參數調用一次工具。沒有確認證據時,門返回預覽信封,絕不會發起交易。客戶端渲染確認卡片;模型看不到預覽,也沒有第二次工具調用。

策略定義在 tool-control-policy.ts。 解釋它的鉤子在 tier-gate.ts。 每個新增的涉及資金的工具都必須聲明 controlPolicy.confirm;未聲明的 PR 會被 code review 拒絕。帶 isFundMoving 卻沒有確認路徑的條目會 fail-closed。

覆蓋範圍

工具在工具註冊表中標記為 isFundMoving: true。以下按用途分組列出:

代幣交易

  • swap_tokens:跨鏈 DEX 閃兌
  • buy_token / sell_token:顯式買入 / 賣出
  • transfer_token:錢包到地址的轉賬

永續合約

  • open_perps_position / close_perps_position
  • minara_perps_wallet_sweep:子賬戶間餘額劃轉
  • minara_perps_wallet_transfer:永續合約餘額轉賬
  • minara_wallet_fund_perp:從現貨向永續合約賬戶充值(存入 USDC)

Autopilot:開啟或關閉自動交易

  • minara_autopilot_enable / minara_autopilot_disable

Autopilot 開關屬於資金類操作,因為開啟它即代表操作員授權 Agent 自主交易。一旦啟用,後續每筆 Autopilot 交易均繼承該授權,不會對每筆交易單獨提示確認。

工作流

  • workflow_activate / workflow_deactivate

邏輯相同:激活工作流的那一刻,即代表你批准該自動化流程獨立運行。

Strategy Studio:自有策略

  • strategy-codegen 技能的 deploy.sh

部署是一次性授權,詳見下文策略部署是一次性授權

運行他人創建的策略

  • minara_top_strategies_apply_start:運行精選 Top Strategies 策略

這些操作會使用用戶資金啟動或停止自主交易,且不存在作者授權時機,因此與 Autopilot 一樣走確認門(apply_start / sub_startMANUAL_ONLYsub_stopALWAYS_CONFIRM)。

直接下單到交易所

  • 所有 hyperliquid_* 下單 / 撤單 / 提現接口

如需新增涉及資金的工具,請標記 isFundMoving: true 並聲明 controlPolicy.confirm。未聲明的 PR 會被 code review 拒絕。

實際流程

從 Agent 調用到你點接受:

LLM: swap_tokens({
  sell_token: "USDC",
  sell_amount: 100,
  buy_token: "ETH",
  chain: "ethereum"
})

→ 门:没有确认证据
→ 运行声明的 preview(模拟),以 minara-confirm 信封拦住调用
→ 客户端渲染预览卡片;模型看不到它

你在卡片上点接受

→ 同一次调用进入只负责执行的 handler
→ handler 签名并广播
→ 返回 {tx_hash: "0x...", executed: true}

調用方傳入的 confirm: true 仍可作為交互式同意證據。檢查是寬鬆的(true"true"1"yes""on"),因為部分工具調用協議會把布爾值序列化成字符串。界面路徑並不依賴模型傳入該標誌。

策略部署是一次性授權

策略部署的工作方式有所不同。strategy-codegen 技能的 deploy.sh 在部署時執行一次兩步確認:不帶 --confirm 運行時只打印完整的部署預覽(標的、K 線週期、槓桿、子賬戶、最大回撤上限),你查看後做出一次性決策,再用同一條命令加 --confirm 重新執行。

之後,策略的生命週期腳本(start.shstop.shreconfig.sh)各自走同樣的「預覽 → --confirm」兩步流程,其中 stop 默認會市價平掉未平倉位。這些是對已授權策略的調度操作,而非新的資金移動。

運行他人創建的策略則不同:不存在作者授權時機,因此 Top Strategies 的 minara_top_strategies_apply_start 確實會走確認門,與啟用 Autopilot 的邏輯相同。

為什麼有這個例外? 如果每筆算法交易都需要人工確認,策略就只是手動交易腳本。Strategy Studio 的意義在於在你預先設定的約束範圍內委託執行。部署是你授權策略運行空間的時機;此後,策略受回撤上限、資產配置上限和部署配置中的標的白名單約束,而非逐筆交易的提示詞約束。

這個例外僅適用於 Strategy Studio。不要在其他地方模仿該模式。工具層面的其他部分都走統一確認門。

MINARA_SKIP_FUND_CONFIRM:操作員級旁路

在非交互式場景下,有一個逃生口:環境變量 MINARA_SKIP_FUND_CONFIRM=1(或偏好 safety.skipFundConfirm)會讓確認門把該調用視為已有證據。以下說明何時可用、何時絕對不可用:

合理用途(少數合法場景):

  • 回測。 調用方是 Python 測試框架,沒有人工讀取預覽,且運行環境已針對歷史數據進行沙盒隔離。
  • 工作流引擎執行。 工作流已在激活時獲得批准,執行循環是在已授權工作流上調度,而非要求用戶逐步確認。
  • CI 冒煙測試。 目的就是驅動涉及資金的路徑並驗證接口調用。

絕對不可用的場景:

  • 交互式 REPL 會話。 這會繞過保護你的最後一道防線。
  • "每次確認太煩了"的生產環境。 這等於把安全機制關掉。
  • Shell rc 文件。 不要把 export MINARA_SKIP_FUND_CONFIRM=1 寫進 .zshrc 後忘掉。下次啟動 Agent 時,它將在無防護狀態下運行。

完整的環境變量參考文檔見 環境變量 → MINARA_SKIP_FUND_CONFIRM

第 3 層與第 4 層各自攔截什麼

最常見的疑惑:攔截行為屬於第 3 層(本頁)還是第 4 層(腳本風險閘門)?快速參考如下:

你的請求攔截層
"把 100 USDC 兌換成 ETH"(直接交易請求)第 3 層:控制策略門先預覽,再確認
運行包含 subprocess.run(["minara","swap",…]) 的 Python 腳本第 4 層:腳本風險閘門檢測到涉及資金的 CLI 調用,觸發 YELLOW 提示
terminal 中運行 cast send 0x… 1ether第 4 層:閘門檢查 shell 命令,觸發 YELLOW 提示
修改文件,導致其內容包含 minara swap第 4 層:閘門掃描應用後的內容,觸發 YELLOW 提示
通過 codegen 技能的 deploy.sh 部署策略腳本級兩步確認:不帶 --confirm 只出預覽,帶上才執行;後端風控層兜底

簡而言之:第 3 層攔截 Agent 直接發起的涉及資金的工具調用;第 4 層攔截 Agent 運行的腳本和命令中包含的涉及資金的代碼。 兩者覆蓋同一威脅的不同維度,並行運作。

操作員檢查清單

  • ✅ 看到預覽時,務必仔細閱讀。核對目標地址、鏈、金額和滑點是否與你的意圖一致。兩步確認的存在,也是為了讓你發現自己的失誤。
  • ✅ 部署策略時,仔細審查部署配置。這是唯一一次被要求確認的機會。
  • ✅ 激活工作流時,在點擊確認前從頭到尾閱讀工作流定義。後續執行不會再次詢問。
  • ❌ 不要在交互式 REPL 會話中設置 MINARA_SKIP_FUND_CONFIRM=1,也不要寫入 .zshrc.envrc
  • ❌ 不要接受你沒讀過的預覽。確認依賴的是你的判斷,而非 Agent。

本頁目錄