guanghulab/scripts/grid-db/update-training-catalog.js
Guanghu Domestic Migration d1e47f4565
Some checks are pending
自动更新代码和重启 / update-and-restart (push) Waiting to run
CI检查 + 自动部署 / check (push) Waiting to run
CI检查 + 自动部署 / deploy (push) Blocked by required conditions
重启聊天服务 / restart (push) Waiting to run
chore: import sanitized domestic snapshot for REPO-002
Source snapshot: ca48d3ddf926d79aa138306164169baf764bb829
2026-07-17 15:54:41 +08:00

127 lines
4.1 KiB
JavaScript

/**
* scripts/grid-db/update-training-catalog.js
*
* 训练数据湖 catalog 更新脚本
*
* 职责:
* - 扫描 grid-db/training-lake/raw/ 和 curated/ 中的 JSONL 文件
* - 统计:总样本数、各开发者样本数、各类型分布、质量分布
* - 更新 grid-db/training-lake/metadata/catalog.json
*
* 守护: PER-ZY001 铸渊
* 系统: SYS-GLW-0001
*/
const fs = require('fs');
const path = require('path');
const GRID_DB = path.join(__dirname, '../../grid-db');
const TRAINING_RAW = path.join(GRID_DB, 'training-lake/raw');
const TRAINING_CURATED = path.join(GRID_DB, 'training-lake/curated');
const CATALOG_PATH = path.join(GRID_DB, 'training-lake/metadata/catalog.json');
function countJsonlLines(dir) {
if (!fs.existsSync(dir)) return { lines: 0, files: [] };
const files = fs.readdirSync(dir).filter(f => f.endsWith('.jsonl'));
let totalLines = 0;
const fileStats = [];
const devCounts = {};
const qualityCounts = { high: 0, medium: 0, low: 0 };
let totalTurns = 0;
for (const file of files) {
const filePath = path.join(dir, file);
const content = fs.readFileSync(filePath, 'utf8');
const lines = content.trim().split('\n').filter(l => l.trim());
let fileLineCount = 0;
for (const line of lines) {
try {
const record = JSON.parse(line);
fileLineCount++;
// Count by developer (standardized on dev_id per schema)
const devId = record.dev_id || record.source_dev || 'unknown';
devCounts[devId] = (devCounts[devId] || 0) + 1;
// Count quality tiers
const tier = record.quality_tier;
if (tier === 'A') qualityCounts.high++;
else if (tier === 'B') qualityCounts.medium++;
else if (tier === 'C') qualityCounts.low++;
// Count turns
if (record.turns) totalTurns += record.turns.length;
} catch {
// Skip unparseable lines
}
}
totalLines += fileLineCount;
fileStats.push({ file, lines: fileLineCount });
}
return { lines: totalLines, files: fileStats, devCounts, qualityCounts, totalTurns };
}
function main() {
console.log('[update-training-catalog] Scanning training-lake...');
const rawStats = countJsonlLines(TRAINING_RAW);
const curatedStats = countJsonlLines(TRAINING_CURATED);
const totalSamples = rawStats.lines + curatedStats.lines;
const totalTurns = rawStats.totalTurns + curatedStats.totalTurns;
// Merge dev counts
const devCounts = { ...rawStats.devCounts };
for (const [dev, count] of Object.entries(curatedStats.devCounts || {})) {
devCounts[dev] = (devCounts[dev] || 0) + count;
}
// Merge quality counts
const qualityDistribution = {
high: (rawStats.qualityCounts?.high || 0) + (curatedStats.qualityCounts?.high || 0),
medium: (rawStats.qualityCounts?.medium || 0) + (curatedStats.qualityCounts?.medium || 0),
low: (rawStats.qualityCounts?.low || 0) + (curatedStats.qualityCounts?.low || 0)
};
// Build catalog
const catalog = {
schema_version: '1.0',
description: '训练数据湖样本目录',
total_samples: totalSamples,
total_turns: totalTurns,
quality_distribution: qualityDistribution,
dev_distribution: devCounts,
raw_files: rawStats.files,
curated_files: curatedStats.files,
batches: [],
last_updated: new Date().toISOString()
};
// Preserve existing batches from previous catalog
if (fs.existsSync(CATALOG_PATH)) {
try {
const existing = JSON.parse(fs.readFileSync(CATALOG_PATH, 'utf8'));
if (existing.batches) {
catalog.batches = existing.batches;
}
} catch {
// Ignore parse errors
}
}
fs.writeFileSync(CATALOG_PATH, JSON.stringify(catalog, null, 2) + '\n');
console.log(`[update-training-catalog] Catalog updated:`);
console.log(` Total samples: ${totalSamples}`);
console.log(` Total turns: ${totalTurns}`);
console.log(` Quality: A=${qualityDistribution.high} B=${qualityDistribution.medium} C=${qualityDistribution.low}`);
console.log(` Dev distribution: ${JSON.stringify(devCounts)}`);
console.log('[update-training-catalog] Complete');
}
main();