Arena 是基因证明自身价值的地方。每个提交到 Arena 的基因都会收到一个适应度分数(F(g))和一个安全分数(V(g)) — 这两个指标决定了它的排名、生存和你的开发者声誉。
本教程将带你提交一个基因、理解它的评分、迭代改进它,并观察它攀升排名。
前置条件
- 已安装 Rotifer CLI(
npm i -g @rotifer/playground) - 准备好一个基因(参见 5 分钟创建你的第一个基因)
- (可选)Cloud 登录以参加全球 Arena(
rotifer login)
第一步:提交到 Arena
提交一个基因。如果还没有,创建一个 JSON 格式化器:
mkdir -p genes/json-fmt && cat > genes/json-fmt/index.ts << 'EOF'
export async function express(input: { code: string; indent?: number }) {
const indent = input.indent ?? 2;
try {
const parsed = JSON.parse(input.code);
return { formatted: JSON.stringify(parsed, null, indent), valid: true };
} catch {
return { formatted: input.code, valid: false };
}
}
EOF
rotifer wrap json-fmt --domain code.format
rotifer compile json-fmt提交:
rotifer arena submit json-fmtTesting 'json-fmt' before submission...
✓ All tests passed
Submitting to Arena...
✓ Gene 'json-fmt' submitted
Rank: #2 in code.format
V(g): 0.9100
Fidelity: Native第二步:理解评分
F(g) — 适应度分数
F(g) 是乘法模型,不是加权求和。自 v0.5.5 起的模型是:
F(g) = S_r · ln(1 + C_util) · (1 + R_rob) · L · Cost| 符号 | 衡量内容 | 怎么来的 |
|---|---|---|
S_r |
沙箱多次运行的成功率 | 实测——这一项为零,总分归零 |
C_util |
覆盖率/利用率 | 未实测时取默认值 0.5 |
R_rob |
对抗输入下的鲁棒性 | 未实测时取默认值 0.5 |
L |
延迟效率分,1 / (1 + 平均毫秒 / 尺度常数)——越快越接近 1 |
实测 |
Cost |
资源效率分,1 / (1 + 平均成本 / 尺度常数)——越省越接近 1 |
实测 |
五个因子相乘,没有封顶。L 与 Cost 是效率分而不是开销本身:跑得越快越省,它们越接近 1,总分越高;越慢越贵,它们越接近 0,总分被拉下去。
保真度不是公式内部的加分项,而是事后乘上的折扣:F(g) = 基础分 × 折扣,Native 为 1.0、Hybrid 为 0.85、Wrapped 为 0.7。
五个输入里有两个仍是占位值,L 与 Cost 用的尺度常数也还是临时值、仍在校准。所以今天提交拿到的是估算而非可排名的分数——本文的示例输出也因此不写死具体分值:该看的是各项之间怎么互相牵动,不是某个绝对数字。把这些数字读作一份可复现的执行记录;它们最终会排出什么顺序,还没有定下来。
V(g) — 安全分数
安全验证是一个硬性门控,独立的 0.0–1.0 分数:
V(g) 是 Test_Pass_Rate / Security_Leak_Risk。泄漏风险来自对基因源码的静态模式扫描——逐行规则匹配,不是 AST 分析:
| 规则 | 检测内容 | 严重级别 |
|---|---|---|
| S-01 | 动态代码执行(eval、new Function) |
CRITICAL |
| S-02 | 系统命令执行(child_process、exec、spawn) |
CRITICAL |
| S-03 | 代码混淆(base64 解码后执行) | CRITICAL |
| S-04 | 可疑的外部通信 | HIGH |
| S-05 | 环境变量访问 | HIGH |
| S-06 | 持久化外连 | HIGH |
| S-07 | 文件系统操作 | MEDIUM |
准入门控
协议为两个分数各定了一道门槛:
- F(g) >= 0.3(默认 τ)
- V(g) >= 0.7(默认 V_min)
V(g) 这道是硬门控:不过就被拒绝,并附带诊断反馈。
F(g) 那道暂时不阻断提交。理由在上一节:它的两个输入还是占位值,效率项的参照刻度也还是临时值——拿一个自己都标着「估算、暂不参与排名」的分数去卡准入,量的是刻度而不是基因。CLI 会照常把 F(g) 打出来并提示它低于 τ,但不会因此拒收。参照刻度校准完成后,这道门会恢复。
第三步:读懂提交实际报告了什么
再提交一次,输出的是完整记录,不只是一个总分:
rotifer arena submit json-fmt✓ Gene 'json-fmt' submitted to Arena
Domain: code.format
Fidelity: Native
V(g): 0.9100
Success Rate: 90.0%
Latency Score: 0.9881
Admission: PASSED
Execution: Sandbox verified (20 runs)
Recorded as: estimated有三处值得仔细读。
Success Rate: 90.0% 才是那根杠杆。 S_r 位于 F(g) 的分子,也是唯一一个「为零就让总分归零」的因子。另外两个输入——C_util 与 R_rob——目前是固定占位值,对 Arena 里每个基因贡献相同,无法针对它们优化。
Recorded as: estimated 不是装饰。 在那两个占位值被真正测量之前,提交一律记为估算:执行确实发生并被记录,但这个数字还不参与排名。
V(g) 是另一条独立的轴,不在 F(g) 内部。 一个基因可以既完全安全又毫无用处,也可以又快又被拒。两者分别在 F(g) >= 0.3 与 V(g) >= 0.7 上把关。
所以这篇教程今天能回答的是一个很窄的问题:20 次运行里为什么有 2 次失败,修好它们分数会怎么动。
第四步:把成功率提上去
express() 抛异常、超时,或返回违反声明 outputSchema 的输出,都算一次失败。对这个 JSON 格式化器来说,失败来自朴素实现直接放弃的畸形输入:
export async function express(input: { code: string; indent?: number }) {
const indent = input.indent ?? 2;
const code = (input.code ?? '').trim();
if (!code) {
return { formatted: '', valid: false };
}
try {
const parsed = JSON.parse(code);
return { formatted: JSON.stringify(parsed, null, indent), valid: true };
} catch {
// 抢救最常见的一种:尾随逗号
try {
const cleaned = code.replace(/,\s*([\]}])/g, '$1');
const parsed = JSON.parse(cleaned);
return { formatted: JSON.stringify(parsed, null, indent), valid: true };
} catch {
return { formatted: code, valid: false };
}
}
}注意这个兜底没有做的事:它从不抛异常,也从不返回半个对象。对真正损坏的输入返回 { formatted, valid: false },是一次成功的运行报告了一个否定结果——这和崩溃是两回事,Arena 的计分方式也不同。
重新编译并提交:
rotifer compile json-fmt
rotifer arena submit json-fmt Success Rate: 100.0%S_r 从 0.90 走到 1.00,F(g) 成比例跟着动——S_r 是一个直乘因子,成功率提高一成,总分就跟着提高一成。这就是乘法结构在做它声称要做的事。
第五步:单独检查安全那条轴
V(g) 来自对源码的静态模式扫描。提交前可以单独跑:
rotifer vg json-fmt扫描是按上文 S-01 到 S-07 规则做的逐行正则匹配。这让它很快,也让它很钝:注释里出现 eval 这个词就可能触发 S-01。要读具体命中项,别只盯着等级——V(g) 的意义在于让使用者在安装前看清你的基因伸手够了什么。
第六步:观察排名
实时监控基因排名:
rotifer arena watch code.formatWatching code.format rankings...
[14:32:01] json-fmt ↑ #2 → #1 (F: 0.82 → 0.86)
[14:32:04] No changes
[14:32:07] No changes
Press Ctrl+C to stop第七步:进军全球 Cloud Arena
本地 Arena 适合测试。要参加全球竞争:
rotifer login
rotifer arena submit json-fmt --cloud✓ Submitted to Cloud Arena
Rank: #8 globally in code.format查看全球排名:
rotifer arena list --cloud -d code.format第八步:查看你的声誉
每次 Arena 提交都会影响你的开发者声誉:
rotifer reputation --mineDeveloper Reputation:
Arena Score: 0.82 (基于基因排名)
Usage Score: 0.45 (基于安装次数)
Stability: 0.91 (基于基因一致性)
Overall: 0.73声誉是你的基因 Arena 表现、被他人使用频率和长期可靠性的综合评分。
优化循环
即使评分模型还在打磨,这个循环本身才是要点:
- 提交 → 拿到执行记录,而不只是一个数字
- 诊断 → 找出哪些运行失败了、为什么
- 改进 → 针对性代码修改
- 重新提交 → 验证
S_r确实动了 - 观察 → 监控竞争位置
这是选择压力最早期的形态:Arena 度量,你的基因适应它所度量的东西。而它今天度量得最扎实的,是这个基因有没有做到它声称要做的事。
高适应度技巧
- 处理边缘情况:null 输入、空字符串、畸形数据——每一个抛出异常的都在扣你的
S_r - 永远返回声明的形状:违反
outputSchema的输出算一次失败运行,哪怕函数并没有崩 - 保持确定性:相同输入应始终产生相同输出,让多次运行彼此一致
- 如实声明保真度:乘进 F(g) 的折扣是 Native 1.0、Hybrid 0.85、Wrapped 0.7——而未声明保真度按 Wrapped 处理,不是 Native
- 跑得更快、更省是加分的:
L与Cost是乘进总分的效率分,延迟和资源开销降下来,F(g) 就升上去。但这两项的参照刻度仍在校准中,所以照着绝对数字调参没有意义——先把S_r做满,再谈效率
深入阅读: 参见基因标准规范了解完整适应度模型,Arena CLI 参考了解所有命令选项。
