欢迎光临
我们一直在努力

Spring AI 核心 API 解析:ChatClient、Prompt、Response

一、核心价值

  • 统一调用范式:ChatClient 抽象层屏蔽不同大模型的调用差异,一套代码适配所有模型

  • 灵活的提示词工程:Prompt 组件支持模板化、参数化构建提示词,降低硬编码维护成本

  • 标准化响应处理:Response 统一封装返回结果,简化多模型响应格式的适配逻辑

  • 可扩展的交互能力:支持同步/异步/流式调用,满足不同业务场景的性能需求

二、前置准备

1. 环境要求

  • JDK 8+、Spring Boot 3.2+、Spring AI 1.0.0.RELEASE

  • 任意大模型 API Key(以 OpenAI GPT-4o 为例)

  • Maven/Gradle 构建工具

2. 依赖配置(Maven)

<!– Spring AI 核心依赖 –> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-openai-spring-boot-starter</artifactId> <version>1.0.0.RELEASE</version> </dependency> <!– Web 依赖(用于接口测试) –> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>

3. 基础配置(application.yml)

spring: ai: openai: api-key: ${OPENAI_API_KEY} # 替换为实际API Key base-url: https://api.openai.com/v1 model: gpt-4o temperature: 0.7 # 生成随机性,0-1之间

三、核心 API 深度解析

1. ChatClient:统一的模型调用入口

核心设计

ChatClient 是 Spring AI 最核心的抽象接口,定义了大模型交互的标准化方法,所有模型(OpenAI/通义千问/文心一言)都实现该接口,核心特性:

  • 屏蔽不同模型的 API 调用细节

  • 支持同步、异步、流式三种调用模式

  • 内置请求参数(temperature、topP 等)适配

核心方法

方法签名

功能说明

使用场景

ChatResponse call(Prompt prompt)

同步调用,阻塞等待结果

简单问答、短文本生成

CompletableFuture<ChatResponse> callAsync(Prompt prompt)

异步调用,非阻塞

高并发场景、批量处理

Flux<ChatResponse> stream(Prompt prompt)

流式调用,逐段返回结果

长文本生成、实时交互

基础使用示例

import org.springframework.ai.chat.ChatClient; import org.springframework.ai.chat.ChatResponse; import org.springframework.ai.chat.prompt.Prompt; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/ai/client") public class ChatClientDemoController { // 自动注入OpenAI实现的ChatClient(Spring AI自动装配) @Autowired private ChatClient chatClient; // 同步调用示例 @GetMapping("/sync") public String syncCall(@RequestParam String question) { // 构建Prompt(下文详解) Prompt prompt = new Prompt(question); // 同步调用获取响应 ChatResponse response = chatClient.call(prompt); // 提取回答内容 return response.getResult().getOutput().getContent(); } // 异步调用示例 @GetMapping("/async") public CompletableFuture<String> asyncCall(@RequestParam String question) { Prompt prompt = new Prompt(question); return chatClient.callAsync(prompt) .thenApply(response -> response.getResult().getOutput().getContent()); } // 流式调用示例(返回SSE流) @GetMapping(value = "/stream", produces = "text/event-stream") public Flux<String> streamCall(@RequestParam String question) { Prompt prompt = new Prompt(question); return chatClient.stream(prompt) .map(response -> response.getResult().getOutput().getContent()); } }

2. Prompt:标准化的提示词构建

核心设计

Prompt 是 Spring AI 对“提示词”的标准化封装,核心能力:

  • 支持纯文本、模板化、多轮对话三种构建方式

  • 可附加模型参数(temperature、topP 等),覆盖单次调用的个性化配置

  • 内置 PromptTemplate 实现参数化提示词,避免硬编码

核心组件

组件

作用

示例

Prompt

核心封装类,包含提示词内容+调用参数

new Prompt(message, parameters)

PromptTemplate

模板化构建,支持变量替换

PromptTemplate.create("生成{language}的{type}代码")

Message

消息单元,支持用户/系统/助手角色

new UserMessage("问题")/new SystemMessage("指令")

进阶使用示例

