avatar

一条在知识海洋的咸鱼

这个家伙很懒,啥也没有留下😋

  • 首页
  • Linux
  • OCJP
  • Java核心技术卷
  • J2EE相关标准
  • 深入理解Java虚拟机
  • NIO与SOcket编程技术指南
  • Java多线程编程核心技术
  • Redis开发与运维
  • Spring Cloud Alibaba 微服务原理与实践
  • DevOps
  • Docker
  • MySQL必知必会
  • AI自学路线
  • Spring Boot 编程思想(核心篇)
主页 07 完成聊天 Demo
文章

07 完成聊天 Demo

发表于 2026-06-7 更新于 2026-06- 10
作者 Administrator
29~37 分钟 阅读

完成聊天 Demo

聊天 Demo 的目标是把前面几天的知识串起来,做出一个能运行、能调用、能说明清楚的最小 AI 聊天项目。

  • 完成聊天 Demo
    • Demo 是什么
    • 项目范围
    • 建议项目结构
    • 依赖准备
    • 配置文件
    • 请求和响应对象
    • Service
    • Controller
    • 基础异常处理
    • 接口文档
    • README 要写什么
    • 提交 Git
    • 常见问题
      • README 为什么重要
      • 接口文档要不要很复杂
      • 为什么要提交 Git
    • 练习清单
    • 小结
    • 参考资料

Demo 是什么

Demo,全称是 Demonstration,中文一般翻译为“演示”或“示例项目”。

这里的 ai-chat-demo 不是完整产品。

它只需要证明一条链路可以跑通:

用户输入
  -> Spring Boot 接口
  -> Spring AI ChatClient
  -> 大模型 API
  -> 返回回答

结论:

Day07 的重点不是加很多功能,而是把一个最小聊天项目整理到可以复现、可以演示、可以提交。

项目范围

先控制范围。

必须完成:

普通聊天接口
统一请求响应对象
基础异常处理
README
接口文档
Git 提交

可以暂时不做:

登录权限
数据库存储
多轮上下文
前端页面
RAG
Tool Calling
复杂流式输出

范围越清楚,Demo 越容易完成。

建议项目结构

ai-chat-demo
├── pom.xml
├── README.md
├── src
│   ├── main
│   │   ├── java
│   │   │   └── com/example/aichat
│   │   │       ├── AiChatDemoApplication.java
│   │   │       ├── controller
│   │   │       │   └── ChatController.java
│   │   │       ├── dto
│   │   │       │   ├── ChatRequest.java
│   │   │       │   └── ChatResponse.java
│   │   │       └── service
│   │   │           └── AiChatService.java
│   │   └── resources
│   │       └── application.yml
│   └── test
│       └── java
└── docs
    └── api.md

结构不要一开始就拆得太复杂。

先保证 Controller、Service、DTO 清楚。

依赖准备

Maven,中文一般翻译为“项目构建和依赖管理工具”。

pom.xml 里至少需要:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-starter-model-openai</artifactId>
    </dependency>
</dependencies>

这里使用 spring-ai-starter-model-openai 是因为阿里云百炼 DashScope 支持 OpenAI 兼容接口。

Spring AI 版本建议通过 BOM 管理。

BOM,全称是 Bill of Materials,中文一般翻译为“物料清单”或“依赖版本清单”。

它的作用是统一依赖版本。

具体版本以当前项目和官方文档为准。

配置文件

application.yml:

server:
  port: 8080

spring:
  application:
    name: ai-chat-demo
  ai:
    openai:
      api-key: ${DASHSCOPE_API_KEY}
      base-url: https://dashscope.aliyuncs.com/compatible-mode/v1
      chat:
        options:
          model: qwen3.5-flash
          temperature: 0.3

后续示例默认使用通义千问 qwen3.5-flash。

原则:

密钥不进代码
密钥不进 Git
模型名可配置
参数可配置

请求和响应对象

请求:

import jakarta.validation.constraints.NotBlank;

public record ChatRequest(
        @NotBlank(message = "message 不能为空")
        String message
) {
}

响应:

public record ChatResponse(
        String answer
) {
}

如果后面要扩展,可以再加字段:

requestId
model
usage
elapsedMs

学习阶段先保留最小字段。

Service

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.stereotype.Service;

@Service
public class AiChatService {

    private final ChatClient chatClient;

    public AiChatService(ChatClient.Builder builder) {
        this.chatClient = builder
                .defaultSystem("你是一个严谨的 Java 后端工程师,回答要简洁。")
                .build();
    }

    public String chat(String message) {
        return chatClient.prompt()
                .user(message)
                .call()
                .content();
    }
}

这里把默认 system prompt 放在 ChatClient 初始化时。

也可以每次调用时传入:

chatClient.prompt()
        .system("你是一个严谨的 Java 后端工程师。")
        .user(message)
        .call()
        .content();

Controller

import jakarta.validation.Valid;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/chat")
public class ChatController {

    private final AiChatService aiChatService;

    public ChatController(AiChatService aiChatService) {
        this.aiChatService = aiChatService;
    }

