Java之家

人工智能(三)- 提供 API,搭建智能客服系统

2026-03-03  本文已影响0人  小小土豆dev

在AI技术快速普及的当下,智能客服系统已成为企业提升服务效率、优化用户体验的核心工具。本文将详细介绍如何通过前端搭建交互界面、后端提供API服务,结合OpenAI SDK访问阿里千问大模型,快速实现一个轻量、可用的智能客服系统,适合Java开发者快速上手实践。

一、前期准备:账号与环境配置

要调用阿里千问大模型API,首先需要完成阿里云账号的注册、百炼服务开通及API Key获取。

1.1 注册阿里云账号

若你尚未拥有阿里云账号,需先前往阿里云注册页面完成注册,建议使用企业或个人常用手机号/邮箱注册,方便后续账号管理与服务开通。

1.2 开通阿里云百炼服务

注册并登录阿里云账号后,前往阿里云百炼大模型服务平台,按照页面指引开通百炼服务。开通过程中需确认服务协议,无需额外付费即可享受新人专属免费额度。

1.3 获取API Key

API Key是调用千问大模型的身份凭证,获取步骤如下:

  1. 登录阿里云百炼控制台,前往密钥管理页面
  2. 点击「创建API Key」按钮,系统会自动生成API Key;
  3. 保存好生成的API Key,后续后端代码中需使用该密钥进行身份验证,建议妥善保管,避免泄露。

1.4 模型与计费说明

阿里云百炼不仅支持阿里千问系列大模型(如qwen-plus、qwen-max等),还兼容DeepSeek、Kimi、GLM、MiniMax等第三方知名大模型,可根据业务需求灵活选择

模型选择

计费规则
首次开通百炼服务时,平台会自动发放各模型的新人专属免费额度,有效期通常为30~90天;免费额度耗尽或过期后,继续使用模型推理服务将按实际调用量计费,具体计费标准可参考阿里云百炼官方定价文档

二、工程搭建:基于Spring Boot的后端开发

本文后端采用Spring Boot框架开发,结合OpenAI Java SDK访问千问大模型API,实现客服对话接口,同时解决跨域问题,确保前端正常调用。

2.1 创建Maven工程

使用IntelliJ IDEA创建一个Maven工程,完成工程初始化。

2.2 引入核心依赖

在pom.xml文件中引入Spring Boot Web和OpenAI Java SDK依赖,版本选择稳定版(本文使用openai-java 3.5.0),具体依赖如下:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.6</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>org.devpotato</groupId>
    <artifactId>chat-service</artifactId>
    <version>1.0-SNAPSHOT</version>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <packaging>jar</packaging>

    <name>ChatService</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.openai</groupId>
            <artifactId>openai-java</artifactId>
            <version>3.5.0</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <repositories>
        <repository>
            <id>public</id>
            <name>aliyun nexus</name>
            <url>https://maven.aliyun.com/repository/public</url>
            <releases>
                <enabled>true</enabled>
            </releases>
        </repository>
        <repository>
            <name>Central Portal Snapshots</name>
            <id>central-portal-snapshots</id>

            <url>https://central.sonatype.com/repository/maven-snapshots/</url>
            <releases>
                <enabled>false</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>
</project>

引入依赖后,点击IDEA的「Refresh」按钮,下载并加载依赖包,确保工程无依赖报错。

2.3 工程配置文件

在src/main/resources目录下创建application.yml文件,配置服务端口(默认8080,可根据需求修改):

server:
  port: 8080

2.4 解决跨域问题

由于前端页面与后端服务可能存在跨域(CORS)问题,导致前端无法正常调用后端API,因此需要添加跨域过滤器。创建MyFilter类,实现Filter接口,具体代码如下:

import org.springframework.stereotype.Component;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class MyFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        // 解决Chrome等浏览器访问本地服务的跨域问题
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        // 允许所有域名跨域访问(生产环境建议指定具体域名,提升安全性)
        httpResponse.setHeader("Access-Control-Allow-Origin", "*");
        // 允许的请求方式
        httpResponse.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        // 允许的请求头
        httpResponse.setHeader("Access-Control-Allow-Headers", "Content-Type");
        // 继续执行过滤链
        chain.doFilter(request, response);
    }
}

