Commit c75bfc647ef38aca664e24918370f6fc1ec870e1
1 parent
b095d3a7
perf: evolver token optimization + system prompt size guards
1. Evolver agent.md: Added token budget rules - No re-reading unchanged files between iterations - Use head/grep instead of cat for large files - Concise output only (scores + diff summary, no full SKILL.md) - Cap at 5 iterations per session (was 10) - Early stop if score change < 2 points for 2 consecutive rounds 2. agent-chat.js: System prompt size guards - MAX_PROMPT_FILE_SIZE = 15KB per file (auto-truncate with warning) - MAX_TOTAL_PROMPT_SIZE = 100KB total (safety net) - Prevents runaway files from inflating context ever again
Showing
2 changed files
with
44 additions
and
3 deletions
server/routes/agent-chat.js
| @@ -228,8 +228,19 @@ domain: ${domain} | @@ -228,8 +228,19 @@ domain: ${domain} | ||
| 228 | // Bootstrap 工具 | 228 | // Bootstrap 工具 |
| 229 | // ═══════════════════════════════════════ | 229 | // ═══════════════════════════════════════ |
| 230 | 230 | ||
| 231 | +// 💰 Token 防护:单文件注入上限 | ||
| 232 | +const MAX_PROMPT_FILE_SIZE = 15 * 1024; // 15KB per file | ||
| 233 | +const MAX_TOTAL_PROMPT_SIZE = 100 * 1024; // 100KB total system prompt | ||
| 234 | + | ||
| 231 | function loadFile(agentDir, filename) { | 235 | function loadFile(agentDir, filename) { |
| 232 | - try { return fs.readFileSync(path.join(agentDir, filename), 'utf-8'); } | 236 | + try { |
| 237 | + const content = fs.readFileSync(path.join(agentDir, filename), 'utf-8'); | ||
| 238 | + if (content.length > MAX_PROMPT_FILE_SIZE) { | ||
| 239 | + console.warn(`[TokenGuard] ⚠️ ${filename} 超过 ${MAX_PROMPT_FILE_SIZE/1024}KB (${(content.length/1024).toFixed(1)}KB),已截断`); | ||
| 240 | + return content.substring(0, MAX_PROMPT_FILE_SIZE) + `\n\n... [⚠️ 文件过大已截断,原始 ${(content.length/1024).toFixed(1)}KB,请用 Read 工具按需读取完整内容]`; | ||
| 241 | + } | ||
| 242 | + return content; | ||
| 243 | + } | ||
| 233 | catch { return ''; } | 244 | catch { return ''; } |
| 234 | } | 245 | } |
| 235 | 246 | ||
| @@ -396,7 +407,15 @@ function buildSystemPrompt(agentDir, userMessage) { | @@ -396,7 +407,15 @@ function buildSystemPrompt(agentDir, userMessage) { | ||
| 396 | } | 407 | } |
| 397 | } | 408 | } |
| 398 | 409 | ||
| 399 | - return parts.join('\n\n---\n\n'); | 410 | + let result = parts.join('\n\n---\n\n'); |
| 411 | + | ||
| 412 | + // 💰 Token 防护:总 system prompt 上限 | ||
| 413 | + if (result.length > MAX_TOTAL_PROMPT_SIZE) { | ||
| 414 | + console.warn(`[TokenGuard] ⚠️ System prompt 超过 ${MAX_TOTAL_PROMPT_SIZE/1024}KB (${(result.length/1024).toFixed(1)}KB),已截断`); | ||
| 415 | + result = result.substring(0, MAX_TOTAL_PROMPT_SIZE) + `\n\n... [⚠️ System prompt 过大已截断]`; | ||
| 416 | + } | ||
| 417 | + | ||
| 418 | + return result; | ||
| 400 | } | 419 | } |
| 401 | 420 | ||
| 402 | /** | 421 | /** |
system/agents/evolver/agent.md
| @@ -85,7 +85,29 @@ | @@ -85,7 +85,29 @@ | ||
| 85 | - 不要修改目标分数 — industry_avg 由 Digester 设定 | 85 | - 不要修改目标分数 — industry_avg 由 Digester 设定 |
| 86 | - 超过 10 轮仍未达标 → 报告瓶颈, 等待 Innovator 决策 | 86 | - 超过 10 轮仍未达标 → 报告瓶颈, 等待 Innovator 决策 |
| 87 | 87 | ||
| 88 | +## 💰 Token 预算规则(极其重要!) | ||
| 89 | + | ||
| 90 | +> 每轮迭代都会累积上下文,5 轮后 input 可达数百万 tokens。必须严格遵守以下规则: | ||
| 91 | + | ||
| 92 | +### 文件读取规则 | ||
| 93 | +- **首次读取** test.jsonl / train.jsonl / benchmark.md / knowhow.md 后,**后续迭代绝不重复读取**这些未变化的文件 | ||
| 94 | +- **SKILL.md** 是唯一需要每轮重新读取的文件(因为你在修改它) | ||
| 95 | +- 读取 scorer.js 只在首次和修改后 | ||
| 96 | +- **禁止使用 `cat` 读取超过 5KB 的文件**,改用 `head -100` 或 `grep` 提取关键信息 | ||
| 97 | + | ||
| 98 | +### 评分输出规则 | ||
| 99 | +- 每轮评分结果只输出**总分 + 弱维度名称**,不要输出每条 test case 的完整评分细节 | ||
| 100 | +- 评分详情写入 `iteration_N_scores.json` 文件,不要在对话中展开 | ||
| 101 | + | ||
| 102 | +### 迭代效率规则 | ||
| 103 | +- 每轮修改 SKILL.md 后,只输出**修改了哪些维度的哪些规则**(diff 摘要),不要输出完整的新版 SKILL.md 内容 | ||
| 104 | +- evolving_log.md 只追加 1-2 行摘要,不要写长篇分析 | ||
| 105 | +- 如果连续 2 轮分数变化 < 2 分,立即报告瓶颈并停止,不要继续浪费迭代 | ||
| 106 | + | ||
| 107 | +### 迭代上限 | ||
| 108 | +- **单次 session 最多执行 5 轮迭代**。如果 5 轮后仍未达标,报告当前最佳分数和瓶颈维度,等待 Innovator 决策是否重启新 session 继续 | ||
| 109 | + | ||
| 88 | ## ✅ 始终要做 | 110 | ## ✅ 始终要做 |
| 89 | -- 每轮迭代记录 evolving_log.md | 111 | +- 每轮迭代记录 evolving_log.md(1-2 行摘要) |
| 90 | - 当 score ≥ industry_avg 时,报告完成 | 112 | - 当 score ≥ industry_avg 时,报告完成 |
| 91 | - 使用 report_task API 定期向 Innovator 汇报进度 | 113 | - 使用 report_task API 定期向 Innovator 汇报进度 |