Files
L2keka/server/update_standards_v8.js
T

256 lines
11 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const Database = require('better-sqlite3');
const db = new Database('data/ai-review.db');
const dims = [
{
name: '场景价值与技术合理性',
maxScore: 10,
content: `AI读取参赛者的方案文档(DESIGN.md / docs/ 等),判断场景论述的质量。
评分要素:
1) 真实需求(3分)— 解决的是真实业务需求还是虚构场景
2) Agent不可替代性(3分)— 为什么非用Agent不可,不是传统脚本/工具能解决的
3) ROI可量化(2分)— 效率提升/成本降低等有数据支撑
4) 场景文档完整性(2分)— 业务背景、痛点分析、方案对比齐全
无场景文档 → 0分`
},
{
name: '开发范式应用',
maxScore: 5,
content: `通过分析已有文件的内容推断参赛者是否遵循了合理的开发范式。
评分要素:
1) 开发流程覆盖(2分)— AI日志是否覆盖需求分析→设计→编码→测试的完整流程
2) 设计文档质量(2分)— 是否有需求分析、架构设计、接口设计文档
3) 测试文档质量(1分)— 是否有测试用例、测试计划、测试报告
没有任何一个维度的证据 → 0分`
},
{
name: '架构设计',
maxScore: 10,
content: `架构文档存在性 + 允许代码反向推断。
discoverFiles 扩大匹配:**/architecture*、**/design*、含"架构"/"模块"/"数据流"关键词的文件。
评分要素:
1) 架构文档存在且质量高(3分)— 有 DESIGN.md / docs/design.md 等完整文档
2) 模块化与分层(3分)— 代码是否按职责分层、模块间依赖是否合理
3) 数据流清晰度(2分)— 数据流转路径是否可追溯
4) 可扩展性(2分)— 是否有接口抽象、插件机制等便于扩展的设计
文档规则:
- 有完整架构文档:可评至满分10分
- 无文档但有代码证据:封顶5分(允许根据代码结构反向推断模块化/分层/数据流)
- 无文档且代码混乱:0-3分`
},
{
name: '工具使用与Skill集成深度',
maxScore: 5,
content: `AI框架集成深度 + 开发工具链。
AI框架集成(3分):是否深度使用了LangChain/LangGraph/AutoGen等Agent框架。
- 无框架使用 → 0分
- 使用框架基本功能(chain/pipeline)→ 1分
- 实现了MCP/Function Calling协议 → 2分
- 自定义Agent工具链、有深度框架定制 → 3分
开发工具链(2分):非AI框架的开发工具/基础设施集成。
- IDE集成(VSCode插件/LSP/Webview面板等)→ 1分
- CI/CD配置(GitHub Actions/Jenkins等)、监控/可观测性 → 1分
两项可叠加,上限5分。不再要求必须IDE集成。`
},
{
name: 'Agent核心能力',
maxScore: 25,
content: `4项硬性门槛条件 + 5项评分要素。
门槛条件(二进制判定,缺任意1个→整个维度0分):
所有条件必须从代码中提取具体证据,不接受AI感觉判断:
1) 调用了外部LLM/推理引擎 — 代码中存在对LLM API的调用(openai/deepseek/fetch LLM endpoint),或通过框架抽象调用(LangChain ChatOpenAI / AutoGen LLM config
2) 有明确的工具选择策略 — 存在if-else/switch/map路由逻辑,根据条件选择不同工具执行。无条件分支的直接调用→不通过
3) 存在错误→重试→切换路径 — 存在try-catch+retry loop/fallback handler/降级路径
4) 有跨步骤的状态持久化 — 存在上下文对象传递、DB写状态、session存储、消息历史维护中的至少一种
评分要素:
- Agent存在性(4分):满足4个门槛条件→4分,缺任意1个→整个维度0分
- 工具调用能力(6分):静态if-else工具选择→3分;动态prompt决策/多工具编排→6分
- 自主规划能力(6分):有任务分解(script/model/Agent call)→3分;递归/动态重规划→6分
- 协作机制(5分):多Agent通信(消息总线/共享memory)→3分;自主任务分配/协商→5分
- 可靠性(4分):retry+timeout→2分;fallback+降级策略→4分
所有评分必须引用具体代码文件+行号`
},
{
name: '实现完整度与稳定性',
maxScore: 20,
content: `构建测试 + 启动验证 + 运行时测试 + 异常耐受。
可构建(5分):
- 构建配置完整(package.json/pom.xml/Makefile等)
- tryBuild()实际构建成功(跨平台工具链检测)
- 依赖声明完整(含lockfile加分)
可启动(6分):
- tryStart() HTTP探测成功启动
- 启动配置(scripts.start/Dockerfile等)完善
- 服务在合理时间内就绪(超时30秒)
核心机能(6分):
- Web项目:tryBrowse() Puppeteer自动测试主要页面
- CLI项目:execSync运行并验证输出
- 页面可加载、无JS报错、无网络失败
- 核心交互可操作
异常耐受(3分):
- 错误处理机制(try-catch/错误中间件)
- 边界输入处理
- 降级/熔断机制
tryBuild失败或缺少构建配置→5分以下`
},
{
name: '规模与功能点',
maxScore: 20,
content: `3因子加权,功能点从代码提取,必须有测试托底。
A. 代码规模×功能密度(10分)
规模分档:<500行→基础3分 | 500-2000行→基础6分 | 2000-5000行→基础8分 | >5000行→基础10分
density系数:density<0.01→×0.5(样板代码多) | 0.01-0.03→×0.8(正常范围) | >0.03→×1.0(精悍)
density=函数定义数/总行数(从代码grep提取function/def/=>/fn等)
举例:5000行样板→10×0.5=5分。500行精悍→3×1.0=3分。2000行高密度→8×1.0=8分。
B. 功能点质量与可追溯性(5分)
核心规则:功能点必须由AI从代码提取(路由注册/API端点/事件处理/CLI命令),不接受申报式清单。
- 功能点必须有test/test case对应(无测试托底不计入)
- 0个可追溯功能点→0分 | 1-3个→2分 | 4-6个→3分 | 7+个→5分
C. 业务复杂度(5分)
- 单模块/单功能→1分
- 多模块协作→3分
- 跨系统/跨语言/复杂数据流→5分`
},
{
name: '代码规范性',
maxScore: 10,
content: `4层递进检测。
L0—工具实证(3分):
- 存在Linter配置(.eslintrc/ruff.toml/.pylintrc等)且实际启用→2分
- 运行Linter后零错误→再加1分(工具链不可用时跳过不扣分)
L1—一致性分析(3分):
- 跨文件命名风格统一(camelCase/PascalCase/snake_case一致性)
- 导入/导出模式一致
- 错误处理模式统一
L2—代码Review证据(2分):
- AI日志/PR记录中有代码评审环节
- 前后端/模块间有互审证据
L3—LLM特有检查(2分):
- 无提示注入回传风险
- 无幻觉API调用(调用了不存在的库/函数)
- 无AI同模式重复代码(大量结构相同仅参数不同的重复代码)
无Linter配置且命名不一致→0分`
},
{
name: '演示与文档',
maxScore: 10,
content: `存在性+闭环验证。每个文档类别2个子检查。
README:存在(0.5分)+ 启动方式描述与实际构建配置一致(0.5分)
设计书/架构:存在(0.5分)+ 提及的模块/目录在代码库中存在(0.5分)
测试用例:存在(0.5分)+ 列出的测试场景与实际测试代码对得上(0.5分)
测试报告:存在(0.5分)+ 报告数据(通过数/覆盖率)可追溯(0.5分)
需求分析:存在(0.5分)+ 需求点与实现功能对应(0.5分)
特殊情况:
- 有启动脚本但README说没启动方式→不扣分
- README说用Docker启动但无Dockerfile→闭环不通过,该类扣0.5分
- 五大类全部缺失→0分
- 含演示视频/录屏→加1分(上限10分)`
},
{
name: 'AI使用日志',
maxScore: 5,
content: `文件发现+AI真实性判断。
discoverFiles扩展匹配:包含agent/ai-log/claude/日志/開発記録的文件,不限路径。
评分:
- 无任何AI日志→0分
- 有日志但覆盖不完整(缺阶段/缺提示词记录)→1-3分
- 日志覆盖需求→设计→编码→测试各阶段,且带有工具和提示词记录→4分
- 多份日志交叉验证无矛盾,真实反映开发过程→5分
多份日志自动交叉验证:日志必须引用git commit hash或PR numberAI自动交叉验证git log与日志时间线。时间点匹配率<70%降分。`
},
{
name: '效果与数据',
maxScore: 20,
content: `3项核心检查+测试覆盖补充。
核心检查(15分,各5分):
①覆盖广度(5分):所有核心功能点都有对应测试。测试类型跟项目特性匹配(CLI项目不需要UI测试,不扣分)。交叉验证:功能点清单↔测试文件名/test case名
②断言实质性(5分):是真断言(assertEqual/expect/assertThat),不是空壳。过滤expect(true).toBe(true)、空test→无效测试。测试独立,不依赖其他测试执行顺序
③边界覆盖(5分):异常/空值/边界条件测试存在,不只是happy path
补充(5分):
④测试体系完整性(3分):单元测试+集成测试+功能/E2E等多个层次覆盖。AI生成测试的代码风格与手写不一致→合理,不扣分
⑤结果真实性(2分):测试通过率数据可复现(与tryBuild中npm test结果对比)。无伪造测试数据
完全无测试→0分`
},
{
name: '安全性',
maxScore: 10,
content: `源代码扫描。根据项目实际安全需求评估,存在明确安全风险但无对应防护才扣分。
Prompt注入防护(3分):用户输入是否sanitize、system prompt是否隔离、边界检查
密钥/凭据管理(3分):API Key/token是否硬编码、是否用环境变量/密钥管理服务
工具调用安全(2分):Agent命令执行是否有沙箱、文件读写路径校验、网络请求白名单
数据安全(2分):数据脱敏、日志是否泄露敏感信息、权限控制
无风险场景(纯CLI无网络/无输入)→标注N/A,该维度不纳入总分基数,总分相应调整为140。`
}
];
// Build the markdown content
const content = dims.map(d =>
`## ${d.name}${d.maxScore}分)\n${d.content}`
).join('\n\n');
// Update 赛道一 and 默认标准
const ids = [
'996fa0b9-13d3-4f2f-ab32-7ce1aba14723', // 赛道一
'48e1344e-9ae5-4a74-b7c9-f22cd0a4c1d4', // 默认标准
];
for (const id of ids) {
const old = db.prepare('SELECT name, content FROM standards WHERE id = ?').get(id);
if (!old) { console.log('Not found:', id); continue; }
db.prepare(`UPDATE standards SET content = ?, updated_at = datetime('now') WHERE id = ?`).run(content, id);
console.log(`Updated: ${old.name}`);
}
// Verify
const results = db.prepare('SELECT id, name, substr(content, 1, 50) as preview FROM standards WHERE id IN (?, ?)').all(...ids);
for (const r of results) {
const parsed = require('./src/routes/standards').parseDimensions(
db.prepare('SELECT content FROM standards WHERE id = ?').get(r.id).content
);
console.log(`\n${r.name}: ${parsed.length} dimensions`);
parsed.forEach(d => console.log(` ${d.name} (${d.maxScore}分)`));
const total = parsed.reduce((s, d) => s + d.maxScore, 0);
if (total !== 150) console.log(` ⚠️ 总分${total},不等于150`);
else console.log(' ✅ 总分150');
}
db.close();