2.5 开发客服对话API

创建ChatController类,作为后端接口的入口,实现与千问大模型的交互,支持多轮对话。核心逻辑:维护对话历史消息列表,每次请求时将历史消息与最新用户提问一起传入模型,实现多轮上下文关联。

import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.core.JsonValue;
import com.openai.models.chat.completions.ChatCompletion;
import com.openai.models.chat.completions.ChatCompletionAssistantMessageParam;
import com.openai.models.chat.completions.ChatCompletionCreateParams;
import com.openai.models.chat.completions.ChatCompletionMessageParam;
import com.openai.models.chat.completions.ChatCompletionUserMessageParam;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/chat")
public class ChatController {
    // 替换为你自己的API Key(生产环境建议通过配置文件读取,避免硬编码)
    private static final String API_KEY = "xxx";
    // 千问大模型OpenAI兼容协议的基础地址
    private static final String BASE_URL = "https://dashscope.aliyuncs.com/compatible-mode/v1";
    // 选择使用的千问模型(qwen-plus轻量高效,适合客服场景;qwen-max性能更强,适合复杂需求)
    private static final String LLM_MODEL = "qwen-plus";
    // 系统提示词:定义客服角色与回复规范,引导模型输出符合预期的内容
    private static final String SYSTEM_PROMPT = "作为一个专业的电商售后支持客服,你具备深厚的问题解决能力。请针对用户提出的问题,提供详细的解答步骤或有效的解决方案,并且考虑到用户的水平可能有所不同,请尽可能地简化语言。";

    /**
     * 注意:通义千问API是无状态的,不会自动保存对话历史
     * 因此需手动维护一个messages列表,存储每一轮的对话消息(用户提问+模型回复)
     * 每次请求时,将该列表传入模型,实现多轮对话的上下文关联
     */
    private static final List<ChatCompletionMessageParam> messageParams = new ArrayList<>();

    /**
     * 客服对话接口,接收前端传入的用户提问,返回模型生成的回复
     * @param map 前端传入的参数,包含用户提问message
     * @return 模型生成的客服回复
     */
    @RequestMapping(path = "", method = RequestMethod.POST)
    public String chat(@RequestBody Map<String, Object> map) {
        // 1. 获取前端传入的用户提问
        String userInput = map.get("message").toString();

        // 2. 构建用户消息对象,添加到对话历史中
        ChatCompletionUserMessageParam userMessage = ChatCompletionUserMessageParam.builder()
                .role(JsonValue.from("user")) // 角色固定为user
                .content(userInput) // 用户提问内容
                .build();
        messageParams.add(ChatCompletionMessageParam.ofUser(userMessage));

        // 3. 创建OpenAI客户端,配置API Key和基础地址
        OpenAIClient client = OpenAIOkHttpClient.builder()
                .apiKey(API_KEY)
                .baseUrl(BASE_URL)
                .build();

        // 4. 构建模型请求参数
        ChatCompletionCreateParams params = ChatCompletionCreateParams.builder()
                .addSystemMessage(SYSTEM_PROMPT) // 添加系统提示词,定义客服角色
                .messages(messageParams) // 传入对话历史,实现多轮对话
                .model(LLM_MODEL) // 指定使用的千问模型
                .build();

        try {
            // 5. 调用千问大模型API,获取响应结果
            ChatCompletion chatCompletion = client.chat().completions().create(params);

            // 6. 解析模型回复内容
            String assistantReply = chatCompletion.choices().get(0).message().content().get();

            // 7. 将模型回复添加到对话历史中,用于下一轮对话
            ChatCompletionAssistantMessageParam assistantMessage = ChatCompletionAssistantMessageParam.builder()
                    .role(JsonValue.from("assistant")) // 角色固定为assistant
                    .content(assistantReply) // 模型回复内容
                    .build();
            messageParams.add(ChatCompletionMessageParam.ofAssistant(assistantMessage));

            // 8. 返回模型回复给前端
            return assistantReply;
        } catch (Exception e) {
            // 异常处理:打印错误信息,返回null(生产环境建议返回更友好的错误提示)
            System.err.println("调用千问大模型失败:" + e.getMessage());
            e.printStackTrace();
            return null;
        }
    }
}

