没有人在回路中——这是设计使然
CommandAGI 为无人值守运行的机器而建。持有授权的智能体可以实时使能(arm)单元、运行程序、发送命令——通过工作台、API 或 MCP——无需对每个动作逐一确认。保障安全的不是有人盯着,而是授权、驱动的边界和记录。
主体
一切行动者都是主体:agent:<name> 或 person:<name>。主体用凭据证明自己的身份——绝不只是报出自己的名字。仅仅声称自己是谁的请求会被拒绝。
- 主机凭据——
cagp_…,由commandagi grant token --principal agent:<name>签发一次(添加授权时也会签发)。主机只保存它的 SHA-256。grant token轮换它;grant forget删除它。 - 账户凭据——
cagc.<payload>.<signature>,用你账户的密钥(Ed25519)签名,供在云端运行的智能体使用。它写明主体、账户、过期时间,并可选地指定一台主机;只对该账户创建的授权有效。用grant revoke-credential吊销。
长期授权
长期授权是一个账户给予某个主体的权限,由人以明确的操作创建。没有任何工具或智能体途径能创建或扩大授权;在每一个改变权限的路由上,智能体的 API 密钥都会被拒绝。
commandagi grant add --principal agent:night-shift \
--world shop --unit mill-1 --channel gcode \
--verb open --verb arm --verb run --verb send \
--for 8h --note "night shift"
commandagi grant list
commandagi grant revoke g-3f9a1c20b7de一条授权指定一个世界,并可选地指定单元、通道和操作——省略某一项即表示全部。授权可以设置过期(--for 8h、--expires <ISO time>)。授权保存在 ~/.commandagi/grants.json 中,每个动作都会重新读取;也可以在工作台的 设置 → 授权 中创建。格式错误的授权文件不会认可任何授权。
{ "grants": [ { "id": "g-3f9a1c20b7de", "principal": "agent:night-shift",
"grantedBy": "acct:user:u_8f2k", "world": "shop", "units": ["mill-1"],
"channels": ["gcode"], "verbs": ["open", "arm", "run", "send"],
"expires": "2026-10-01T06:00:00Z", "note": "night shift" } ] }同一个命令还能创建另外三种授权:--file PREFIX…(在某个路径下写文件)、--outreach APP… --per-day N(通过已连接的应用发送消息)和 --market VENUE… --symbol S --max-qty N --max-notional N --per-day N(下单)。
授权适用于物理世界。仿真世界不需要授权。
操作、使能与安全停机
一条授权可以给予四种操作:open 打开通道、arm 使能单元、run 运行程序、send 发送命令。
- 驱动硬件运动的驱动在打开时处于未使能状态。任何在该单元上持有授权的主体都可以使能它。已使能的连接会话空闲五分钟后会自动解除使能。
- 只接收输入的驱动——shell、Python 内核、作业交接——不需要使能;每次输入都会检查授权。
- 安全停机始终允许。
stop、disarm和close——以及进给保持、暂停、紧急停止、关闭扭矩等安全停机命令——对任何在该单元上持有未过期授权的人、对打开该连接会话的人、以及对账户本人都始终允许。撤销一张挂单也属于安全停机。
每个动作遵循的规则
- 发送前先记录。 在调用驱动之前,一条备注——主体和动作——会追加到运行的数据流中并落盘。只读项目会拒绝该动作,而不是在没有记录的情况下执行。
- 确认不等于状态。 一条回复或
ok绝不意味着已达到所命令的状态。命令会一直处于待定状态,直到机器报告状态。 - 未知就保持未知。 断开的链路记录为
state: unknown。没有结束记录就终止的数据流显示为 interrupted: state unknown(已中断:状态未知)。 - 绝不静默重试。 系统从不重试物理命令。智能体可以决定再试一次;这个决定本身会作为一条命令被记录。
- 边界由驱动负责。 声明的限位、间隔和允许的操作由驱动强制执行,而不是由人。输入流有节奏控制:一次一个动作,间隔至少 30 ms。
- 仿真与物理绝不混合。 一次运行只属于一个世界,其记录的来源必须与该世界的类型一致。
线程及其智能体
在物理世界中开启一个线程,会把该世界所有单元上的全部操作授予该线程的智能体(threads.agent,默认为 agent:mcp),最长 24 小时,并在线程关闭时撤销。可通过设置 "threads.agentControl": false 关闭此行为。
下一步
通过 MCP 把智能体接入这一切:SDK 与 MCP。