fitness-calculator.js
2.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
/**
* Fitness Calculator — 6 维适应度评估
*
* 所有评估由 LLM Agent 完成,无规则降级。
* evaluator.evaluateGenomeFitness 做语义级质量评估。
*/
const evolutionQueries = require('../queries').evolutionQueries;
const { evaluateGenomeFitness } = require('../evaluator');
const DEFAULT_WEIGHTS = {
mentalModels: 0.10,
patternLibrary: 0.20,
judgment: 0.25,
toolFluency: 0.15,
taste: 0.15,
scarTissue: 0.15,
};
/**
* 评估并持久化单个基因组的适应度
*/
async function evaluateAndPersistFitness(genomeId, runId) {
const genome = await evolutionQueries.getGenome(genomeId);
if (!genome) throw new Error(`Genome ${genomeId} not found`);
const result = await evaluateGenomeFitness(genome);
const dimensionScores = result.dimensionScores || {};
const overall = result.overall || Object.entries(dimensionScores).reduce(
(sum, [key, score]) => sum + (score || 0) * (DEFAULT_WEIGHTS[key] || 0), 0,
);
await evolutionQueries.updateGenomeFitness(genomeId, dimensionScores, parseFloat(overall.toFixed(4)));
await evolutionQueries.insertEvaluation({
genomeId, runId,
benchmarkId: null,
generation: genome.generation,
probeResults: null,
dimensionScores,
overallScore: parseFloat(overall.toFixed(4)),
weights: DEFAULT_WEIGHTS,
totalToolCalls: null,
redundantCalls: null,
executionTimeMs: null,
});
return { genomeId, dimensionScores, overall: parseFloat(overall.toFixed(4)) };
}
/**
* 批量评估 run 中所有存活基因组
*/
async function evaluateRunFitness(runId) {
const genomes = await evolutionQueries.getGenomesByRun(runId, { aliveOnly: true });
console.log(`📊 适应度评估: ${genomes.length} 个基因组\n`);
const results = [];
for (const genome of genomes) {
try {
const result = await evaluateAndPersistFitness(genome.id, runId);
results.push(result);
console.log(` ${genome.skill_name}: ${(result.overall * 100).toFixed(1)}%`);
} catch (err) {
console.error(` ❌ ${genome.skill_name}: ${err.message}`);
}
}
if (results.length > 0) {
const best = results.reduce((max, r) => r.overall > max.overall ? r : max, results[0]);
await evolutionQueries.updateRun(runId, { best_fitness: best.overall });
}
return results;
}
module.exports = {
evaluateAndPersistFitness,
evaluateRunFitness,
DEFAULT_WEIGHTS,
};