一、环境构建与模型部署
1.1 Ollama本地化部署
关于本地部署deepseek,可以看我之前的文章,此处不再详细介绍:Windows零门槛部署DeepSeek大模型:Ollama+7B参数模型
文中进行了详细的部署说明。
另外,不想本地部署deepseek的同学,可以调用deepseek的api进行访问,这里我给大家推荐我用的平台:硅基流动 官网,他整合了目前主流的ai大模型,可以直接从这个平台申请秘钥,而且解决了目前deepseek不能充值的问题。
1.1.1 Windows环境配置
# 安装Windows子系统Linux(WSL2)
wsl --install -d Ubuntu-22.04
# 在WSL中安装Ollama
curl -fsSL https://ollama.ai/install.sh | sh
# 拉取DeepSeek模型(7B/67B按需选择)
ollama run deepseek-r1:7b
避坑指南:若出现CUDA out of memory错误,增加虚拟内存至16GB1:
1.2 Spring AI环境搭建
1.2.1 项目依赖配置(pom.xml )
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-ollama-spring-boot-starter</artifactId>
<version>0.8.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
1.2.2 配置文件(application.yml )
spring:
ai:
ollama:
base-url: http://localhost:11434
chat:
options:
model: deepseek-ai/deepseek-coder:7b
temperature: 0.5
top_p: 0.9
具体的参数需要根据你本地安装的模型版本而定,我这里选的是7B模型。
二、核心功能实现
2.1 基础对话接口
@RestController
@RequiredArgsConstructor
public class DeepSeekController {
private final OllamaChatClient chatClient;
@PostMapping("/chat")
public Flux<String> streamChat(@RequestBody ChatRequest request) {
return chatClient.stream(request.toPrompt());
}
@Data
static class ChatRequest {
private String message;
private boolean stream = true;
public Prompt toPrompt() {
return new Prompt(new UserMessage(message));
}
}
}
j
2.2 代码生成增强实现
@Service
public class CodeGenerator {
@ChatClient
private OllamaChatClient chatClient;
public String generateCode(String requirement) {
String systemPrompt = """
你是一个全栈开发专家,按以下规则生成代码:
1. 使用Java 17语法
2. 包含必要的异常处理
3. 添加Swagger文档注解
4. 返回格式:``````java <代码> ```
""";
Prompt prompt = new Prompt(List.of(
new SystemMessage(systemPrompt),
new UserMessage(requirement)
));
return chatClient.call(prompt).getResult().getOutput().getContent();
}
}
2.3 流式响应处理
@Configuration
public class StreamingConfig {
@Bean
RouterFunction<ServerResponse> sseEndpoint(OllamaChatClient chatClient) {
return route()
.POST("/stream", req ->
ServerResponse.ok()
.contentType(MediaType.TEXT_EVENT_STREAM)
.body(chatClient.stream(req.bodyToMono(Prompt.class)), String.class)
).build();
}
}
三、工业级优化方案
3.1 性能调优参数
spring:
ai:
ollama:
connect-timeout: 10s
read-timeout: 30s
max-in-memory-size: 50MB
retry:
max-attempts: 3
backoff:
initial: 1s
max: 5s
3.2 本地模型监控
集成Micrometer指标采集:
@Bean
MeterRegistryCustomizer<OllamaMetrics> ollamaMetrics(MeterRegistry registry) {
return metrics -> metrics.bindTo(registry);
}
四、安全防护机制
4.1 请求内容过滤
public class XSSFilter implements PromptTransformer {
@Override
public Prompt transform(Prompt prompt) {
String sanitized = prompt.getContents().stream()
.map(msg -> msg.getContent()
.replaceAll("<script>", "")
.replaceAll("\\bexec\\b", ""))
.collect(Collectors.joining());
return new Prompt(sanitized);
}
}
4.2 访问频率控制
@Bean
RateLimiterGatewayFilterFactory rateLimiter() {
return new RateLimiterGatewayFilterFactory(
RedisRateLimiter.of(10, 20) // 10请求/秒,突发20
);
}
五、实战场景测试
5.1 压力测试结果
使用JMeter模拟100并发:
5.2 效果对比
// 测试用例
@Test
void testCodeGeneration() {
String requirement = "实现JWT登录验证";
String code = codeGenerator.generateCode(requirement);
assertThat(code)
.contains("@RestController")
.containsPattern("HttpStatus\\.UNAUTHORIZED")
.contains("io.jsonwebtoken.Claims");
}