乐于分享
好东西不私藏

AI应用开发入门这么简单?附可直接运行源码

AI应用开发入门这么简单?附可直接运行源码

很多人学 Spring AI Alibaba,卡住的不是概念,而是落地。
常见问题就三个:
  • 依赖版本不好控,组件一组合就冲突
  • 示例项目太重,想跑个 demo 成本很高
  • 就算跑通了,也不知道代码为什么这样写
所以这篇文章不讲大而全,只围绕一个最精简的入口,把 Spring AI Alibaba 最基础的调用链先跑通。
主线很简单:
  • 先跑起来
  • 再看懂它
  • 最后把一次最小调用串起来
这篇我直接给你完整可运行代码,照着复制粘贴,10分钟就能跑通你的第一个Java AI接口
先从一个最小接口开始
@RequestMapping("chat1")public String chat1(@RequestParamString 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 是“方向盘 + 仪表盘”

它更适合业务开发,原因也很直接:
  • 支持链式调用,写起来更顺
  • 能放默认配置,不用每次重复写
  • 更方便挂日志、顾问和后续扩展逻辑
基础用法:
@Beanpublic 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<Stringchat4(@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` 这几层能力。
为了方便大家直接上手,我把本文完整可运行项目源码打包好了,包含依赖、配置、启动类全套,导入就能跑
需要的朋友可以关注我,后台回复【SpringAI入门】即可领取。后续我会持续更新java+AI实战干活,带你少踩坑、快落地。