diff --git a/.env.example b/.env.example index 7b31756..61bc22d 100644 --- a/.env.example +++ b/.env.example @@ -7,6 +7,10 @@ OPENAI_BASE_URL=https://api.openai.com/v1 OPENAI_API_KEY=your_openai_api_key OPENAI_MODEL=gpt-4o-mini +# 自定义AI Prompt (可选) +# CUSTOM_SUMMARY_PROMPT=你的自定义总结Prompt,变量会自动注入 +# CUSTOM_LINE_COMMENT_PROMPT=你的自定义行评论Prompt,变量会自动注入 + # 应用配置 PORT=3000 # 建议使用以下命令生成一个安全的随机字符串作为webhook密钥: diff --git a/README.md b/README.md index 6b59b9f..50623db 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,8 @@ - `OPENAI_BASE_URL`: OpenAI 请求地址 - `OPENAI_API_KEY`: OpenAI API密钥 - `OPENAI_MODEL`:OpenAI 使用模型 +- `CUSTOM_SUMMARY_PROMPT`: 自定义总结审查提示 (可选) +- `CUSTOM_LINE_COMMENT_PROMPT`: 自定义行评论提示 (可选) - `PORT`: 应用监听端口 (默认: 3000) - `WEBHOOK_SECRET`: Webhook秘钥,用于验证请求来源 @@ -119,3 +121,24 @@ ## 许可证 MIT + +## 自定义AI审查提示 + +默认情况下,AI代码审查工具配置为只对明显的bug和严重问题进行评论。你可以通过环境变量自定义AI使用的提示: + +### 自定义总结提示 + +设置`CUSTOM_SUMMARY_PROMPT`环境变量来自定义代码审查总结。你可以在提示中使用以下变量,它们会在运行时被自动替换: + +- `${context.diffContent}` - 代码差异内容 +- `${JSON.stringify(fileInfo, null, 2)}` - 变更文件的完整信息 + +### 自定义行评论提示 + +设置`CUSTOM_LINE_COMMENT_PROMPT`环境变量来自定义行级评论生成。你可以在提示中使用以下变量: + +- `${file.path}` - 当前文件路径 +- `${fileContent}` - 文件的完整内容 +- `${file.changes.map(c => `${c.lineNumber}: ${c.content} (${c.type === 'add' ? '新增' : '上下文'})`).join('\n')}` - 变更行的上下文 + +请确保你的自定义提示返回正确的格式,特别是对于行评论,必须返回有效的JSON数组。 diff --git a/src/config/index.ts b/src/config/index.ts index 5ee8914..941b240 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -17,6 +17,8 @@ const envSchema = z.object({ OPENAI_BASE_URL: z.string().url().default('https://api.openai.com/v1'), OPENAI_API_KEY: z.string().default('test_openai_key'), OPENAI_MODEL: z.string().default('gpt-4o-mini'), + CUSTOM_SUMMARY_PROMPT: z.string().optional(), + CUSTOM_LINE_COMMENT_PROMPT: z.string().optional(), // 应用配置 PORT: z.string().transform(Number).default('3000'), @@ -47,6 +49,8 @@ export default { baseUrl: envParseResult.success ? envParseResult.data.OPENAI_BASE_URL : 'https://api.openai.com/v1', apiKey: envParseResult.success ? envParseResult.data.OPENAI_API_KEY : 'test_openai_key', model: envParseResult.success ? envParseResult.data.OPENAI_MODEL : 'gpt-4o-mini', + customSummaryPrompt: envParseResult.success ? envParseResult.data.CUSTOM_SUMMARY_PROMPT : undefined, + customLineCommentPrompt: envParseResult.success ? envParseResult.data.CUSTOM_LINE_COMMENT_PROMPT : undefined, }, app: { port: envParseResult.success ? envParseResult.data.PORT : 3000, diff --git a/src/services/ai-review.ts b/src/services/ai-review.ts index b137bb7..d1d5931 100644 --- a/src/services/ai-review.ts +++ b/src/services/ai-review.ts @@ -184,8 +184,8 @@ export const aiReviewService = { }; }); - // 构建更丰富的提示 - const summaryPrompt = `作为经验丰富的代码审查专家,请对以下代码变更进行深入审查,提供一个全面详细的评价和建议。 + // 使用自定义prompt或默认prompt + const defaultSummaryPrompt = `作为经验丰富的代码审查专家,请对以下代码变更进行深入审查,提供一个全面详细的评价和建议。 关注点包括但不限于:代码质量、潜在bug、性能问题、安全问题、最佳实践等。 请用中文回复,保持专业简洁。 @@ -195,7 +195,9 @@ export const aiReviewService = { ==== 变更文件的完整信息 ==== ${JSON.stringify(fileInfo, null, 2)} - 请根据以上信息,特别是考虑每个文件的完整内容和上下文,提供详细的代码审查评价。`; + 请根据以上信息,特别是考虑每个文件的完整内容和上下文,提供代码审查评价。如果没有发现明显问题,请简短说明代码质量良好即可。`; + + const summaryPrompt = config.openai.customSummaryPrompt || defaultSummaryPrompt; // 获取总体评价 const summaryResponse = await openai.chat.completions.create({ @@ -203,7 +205,7 @@ export const aiReviewService = { messages: [ { role: 'system', - content: '你是一个专业的代码审查助手,擅长提供有建设性的代码评审意见。你会查看代码的完整上下文,而不仅仅是变更部分,从而提供更准确的评价。' + content: '你是一个专业的代码审查助手,擅长识别代码中的严重问题和bug。你会查看代码的完整上下文,而不是为了评论而评论。如无明显问题,应给予简短肯定。' }, { role: 'user', content: summaryPrompt } ], @@ -238,10 +240,16 @@ export const aiReviewService = { // 获取文件的完整内容作为上下文 const fileContent = context.fileContents[file.path] || ''; - // 构建提示 - const filePrompt = `分析以下代码文件的新增代码行,找出潜在问题并提供具体行级评论。 - 只对有问题的代码行提供评论,如果代码行没有明显问题则不需要评论。 - 为每个评论提供行号和具体的改进建议。 + // 使用自定义prompt或默认prompt + const defaultFilePrompt = `分析以下代码文件的新增代码行,只针对存在明显bug或严重问题的代码行提供具体评论。 + 大多数代码行不需要评论,除非它们包含以下问题: + - 明显的bug或逻辑错误 + - 严重的安全漏洞 + - 可能导致崩溃的代码 + - 明显的性能瓶颈 + - 数据一致性问题 + + 如果没有发现严重问题,请返回空数组。不要为了提供评论而勉强寻找问题。 文件路径: ${file.path} @@ -260,13 +268,15 @@ export const aiReviewService = { ] 只返回JSON数组,不要有其他文本。`; + const filePrompt = config.openai.customLineCommentPrompt || defaultFilePrompt; + // 获取行级评论 const lineResponse = await openai.chat.completions.create({ model: config.openai.model, messages: [ { role: 'system', - content: '你是一个精确的代码审查助手,只对有问题的代码行提供具体评论。你会考虑文件的完整上下文,而不仅仅是变更部分。请以JSON格式返回结果。' + content: '你是一个谨慎的代码审查助手,只对有明显bug或严重问题的代码行提供评论。大多数情况下,如果代码没有严重问题,你应该返回空数组。请以JSON格式返回结果。' }, { role: 'user', content: filePrompt } ],