API输入输出参数说明

输入输出参数说明
前往详细文档

2.6 启动类开发

创建StartServer类,作为Spring Boot工程的启动入口,代码如下:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class StartServer {

    public static void main(String[] args) {
        // 启动Spring Boot服务
        SpringApplication.run(StartServer.class, args);
        System.out.println("智能客服后端服务启动成功,端口:8080");
    }
}

三、前端页面搭建(简易版)

前端采用简单的HTML+JavaScript搭建聊天界面,实现用户输入提问、展示客服回复的功能。创建index.html文件,代码如下(可直接在浏览器中打开使用):

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>电商客服中心</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Microsoft YaHei', sans-serif;
        }

        body {
            background-color: #f5f7fa;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            padding: 20px;
        }

        .chat-container {
            width: 100%;
            max-width: 800px;
            height: 80vh;
            background-color: #fff;
            border-radius: 10px;
            box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
            display: flex;
            flex-direction: column;
            overflow: hidden;
        }

        .chat-header {
            background-color: #409eff;
            color: #fff;
            padding: 15px 20px;
            display: flex;
            align-items: center;
            gap: 10px;
        }

        .chat-header img {
            width: 40px;
            height: 40px;
            border-radius: 50%;
            background-color: #fff;
        }

        .chat-header h2 {
            font-size: 18px;
            font-weight: 600;
        }

        .chat-messages {
            flex: 1;
            padding: 20px;
            overflow-y: auto;
            background-color: #f9f9f9;
        }

        .message {
            margin-bottom: 15px;
            max-width: 70%;
            display: flex;
            animation: fadeIn 0.3s ease;
        }

        @keyframes fadeIn {
            from { opacity: 0; transform: translateY(10px); }
            to { opacity: 1; transform: translateY(0); }
        }

        .user-message {
            margin-left: auto;
            flex-direction: row-reverse;
        }

        .message-avatar {
            width: 36px;
            height: 36px;
            border-radius: 50%;
            margin: 0 8px;
            flex-shrink: 0;
        }

        .user-message .message-content {
            background-color: #409eff;
            color: #fff;
            border-radius: 10px 10px 0 10px;
        }

        .bot-message .message-content {
            background-color: #fff;
            color: #333;
            border-radius: 10px 10px 10px 0;
            border: 1px solid #eee;
        }

        .message-content {
            padding: 10px 15px;
            word-wrap: break-word;
            line-height: 1.4;
        }

        /* 快捷按钮区域样式 */
        .quick-buttons {
            padding: 10px 15px;
            border-top: 1px solid #eee;
            background-color: #fafafa;
            display: flex;
            flex-wrap: wrap;
            gap: 10px;
        }

        .quick-button {
            padding: 6px 15px;
            background-color: #e8f4ff;
            color: #409eff;
            border: 1px solid #d1e9ff;
            border-radius: 20px;
            cursor: pointer;
            font-size: 13px;
            transition: all 0.2s;
        }

        .quick-button:hover {
            background-color: #409eff;
            color: #fff;
            border-color: #409eff;
        }

        .chat-input {
            display: flex;
            padding: 15px;
            border-top: 1px solid #eee;
            background-color: #fff;
        }

        #message-input {
            flex: 1;
            padding: 12px 15px;
            border: 1px solid #ddd;
            border-radius: 25px;
            outline: none;
            font-size: 14px;
            resize: none;
            height: 45px;
            max-height: 120px;
        }

        #message-input:focus {
            border-color: #409eff;
            box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
        }

        #send-button {
            margin-left: 10px;
            padding: 0 20px;
            background-color: #409eff;
            color: #fff;
            border: none;
            border-radius: 25px;
            cursor: pointer;
            font-size: 14px;
            transition: background-color 0.2s;
        }

        #send-button:hover {
            background-color: #337ecc;
        }

        #send-button:disabled {
            background-color: #b3d8ff;
            cursor: not-allowed;
        }

        .loading {
            display: inline-block;
            width: 20px;
            height: 20px;
            border: 3px solid rgba(255,255,255,.3);
            border-radius: 50%;
            border-top-color: white;
            animation: spin 1s ease-in-out infinite;
        }

        @keyframes spin {
            to { transform: rotate(360deg); }
        }

        .empty-hint {
            text-align: center;
            color: #999;
            padding: 50px 0;
            font-size: 14px;
        }
    </style>
