MINARA

自定义 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 相同的 进程内本地执行,共享同一份技能目录,继承同一组安全边界。 它们不是沙箱化的第三方运行时。

自定义 Agent 流程:保存的定义由触发器触发,运行时收紧其风险上限,在资金确认门后于共享 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_idstool_names

新建 agent 默认 free_discovery:和主助手一样,agent 自行发现所需技能, Web UI 向导无需你预先勾选。工具由所选技能加上 risk_tier_max 上限决定, 因此 tool_namestool_setsdiscovery_skill_pool 是高级字段,只能通过 JSON 文件加载或 HTTP API 设置,不在向导里暴露。

constrained

硬白名单。Runner 完全按照声明的 skill_ids 激活, 完全按照声明的 tool_names(与 tool_sets 的并集取交集)暴露工具。 activate_skills 元工具被禁用,LLM 无法在中途自我扩展。

生产可靠性场景请选这个。Agent 每次都按同样的形状运行。 易于审阅、易于测试、易于做预算。

scenario_aware

为向后兼容保留,当前行为与 constrained 完全一致。 原先按提示词预加载技能的场景分类器已下线,因此该模式只运行声明的 skill_idsactivate_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 子命令暴露完整生命周期。

动作形式用途
listminara agents list [--archived]列出每一个已注册的 Agent
getminara agents get <id>以 JSON 形式打印完整 definition
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]启动一次 ad-hoc 运行;事件流到 stdout
exportminara agents export <id>打印 JSON,方便管道写入文件
importminara 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:startedworkflow: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 查询拿到。

资金动作 handler 契约参见 资金动作确认。 完整审计面参见 审计与覆盖

本页目录