全图
决定这一切形状的那条规则
控制台进程持有数据库连接、JWT 签名密钥和对象存储凭据。在那里跑插件,等于把整个平台交给发布者。 所以代码类插件只会在已经属于你的地方执行:你的训练容器,或者你自己的笔记本。 要改控制平面的行为,请跨进程边界:通知通道用 webhook,agent 工具用外部 MCP server。 这也是为什么没有runs_in: console 这一档插件,以及为什么将来也不会有。
声明包里不能有代码
平台只读不执行的那类包(recipe、benchmark、playbook、prompt),
根层出现可执行文件就会在发布期被拒——.py、.sh、.so、.js 以及另外约二十种后缀。
template/ 是例外,理由值得知道:那是 sf new 拷进你的仓库、由你在你的容器里跑的脚手架,
平台一行都不碰。
这把「平台永不执行声明包」从一句承诺变成了脚本能检查的事实。踩到时的报错:
代码插件要过三道闸
只要代码会被执行,就要过同样的三道内容摘要校验。它们保证「集群上跑的」和「你发布的」是同一份东西。1
发布时
服务端解包重算内容摘要,与客户端声明的比对,不一致就拒绝。
2
提交时
校验 JobSpec 里的
(id, version, digest) 三元组与库内记录一致,且插件未被管理员禁用。3
启动时
launcher 对真正注入到作业里的目录再算一次摘要。与 JobSpec 锁定值不同,作业直接拒绝启动——
宁可不跑,也不产出一个没人能复现的结果。
__pycache__、.git、.venv、*.pyc 和 .DS_Store 不参与摘要。它们是环境副产物,不是插件内容。代码包还要多过两道检查
发布期的结构校验,让错误在你的笔记本上就暴露,而不是在集群跑了四十分钟之后:entrypoint 模块必须真实存在
entrypoint 模块必须真实存在
entrypoint: patch:install 要求包里有 patch.py 或 patch/__init__.py。拼错在发布期就被拒:顶层名不得遮蔽真实依赖
顶层名不得遮蔽真实依赖
插件根目录会加入
sys.path,所以根层一个叫 torch.py 的文件会让训练进程之后所有的
import torch 都拿到你的文件。症状离病因极远,因此这些名字是保留字,直接拒绝:版本不可变
同一个1.2.0 发两次会得到 409。修 bug 请发 1.2.1。
这是 digest 锁定成立的前提:版本能被覆盖,锁文件指向的东西就可能已经不存在了。
README.md 也一样在摘要覆盖范围内,所以改长描述同样要换版本号。
「文档说的和代码做的不一致」是插件市场最常见的坑,这是防住它最便宜的办法。
命名与命名空间
治理
禁用只挡新提交。已经在跑和已经排队的作业不受影响。
下一步
插件包
manifest、目录结构、发布与安装。
Algorithm 插件
入口函数签名,以及它什么时候被调用。
Recipe 包
不发平台版本就加一种训练方法。
Benchmark 包
声明跑什么、读哪些数。
环境
Agent RL 的任务集,以及四种协议。
Verifier
判定任务是否完成的三种方式。