很多人学 Spring AI Alibaba,卡住的不是概念,而是落地。

常见问题就三个:

  • 依赖版本不好控,组件一组合就冲突

  • 示例项目太重,想跑个 demo 成本很高

  • 就算跑通了,也不知道代码为什么这样写

所以这篇文章不讲大而全,只围绕一个最精简的入口,把 Spring AI Alibaba 最基础的调用链先跑通。

主线很简单:

  • 先跑起来

  • 再看懂它

  • 最后把一次最小调用串起来

这篇我直接给你完整可运行代码,照着复制粘贴,10分钟就能跑通你的第一个Java AI接口

先从一个最小接口开始:

@RequestMapping("chat1")
public String chat1(@RequestParam String msg) {  
   Message systemMessage = new SystemMessage("你是一位专业的 Java 技术顾问。");   
   Message userMessage = new UserMessage(msg);    
  return chatClient.prompt(new Prompt(List.of(systemMessage, userMessage))).call().content();
}

    这段代码很短,但已经包含了 3 个核心概念:

    Message(消息)

    Prompt(提示词)

    ChatModel(聊天模型)

    后面就顺着这 3 层往下拆。

    Message:先把“谁说了什么”说明白

    在 Spring AI 中,Message 是对话的最小单位,每一条消息都带有明确的“角色”。

    常见的几种角色如下:

    回到刚刚那段代码,其实只做了两件事:

    Message systemMessage = new SystemMessage("你是一位专业的 Java 技术顾问。");
    Message userMessage = new UserMessage(msg);

      👉 一条用来定义 AI 角色

      👉 一条用来传递用户问题

      这两条消息组合在一起,就构成了一次最基础的对话。

      这是运行结果:

      上面我们用 Message,已经能完成一次最基础的对话。

      但问题也很明显:

      👉 每次都手动拼 Message,不够灵活,也不方便复用。

      这时候,就需要引入第二个核心概念:Prompt(提示词)。

      Prompt:把一组 Message 组织成一次请求

      Prompt 就是一整次 AI 请求,本质是对一组 Message 的封装。

      可以简单理解:

      Message 是一句话,Prompt 是一整次对话

      来看一个更实用的写法:

      @GetMapping("/chat2")
      public String chat2() {
           PromptTemplate template = new PromptTemplate("请用{language},向{level}程序员解释什么是{concept}。");   
           Prompt renderedPrompt = template.create(Map.of(    
                   "language", "中文",       
                   "level", "初级",     
                   "concept", "微服务"  
                   ));   
         return chatClient.prompt(renderedPrompt).call().content();
         }

      比前面,这里做了一件事:

      👉 把提示词从“写死”,变成“可参数化”。

      所以 `Prompt` 解决的不是“能不能发请求”,而是“这次请求怎么组织得更清楚、更可复用”。

      那组织好之后,谁来真正把请求发给模型?

      这就要用到第三个核心概念:ChatModel(聊天模型)

      Prompt 组织好了,接下来谁来真正发请求

      这就轮到 `ChatModel` 出场了。

      ChatModel:负责把请求发出去

      ChatModel 是与大模型交互的核心接口,

      Spring AI 对不同模型做了统一抽象。

      可以简单理解成:

      👉 一个“通用遥控器”,无论底层是通义千问还是 GPT,用法都一样

      来看一个最直接的调用方式:

      @GetMapping("/chat3")
      public String chat3() { 
         Prompt prompt = new Prompt(List.of(          
           new SystemMessage("你是一位经验丰富的 Java 架构师。"),  
           new UserMessage("什么是 LLM") 
          ));
          ChatResponse response = chatModel.call(prompt);   
          Usage usage = response.getMetadata().getUsage(); 
          log.info( "promptTokens: {}, completionTokens: {}, totalTokens: {}",     
                 usage.getPromptTokens(),
                 usage.getCompletionTokens(), 
                 usage.getTotalTokens());  
          for (Generation result : response.getResults()) {     
              log.info("result: {}", result.getOutput().getText());   
              }  
           return response.getResult().getOutput().getText();
      }

        这段代码做的事很简单:把 `Prompt` 发给模型,再把结果取回来。

        这里顺手记住 4 个点就够了:

        • ChatModel 更偏底层接口,业务里通常更常用的是ChatClient

        • PromptTemplate 用的是{},不要和${} 混淆

        • call() 本身是无状态调用,多轮对话需要自己维护上下文

        • Token 是计费单位,输入和输出都会消耗

        看到这里,其实这三层关系已经比较清楚了:

        • Message 负责“说什么”

        • Prompt 负责“怎么组织”

        • ChatModel 负责“把请求发出去并拿回结果”

        不过,如果实际开发里每次都直接操作 `ChatModel`,代码还是会显得偏底层。

        所以 Spring AI 又往上给了一层更顺手的封装。

        为什么实际开发里更常用 ChatClient

        ChatClient 是基于 ChatModel 的高层封装,让调用方式更简洁。

        如果打个比方:

        👉 ChatModel 是“发动机”👉 ChatClient 是“方向盘 + 仪表盘”

        它更适合业务开发,原因也很直接:

        • 支持链式调用,写起来更顺

        • 能放默认配置,不用每次重复写

        • 更方便挂日志、顾问和后续扩展逻辑

        基础用法:

        @Bean
        public ChatClient chatClient(ChatModel chatModel) { 
          return ChatClient.builder(chatModel)
            .defaultSystem("你是一位专业的 Java 技术顾问,请用简洁专业的语言回答问题。")
            .defaultAdvisors(new SimpleLoggerAdvisor()) 
            .defaultTools(weatherTool)
            .build();
           }

          流式返回调用:

          @GetMapping(value = "/chat4", produces = "text/html;charset=utf-8")
          public Flux<String> chat4(@RequestParam(name = "msg", defaultValue = "你好") String msg) {  
            return chatClient.prompt().user(msg).stream().content();
           }

            到这里,这条最小链路就清楚了:

            `Message -> Prompt -> ChatModel -> ChatClient`

            先把这条线跑通,你再去看 Spring AI Alibaba,很多东西就不会觉得乱。

            这一篇我们先停在“怎么把一次请求发好”。

            下一篇再继续往下走,讲另外几个更关键的问题:

            • 怎么让 AI 调工具

            • 怎么让 AI 自己规划步骤

            • 怎么让 AI 记住上下文

            也就是 `Tool`、`Agent`、`Memory`、`Hook` 这几层能力。

            为了方便大家直接上手,我把本文完整可运行项目源码打包好了,包含依赖、配置、启动类全套,导入就能跑

            如果你对 Java + AI 实战、Spring AI 落地、RAG、MCP、Agent、AI 支付这些内容感兴趣,可以关注我的技术号,想领取 Spring AI 入门资料的话,关注后后台回复:SpringAI入门 即可。

            Logo

            AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

            更多推荐