</head>
<body>
    <div class="chat-container">
        <div class="chat-header">
            <img src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAiIGhlaWdodD0iNDAiIHZpZXdCb3g9IjAgMCA0MCA0MCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPGNpcmNsZSBjeD0iMjAiIGN5PSIyMCIgcj0iMjAiIGZpbGw9IiM0MDllZmYiLz4KPHBhdGggZD0iTTE1IDI1QzE1IDI3LjcxIDE2Ljk5IDI5IDE5IDI5QzIxLjAxIDI5IDIzIDI3LjcxIDIzIDI1QzIzIDIyLjc5IDIxLjAxIDIxIDE5IDIxQzE2Ljk5IDIxIDE1IDIyLjc5IDE1IDI1WiIgZmlsbD0id2hpdGUiLz4KPC9zdmc+Cg==" alt="客服图标">
            <h2>在线客服中心</h2>
        </div>
        <div class="chat-messages" id="chat-messages">
            <div class="empty-hint" id="empty-hint">欢迎咨询,我是您的专属客服😊</div>
        </div>
        
        <!-- 新增快捷按钮区域 -->
        <div class="quick-buttons" id="quick-buttons">
            <div class="quick-button" onclick="sendQuickMessage('查看订单')">查看订单</div>
            <div class="quick-button" onclick="sendQuickMessage('查看物流')">查看物流</div>
            <div class="quick-button" onclick="sendQuickMessage('申请退款')">申请退款</div>
            <div class="quick-button" onclick="sendQuickMessage('修改收货地址')">修改收货地址</div>
            <div class="quick-button" onclick="sendQuickMessage('商品质量问题')">商品质量问题</div>
        </div>
        
        <div class="chat-input">
            <textarea id="message-input" placeholder="请输入您想咨询的问题..." onkeydown="if(event.keyCode===13&&!event.shiftKey){event.preventDefault();sendMessage();}"></textarea>
            <button id="send-button" onclick="sendMessage()">发送</button>
        </div>
    </div>

    <script>
        // 获取DOM元素
        const messageInput = document.getElementById('message-input');
        const sendButton = document.getElementById('send-button');
        const chatMessages = document.getElementById('chat-messages');
        const emptyHint = document.getElementById('empty-hint');

        // 头像URL(使用base64编码的SVG,也可以替换为实际图片URL)
        const BOT_AVATAR = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzYiIGhlaWdodD0iMzYiIHZpZXdCb3g9IjAgMCAzNiAzNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPGNpcmNsZSBjeD0iMTgiIGN5PSIxOCIgcj0iMTgiIGZpbGw9IiM0MDllZmYiLz4KPHBhdGggZD0iTTEzIDIyQzEzIDI0LjIxIDE0Ljk5IDI2IDE3IDI2QzE5LjAxIDI2IDIxIDI0LjIxIDIxIDIyQzIxIDE5Ljc5IDE5LjAxIDE4IDE3IDE4QzE0Ljk5IDE4IDEzIDE5Ljc5IDEzIDIyWiIgZmlsbD0id2hpdGUiLz4KPC9zdmc+Cg==';
        const USER_AVATAR = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzYiIGhlaWdodD0iMzYiIHZpZXdCb3g9IjAgMCAzNiAzNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPGNpcmNsZSBjeD0iMTgiIGN5PSIxOCIgcj0iMTgiIGZpbGw9IiNmZmYwMDAiLz4KPHBhdGggZD0iTTEyIDIwQzEyIDIyLjcxIDEzLjk5IDI1IDE2IDI1QzE4LjAxIDI1IDIwIDIyLjcxIDIwIDIwQzIwIDE3Ljc5IDE4LjAxIDE1IDE2IDE1QzEzLjk5IDE1IDEyIDE3Ljc5IDEyIDIwWiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTIwIDI5QzIwIDI5IDE3IDMwIDE3IDMwQzE0IDMwIDEyIDI5IDEyIDI5QzEyIDI5IDEyIDI3IDEyIDI3QzEyIDI3IDE0IDI2IDE2IDI2QzE4IDI2IDIwIDI3IDIwIDI3QzIwIDI3IDIwIDI5IDIwIDI5WiIgZmlsbD0id2hpdGUiLz4KPC9zdmc+Cg==';

        // 自动调整输入框高度
        messageInput.addEventListener('input', function() {
            this.style.height = 'auto';
            this.style.height = (this.scrollHeight > 45 ? this.scrollHeight : 45) + 'px';
        });

        // 快捷消息发送函数
        function sendQuickMessage(message) {
            // 将快捷消息填入输入框
            messageInput.value = message;
            messageInput.style.height = 'auto';
            messageInput.style.height = (messageInput.scrollHeight > 45 ? messageInput.scrollHeight : 45) + 'px';
            
            // 自动发送该消息
            sendMessage();
        }

        // 发送消息函数
        async function sendMessage() {
            const message = messageInput.value.trim();
            
            // 验证输入内容
            if (!message) {
                alert('请输入咨询内容!');
                return;
            }

            // 禁用发送按钮和输入框
            sendButton.disabled = true;
            messageInput.disabled = true;

            try {
                // 隐藏空提示
                emptyHint.style.display = 'none';

                // 添加用户消息到聊天窗口
                addMessageToChat(message, 'user');
                
                // 清空输入框并恢复高度
                messageInput.value = '';
                messageInput.style.height = '45px';

                // 添加加载状态
                const loadingId = addLoadingMessage();

                // 调用后端接口
                const response = await fetch('http://127.0.0.1:8080/chat', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({ message: message })
                });

                // 移除加载状态
                removeLoadingMessage(loadingId);

                // 处理响应
                if (response.ok) {
                    const data = await response.text();
                    // 添加客服回复到聊天窗口
                    addMessageToChat(data, 'bot');
                } else {
                    addMessageToChat('抱歉,服务器暂时无法响应,请稍后再试!', 'bot');
                    console.error('接口请求失败:', response.status);
                }
            } catch (error) {
                // 移除加载状态
                const loadingElements = document.querySelectorAll('.loading-message');
                loadingElements.forEach(el => el.remove());
                
                addMessageToChat('网络错误,请检查您的网络连接!', 'bot');
                console.error('请求出错:', error);
            } finally {
                // 恢复发送按钮和输入框
                sendButton.disabled = false;
                messageInput.disabled = false;
                messageInput.focus();
                
                // 滚动到最新消息
                scrollToBottom();
            }
        }

        // 添加消息到聊天窗口
        function addMessageToChat(content, sender) {
            const messageDiv = document.createElement('div');
            messageDiv.className = `message ${sender}-message`;
            
            // 创建头像元素
            const avatarImg = document.createElement('img');
            avatarImg.className = 'message-avatar';
            avatarImg.src = sender === 'user' ? USER_AVATAR : BOT_AVATAR;
            avatarImg.alt = sender === 'user' ? '用户头像' : '客服头像';
            
            // 创建消息内容元素
            const contentDiv = document.createElement('div');
            contentDiv.className = 'message-content';
            contentDiv.textContent = content;
            
            // 组装消息元素
            messageDiv.appendChild(avatarImg);
            messageDiv.appendChild(contentDiv);
            
            chatMessages.appendChild(messageDiv);
            
            // 滚动到最新消息
            scrollToBottom();
        }

        // 添加加载中的消息
        function addLoadingMessage() {
            const loadingId = 'loading-' + Date.now();
            const loadingDiv = document.createElement('div');
            loadingDiv.id = loadingId;
            loadingDiv.className = 'message bot-message loading-message';
            
            // 创建客服头像
            const avatarImg = document.createElement('img');
            avatarImg.className = 'message-avatar';
            avatarImg.src = BOT_AVATAR;
            avatarImg.alt = '客服头像';
            
            // 创建加载内容
            const contentDiv = document.createElement('div');
            contentDiv.className = 'message-content';
            contentDiv.innerHTML = '<div class="loading"></div>';
            
            // 组装加载消息
            loadingDiv.appendChild(avatarImg);
            loadingDiv.appendChild(contentDiv);
            chatMessages.appendChild(loadingDiv);
            
            scrollToBottom();
            return loadingId;
        }

        // 移除加载中的消息
        function removeLoadingMessage(loadingId) {
            const loadingDiv = document.getElementById(loadingId);
            if (loadingDiv) {
                loadingDiv.remove();
            }
        }

        // 滚动到聊天底部
        function scrollToBottom() {
            chatMessages.scrollTop = chatMessages.scrollHeight;
        }

        // 监听输入框回车事件(兼容)
        messageInput.addEventListener('input', function() {
            this.style.height = 'auto';
            this.style.height = (this.scrollHeight > 45 ? this.scrollHeight : 45) + 'px';
        });
        
        messageInput.addEventListener('keypress', function(e) {
            if (e.key === 'Enter' && !e.shiftKey) {
                e.preventDefault();
                sendMessage();
            }
        });
    </script>
