参照该课程
基础概念
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文件:
spring:ai:deepseek:api-key:你的apikeyAPI - Message
Spring AI 提供消息类型对应prompt中messages列表的不同message。
常见的消息类型有:
SystemMessage:系统消息,用于设定AI的行为和角色。UserMessage:用户消息,表示用户的输入。AssistantMessage:助手消息,表示AI的回复。ToolMessage:工具消息,表示工具调用的消息。
他们都继承自AbstractMessage,包含textContent和messageType两个属性,对应’content’和’role’。
各message之间关系如图:
一个简单的示例展示构建一个聊天接口:
packagecom.example.springai.controller;importorg.springframework.ai.chat.messages.SystemMessage;importorg.springframework.ai.chat.messages.UserMessage;importorg.springframework.ai.chat.model.ChatResponse;importorg.springframework.ai.chat.prompt.Prompt;importorg.springframework.ai.deepseek.DeepSeekChatModel;importorg.springframework.ai.deepseek.DeepSeekChatOptions;importorg.springframework.ai.deepseek.api.DeepSeekApi;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RequestParam;importorg.springframework.web.bind.annotation.RestController;importreactor.core.publisher.Flux;importjava.util.List;importjava.util.Map;@RestControllerpublicclassChatController{// 注入一个DeepSeekChatModel,这个模型是Spring AI提供的一个接口,封装了调用DeepSeek模型的逻辑,我们可以通过它来调用DeepSeek模型生成文本。privatefinalDeepSeekChatModelchatModel;@AutowiredpublicChatController(DeepSeekChatModelchatModel){this.chatModel=chatModel;}@GetMapping("/ai/generate")publicMapgenerate(@RequestParam(value="message",defaultValue="Tell me a joke")Stringmessage){// 构建messages列表UserMessageuserMessage=newUserMessage(message);SystemMessagesystemMessage=newSystemMessage("你是一个段子高手");// 准备构建Prompt(消息列表和相关参数),参数通过DeepSeekChatOptions来设置DeepSeekChatOptionsdeepSeekChatOptions=newDeepSeekChatOptions();deepSeekChatOptions.setTemperature(1.4);deepSeekChatOptions.setModel("deepseek-v4-flash");deepSeekChatOptions.setMaxTokens(2048);// 通过builder构建DeepSeekChatOptionsDeepSeekChatOptionschatoptions=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) ); // 传入messagereturnMap.of("generation",chatModel.call(newPrompt(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。
需要使用的时候这样注入一下就行了。
privatefinalDeepSeekChatModelchatModel;@AutowiredpublicChatController(DeepSeekChatModelchatModel){this.chatModel=chatModel;}此外,前面用的都是一次性的返回,chatmodel还支持流式响应。使用chatModel.stream()方法,返回一个流Flux。Flux<>中的内容取决于入参,如果入参是String或者Message,那么流中的内容就是String,直接返回就行;
如果入参是Prompt,流中的内容是ChatResponse,需要chatResponse.getResult().getOutput().getText()获取文本。
如果是用中文输入,会返回乱码,解决方案是调整编码:
server:servlet:encoding:charset:UTF-8enabled:trueforce:true待更新…