晴天技术
AI4 min read

Spring Boot 集成大模型 API 实战:用 Java 调用 Claude/GPT

Spring Boot 集成大模型 API 实战:用 Java 调用 Claude/GPT

Spring BootLLMClaude APIJavaAI开发

用 Java 集成大模型 API 是当前热门需求。本文介绍如何在 Spring Boot 中调用 Claude 和 GPT API。

准备工作

1. 获取 API Key

  • Claude: 访问 console.anthropic.com 获取
  • GPT: 访问 platform.openai.com 获取

2. 添加依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

调用 Claude API

配置

# application.yml
ai:
  claude:
    api-key: ${CLAUDE_API_KEY}
    base-url: https://api.anthropic.com
    model: claude-sonnet-4-20250514

Service 实现

@Service
public class ClaudeService {

    @Value("${ai.claude.api-key}")
    private String apiKey;

    @Value("${ai.claude.model}")
    private String model;

    private final WebClient webClient;

    public ClaudeService(WebClient.Builder builder,
                         @Value("${ai.claude.base-url}") String baseUrl) {
        this.webClient = builder.baseUrl(baseUrl).build();
    }

    public String chat(String userMessage) {
        Map<String, Object> body = Map.of(
            "model", model,
            "max_tokens", 1024,
            "messages", List.of(
                Map.of("role", "user", "content", userMessage)
            )
        );

        Map response = webClient.post()
            .uri("/v1/messages")
            .header("x-api-key", apiKey)
            .header("anthropic-version", "2023-06-01")
            .bodyValue(body)
            .retrieve()
            .bodyToMono(Map.class)
            .block();

        List<Map> content = (List<Map>) response.get("content");
        return (String) content.get(0).get("text");
    }
}

Controller

@RestController
@RequestMapping("/api/ai")
public class AiController {

    @Autowired
    private ClaudeService claudeService;

    @PostMapping("/chat")
    public Result<String> chat(@RequestBody ChatRequest request) {
        String response = claudeService.chat(request.getMessage());
        return Result.success(response);
    }
}

调用 OpenAI API

@Service
public class OpenAiService {

    @Value("${ai.openai.api-key}")
    private String apiKey;

    private final WebClient webClient;

    public OpenAiService(WebClient.Builder builder) {
        this.webClient = builder
            .baseUrl("https://api.openai.com/v1")
            .build();
    }

    public String chat(String userMessage) {
        Map<String, Object> body = Map.of(
            "model", "gpt-4o",
            "messages", List.of(
                Map.of("role", "user", "content", userMessage)
            )
        );

        Map response = webClient.post()
            .uri("/chat/completions")
            .header("Authorization", "Bearer " + apiKey)
            .bodyValue(body)
            .retrieve()
            .bodyToMono(Map.class)
            .block();

        List<Map> choices = (List<Map>) response.get("choices");
        Map message = (Map) choices.get(0).get("message");
        return (String) message.get("content");
    }
}

流式输出(SSE)

大模型响应慢,流式输出体验更好:

@GetMapping(value = "/chat/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> chatStream(@RequestParam String message) {
    return claudeService.chatStream(message);
}

// Service 中
public Flux<String> chatStream(String userMessage) {
    Map<String, Object> body = Map.of(
        "model", model,
        "max_tokens", 1024,
        "stream", true,
        "messages", List.of(
            Map.of("role", "user", "content", userMessage)
        )
    );

    return webClient.post()
        .uri("/v1/messages")
        .header("x-api-key", apiKey)
        .header("anthropic-version", "2023-06-01")
        .bodyValue(body)
        .retrieve()
        .bodyToFlux(String.class)
        .filter(line -> line.contains("text"))
        .map(this::extractText);
}

实际应用场景

1. 智能客服

@PostMapping("/customer-service")
public Result<String> customerService(@RequestBody CustomerQuestion question) {
    String prompt = String.format(
        "你是客服助手。用户问题:%s\n订单信息:%s\n请用友好语气回答。",
        question.getQuestion(),
        orderService.getOrderInfo(question.getOrderId())
    );
    return Result.success(claudeService.chat(prompt));
}

2. 代码审查

@PostMapping("/code-review")
public Result<String> codeReview(@RequestBody CodeReviewRequest request) {
    String prompt = String.format(
        "审查以下 Java 代码,指出问题和改进建议:\n```java\n%s\n```",
        request.getCode()
    );
    return Result.success(claudeService.chat(prompt));
}

3. SQL 生成

@PostMapping("/generate-sql")
public Result<String> generateSql(@RequestBody SqlRequest request) {
    String prompt = String.format(
        "根据表结构:%s\n生成 SQL:%s",
        request.getTableSchema(),
        request.getRequirement()
    );
    return Result.success(claudeService.chat(prompt));
}

注意事项

  1. API Key 安全:不要硬编码,用环境变量或配置中心
  2. 超时设置:大模型响应慢,设置合理的超时时间(30-60s)
  3. 错误处理:API 可能限流或报错,做好重试和降级
  4. 成本控制:按 token 计费,控制输入输出长度
  5. Prompt 注入:用户输入可能包含恶意 prompt,做好过滤

总结

Spring Boot 集成大模型 API 并不复杂,核心就是 HTTP 调用 + JSON 解析。关键在于:

  • 选对模型(Claude 适合长文本和代码,GPT 适合通用场景)
  • 写好 Prompt(决定输出质量)
  • 做好工程化(错误处理、流式输出、成本控制)