2025.4.11

从你的代码和报错信息来看,问题出在 chatClient.prompt().user(userMessage).call().content() 这一行,具体是在构建 HTTP 请求时,某个 HTTP 头的值为 null,导致 NullPointerException。以下是解决方案:


问题定位

  1. 错误根源

    • 报错发生在 HttpRequestBuilderImpl.checkNameAndValue(),说明 chatClient 在发送请求时,某个 HTTP 头的值为 null
    • 可能是 chatClient 的默认配置中包含了未初始化的请求头(例如 AuthorizationContent-Type 等)。
  2. 关键点

    • chatClientSpring AIAnthropicChatModel 或类似组件,它在内部会添加一些请求头(如 API 密钥)。
    • 如果这些头未被正确设置(例如 API 密钥未配置),会导致值为 null

解决方案

1. 检查 chatClient 的配置

确保 chatClient 的依赖配置正确,尤其是 API 密钥和请求头。例如:

# application.yml
spring:
  ai:
    anthropic:
      api-key: YOUR_API_KEY  # 确保这里已配置
      chat:
        model: claude-3-opus-20240229  # 或其他支持的模型

2. 显式设置请求头

如果 chatClient 是自定义的,手动设置必要的头(如 Authorization):

@Bean
public ChatClient chatClient(AnthropicApi anthropicApi) {
    return ChatClient.builder(anthropicApi)
            .defaultHeader("Authorization", "Bearer YOUR_API_KEY") // 确保非空
            .build();
}

3. 捕获并打印详细日志

在调用前打印请求信息,定位具体是哪个头为 null

public ResponseEntity<ChatResponse> chat(@RequestBody ChatRequest request) {
    System.out.println("收到聊天请求: " + request);
    try {
        // 打印当前请求头(调试用)
        System.out.println("当前请求头: " + chatClient.getRequestHeaders()); 

        String content = chatClient.prompt()
                .user(request.getMessage())
                .call()
                .content();
        return ResponseEntity.ok(new ChatResponse(content));
    } catch (Exception e) {
        e.printStackTrace();
        return ResponseEntity.status(500).body(new ChatResponse("错误: " + e.getMessage()));
    }
}

4. 替换为 WebClient(可选)

如果问题持续,改用更现代的 WebClient(Spring WebFlux 的 HTTP 客户端):

@Bean
public WebClient anthropicWebClient() {
    return WebClient.builder()
            .baseUrl("https://api.anthropic.com")
            .defaultHeader("Authorization", "Bearer YOUR_API_KEY")
            .build();
}

5. 升级依赖版本

如果是 Spring AI 或 Anthropic 客户端的 Bug,尝试升级到最新版本:

<!-- pom.xml -->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-anthropic</artifactId>
    <version>0.8.1</version> <!-- 检查最新版本 -->
</dependency>

修复后的代码示例

@PostMapping
public ResponseEntity<ChatResponse> chat(@RequestBody ChatRequest request) {
    try {
        // 确保消息非空
        if (request.getMessage() == null || request.getMessage().isEmpty()) {
            return ResponseEntity.badRequest().body(new ChatResponse("消息不能为空"));
        }

        // 调用聊天接口
        String content = chatClient.prompt()
                .user(request.getMessage())
                .call()
                .content();

        return ResponseEntity.ok(new ChatResponse(content));
    } catch (Exception e) {
        return ResponseEntity.internalServerError()
                .body(new ChatResponse("请求失败: " + e.getMessage()));
    }
}

关键检查点

  1. 环境变量
    确保 spring.ai.anthropic.api-key 已正确设置在 application.yml 或环境变量中。

  2. 依赖注入
    确认 chatClient 是通过 @Autowired 注入的,而非手动实例化:

    @Autowired
    private ChatClient chatClient;
    
  3. 错误处理
    catch 块中的响应码改为 500(服务器错误),而非 200


如果问题仍未解决,请提供:

  1. chatClient 的初始化代码。
  2. application.yml 中 Anthropic 相关的配置。
  3. 完整的请求/响应日志(启用 DEBUG 日志级别)。
posted @ 2025-04-11 23:01  258333  阅读(88)  评论(0)    收藏  举报