AI对话机器人简单实现--智谱BigModel+SpringBoot+Vue2+ElementUI

成品展示

一、首先去注册个账号然后申请个API keys

二、引入依赖 

        <dependency>
            <groupId>cn.bigmodel.openapi</groupId>
            <artifactId>oapi-java-sdk</artifactId>
            <version>release-V4-2.3.0</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.75</version>
        </dependency>

三、后端代码 

此处参考的是这位大佬的文章Java(Spring boot)集成智谱AI聊天(简易版)_智谱ai问答springboot-CSDN博客

 ZhipuAIService.java:

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zhipu.oapi.ClientV4;
import com.zhipu.oapi.Constants;
import com.zhipu.oapi.service.v4.model.ChatCompletionRequest;
import com.zhipu.oapi.service.v4.model.ChatMessage;
import com.zhipu.oapi.service.v4.model.ModelApiResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Service
public class ZhipuAIService {
    private final ClientV4 client;
    private final ObjectMapper objectMapper;
    public ZhipuAIService(@Value("${bigmodel.api.key}") String apiKey) {
        this.client = new ClientV4.Builder(apiKey).build();
        this.objectMapper = new ObjectMapper();
    }
    //构建信息
    public String invokeChatCompletion(String userMessage) {
        List<ChatMessage> messages = new ArrayList<>();
        ChatMessage chatMessage = new ChatMessage("user", userMessage);
        messages.add(chatMessage);
        ChatCompletionRequest chatCompletionRequest = ChatCompletionRequest.builder()
                //表明使用的模型
                .model("glm-4-flash")
                //表示不使用流式响应
                .stream(Boolean.FALSE)
                .invokeMethod(Constants.invokeMethod)
                .messages(messages)
                .requestId("request-id-" + System.currentTimeMillis())
                .build();
        ModelApiResponse response = client.invokeModelApi(chatCompletionRequest);
        try {
            // 将response的数据转换为Map
            String jsonString = objectMapper.writeValueAsString(response.getData());
            Map<String, Object> dataMap = objectMapper.readValue(jsonString, new TypeReference<Map<String, Object>>() {});
            // 提取内容
            if (dataMap.containsKey("choices")) {
                List<Map<String, Object>> choices = (List<Map<String, Object>>) dataMap.get("choices");
                if (!choices.isEmpty()) {
                    Map<String, Object> firstChoice = choices.get(0);
                    Map<String, Object> message = (Map<String, Object>) firstChoice.get("message");
                    if (message != null && message.containsKey("content")) {
                        return (String) message.get("content");
                    }
                }
            }
            return "找不到内容";
        } catch (Exception e) {
            return "响应错误";
        }
    }
}

 ZhipuAiController.java:

import org.springframework.beans.factory.annotation.Autowired;
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;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;


@RestController
@RequestMapping("/app/chat")
public class ZhipuAiController {

    @Autowired
    private final ZhipuAIService zhipuAiService;

    public ZhipuAiController(ZhipuAIService zhipuAiService) {
        this.zhipuAiService = zhipuAiService;
    }

    @PostMapping("/ask")
    public String chat(@RequestBody String userInput) {
        try {
            // 对接收到的userInput进行URL解码
            userInput = URLDecoder.decode(userInput, StandardCharsets.UTF_8.toString());
        } catch (UnsupportedEncodingException e) {
            return "解码错误";
        }
        String response = zhipuAiService.invokeChatCompletion(userInput);
        return response;
    }

}

 四、前端代码

请求路径要换成自己的

