模块1(下):用Spring AI从0到1搭一个代码审查助手
上篇讲了4个核心技巧——角色约束、格式控制、Few-shot、思维链。今天用完整实战把它们串起来,再聊聊温度参数怎么选、以及我踩过的4个坑。
温度参数怎么选
这是另一个让我踩坑的点。
一开始我以为temperature=0最稳定,结果发现模型回答越来越"保守",稍微有点开放性的问题就直接说"这个问题我无法回答"。
后来才明白:temperature控制的是"随机性",不是"准确性"。
Java代码里的设置:
// 精确场景:代码审查var strictRequest = OpenAiChatOptions.builder() .withTemperature(0.1) .build();// 平衡场景:日常问答var balancedRequest = OpenAiChatOptions.builder() .withTemperature(0.5) .build();// 创意场景:起名字、想创意var creativeRequest = OpenAiChatOptions.builder() .withTemperature(0.8) .build();所以:温度不是越高越好,也不是越低越稳定。选对场景就行。
完整实战:Spring AI代码审查助手
来一个能直接跑的完整例子。
Maven依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-openai-spring-boot-starter</artifactId></dependency>application.yml配置
spring:ai:openai:api-key:${OPENAI_API_KEY}model:gpt-4o完整Controller
@RestController@RequestMapping("/api/review")publicclassCodeReviewController{privatefinal ChatModel chatModel;publicCodeReviewController(ChatModel chatModel){this.chatModel = chatModel; }/** * 代码审查主接口 * 结合了:角色约束 + Few-shot + CoT + 结构化输出 */@PostMapping("/java")public Map<String, Object> reviewJavaCode(@RequestBody Map<String, String> request){ String code = request.get("code"); String prompt = buildReviewPrompt(code);var options = OpenAiChatOptions.builder() .withModel("gpt-4o") .withTemperature(0.2) // 低温保证格式稳定 .withResponseFormat(new ResponseFormat("json_object")) .withMaxTokens(2000) .build();try { String result = chatModel.call(new Prompt(prompt, options)) .getResult().getOutput().getText();return Map.of("success", true,"result", parseJson(result),"raw", result ); } catch (Exception e) {return Map.of("success", false,"error", e.getMessage() ); } }private String buildReviewPrompt(String code){return""" 你是一个拥有15年经验的Java架构师,精通Spring全家桶、并发编程、JVM调优。 请用思维链方式审查代码,先分析逻辑,再指出问题,最后给出评分和建议。 评分标准: - 90-100:生产级代码,可直接上线 - 70-89:有优化空间,需要review - 50-69:存在明显风险,需要重构 - 50以下:建议重写 审查代码: %s 请返回JSON格式(不要添加任何解释性文字): { "score": 分数, "grade": "等级描述", "thinking": ["思考步骤1", "思考步骤2", "思考步骤3"], "issues": [ { "severity": "high|medium|low", "type": "NPE|并发|性能|安全|规范", "location": "代码位置", "description": "问题描述", "suggestion": "修改建议" } ], "summary": "整体评价" } """.formatted(code); }private Map<String, Object> parseJson(String json){// 实际项目中建议使用Jackson解析// 这里简化处理return Map.of("raw", json); }}测试请求
curl -X POST http://localhost:8080/api/review/java \ -H "Content-Type: application/json" \ -d '{ "code": "public String getUserName(Integer userId) { return userDao.findById(userId).getName(); }" }'返回示例:
{"success": true,"result": {"score": 45,"grade": "建议重写","thinking": ["userId可能是null,直接传入会导致NPE","findById可能返回null,调用getName()会NPE","整体缺乏参数校验和异常处理" ],"issues": [ {"severity": "high","type": "NPE","location": "第1行","description": "Integer参数可能为null","suggestion": "添加 Objects.requireNonNull(userId) 或判空处理" }, {"severity": "high","type": "NPE","location": "第1行","description": "findById可能返回Optional.empty()","suggestion": "使用 Optional.ofNullable() 或 ifPresent()" } ],"summary": "存在严重的空指针风险,建议重构后上线" }}常见坑,我帮你踩过了
坑1:Prompt越长越好?
不是。Prompt太长会导致:
模型"注意力分散",关键指令被稀释 token消耗增加,响应变慢 成本上涨
解法:删除所有"礼貌性废话",只留指令。模型不需要"请您帮我...",直接"帮我..."就行。
坑2:temperature=0就稳定?
不一定。温度控制的是token选择的随机性,但模型本身有"默认行为"。
想让输出稳定,温度+结构化输出要组合使用。
var options = OpenAiChatOptions.builder() .withTemperature(0.1) // 低温 .withResponseFormat(new ResponseFormat("json_object")) // 强制JSON .build();坑3:示例越多越好?
不是。3个示例足够,再多反而会让模型"过度拟合"到示例的风格。
Few-shot的黄金规则:3个示例,覆盖正向、负向、边界情况。
坑4:直接问"你理解了吗?"
没用。模型会说"我理解了",但不代表它真的理解了。
解法:让模型复述任务或给出执行计划,通过输出来验证理解。
今天就能动手的任务
学再多不如动手练。今天给你三个任务,从简单到复杂:
任务1(5分钟):改造你现有的一个Prompt,加上角色约束。
把"帮我写代码"改成:
"你是一个Spring Boot专家,请帮我写一个用户注册接口,包含参数校验和异常处理"
看看回答质量有没有变化。
任务2(15分钟):让ChatGPT返回一个JSON结构化的自我介绍。
用这个Prompt:
"请以JSON格式返回你自己的介绍,包含name、experience(年数)、skills(数组)"
然后在代码里解析这个JSON,感受结构化输出的价值。
任务3(30分钟):用Spring AI写一个带Few-shot的翻译接口。
System Prompt定义角色(中英翻译专家) Few-shot给出3个翻译示例 让用户输入中文,返回英文JSON
完整代码可以参考上面的Controller,改改Prompt就行。
总结
这一篇我们用Spring AI把四个技巧——角色约束、格式控制、Few-shot、CoT——串起来,实现了完整的代码审查助手。
关键点回顾:
温度参数要匹配场景,不是越低越好 结构化输出+低温是稳定JSON的黄金组合 Few-shot用3个示例覆盖正负向和边界情况 思维链能显著提升复杂任务的准确率
下一篇文章,我们聊模块2:RAG深度调优——怎么让你的AI真正"懂"你的业务数据。
(完整代码已上传到GitHub,文末有链接)
往期文章:
Java转AI,我整理了8个模块的学习路线图
如果这篇文章对你有帮助,欢迎关注我
我会持续分享Java AI落地的实战经验,涵盖Spring AI、RAG、智能体开发等核心模块。
夜雨聆风