参照该课程
基础概念
token
token是语言模型的 计费/生成 基本单位,大概理解成每token生成0.75个中文。
API KEY
由于大部分人不会部署模型到本地,所以需要消耗token来调用模型,而调用模型的时候需要使用API Key进行身份验证,所以需要准备一个厂商的API Key。
prompt
prompt是输入给模型的文本,模型会根据这个文本来生成相应的输出。
狭义上,prompt就是我们对大模型说了什么,广义上,还包括了其他属性,比如当前设置的 温度Temperature、top_p等参数,这些参数会影响模型的输出结果。
例如:
{
"model": "deepseek-v4-pro",
"messages": [
{
"role": "system",
"content": "这里输入一些人物设定、场景设定、对话风格等信息,来引导模型生成符合预期的内容,如:你是一个段子高手。"
},
{
"role": "user",
"content": "这里是用户输入的内容,如:开个玩笑"
}
],
"temperature": 1.0,
}
接口调用
当拥有一个API Key后,就可以通过HTTP的post请求来调用大模型的接口,向厂家提供的接口发送一个包含prompt与api key的请求,模型会根据这个prompt来生成相应的输出。
例如:
curl https://api.deepseek.com/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${DEEPSEEK_API_KEY}" \
-d '{
"model": "deepseek-v4-pro",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello!"}
],
"thinking": {"type": "enabled"},
"reasoning_effort": "high",
"stream": false
}'
一些参数
上面prompt除了我们发送给大模型的messages,还有一些参数会影响模型的输出结果,常见的参数有:
temperature:控制生成文本的随机程度,值越高,生成的文本越随机,值越低,生成的文本越确定。top_p:与Temperature类似,值越高,生成的文本越多样化,值越低,生成的文本越集中。
大模型本质是一个概率模型,输入一个字后面有不同概率接不同的字,假如输入"我",后面可能接40%接"是"、30%接"喜欢"、20%接"想"等等,
top_p假如说是100%,就会考虑所有的可能性,top_p如果是40%,就只会考虑这里的"是"了。max_tokens:控制生成文本的最大长度,单位是token。stream:控制是否开启流式输出,开启后模型会在生成文本的过程中逐步返回结果,而不是等到生成完成后一次性。
上面的messages列表中可以发现出现了不同的role,常见的有:
system:系统角色,设定AI的行为和角色。user:用户角色,表示用户的输入。assistant:助手角色,表示AI的回复。tool:工具调用的消息。
SpringAI
Spring AI 作为 Spring 官方推出的 AI 应用开发框架,其核心设计哲学是将 AI 能力无缝集成到 Spring 生态系统中,为 Java 开发者提供熟悉、一致的编程模型。
Spring AI 不是要重新发明轮子,而是基于 Spring 的核心原则------依赖注入、面向切面编程和模板模式,为各种 AI 服务提供统一的抽象层。
准备
参考:https://springdoc.cn/spring-ai/index.html
版本/依赖:
JDK:17 (官方最低要求17)
SpringAI :1.0.0
SpringBoot : 3.4.0
一个大模型的starter: 我用的deepseek
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-deepseek</artifactId>
</dependency>
配置yml文件:
yaml
spring:
ai:
deepseek:
api-key: 你的apikey
API - Message
Spring AI 提供消息类型对应prompt中messages列表的不同message。
常见的消息类型有:
SystemMessage:系统消息,用于设定AI的行为和角色。UserMessage:用户消息,表示用户的输入。AssistantMessage:助手消息,表示AI的回复。ToolMessage:工具消息,表示工具调用的消息。
他们都继承自AbstractMessage,包含textContent和messageType两个属性,对应'content'和'role'。
各message之间关系如图:

一个简单的示例展示构建一个聊天接口:
java
package com.example.springai.controller;
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.deepseek.DeepSeekChatModel;
import org.springframework.ai.deepseek.DeepSeekChatOptions;
import org.springframework.ai.deepseek.api.DeepSeekApi;
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;
import reactor.core.publisher.Flux;
import java.util.List;
import java.util.Map;
@RestController
public class ChatController {
// 注入一个DeepSeekChatModel,这个模型是Spring AI提供的一个接口,封装了调用DeepSeek模型的逻辑,我们可以通过它来调用DeepSeek模型生成文本。
private final DeepSeekChatModel chatModel;
@Autowired
public ChatController(DeepSeekChatModel chatModel) {
this.chatModel = chatModel;
}
@GetMapping("/ai/generate")
public Map generate(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
// 构建messages列表
UserMessage userMessage = new UserMessage(message);
SystemMessage systemMessage = new SystemMessage("你是一个段子高手");
// 准备构建Prompt(消息列表和相关参数),参数通过DeepSeekChatOptions来设置
DeepSeekChatOptions deepSeekChatOptions = new DeepSeekChatOptions();
deepSeekChatOptions.setTemperature(1.4);
deepSeekChatOptions.setModel("deepseek-v4-flash");
deepSeekChatOptions.setMaxTokens(2048);
// 通过builder构建DeepSeekChatOptions
DeepSeekChatOptions chatoptions = DeepSeekChatOptions.builder()
.model("deepseek-v4-flash")
.temperature(1.4)
.maxTokens(2048)
.build();
// .call()方法通过ctrl+P查看参数,他可以传入三种类型,分别是String、Message、Prompt。
// 例如:
// return Map.of("generation", chatModel.call("Tell me a joke") ); // 传入string
// return Map.of("generation", chatModel.call(systemMessage, userMessage) ); // 传入message
return Map.of("generation", chatModel.call(new Prompt(List.of(systemMessage, userMessage), deepSeekChatOptions)) ); // 传入prompt
}
}
API - Prompt
刚才的案例中已经初步展示了Prompt的使用,Prompt包括消息列表和相关参数。可以new一个Prompt,包含List.of<Message>和DeepSeekChatOptions,也可以通过builder来构建chatoptions。
API - ChatResponse
.call()方法的返回值是一个ChatResponse对象,包含generation、chatResponseMetadata。
其中generation是模型生成的信息,包含assisantMessage和chatGenerationMetadata;chatResponseMetadata包含一些元信息,如生成的token数量、使用的模型等。
assisantMessage里面包含了生成的文本内容、消息类型等信息。
遇到陌生API快速学习的小tip:
- 可以打个断点,运行的时候看一下
- 尝试调用对象的方法(对象.方法)
- 右键对象,可以
对表达式求值,看看每一个getxxx方法都出来些什么东西
API - ChatModel
结构如图:

其实流程和prompt/chatresponse的结构上文已经有所提及了,chatmodel就是把我们输入的prompt转换成厂商接口需要的requset格式,调用厂商接口,拿到response后再把结果转换成chatresponse。
需要使用的时候这样注入一下就行了。
java
private final DeepSeekChatModel chatModel;
@Autowired
public ChatController(DeepSeekChatModel chatModel) { this.chatModel = chatModel; }
此外,前面用的都是一次性的返回,chatmodel还支持流式响应。使用chatModel.stream()方法,返回一个流Flux。
Flux<>中的内容取决于入参,如果入参是String或者Message,那么流中的内容就是String,直接返回就行;
如果入参是Prompt,流中的内容是ChatResponse,需要chatResponse.getResult().getOutput().getText()获取文本。
如果是用中文输入,会返回乱码,解决方案是调整编码:
yaml
server:
servlet:
encoding:
charset: UTF-8
enabled: true
force: true
待更新...