<template>
    <div class="ai-chat">
      <!-- 页面栏 -->
      <van-nav-bar title="文章详情" left-text="返回" right-text="按钮" left-arrow @click-left="onClickLeft" />
      <div class="ai-chat-container">
        <div class="title">街健佳AI助手</div>
        <el-card class="chat-card">
          <div v-for="(message, index) in messages" :key="index" class="message">
            <div :class="{ 'user-message': message.role === 'USER', 'ai-message': message.role === 'AI' }">
              {{ message.content }}
            </div>
          </div>
          <div v-if="isAnalyzing" class="analyzing">分析中...</div>
          <div class="input-wrapper">
            <el-input
              type="textarea"
              v-model="inputMessage"
              :rows="2"
              placeholder="请输入内容"
              class="chat-input"
              @keyup.enter.native="sendMessage"
            ></el-input>
            <el-button type="primary" @click="sendMessage">发送</el-button>
          </div>
        </el-card>
      </div>
    </div>
  </template>
  <script>
  import axios from 'axios';
  import { MessageBox } from 'element-ui';
  import { API_URL } from '../../config/config';
  
  export default {
    data() {
      return {
        messages: [],
        inputMessage: '',
        isAnalyzing: false,
      };
    },
    created() {
      // 页面加载时发送欢迎消息
      this.messages.push({ role: 'AI', content: '您好,我是小佳,请问您有什么问题呢?' });
    },
    methods: {
      async sendMessage() {
        if (this.inputMessage.trim()) {
          this.messages.push({ role: 'USER', content: this.inputMessage });
          this.isAnalyzing = true; // 显示“分析中”提示
          try {
            const response = await axios.post(API_URL + 'app/chat/ask', { message: this.inputMessage });
            this.isAnalyzing = false; // 隐藏“分析中”提示
            if (response.data) {
              this.messages.push({ role: 'AI', content: response.data });
            } else {
              MessageBox.alert('没有收到AI的回复', '提示', { type: 'warning' });
            }
          } catch (error) {
            this.isAnalyzing = false; // 隐藏“分析中”提示
            MessageBox.alert('发送失败: ' + error.message, '错误', { type: 'error' });
          }
          this.inputMessage = '';
        }
      },
      onClickLeft() {
        this.$router.go(-1);
      },
    },
  };
  </script>
  <style scoped>
  .ai-chat {
    display: flex;
    flex-direction: column;
    height: 100vh;
  }
  
  .ai-chat-container {
    background: linear-gradient(to bottom, #007bff, #ffffff);
    max-width: 800px;
    height: calc(100vh - 50px); /* 减去顶部栏的高度 */
    margin: auto;
    padding: 20px;
    border-radius: 8px;
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
    overflow: hidden;
    position: relative;
    overflow-y: auto; /* 允许垂直滚动 */
  }
  
  .title {
    position: absolute;
    top: 10px;
    left: 50%;
    transform: translateX(-50%);
    background-color: #007bff;
    color: #ffffff;
    padding: 5px 20px;
    border-radius: 999px;
    text-align: center;
    font-size: 20px;
    font-weight: bold;
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
  }
  
  .chat-card {
    background-color: #fff;
    border-radius: 6px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    padding: 0px;
    margin-top: 50px;
    flex: 1;
    overflow-y: auto;
  }
  
  .message {
    margin-bottom: 20px;
    display: flex;
    align-items: flex-end;
  }
  
  .user-message {
    background-color: #e6f7ff;
    border-radius: 4px;
    padding: 10px;
    max-width: 60%;
    margin-left: auto;
  }
  
  .ai-message {
    background-color: #f3e5fd;
    border-radius: 4px;
    padding: 10px;
    max-width: 70%;
    margin-right: auto;
    text-align: left;
  }
  
  .input-wrapper {
    display: flex;
    align-items: center;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    background-color: #f9f9f9;
    padding: 10px;
    box-shadow: 0 -2px 4px rgba(0, 0, 0, 0.1);
  }
  
  .chat-input {
    flex-grow: 1;
    margin-right: 10px;
    
  }
  
  .el-button {
    width: auto;
    padding: 10px 20px;
  }
  
  .analyzing {
    text-align: center;
    margin-top: 20px;
    color: #909399;
  }
  </style>

如果这篇文章帮助到了您,麻烦点个赞哦~ 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/942963.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

每天40分玩转Django:Django静态文件

Django静态文件 一、今日学习内容概述 学习模块重要程度主要内容静态文件配置⭐⭐⭐⭐⭐基础设置、路径配置CDN集成⭐⭐⭐⭐⭐CDN配置、资源优化静态文件处理⭐⭐⭐⭐压缩、版本控制部署优化⭐⭐⭐⭐性能优化、缓存策略 二、基础配置 # settings.py import os# 静态文件配置…

改进爬山算法之一:随机化爬山法(Stochastic Hill Climbing,SHC)

随机化爬山法(Stochastic Hill Climbing),也被称为随机爬山法,是一种基于搜索算法的优化方法,是爬山算法的一个变种,它通过引入随机性来减少算法陷入局部最优解的风险,并增加搜索解空间的能力。这种方法特别适合于解决那些具有多个局部最优解的优化问题。 一、算法思想 …

农家乐系统|Java|SSM|VUE| 前后端分离

【技术栈】 1⃣️&#xff1a;架构: B/S、MVC 2⃣️&#xff1a;系统环境&#xff1a;Windowsh/Mac 3⃣️&#xff1a;开发环境&#xff1a;IDEA、JDK1.8、Maven、Mysql5.7 4⃣️&#xff1a;技术栈&#xff1a;Java、Mysql、SSM、Mybatis-Plus、VUE、jquery,html 5⃣️数据库可…

探究音频丢字位置和丢字时间对pesq分数的影响

丢字的本质 丢字的本质是在一段音频中一小段数据变为0 丢字对主观感受的影响 1. 丢字位置 丢字的位置对感知效果有很大影响。如果丢字发生在音频信号的静音部分或低能量部分&#xff0c;感知可能不明显&#xff1b;而如果丢字发生在高能量部分或关键音素上&#xff0c;感知…

《Java源力物语》-3.空值猎手

~犬&#x1f4f0;余~ “我欲贱而贵&#xff0c;愚而智&#xff0c;贫而富&#xff0c;可乎&#xff1f; 曰&#xff1a;其唯学乎” \quad 夜色渐深&#xff0c;在一处偏僻小径上&#xff0c;月光透过浓密的源力云层&#xff0c;在地面上投下斑驳的光影。String正独自练习着刚从…

产品初探Devops!以及AI如何赋能Devops?

DevOps源自Development&#xff08;开发&#xff09;和Operations&#xff08;运维&#xff09;的组合&#xff0c;是一种新的软件工程理念&#xff0c;旨在打破传统软件工程方法中“开发->测试->运维”的割裂模式&#xff0c;强调端到端高效一致的交付流程&#xff0c;实…

使用 OpenCV 在图像中添加文字

在图像处理任务中&#xff0c;我们经常需要将文本添加到图像中。OpenCV 提供了 cv2.putText() 函数&#xff0c;可以很方便地在图像上绘制文本&#xff0c;支持多种字体、颜色、大小和位置等参数。 本文将详细介绍如何使用 OpenCV 在图像中添加文字&#xff0c;介绍 cv2.putTe…

接口测试Day-02-安装postman项目推送Gitee仓库

postman安装 下载 Postman&#xff08;已提供安装包&#xff0c;此步可以跳过&#xff09; https://www.postman.com/downloads/安装 Postman 安装Postman插件newman 要想给 postman 安装 newman 插件&#xff0c;必须 先 安装 node.js。 这是前提&#xff01; 安装node.js 可能…

MySQL索引为什么是B+树

MySQL索引为什么是B树 索引是帮助MySQL高效获取数据的数据结构&#xff0c;在数据之外&#xff0c;数据库还维护着满足特定查找算法的数据结构B树&#xff0c;这些数据结果以某种特定的方式引用数据&#xff0c;这样就可以在这些数据结构上实现高级查找算法&#xff0c;提升数据…

C#实现图像骨架化(ZhangSuen细化算法)

原始图像: 骨架化后图像: 需要安装一个NuGet包:System.Drawing.Common 代码如下: using System.Drawing; using System.Drawing.Imaging;public class Image {public int Width { get; }public int Height { get; }private bool[,] pixels;// 构造函数,初始化图像的宽度…

【无标题】学生信息管理系统界面

网页是vue框架&#xff0c;后端直接python写的没使用框架

Flow Field——流场寻路算法

目的 一群物体到达某个目的地时&#xff0c;需要对这些海量单位做寻路和避障&#xff0c;类似塔防类游戏的怪物步行到终点的过程。 参考视频&#xff1a;https://www.bilibili.com/video/BV12bzZY2EfA 演示动画&#xff1a;https://howtorts.github.io/examples/4-basic-flow-f…

Bash 脚本教程

注&#xff1a;本文为 “Bash 脚本编写” 相关文章合辑。 BASH 脚本编写教程 as good as well于 2017-08-04 22:04:28 发布 这里有个老 American 写的 BASH 脚本编写教程&#xff0c;非常不错&#xff0c;至少没接触过 BASH 的也能看懂&#xff01; 建立一个脚本 Linux 中有…

区块链期末复习3.2:比特币脚本

目录 一、输入输出脚本的执行 二、简单脚本实例及压栈过程 1.P2PK&#xff08;pay to public key hash&#xff09; 2、P2PH&#xff08;pay to public key hash&#xff09; 3.多重签名 4.比特币脚本的应用&#xff1a; 三、其他常见指令 1.OP_EQUAL与OP&#xff3f;EQ…

2024大模型在软件开发中的具体应用有哪些?(附实践资料合集)

大模型在软件开发中的具体应用非常广泛&#xff0c;以下是一些主要的应用领域&#xff1a; 自动化代码生成与智能编程助手&#xff1a; AI大模型能够根据开发者的自然语言描述自动生成代码&#xff0c;减少手动编写代码的工作量。例如&#xff0c;GitHub Copilot工具就是利用AI…

【数据可视化复习方向】

1.数据可视化就是数据中信息的可视化 2.数据可视化主要从数据中寻找三个方面的信息&#xff1a;模式、关系和异常 3.大数据可视化分类&#xff1a;科学可视化、信息可视化、可视分析学 4.大数据可视化作用&#xff1a;记录信息、分析推理、信息传播与协同 5.可视化流程&…

Python 多进程编程详解

目录 一、多进程编程简介 1. 什么是多进程 2. 多进程与多线程的区别 二、Python 中的多进程编程 1. 创建进程 2. 进程间通信 3. 进程池 4. 进程同步 5. 注意事项 三、实际应用案例 四、总结 在 Python 中&#xff0c;多进程编程是一种提高程序运行效率的有效手段。相…

Redis篇--应用篇1--会话存储(session共享)

1、概述 实现Session共享是构建分布式Web应用时的一个重要需求&#xff0c;尤其是在水平扩展和高可用性要求较高的场景下。 在分布式服务或集群服务中往往会出现这样一个问题&#xff1a;用户登录A服务后可以正常访问A服务中的接口。但是我们知道&#xff0c;分布式服务通常都…

ip-协议

文章目录 1. 网络层2. ip协议2.1 ip协议格式2.2 网段划分基本概念网段划分的两种方式为什么要网段划分&#xff1f;特殊的IP地址IP地址数量不足 2.3 私有IP与公网IP2.4 路由 3. IP的分片与组装为什么要分片与组装&#xff1f;如何分片&#xff1f;如何组装&#xff1f; 1. 网络…

ECharts散点图-气泡图,附视频讲解与代码下载

引言&#xff1a; ECharts散点图是一种常见的数据可视化图表类型&#xff0c;它通过在二维坐标系或其它坐标系中绘制散乱的点来展示数据之间的关系。本文将详细介绍如何使用ECharts库实现一个散点图&#xff0c;包括图表效果预览、视频讲解及代码下载&#xff0c;让你轻松掌握…