构建了一个同时评估 AI 生成代码正确性、安全性、性能、可维护性、资源使用的自动化验证框架,含权重分配和 Wasm 沙箱执行。
The Problem: Candidate Code Without Trust
你在用 Cursor、Claude Code 或 GitHub Copilot。AI 给出了同一个功能的三种实现方案。
AI: "Here are three approaches:
A) Quick but uses unsafe
B) Slower but memory-safe
C) Balanced tradeoffs"
You: "Which one should I ship?"
AI: "It depends..."
那个"视情况而定"就是责任掉进裂缝的地方。
测试告诉你代码能否编译、是否符合规格。但它们无法同时告诉你安全性、性能、可维护性或资源限制。你最后只能凭直觉做决定。
这篇文章讲的是如何构建一个不让这种事发生的系统。
The Solution: Multi-Axis Scoring
我构建了 SafeCode Arena——一个自动化验证器,能同时从五个维度评估代码候选方案,分别打分,并呈现权衡结果。
正确性占主导——不能运行的代码毫无价值,所以占 50%
安全性是明确的——unsafe 能通过编译,但你需要自己检测
性能和可维护性同等重要——一个快速的烂摊子与一个缓慢的杰作没有可比性
资源限制是真实的——一个 100 分的算法如果消耗 2GB 内存,在生产环境就是不合格
Candidate A: 85 points
├─ correctness: 100 (all tests pass)
├─ security: 60 (2 unsafe blocks flagged)
├─ performance: 70 (10% slower than B)
├─ maintainability: 85 (avg function 25 lines)
└─ resource_usage: 80 (Wasm sandbox: 512MB, OK)
Candidate B: 92 points ✓ Recommended
├─ correctness: 95 (1 edge case warning)
├─ security: 95 (no unsafe)
├─ performance: 95 (fastest)
├─ maintainability: 88 (avg function 20 lines)
└─ resource_usage: 100 (Wasm sandbox: 200MB)
现在这个选择是有据可依的。你可以解释为什么 B 赢了。
Implementation Patterns
AI 生成的代码可能挂起、崩溃或消耗无限内存。在裸机上运行它是鲁莽的。
// Compile the candidate → link to Wasm
let instance = linker.instantiate(&module)?;
let run_fn = instance.get_typed_func::<(), ()>(&mut store, "run")?;
// Set fuel (instruction budget) and memory limit
store.set_fuel(100_000_000)?; // ~100M instructions
store.set_memory_limit(1_000_000_000)?; // 1GB max
// Run with hard limits
run_fn.call(&mut store, ())?; // Will trap if it exceeds limits
结果:代码在沙箱里运行。如果它试图无限循环或分配无限内存,会被干净地终止(trap)。不会崩溃、不会 OOM,只是 resource_usage 得分为 0。
比较一个候选方案是有用的。与过去的候选方案比较才是宝藏。
// Log every evaluation to SQLite
db.execute(
"INSERT INTO evals
(spec_hash, code_hash, correctness, security, perf, maintain, resource, timestamp)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
params![
hash(spec), hash(code),
score.correctness, score.security, score.perf, score.maintain, score.resource,
now()
],
)?;
// Detect regressions
let best = db.query_row(
"SELECT score FROM evals WHERE spec_hash = ? ORDER BY timestamp DESC LIMIT 1",
[spec_hash],
|row| row.get(0),
)?;
if new_score < best - threshold {
println!("⚠️ Regression detected: {} → {}", best, new_score);
}
为什么这很重要:你可以构建一份"这个 spec 的每个候选方案的排名"变更日志。未来的开发者能看到尝试过什么、为什么选择了某个方案。这是审计轨迹。
Rust 和 Python 现在到处共存。SafeCode Arena 不强迫你用一种语言重写一切。
let scorer = match candidate.extension() {
"rs" => RustScorer::new(),
"py" => PythonScorer::new(),
_ => return Err("Unsupported"),
};
let score = scorer.evaluate(candidate, tests)?;
好处:你可以用同一个评分标准比较"Rust 方案"和"Python 方案"。语言对排名是透明的。
# .github/workflows/evaluate-candidate.yml
name: Evaluate PR Candidate
on: pull_request
jobs:
safecode:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Evaluate candidates
run: |
safecode evaluate pr-candidate.rs \
--tests tests/ \
--format json \
--db history.db > score.json
- name: Post score to PR
run: |
gh pr comment -b "$(cat score.json | jq -r '.report')"
结果:每个提议代码的 PR 都会收到一份评分报告。开发者在合并前看到评分卡。生产环境不会有意外。
The Deeper Point: Rubrics as Responsibility
构建这个系统的过程中,有一点一直萦绕在我脑海中。
选择评分标准就是选择你信任什么。
The Old Way: "I Know It When I See It"
Reviewer: "This code feels unsafe."
(Why? Personal experience, gut instinct, luck)
Next reviewer: "Is that still true?"
(No way to know. Depends on their experience.)
这不可扩展。它不可复现,也不可传授。
SafeCode Arena's Way: Rubric Is Explicit
"Unsafe block found → -5 security points (non-negotiable)"
"Property test passes → +10 correctness points"
...
每个人使用同一套标准。没有意外。
你可以争论它。("那个 unsafe 真的是风险吗?" → 调查 → 可能调整评分标准)
未来的你可以解释过去的你。可审计。
在 AI 生成代码的时代,明确的评分标准是你为信任承担责任的方式。
你不是在说"AI 总是对的"或"AI 总是错的"。你是在说:"这是我检查过的。这是分数。这是我为什么合并它的原因。"
# 1. AI generates 3 candidates (you pick the most promising)
# 2. Run the scorer
$ safecode evaluate solution_a.rs solution_b.rs \
--tests tests/ \
--db evals.db
# 3. Results
SafeCode Arena Comparison Report
─────────────────────────────────
Solution A: 78 points (correctness 85, security 60, perf 70, maintain 80, resource 95)
Solution B: 91 points (correctness 100, security 90, perf 95, maintain 85, resource 100) ← Winner
# 4. Confidence
(Run regression check: best_previous_score = 75, new = 91 → no regression, all good)
# 5. Merge
You ship Solution B, confident you can explain your choice.
SafeCode Arena has completed phases 1–5:
✅ All 5 scoring axes implemented
✅ Rust & Python support
✅ Wasm sandbox isolation
✅ SQLite persistence + regression detection
✅ Multi-output formats (JSON, table, HTML)
Go & JavaScript support
Mutation testing (bonus axis)
Integration with GitHub PR workflows
Cursor、Claude Code、GitHub Copilot 以及类似工具每天都在交付代码。整个行业共同表现得好像"AI 选了它,所以没问题",这就是你最终在生产环境里遇到安全漏洞的原因。
SafeCode Arena 是我的答案:不是"不要相信 AI",而是"相信 AI + 系统化验证"。
GitHub: https://github.com/flipslidersand/safecode-arena License: MIT Stack: Rust, Wasm (wasmtime), SQLite, Python