关于 multica-creating-agents
此 Multica 技能说明 Agent 创建路径中的字段校验、存储和运行时读取规则,面向需要检查或配置 Agent 的操作者。内容基于源码追踪,并提供只读检查命令。
主要功能
- 01说明 CLI 与 API 创建入口
- 02解释字段校验、默认值和持久化
- 03区分目录描述与运行指令
- 04记录复制 Agent 时的字段规则
- 05提供只读状态检查命令
适用场景
- 01创建 Agent 前核对所需字段与限制
- 02检查已保存的 Agent 配置和技能绑定
- 03复制 Agent 并确认哪些配置会继承
MCP 相关
说明 Agent 的 mcp_config 如何传给运行时及其读取时的脱敏行为。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ multica-ai/ multica --skill multica-creating-agents安装后在 Claude Code 中输入/multica-creating-agents确认已加载。
附带文件references/creating-agents-source-map.md
详细介绍
创建 Multica Agent
这是 Multica 的 Agent 创建路径的契约:创建入口接受什么、服务端校验和拒绝什么、每个字段如何持久化,以及守护进程在领取任务时实际读取哪些字段。这不是参数手册——它陈述的是经源码追踪的事实,且每条论断都有 references/creating-agents-source-map.md 中的 file:line 作为依据。
快速开始(只读检查)
这些命令只读取状态,没有任何副作用:
multica agent get <agent-id> --output json # full persisted agent record
multica agent skills list <agent-id> --output json # current skill bindings
multica agent env get <agent-id> --output json # plaintext env (agent owner or ws owner/admin; agents denied)
Agent 也可以处于 未绑定 状态:在其运行时被删除后,runtime_id 为 NULL(以 "" 提供,并带有 runtime_bound: false),删除运行时会解除绑定而不是删除其 Agent(MUL-5559)。未绑定的 Agent 会保留其拥有的全部内容并保持可编辑,但没有任何触发路径会运行它——它们都会以 agent_runtime_required 拒绝——直到 agent update <id> --runtime-id <runtime-id> 将其重新绑定。未绑定与已归档是两个正交的概念。
agent get 返回持久化的 Agent,包括 runtime_id、model、thinking_level、service_tier、custom_args、has_custom_env、custom_env_key_count 和 skills。它绝不返回明文 custom_env。
核心模型
Agent 是工作区范围内的一行(表 agent)。创建是单次 POST /api/agents(multica agent create)。在任务领取时,守护进程会重新读取 Agent 行并组装运行时载荷——因此 Agent 运行所依据的是持久化的字段,而非创建时的输出。
有两个不同的文本字段,常被混淆:
description是目录摘要。它会被存储并显示在列表中;守护进程不会将其注入 Agent 的运行时提示词。仅将其视为面向人的元数据。上限为 255 个 Unicode 码点。instructions是运行时行为契约。守护进程在领取任务时读取它,并将其作为 Agent 的持久指令发送给提供方。人设、职责、边界、输出和升级规则放在这里,而不是放在description中。
命令行 / API 入口点
最小创建调用(--name 和 --runtime-id 均为必填):
multica agent create --name <name> --runtime-id <runtime-id> \
--description "<short catalog summary>" \
--instructions "<runtime behavior contract>" \
--output json
runAgentCreate 构建一个 JSON 请求体并 POST 到 /api/agents。它仅在其标志被提供时才添加键——description/instructions 在值非空时添加,其余(runtime-config、custom-args、model、thinking-level、service-tier、visibility 等)在标志为 Changed 时添加——因此省略的标志会落到服务端默认值,而不是发送空字符串。--max-concurrent-tasks 在发送请求前会按 1–50 进行校验。
HTTP 请求体(CreateAgentRequest)接受:name、description、instructions、conversation_starters、avatar_url、runtime_id、runtime_config、custom_env、custom_args、model、thinking_level、service_tier、visibility、max_concurrent_tasks、mcp_config、skill_ids。
请求体接受的内容比命令行暴露的更多。conversation_starters 没有对应的 agent create / agent update 标志——命令行只能通过 agent copy 携带它。为新 Agent 设置它意味着要么直接调用 /api/agents,要么告诉用户改用 Web UI;关于他们在哪里能找到它,见下文。
复制 Agent
multica agent copy <source-agent-id> 将现有 Agent 的可移植配置复刻为一个全新的 Agent,源 Agent 保持不变。它是 Web 端“Duplicate”操作的 CLI/无头等效实现。此过程不涉及专用服务端 API:runAgentCopy 通过 GET /api/agents/<id> 读取源 Agent,然后 POST 一个 CreateAgentRequest —— 在 skill_ids 中传入源 Agent 的技能 id,使绑定在同一次创建事务中建立(不同于 agent create,后者不绑定任何内容)。因此该变更是一次单独的原子创建。
multica agent copy <source-agent-id> --name "My Agent (copy)" # same runtime
multica agent copy <source-agent-id> --runtime-id <target> --model <model> # cross-runtime fork
- 默认复制且无专用覆盖标志:
conversation_starters。 - 默认复制,且各自可通过对应标志覆盖:
name(追加后缀" (copy)")、description、instructions、头像、custom_args、max_concurrent_tasks、调用权限(permission_mode+ 允许列表),以及已分配的工作区技能。 - 仅当源值在 1–50 范围内时,才会复制
max_concurrent_tasks。历史上超出范围的值会被省略,使新 Agent 获得服务端默认值(6);显式的超出范围--max-concurrent-tasks覆盖会在任何 API 请求之前被拒绝。 - 运行时相关字段(
model、thinking_level、service_tier)仅在目标运行时不变时复制。--runtime-id选择了不同的运行时会丢弃这些字段,并且必须提供--model(传入--model ""以接受目标运行时默认值),与 Web 端 Duplicate 在切换运行时清空模型的行为一致。 - 永不复制:
custom_env、mcp_config、runtime_config(属于密钥/本机本地数据;读取时本就会被隐去或掩码)。请使用与agent create相同的密钥安全标志(--custom-env*、--mcp-config*、--runtime-config)提供新值,或在复制完成后使用agent env set设置。 --no-skills会跳过复制源 Agent 的技能绑定。
字段契约
| 字段 | 持久化为 | 是否校验? | 由谁使用 |
|---|---|---|---|
name | agent.name | 必填,为空时返回 400 | 列表、运行时负载 |
description | agent.description | 超过 255 个码点时返回 400 | 仅用于目录/列表 — 不用于运行时提示词 |
instructions | agent.instructions | 无 | 守护进程 → 在认领时提供给提供方 |
conversation_starters | agent.conversation_starters(JSON 数组) | 最多 3 项;每项需要一个标签(≤80 个码点)和提示词(≤4000 个码点) | 仅用于面向用户的 Chat 空状态;选择一项会预填输入框,不会启动运行 |
avatar_url | agent.avatar_url | 无;显式非空值会被保留,而省略/空值会创建一个随机的 emoji:<glyph> 头像 | 仅用于目录/列表 UI — 不用于运行时提示词 |
runtime_id | agent.runtime_id(可为空) | 创建时必填(400)+ 必须解析为此工作区中的运行时 | 选择运行时/提供方;NULL 表示未绑定 — 见下文 |
model | agent.model(可为空) | 除运行时支持外无其他校验 | 守护进程读取;为空 = 运行时默认值 |
thinking_level | agent.thinking_level(可为空) | 提供方级别的枚举/安全令牌门控;未知字面量 → 400。Pi 仅接受 `off | minimal |
service_tier | agent.service_tier(可为空) | 仅 Codex 的安全令牌;其他提供方拒绝;守护进程检查显式 standard 能力或确切的模型/目录层级对 | 守护进程 → Codex app-server;为空 = 本地 Codex 配置,default = 显式 Standard,目录层级如 priority = 显式 Fast |
custom_args | agent.custom_args(JSON 数组) | JSON 结构由命令行侧检查;服务器按原样存储 | 守护进程(额外 CLI 开关);默认为 [] |
runtime_config | agent.runtime_config(JSON) | JSON 结构由命令行侧检查;服务器按原样存储 | 运行时特定的配置;默认为 {} |
custom_env | agent.custom_env(JSON 对象) | — | 守护进程(进程环境变量);见环境变量与密钥 |
mcp_config | agent.mcp_config(原始 JSON) | 命令行检查其为 JSON 对象或 null;服务器按原样存储。创建时,字面量 null 会被丢弃(无操作);更新时,null 会清空该列 | 守护进程 → 提供方(提供方特定的 MCP 处理);读取时脱敏 |
visibility | agent.visibility | — | 访问控制;默认为 private;控制谁可以读取/路由私有 Agent(例如私有小队队长)— 不用于运行时提示词 |
max_concurrent_tasks | agent.max_concurrent_tasks | 1 到 50 的整数;超出范围的值返回 400 | 调度器任务上限;默认为 6 |
省略或显式设为 null 时的默认值:max_concurrent_tasks → 6。 | |||
省略时的其他默认值:runtime_config → {},custom_env → {}, | |||
custom_args → [],avatar_url → 随机的 emoji:<glyph>,visibility → | |||
private | |||
(全部在插入前于服务端实例化)。custom_args/runtime_config | |||
的类型为 []string/any,并按原样序列化——JSON 结构校验失败 | |||
| 发生在 CLI 中,而不是 create 处理程序中。 |
1–50 的并发范围一致适用于 create 和 update。在 create 时,省略的字段默认为 6,而显式提供 0 会被 拒绝;在 update 时,省略则保留当前值。CLI 在发送 create 或 update 请求之前 也会执行相同的范围检查。
thinking_level 仅在提供方层面进行校验:固定词表的
提供方会拒绝无法识别的字面量,而动态词表的提供方
(如 Codex/OpenCode)接受语法上安全的 token。Pi 的提供方层面
词表是固定的(off|minimal|low|medium|high|xhigh|max),但其确切
支持的子集因模型而异,并从本地 Pi RPC 模型
目录中发现。对于所选模型不支持的值不会在此处被拒绝——
守护进程会在执行时检查其本地模型目录,记录警告,并
省略不兼容的覆盖项。
在 CLI 中通过 agent create 和 agent update 上的 --thinking-level 设置它,与 --model 对应:该标志是到顶层
thinking_level 字段的简单透传,并且在 update 时,空字符串(--thinking-level "")
会将其清除回运行时默认值。CLI 有意不枚举
有效级别——它们因运行时/模型而异(Claude 目前使用
low|medium|high|xhigh|max;Pi 使用
off|minimal|low|medium|high|xhigh|max;Codex 的取值从
运行时的模型目录中发现)。它转发该 token,服务器应用
提供方的固定枚举或安全 token 门控,守护进程执行确切的
模型/级别检查。若运行时的提供方没有 thinking 概念,则任何
非空值都会被以 400 拒绝。
service_tier 是与之匹配的一等 Codex 速度控制项。它有三种
不同的状态:
- 空表示继承本地 Codex 配置;
default表示显式使用 Standard 路由;- 运行时目录中的层级(如
priority)表示显式使用 Fast。
在 create/update 时用 --service-tier <value> 设置它;在 update 时使用
--service-tier "" 清除它。仅当守护进程报告其安装的 Codex CLI 支持
仅用于请求的显式 standard 哨兵值(Codex 0.133.0+)时,选择器才提供 default。
来自旧版守护进程的缺失能力会被视为不支持。运行时模型目录拥有替代层级的可用性
和显示文案。服务器接受安全的未来 Codex
值,而守护进程在执行前验证显式 standard 能力或确切的
模型/目录层级组合,并省略过时的不兼容
覆盖项。在未显式指定模型的 Agent 上使用替代目录层级仍会失败关闭,
因为有效的 config.toml 模型未知;
一旦运行时能力已知,default 便与模型无关。
conversation_starters
产品将该功能称为 Conversation starters(中文:对话开场建议)。
与真人交流时请使用这个名称——传输字段 conversation_starters
是实现细节,他们永远看不到。用户可在 Agent 的 Instructions 标签页配置它们;深链接为
/<workspace>/agents/<id>?view=instructions&focus=conversation_starters。
它们是至多三组 label + prompt 配对,当有人与此 Agent 发起新 Chat 时显示在
输入框上方。选中其中一项只会填充输入框——它绝不会启动运行,因此它们是建议,而非操作。
创建时省略该字段默认为 [];更新时省略则保留
已存储的值,显式传入 [] 则清空它。未配置任何内容的 Agent 在该空状态下仍会显示三个内置的通用默认项,因此
“Chat 显示了建议”并不意味着该 Agent 拥有自己的建议。
model vs custom_args
model 是一等的持久化列,daemon 会直接读取。
custom_args 通常是原始 provider CLI 参数。CLI 帮助指出某些
provider(codex app-server、openclaw)会拒绝 custom_args 中的 --model——
但这是 CLI 文档中的指引,并非服务端强制的不变量;create 处理程序中
没有任何逻辑会检查 custom_args 中是否存在 model 标志。Provider
后端可能会在启动前消费协议选择器:
- Pi 会过滤
--thinking,因为一等的thinking_level字段拥有 该标志,且必须是其唯一来源。 - ZeroClaw 会消费
--agent <alias>/--agent-alias <alias>(包括=value形式),并将该值作为 ACPsession/new.agentAlias参数发送。zeroclaw acp没有这样的 CLI 标志。当 ZeroClaw 有多个 Agent 且没有[acp].default_agent时,请设置其中一个自定义参数;对于 单 Agent 配置则省略它,以便 ZeroClaw 能自动选择该 Agent。
切勿将凭据或其他机密放入 custom_args。Daemon 命令日志会
对参数值脱敏,但后端不会消费的值仍然存在于
provider 进程的 argv 中,并可能通过 ps 或 /proc 被其他本地进程
看到。请将 provider 凭据放入 custom_env,
尽可能使用其 stdin 或 0600 文件输入。
Env & secrets
custom_env 是机密材料。CLI 提供三种输入渠道;其中两种可让
机密不出现在 shell 历史和进程列表中:
multica agent create --name <name> --runtime-id <runtime-id> --custom-env-stdin --output json
multica agent create --name <name> --runtime-id <runtime-id> --custom-env-file <0600-json> --output json
--custom-env-stdin 从 stdin 读取 JSON 对象;--custom-env-file
从文件读取(建议权限模式 0600)。第三种渠道
--custom-env <json> 会把值放到命令行上,shell 历史和
ps 都能看到——真实机密请避免使用它。
读取侧的事实(这些是需要避免的错误假设):
- Agent 资源绝不会暴露明文
custom_env。agent list/get/create/update和 WS 事件只返回has_custom_env(bool)和custom_env_key_count(int)。 - 读取明文值需要专用的
GET /api/agents/{id}/env端点(multica agent env get)。它仅限 Agent 自己的人类 所有者或工作区 owner/admin 访问,并且无论背后成员的角色如何, Agent 参与者都会被拒绝——正在运行的 Agent 无法读取另一个 Agent 的机密,即使是其自己人类所拥有的那个也不行。 - 创建后写入值不会经过
agent update。通用 更新处理程序会以 400 拒绝任何custom_env字段(“use PUT /api/agents/{id}/env”)。明文 env 写入由PUT /api/agents/{id}/env(multica agent env set)处理,它带有相同的 门禁并写入一条审计记录。
mcp_config
mcp_config 是 Agent 的 MCP 服务配置(一个 JSON 对象,例如
{"mcpServers": {…}})。它同样是敏感材料 —— MCP 条目通常会内嵌
API token —— 并且在 agent create 和 agent update 上都提供与 custom_env
相同的三种输入渠道:
multica agent create --name <name> --runtime-id <runtime-id> --mcp-config-file <0600-json> --output json
multica agent update <agent-id> --mcp-config-stdin --output json
multica agent update <agent-id> --mcp-config 'null' # clears the config
--mcp-config-stdin / --mcp-config-file 可避免该值出现在 shell 历史记录
和 ps 中;内联的 --mcp-config <json> 则不能。CLI 要求传入 JSON
对象或字面量 null;顶层数组或基本类型会在客户端被拒绝,而空的
stdin/文件输入会报错,而不是静默清空。
mcp_config 与 custom_env 有两点不同:
- 它可以通过
agent update设置。 与custom_env不同,mcp_config没有专门的审计端点 —— 通用的PUT /api/agents/{id}即可接受它。 按原始请求体的三态语义:字段省略 → 不更改;null→ 清空;对象 → 替换。 - 读取时会被序列化,但会被脱敏。
agent get/list仅向有权查看 Agent 密钥的调用方返回mcp_config;否则该字段为null且mcp_config_redacted为true。Agent 参与者永远看不到它, 并且工作区可以强制对所有人脱敏。
各提供商的支持并不一致:Qwen Code 通过一个由守护进程持有的 0600 临时 JSON 文件接受托管的 mcp_config,并以 --mcp-config 传入;该文件在运行退出时被删除。将字段保持未设置(null)即可继承 Qwen Code 原生设置。
工作区 MCP 服务
工作区维护一个 MCP 服务库(工作区 Settings → MCP,或
multica workspace mcp list|add|update|remove)。在那里添加一个 MCP 服务不会将其授予任何 Agent —— 与工作区技能的形态相同。只有被分配后,它才会到达某个 Agent:
multica workspace mcp list --output table # find the server id
multica agent mcp add <agent-id> <server-id> # give it to one agent
multica agent mcp disable <agent-id> <server-id> # stop sending it, keep the assignment
multica agent mcp remove <agent-id> <server-id> # take it away
在认领时,生效集为:
| 层级 | 何时到达 Agent |
|---|---|
| 运行时本地服务 | 始终(守护进程会合并运行时自身的文件) |
| 工作区服务 | 分配给此 Agent 且保持启用 |
Agent 自身的 mcp_config | 始终;在名称冲突时它胜出 |
在编写 Agent 配置之前,有两点值得了解:分配共享服务无需在 mcp_config 中重新列出(它们会合并),且 mcp_config 现在只关乎该 Agent 私有的服务 —— 托管但为空的 {} 不再对工作区层有任何含义,因为一开始就没有任何继承。
存储的条目是只写的 —— 读取仅返回服务名称和传输方式,绝不返回 url、命令、请求头或环境变量,对任何角色都是如此。
技能绑定
创建 Agent 不会绑定任何工作区技能 —— 绑定是在 Agent 存在之后的一次单独调用。有两个不同的动词:
add是追加式的 —— 它将给定 id 与现有绑定合并 (POST /api/agents/{id}/skills/add)。set是全量替换 —— 它用给定的 id 精确覆盖整个绑定列表 (PUT /api/agents/{id}/skills);--skill-ids ''会清空全部。
multica agent skills add <agent-id> --skill-ids <skill-id> --output json
multica agent skills list <agent-id> --output json
在认领时,守护进程先组装 Agent 的技能:先是工作区绑定的技能,
然后追加平台内置技能。LoadAgentSkills 加载每个已绑定技能的内容及其配套文件;内置技能在编译时嵌入,并从 SKILL.md + 同级文件加载。两者都以技能内容的形式到达提供商 —— 这就是为什么能力应放在已绑定的技能中,而不是粘贴到 instructions 里。
需要批准的副作用
只读(安全):agent get、agent skills list、agent env get。
改变状态(需要明确指令 —— 不要推测性地运行):
multica agent create—— 插入一行新的 Agent 记录。multica agent copy—— 插入一行新的 Agent 记录(现有 Agent 的分叉); 源 Agent 保持不变。multica agent skills add/set—— 变更绑定(set具有破坏性: 它会丢弃不在新列表中的绑定)。multica agent env set—— 覆盖完整的custom_env映射并写入一行 审计记录。
常见错误假设
- “
description就是提示词。”并非如此——只有instructions会进入 运行时。描述再丰富但 instructions 为空,得到的只是一个有名字的壳, 没有运行契约。 - “Create 会绑定 Agent 的技能。”并不会;之后需要显式绑定。
- “
agent update可以轮换 env。”不能——遇到custom_env会返回 400;请使用 env 端点。 - “
mcp_config在更新时与custom_env行为一致。”并非如此——mcp_config可以通过agent update(--mcp-config)设置,用--mcp-config null来 清除;只有custom_env被限制在专用的 env 端点之后。 - “
agent get会显示 env 值。”它只显示has_custom_env和custom_env_key_count。 - “每个被接受的请求体字段都有对应的 CLI 标志。”
conversation_starters没有 ——agent create/agent update无法设置它,而agent copy只会 沿用已有的值。 - “无效的
thinking_level/model组合会在创建时被捕获。”只有 未知的提供商级字面量会被捕获——模型特有的缺口会在运行时失败。 - “
set和add在技能方面可以互换。”set会替换所有 绑定;当你本意是add时使用它,会静默移除能力。
参考资料
references/creating-agents-source-map.md 将上述每一项契约映射到当前代码树上的
file:line、运行时影响,以及一条安全的只读
验证命令。