SpringAI系列(基础概念&springai系列 API)

参照该课程

基础概念

token

token是语言模型的 计费/生成 基本单位,大概理解成每token生成0.75个中文。

API KEY

由于大部分人不会部署模型到本地,所以需要消耗token来调用模型,而调用模型的时候需要使用API Key进行身份验证,所以需要准备一个厂商的API Key。

prompt

prompt是输入给模型的文本,模型会根据这个文本来生成相应的输出。

狭义上,prompt就是我们对大模型说了什么,广义上,还包括了其他属性,比如当前设置的 温度Temperaturetop_p等参数,这些参数会影响模型的输出结果。

例如:

复制代码
{
    "model": "deepseek-v4-pro",
    "messages": [
        {
        "role": "system",
        "content": "这里输入一些人物设定、场景设定、对话风格等信息,来引导模型生成符合预期的内容,如:你是一个段子高手。"
        },
        {
        "role": "user",
        "content": "这里是用户输入的内容,如:开个玩笑"
        }
    ],
    "temperature": 1.0,
}

接口调用

当拥有一个API Key后,就可以通过HTTP的post请求来调用大模型的接口,向厂家提供的接口发送一个包含promptapi 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 提供消息类型对应promptmessages列表的不同message

常见的消息类型有:

  • SystemMessage:系统消息,用于设定AI的行为和角色。
  • UserMessage:用户消息,表示用户的输入。
  • AssistantMessage:助手消息,表示AI的回复。
  • ToolMessage:工具消息,表示工具调用的消息。

他们都继承自AbstractMessage,包含textContentmessageType两个属性,对应'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对象,包含generationchatResponseMetadata

其中generation是模型生成的信息,包含assisantMessagechatGenerationMetadatachatResponseMetadata包含一些元信息,如生成的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

待更新...

相关推荐
SXJR17 小时前
langchain4j是如何保证tools或者funcation call不出错的
java·网络·数据库·ai·语言模型
向宇it17 小时前
【AI视频】生成AI短剧、漫剧
人工智能·ai·音视频·动画·ai视频·短剧
金融RPA机器人丨实在智能17 小时前
选择Agent平台如何避免“厂商锁定”?深度解析企业级AI智能体架构解耦与落地实践
人工智能·ai·架构
子一!!17 小时前
spring基础学习
java·学习·spring
searchforAI17 小时前
CC-Switch教程:统一管理Skills、MCP、模型供应商、系统提示词等多项配置
人工智能·gpt·ai·大模型·agent·claudecode
长空任鸟飞_阿康17 小时前
驾驭 AI 这匹野马:深入解析智能体 Harness 工程
人工智能·python·ai
老A的AI实验室18 小时前
Cyber Weekly #66
人工智能·ai·llm·agi·genai
俊哥V18 小时前
每日 AI 研究简报 · 2026-06-02
人工智能·ai
DS随心转小程序18 小时前
ChatGPT和Gemini输出乱码怎么解决?借助AI导出鸭高效处理
人工智能·ai·chatgpt·豆包·deepseek·ai导出鸭
Super Scraper18 小时前
如何将赋予千问(Qwen Code)网络检索功能:集成MCP服务器
人工智能·爬虫·ai·自动化·千问·mcp·qwen code