    @PostMapping
    public ChatResponse chat(@Valid @RequestBody ChatRequest request) {
        String answer = aiChatService.chat(request.message());
        return new ChatResponse(answer);
    }
}

接口先保持简单。

如果后面要做前端页面,再补 CORS。

CORS,全称是 Cross-Origin Resource Sharing,中文一般翻译为“跨源资源共享”。

基础异常处理

可以先定义一个统一错误响应:

public record ErrorResponse(
        String code,
        String message
) {
}

全局异常处理:

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ErrorResponse handleValidation() {
        return new ErrorResponse("BAD_REQUEST", "请求参数不合法");
    }

    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ErrorResponse handleException() {
        return new ErrorResponse("INTERNAL_ERROR", "服务暂时不可用");
    }
}

注意:

不要把 API Key 打到日志里
不要把完整异常堆栈返回给前端
服务端日志保留真实异常
用户侧返回可理解的提示

接口文档

可以先写 docs/api.md。

示例:

# API 文档

## 聊天接口

POST /api/chat

### 请求

```json
{
  "message": "什么是 Spring AI?"
}
```

### 响应

```json
{
  "answer": "Spring AI 是 Spring 生态中用于接入大模型能力的应用开发框架。"
}
```

### 错误响应

```json
{
  "code": "BAD_REQUEST",
  "message": "请求参数不合法"
}
```

如果使用接口文档工具,后面可以再接 OpenAPI。

OpenAPI,中文一般翻译为“开放接口规范”。

README 要写什么

README 是别人运行项目的入口。

至少写清楚:

项目说明
技术栈
环境要求
启动方式
环境变量
接口示例
目录结构
常见问题

示例结构:

# ai-chat-demo

## 项目说明

最小 AI 聊天 Demo,基于 Spring Boot 和 Spring AI。

## 环境要求

- JDK 21
- Maven 3.9+
- Spring Boot 3.x

## 环境变量

```bash
export DASHSCOPE_API_KEY=你的阿里云百炼 API Key
```

## 启动

```bash
mvn spring-boot:run
```

## 测试

```bash
curl -X POST http://localhost:8080/api/chat \
  -H "Content-Type: application/json" \
  -d '{"message":"什么是 Spring AI?"}'
```

截屏20260607 23.13.47.png

提交 Git

Git,中文一般翻译为“分布式版本控制系统”。

先检查不要提交密钥:

git status

.gitignore:

.env
target/
*.log
.idea/

提交:

git add .
git commit -m "feat: add ai chat demo"

提交前检查:

项目能启动
curl 能调用成功
README 能按步骤复现
没有提交 API Key

常见问题

README 为什么重要

Demo 不是只给自己看。

README 能说明项目怎么运行、怎么测试、解决了什么问题。

后面写简历或面试复盘时,也能直接引用。

接口文档要不要很复杂

不需要。

Day07 先写 Markdown 版接口文档即可。

重点是请求、响应、错误格式清楚。

为什么要提交 Git

Git 提交能保留阶段成果。

后面做 RAG、Tool Calling、Agent 时,遇到问题可以回到稳定版本。

练习清单

完成几件事情:

创建 ai-chat-demo 项目
完成 /api/chat 接口
完成 AiChatService
完成 ChatRequest 和 ChatResponse
配置 API Key 环境变量
curl 能调用成功
写 README
写接口文档
提交 Git

小结

Day07 的结论:

聊天 Demo 要做到能启动、能调用、能复现、能提交。

最小交付物:

Spring Boot 项目
聊天接口
README
接口文档
Git 提交

后面所有复杂能力都可以从这个 Demo 往上加。

参考资料

  • Spring AI Alibaba Examples
  • Spring AI ChatClient
AI自学路线
许可协议: 
分享

相关文章

7月 13, 2026

55 异常兜底:工具失败、非法输出、空检索与超时

异常兜底:工具失败、非法输出、空检索与超时 Agent 的可靠性主要体现在失败时。工ࠥ

7月 13, 2026

54 Agent Memory:短期记忆、用户上下文与摘要

Agent Memory:短期记忆、用户上下文与摘要 Memory 的目标是保持任务连续性,不是永久保存所有聊天。记忆Š

7月 13, 2026

53 Human-in-the-loop:让关键动作暂停、确认与恢复

Human-in-the-loop:让关键动作暂停、确认与恢复 HITL 不是弹一个“确定吗”,而是让工作流在关键动作前持久

下一篇

08 Tool Calling 概念

上一篇

06 Spring AI 入门

最近更新

  • 55 异常兜底:工具失败、非法输出、空检索与超时
  • 54 Agent Memory:短期记忆、用户上下文与摘要
  • 53 Human-in-the-loop:让关键动作暂停、确认与恢复
  • 52 工单 Tool:字段校验、创建结果与失败补偿
  • 51 订单 Tool:Mock、鉴权、状态解析与脱敏

热门标签

java基础 微服务 maven Spring Tomcat DDD Linux Linux基础 SQL基础 数据结构算法

目录

©2026 一条在知识海洋的咸鱼. 保留部分权利。

使用 Halo 主题 Chirpy