</body>
</html>

四、系统测试与优化建议

4.1 系统测试步骤

  1. 启动后端服务:运行StartServer类,控制台输出「智能客服后端服务启动成功,端口:8080」即为启动成功;

  2. 打开前端页面:双击index.html文件,在浏览器中打开(推荐Chrome、Edge浏览器);

  3. 测试对话功能:在输入框中输入售后相关问题,点击发送,查看客服回复是否符合预期。


    对话界面

4.2 优化建议(提升系统可用性)

本文实现的是简易版智能客服系统,实际生产环境中可从以下几个方面进行优化:

  1. API Key安全优化:将API Key从硬编码改为通过配置文件(如application. yml)读取,生产环境可使用阿里云密钥管理服务,避免密钥泄露;

  2. 对话历史优化:当前对话历史存储在内存中,服务重启后会丢失,可结合Redis等缓存工具,持久化存储对话历史;

  3. 异常处理优化:完善后端异常捕获,返回更友好的错误提示(如“模型调用超时,请重试”“参数错误”等),提升用户体验;

  4. 上下文工程优化:结合提示词工程(Prompt Engineering)、检索增强生成(RAG)等技术,提升客服回复的准确性和专业性。例如,通过RAG将企业产品手册、售后规则等知识库导入,让客服能够基于具体业务知识回复用户;

  5. 前端优化:美化聊天界面,添加加载动画、消息时间戳、表情发送等功能,提升交互体验。

五、核心技术补充:上下文工程简介

在调用大模型时,直接输入大量原始数据会受限于上下文容量,导致调用成本增加、回复效果下降。上下文工程(Context Engineering)通过一系列技术手段,动态加载精准知识,显著提升模型生成质量与效率,核心技术包括:

六、总结

本文通过Java Spring Boot框架+OpenAI SDK,结合阿里千问大模型API,快速实现了一个简易智能客服系统,涵盖账号配置、后端开发、前端交互、系统测试等完整流程。对于Java工程师而言,该方案上手简单、可扩展性强,可根据实际业务需求,结合上下文工程等技术,进一步优化系统性能与用户体验。

如果在开发过程中遇到问题,可参考阿里云百炼官方文档,或留言交流探讨。希望本文能为你搭建智能客服系统提供一些帮助!

上一篇 下一篇

猜你喜欢

热点阅读