Repository navigation
Expand file tree
/
Copy path_run_review.js
More file actions
131 lines (108 loc) · 5.18 KB
/
Copy path_run_review.js
File metadata and controls
131 lines (108 loc) · 5.18 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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
const { loadSchemaPrompt } = require('./dist-electron/schema-loader')
const { compileNewPages, chat } = require('./dist-electron/llm-service')
const { validateMultiPage } = require('./dist-electron/compile-validator')
const fs = require('fs')
const path = require('path')
const kbPath = 'E:/my_llm_wiki'
const rawDir = path.join(kbPath, 'raw')
function now() { return new Date().toLocaleTimeString('zh-CN', { hour12: false }) }
function issueSummary(issues) {
const byRule = {}
for (const i of issues) {
if (!byRule[i.rule]) byRule[i.rule] = { errors: 0, warns: 0 }
byRule[i.rule][i.severity === 'error' ? 'errors' : 'warns']++
}
return Object.entries(byRule).map(([rule, c]) =>
`${rule}(${c.errors > 0 ? '✗' + c.errors : ''}${c.warns > 0 ? ' △' + c.warns : ''})`
).join(' ')
}
async function main() {
const rawFiles = fs.readdirSync(rawDir).filter(f => !f.startsWith('.') && /\.(md|markdown|txt)$/i.test(f))
const wikiDir = path.join(kbPath, 'wiki')
const existingTitles = fs.existsSync(wikiDir)
? fs.readdirSync(wikiDir).filter(f => f.endsWith('.md')).map(f => f.replace('.md', ''))
: []
const totalStart = Date.now()
console.log(`\n${'═'.repeat(60)}`)
console.log(` 提示词质量评审 — ${rawFiles.length} 个文件,每文件 ≤3 轮,目标 ≥80 分`)
console.log(` MiniMax-M2.7 | 开始: ${now()}`)
console.log(`${'═'.repeat(60)}\n`)
const allResults = []
for (let fi = 0; fi < rawFiles.length; fi++) {
const rawName = rawFiles[fi]
const rawFilePath = path.join(rawDir, rawName)
const rawContent = fs.readFileSync(rawFilePath, 'utf-8')
console.log(`┌─ [${fi + 1}/${rawFiles.length}] ${rawName}`)
console.log(`│ ${rawContent.length} 字符 | ${rawContent.split('\n').length} 行`)
const maxIterations = 3
const targetScore = 80
let lastOutput = ''
let bestScore = 0
for (let i = 0; i < maxIterations; i++) {
const roundStart = Date.now()
let compileOutput
if (i === 0) {
const promptLen = 8000 + existingTitles.join('').length
console.log(`├ 第1轮·编译 | prompt ~${(promptLen / 1000).toFixed(1)}k | ${now()}`)
compileOutput = await compileNewPages(rawContent, rawName, existingTitles, kbPath)
} else {
const issues = validateMultiPage(lastOutput)
const errorList = issues.reports
.flatMap(r => r.issues.map(iss => `[${iss.severity}] ${iss.rule}: ${iss.message}`))
.join('\n')
if (!errorList) {
console.log(`├ 第${i + 1}轮·跳过 — 无可修复问题`)
break
}
const fixPromptLen = errorList.length + lastOutput.length
console.log(`├ 第${i + 1}轮·修复 | prompt ~${(fixPromptLen / 1000).toFixed(1)}k | ${now()}`)
const schema = loadSchemaPrompt(kbPath)
compileOutput = await chat([
{ role: 'system', content: schema },
{ role: 'user', content: `上一轮的输出有以下质量问题,请逐一修复后重新输出:\n\n${errorList}\n\n上一轮输出:\n${lastOutput}` },
], undefined, { kbPath, role: 'compile' })
}
const roundMs = Date.now() - roundStart
lastOutput = compileOutput
const validation = validateMultiPage(compileOutput)
const score = validation.overallScore
if (score > bestScore) bestScore = score
const sections = compileOutput.split(/(?=^# )/m).filter(s => s.trim())
const pageCount = sections.length
const allIssues = validation.reports.flatMap(r => r.issues)
const icon = score >= 80 ? '✅' : score >= 60 ? '⚠️' : '❌'
console.log(`│ ${icon} ${score}分 ${pageCount}页 | ${(roundMs / 1000).toFixed(1)}s | 输出 ${(compileOutput.length / 1000).toFixed(1)}k`)
if (allIssues.length > 0) {
console.log(`│ 问题: ${issueSummary(allIssues)}`)
}
if (validation.overallScore >= targetScore) {
console.log(`│ ✓ 达标`)
break
} else if (i < maxIterations - 1) {
console.log(`│ ↻ 未达标,下一轮修复...`)
}
}
allResults.push({
rawName, rawSize: rawContent.length, bestScore,
pages: lastOutput.split(/(?=^# )/m).filter(s => s.trim()).length,
})
console.log(`└─ 最高分: ${bestScore}\n`)
}
// Summary
const totalMs = Date.now() - totalStart
const avgScore = Math.round(allResults.reduce((s, r) => s + r.bestScore, 0) / allResults.length)
const goodFiles = allResults.filter(r => r.bestScore >= 80)
const badFiles = allResults.filter(r => r.bestScore < 60)
console.log(`${'═'.repeat(60)}`)
console.log(` 结果 | ${now()} | 总耗时 ${(totalMs / 60000).toFixed(1)}min`)
console.log(` 总分: ${avgScore}/100 | 达标: ${goodFiles.length} | 不及格: ${badFiles.length}`)
console.log(`${'═'.repeat(60)}\n`)
for (const r of allResults) {
const icon = r.bestScore >= 80 ? '✅' : r.bestScore >= 60 ? '⚠️' : '❌'
console.log(` ${icon} ${String(r.bestScore).padStart(3)} ${r.rawName} → ${r.pages} 页`)
}
if (badFiles.length > 0) {
console.log(`\n关键问题: ${badFiles.length} 个文件不及格,提示词仍需改进。`)
}
}
main().catch(err => { console.error('Fatal:', err); process.exit(1) })