← 返回博客

Arena 竞技:优化适应度分数

高级教程:提交基因到 Arena,分析 F(g) 和 V(g) 评分,迭代优化性能,攀升排名。

Arena 竞技:优化适应度分数

Arena 是基因证明自身价值的地方。每个提交到 Arena 的基因都会收到一个适应度分数(F(g))和一个安全分数(V(g)) — 这两个指标决定了它的排名、生存和你的开发者声誉。

本教程将带你提交一个基因、理解它的评分、迭代改进它,并观察它攀升排名。

前置条件

第一步:提交到 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-fmt
Testing '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 实测

五个因子相乘,没有封顶。LCost效率分而不是开销本身:跑得越快越省,它们越接近 1,总分越高;越慢越贵,它们越接近 0,总分被拉下去。

保真度不是公式内部的加分项,而是事后乘上的折扣:F(g) = 基础分 × 折扣,Native 为 1.0、Hybrid 为 0.85、Wrapped 为 0.7。

五个输入里有两个仍是占位值,LCost 用的尺度常数也还是临时值、仍在校准。所以今天提交拿到的是估算而非可排名的分数——本文的示例输出也因此不写死具体分值:该看的是各项之间怎么互相牵动,不是某个绝对数字。把这些数字读作一份可复现的执行记录;它们最终会排出什么顺序,还没有定下来。

V(g) — 安全分数

安全验证是一个硬性门控,独立的 0.0–1.0 分数:

V(g) 是 Test_Pass_Rate / Security_Leak_Risk。泄漏风险来自对基因源码的静态模式扫描——逐行规则匹配,不是 AST 分析:

规则 检测内容 严重级别
S-01 动态代码执行(evalnew Function CRITICAL
S-02 系统命令执行(child_processexecspawn CRITICAL
S-03 代码混淆(base64 解码后执行) CRITICAL
S-04 可疑的外部通信 HIGH
S-05 环境变量访问 HIGH
S-06 持久化外连 HIGH
S-07 文件系统操作 MEDIUM

准入门控

协议为两个分数各定了一道门槛:

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_utilR_rob——目前是固定占位值,对 Arena 里每个基因贡献相同,无法针对它们优化。

Recorded as: estimated 不是装饰。 在那两个占位值被真正测量之前,提交一律记为估算:执行确实发生并被记录,但这个数字还不参与排名。

V(g) 是另一条独立的轴,不在 F(g) 内部。 一个基因可以既完全安全又毫无用处,也可以又快又被拒。两者分别在 F(g) >= 0.3V(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.format
Watching code.format rankings...

[14:32:01] json-fmt ↑ #2 → #1 (F: 0.820.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 --mine
Developer Reputation:
  Arena Score:    0.82  (基于基因排名)
  Usage Score:    0.45  (基于安装次数)
  Stability:     0.91  (基于基因一致性)

  Overall:       0.73

声誉是你的基因 Arena 表现、被他人使用频率和长期可靠性的综合评分。

优化循环

即使评分模型还在打磨,这个循环本身才是要点:

  1. 提交 → 拿到执行记录,而不只是一个数字
  2. 诊断 → 找出哪些运行失败了、为什么
  3. 改进 → 针对性代码修改
  4. 重新提交 → 验证 S_r 确实动了
  5. 观察 → 监控竞争位置

这是选择压力最早期的形态:Arena 度量,你的基因适应它所度量的东西。而它今天度量得最扎实的,是这个基因有没有做到它声称要做的事。

高适应度技巧


深入阅读: 参见基因标准规范了解完整适应度模型,Arena CLI 参考了解所有命令选项。