Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ public final class GlobalPromptBuilder {
static final String SYSTEM_ROLE = """
你是一位资深的代码评审专家。请基于以下 Pull Request 的各文件分析摘要和跨文件线索,
进行全局推理分析。不要重复描述各文件摘要,而是聚焦于:
1. 跨文件交互可能引入的风险
1. 跨文件交互可能引入的风险(接口变更、数据流影响)
2. 架构层面的影响(模块耦合、接口兼容性等)
3. 整体代码质量评估与改进建议
3. 实现与测试的对应性:测试是否覆盖了关键路径和边界条件
4. 整体代码质量评估与改进建议
""";

/** 推理要求 */
Expand All @@ -29,6 +30,8 @@ public final class GlobalPromptBuilder {
2. 如果无法确定某个风险,标注为 "需进一步确认"
3. crossFileIssues 必须涉及至少两个文件
4. topPriorityFiles 不超过 3 个
5. 注意检查实现文件与测试文件的对应:有实现变更但无测试补充时,应标注测试缺失风险
6. architectureSuggestions 必须针对本次 PR 已变更的具体代码给出改进,每条建议应关联到具体文件路径,禁止建议"引入第三方库全面替换"等超出本次变更范围的重构
""";

/** 全局输出格式要求 */
Expand All @@ -40,7 +43,7 @@ public final class GlobalPromptBuilder {
"globalRiskReason": "全局风险评级理由",
"crossFileIssues": [
{
"issueType": "INTERFACE_MISMATCH|DUPLICATE_LOGIC|TRANSACTION_MISSING|SECURITY_PROPAGATION|DB_CODE_INCONSISTENCY|OTHER",
"issueType": "INTERFACE_MISMATCH|INTERFACE_INCONSISTENCY|DUPLICATE_LOGIC|REPEAT_LOGIC|TRANSACTION_MISSING|SECURITY_PROPAGATION|SECURITY_VULNERABILITY|DB_CODE_INCONSISTENCY|NUMERICAL_ACCURACY|ALGORITHM_CHOICE|PERFORMANCE|OTHER",
"description": "问题描述",
"involvedFiles": ["文件路径1", "文件路径2"],
"severity": "HIGH|MEDIUM|LOW",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,19 @@ public enum RiskLevel {
HIGH, MEDIUM, LOW
}

/** 跨文件关联问题类型枚举 */
/** 跨文件关联问题类型枚举(与提示词 issueType 枚举一致) */
public enum IssueType {
INTERFACE_MISMATCH,
INTERFACE_INCONSISTENCY,
DUPLICATE_LOGIC,
REPEAT_LOGIC,
TRANSACTION_MISSING,
SECURITY_PROPAGATION,
SECURITY_VULNERABILITY,
DB_CODE_INCONSISTENCY,
NUMERICAL_ACCURACY,
ALGORITHM_CHOICE,
PERFORMANCE,
OTHER
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ public final class ChunkPromptBuilder {

/** 系统角色设定 */
static final String SYSTEM_ROLE = """
你是一位资深的代码评审专家。专注于以下方面:
你是资深数值计算与代码审查专家。审查任何涉及矩阵运算、浮点运算、迭代算法的代码时,必须强制检查以下 3 项,并在输出中明确标注是否通过:
1. 【数值稳定性】若涉及正交化、QR分解、最小二乘等算法,必须评估经典实现(如经典 Gram-Schmidt)的累积舍入误差风险,并对比 Modified GS 或 Householder 变换的适用性。
2. 【维度边界】若涉及矩阵运算,必须检查是否对 m < n(列数大于行数)、零矩阵、秩亏矩阵、非方阵做了前置验证或异常处理。
3. 【浮点比较】禁止直接使用 == 0 或 == 1.0 判断浮点/双精度数值,必须建议引入 epsilon 容差。
同时兼顾代码的通用审查维度:
- 正确性:逻辑错误、边界条件、异常处理
- 安全性:注入风险、权限校验、数据加密
- 性能:N+1查询、资源泄漏、缓存机会
Expand All @@ -28,21 +32,29 @@ public final class ChunkPromptBuilder {
static final String OUTPUT_FORMAT = """
请严格按以下 JSON 格式输出(仅 JSON,不要包含 Markdown 代码块标记或任何额外文字):
{
"summary": "变更摘要(不超过30字)",
"summary": "【变更本质】,影响【影响范围】(严格按此模板,30字内)",
"risks": [
{ "type": "NullPointer|Concurrency|Security|Performance|Maintainability|Other", "line": 行号, "description": "风险说明(不超过100字)" }
{ "type": "NullPointer|Concurrency|Security|Performance|Arithmetic|Maintainability|Other", "line": 行号, "description": "风险说明(不超过100字)" }
],
"suggestions": [
{ "priority": 1-5, "description": "建议内容(不超过100字)" }
],
"riskLevel": "HIGH|MEDIUM|LOW"
}

【风险评级硬性规则】(必须遵守,不得自由发挥)
- HIGH:存在内存安全、并发安全、数据丢失、算法数值崩溃、死循环风险
- MEDIUM:存在算术精度损失、边界条件缺失(如 m<n 未校验)、性能瓶颈、接口不一致风险
- LOW:仅涉及代码风格、命名、注释、轻微可维护性建议
- 强制升级规则:只要存在 1 个数值精度/算法稳定性风险,全局评级至少为 MEDIUM;存在 1 个 HIGH 风险,必须为 HIGH
""";

/** 单块模式额外要求 */
static final String CHUNK_CROSS_CHUNK_HINT =
"5. 跨块依赖提示:如果当前块修改了接口签名、删除了方法、新增了全局变量或修改了配置项,"
+ "请详细描述这些变更,格式:变更内容 -> 影响范围 -> 后续需关注的文件\n";
"6. 跨块依赖提示:如果当前块修改了接口签名、删除了方法、新增了全局变量或修改了配置项,"
+ "请详细描述这些变更,格式:变更内容 -> 影响范围 -> 后续需关注的文件\n"
+ "7. 实现与测试关联提示:如果当前块是实现代码,检查是否有对应的测试文件变更;"
+ "如果是测试代码,说明覆盖了哪些实现路径\n";

/** 反幻觉约束 */
static final String ANTI_HALLUCINATION =
Expand Down Expand Up @@ -75,7 +87,8 @@ public static String buildWholeFile(SanitizedDiff diff) {
+ "1. 变更摘要(30字内)\n"
+ "2. 风险点(标注类型:NullPointer/Concurrency/Security/Performance 等)\n"
+ "3. Review 建议\n"
+ "4. 风险评级(HIGH / MEDIUM / LOW)\n\n"
+ "4. 风险评级(HIGH / MEDIUM / LOW)\n"
+ "5. 矩阵维度边界检查:若代码涉及矩阵初始化、分解、求逆、乘法,检查是否对 m < n(列数大于行数)的情况做了前置校验或异常抛出。若未处理,必须作为 MEDIUM 风险上报\n\n"
+ ANTI_HALLUCINATION + "\n"
+ OUTPUT_FORMAT;
}
Expand Down Expand Up @@ -105,6 +118,7 @@ public static String buildChunk(Chunk chunk) {
sb.append("2. 风险点(标注类型:NullPointer/Concurrency/Security/Performance 等)\n");
sb.append("3. Review 建议\n");
sb.append("4. 风险评级(HIGH / MEDIUM / LOW)\n");
sb.append("5. 矩阵维度边界检查:若代码涉及矩阵初始化、分解、求逆、乘法,检查是否对 m < n(列数大于行数)的情况做了前置校验或异常抛出。若未处理,必须作为 MEDIUM 风险上报\n");
sb.append(CHUNK_CROSS_CHUNK_HINT).append("\n");
sb.append(ANTI_HALLUCINATION).append("\n");
sb.append(OUTPUT_FORMAT);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ void shouldContainSystemRole() {
assertTrue(prompt.contains("资深的代码评审专家"));
assertTrue(prompt.contains("全局推理分析"));
assertTrue(prompt.contains("架构层面的影响"));
assertTrue(prompt.contains("实现与测试的对应性"));
}

@Test
Expand Down Expand Up @@ -111,6 +112,8 @@ void shouldContainReasoningRules() {
assertTrue(prompt.contains("推理要求"));
assertTrue(prompt.contains("至少两个文件"));
assertTrue(prompt.contains("不超过 3 个"));
assertTrue(prompt.contains("测试缺失风险"));
assertTrue(prompt.contains("architectureSuggestions 必须针对本次 PR"));
}

@Test
Expand All @@ -124,6 +127,10 @@ void shouldContainOutputFormat() {
assertTrue(prompt.contains("crossFileIssues"));
assertTrue(prompt.contains("architectureSuggestions"));
assertTrue(prompt.contains("topPriorityFiles"));
assertTrue(prompt.contains("NUMERICAL_ACCURACY"));
assertTrue(prompt.contains("ALGORITHM_CHOICE"));
assertTrue(prompt.contains("INTERFACE_MISMATCH"));
assertTrue(prompt.contains("DUPLICATE_LOGIC"));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,20 @@ void shouldHaveThreeValues() {
class IssueTypeEnum {

@Test
@DisplayName("应包含六种问题类型")
void shouldHaveSixValues() {
assertEquals(6, GlobalReviewReport.IssueType.values().length);
@DisplayName("应包含 12 种问题类型(含新增的数值精度、算法选型、性能等)")
void shouldHaveTwelveValues() {
assertEquals(12, GlobalReviewReport.IssueType.values().length);
assertNotNull(GlobalReviewReport.IssueType.valueOf("INTERFACE_MISMATCH"));
assertNotNull(GlobalReviewReport.IssueType.valueOf("INTERFACE_INCONSISTENCY"));
assertNotNull(GlobalReviewReport.IssueType.valueOf("DUPLICATE_LOGIC"));
assertNotNull(GlobalReviewReport.IssueType.valueOf("REPEAT_LOGIC"));
assertNotNull(GlobalReviewReport.IssueType.valueOf("TRANSACTION_MISSING"));
assertNotNull(GlobalReviewReport.IssueType.valueOf("SECURITY_PROPAGATION"));
assertNotNull(GlobalReviewReport.IssueType.valueOf("SECURITY_VULNERABILITY"));
assertNotNull(GlobalReviewReport.IssueType.valueOf("DB_CODE_INCONSISTENCY"));
assertNotNull(GlobalReviewReport.IssueType.valueOf("NUMERICAL_ACCURACY"));
assertNotNull(GlobalReviewReport.IssueType.valueOf("ALGORITHM_CHOICE"));
assertNotNull(GlobalReviewReport.IssueType.valueOf("PERFORMANCE"));
assertNotNull(GlobalReviewReport.IssueType.valueOf("OTHER"));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ void shouldNotIncludePreviousSummaryWhenAbsent() {
}

@Test
@DisplayName("应包含跨块依赖提示(第 5 项)")
@DisplayName("应包含跨块依赖提示(第 6 项)")
void shouldIncludeCrossChunkHint() {
Chunk chunk = Chunk.builder()
.chunkId("test#hunk-1")
Expand All @@ -165,7 +165,7 @@ void shouldIncludeCrossChunkHint() {
String prompt = ChunkPromptBuilder.buildChunk(chunk);

assertTrue(prompt.contains("跨块依赖提示"));
assertTrue(prompt.contains("5."));
assertTrue(prompt.contains("6."));
}

@Test
Expand Down Expand Up @@ -222,6 +222,8 @@ void wholeFileExcludesCrossChunkHint() {

assertFalse(wholeFilePrompt.contains("跨块依赖提示"));
assertTrue(chunkPrompt.contains("跨块依赖提示"));
assertTrue(chunkPrompt.contains("5. 矩阵维度边界检查"));
assertTrue(chunkPrompt.contains("6. 跨块依赖提示"));
}

@Test
Expand Down