import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.chat.prompt.PromptTemplate; import org.springframework.ai.chat.messages.UserMessage; import org.springframework.ai.chat.messages.SystemMessage; import org.springframework.ai.openai.OpenAiChatOptions; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.List; import java.util.Map; @RestController @RequestMapping("/ai/prompt") public class PromptDemoController { @Autowired private ChatClient chatClient; // 1. 多角色消息(系统指令+用户问题) @GetMapping("/multi-role") public String multiRolePrompt(@RequestParam String task) { // 系统消息:定义模型行为 SystemMessage systemMessage = new SystemMessage("你是资深Java工程师,仅输出代码和简要注释,不解释其他内容"); // 用户消息:具体需求 UserMessage userMessage = new UserMessage(task); // 构建Prompt Prompt prompt = new Prompt(List.of(systemMessage, userMessage)); // 调用模型 return chatClient.call(prompt).getResult().getOutput().getContent(); } // 2. 模板化Prompt(参数化替换) @GetMapping("/template") public String templatePrompt( @RequestParam String language, @RequestParam String functionName) { // 定义模板 String template = """ 生成{language}语言的{functionName}函数,要求: 1. 符合行业最佳实践 2. 包含参数校验 3. 输出完整代码和注释 """; // 构建模板并绑定参数 PromptTemplate promptTemplate = PromptTemplate.create(template); Map<String, Object> params = new HashMap<>(); params.put("language", language); params.put("functionName", functionName); // 生成Prompt Prompt prompt = promptTemplate.create(params); // 调用模型 return chatClient.call(prompt).getResult().getOutput().getContent(); } // 3. 自定义调用参数(覆盖全局配置) @GetMapping("/custom-params") public String customParamsPrompt(@RequestParam String question) { // 自定义参数:调低随机性,设置最大Token OpenAiChatOptions options = OpenAiChatOptions.builder() .temperature(0.1) // 趋近确定性输出 .maxTokens(1000) // 限制返回长度 .build(); // 构建Prompt并附加参数 Prompt prompt = new Prompt(question, options); // 调用模型 return chatClient.call(prompt).getResult().getOutput().getContent(); } }

3. ChatResponse:标准化的响应处理

核心设计

ChatResponse 是模型返回结果的统一封装,核心特性:

  • 屏蔽不同模型的响应格式差异(OpenAI/通义千问等返回结构统一)

  • 支持提取核心内容、元数据(Token消耗、模型名称等)、多轮对话ID

  • 流式响应逐段封装,便于实时处理

核心属性与方法

属性/方法

作用

示例

getResult()

获取核心结果对象

response.getResult()

getOutput().getContent()

提取回答文本

response.getResult().getOutput().getContent()

getMetadata()

获取元数据(Token、耗时等)

response.getMetadata().get("token_usage")

getId()

获取对话ID(用于多轮对话)

response.getId()

完整解析示例

import org.springframework.ai.chat.ChatResponse; import org.springframework.ai.chat.metadata.ChatGenerationMetadata; import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.openai.metadata.OpenAiChatResponseMetadata; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.Map; @RestController @RequestMapping("/ai/response") public class ResponseDemoController { @Autowired private ChatClient chatClient; @GetMapping("/parse") public Map<String, Object> parseResponse(@RequestParam String question) { Prompt prompt = new Prompt(question); ChatResponse response = chatClient.call(prompt); // 1. 核心回答内容 String content = response.getResult().getOutput().getContent(); // 2. 元数据解析(以OpenAI为例) ChatGenerationMetadata metadata = response.getResult().getMetadata(); OpenAiChatResponseMetadata openAiMetadata = (OpenAiChatResponseMetadata) metadata; // Token消耗 int promptTokens = openAiMetadata.getTokenUsage().getPromptTokens(); int completionTokens = openAiMetadata.getTokenUsage().getCompletionTokens(); // 模型名称 String modelName = openAiMetadata.getModel(); // 响应ID String responseId = response.getId(); // 封装返回结果 return Map.of( "content", content, "prompt_tokens", promptTokens, "completion_tokens", completionTokens, "model_name", modelName, "response_id", responseId ); } }

四、常见问题及解决方案

错误类型

报错信息

解决方案

Prompt 构建异常

"Message list cannot be empty"

确保 Prompt 至少包含一条有效 Message(UserMessage/SystemMessage)

响应解析失败

"ClassCastException: xxx cannot be cast to OpenAiChatResponseMetadata"

按模型类型强转元数据,或使用通用 Metadata 接口

流式响应无输出

"Flux stream is empty"

检查请求头是否为 text/event-stream,或模型是否支持流式输出

自定义参数不生效

"Temperature setting ignored"

确认参数类与模型匹配(如 OpenAiChatOptions 仅适用于 OpenAI)

五、进阶扩展

1. 自定义 ChatClient 包装类(统一异常处理)

import org.springframework.ai.chat.ChatClient; import org.springframework.ai.chat.ChatResponse; import org.springframework.ai.chat.prompt.Prompt; import org.springframework.stereotype.Component; @Component public class CustomChatClient { private final ChatClient delegate; public CustomChatClient(ChatClient chatClient) { this.delegate = chatClient; } // 包装调用逻辑,统一异常处理 public String safeCall(Prompt prompt) { try { ChatResponse response = delegate.call(prompt); return response.getResult().getOutput().getContent(); } catch (Exception e) { // 统一异常处理+降级逻辑 return "模型调用失败:" + e.getMessage() + ",建议稍后重试"; } } }

2. Prompt 模板复用(全局模板管理)

import org.springframework.ai.chat.prompt.PromptTemplate; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @Configuration public class PromptTemplateConfig { // 全局Prompt模板缓存 @Bean public Map<String, PromptTemplate> promptTemplateCache() { Map<String, PromptTemplate> cache = new ConcurrentHashMap<>(); // 预加载常用模板 cache.put("java-code", PromptTemplate.create("生成符合{standard}标准的Java{type}代码,包含完整注释")); cache.put("sql-optimize", PromptTemplate.create("优化以下SQL:{sql},说明优化思路和执行计划")); return cache; } }

3. 响应结果封装(统一返回格式)

// 自定义响应DTO public record AiResponseDTO( String content, // 核心回答 Integer promptTokens, // 输入Token Integer compTokens, // 输出Token String model, // 调用模型 Long responseTime // 响应耗时 ) {} // 封装工具方法 public AiResponseDTO wrapResponse(ChatResponse response, long startTime) { OpenAiChatResponseMetadata metadata = (OpenAiChatResponseMetadata) response.getResult().getMetadata(); return new AiResponseDTO( response.getResult().getOutput().getContent(), metadata.getTokenUsage().getPromptTokens(), metadata.getTokenUsage().getCompletionTokens(), metadata.getModel(), System.currentTimeMillis() – startTime ); }


总结

  • ChatClient 是核心调用入口,通过抽象层实现多模型统一调用,支持同步/异步/流式三种模式,适配不同业务场景;

  • Prompt 组件支持多角色消息、模板化构建,是实现精准提示词工程的核心,可附加自定义调用参数覆盖全局配置;

  • ChatResponse 标准化封装响应结果,不仅能提取核心回答,还可解析Token消耗、模型名称等元数据,便于监控和成本核算。

  • 赞(0)
    未经允许不得转载:171主机测评 » Spring AI 核心 API 解析:ChatClient、Prompt、Response
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址