当前位置: 首页 > article >正文

项目接入通义千问 api 接口实现步骤详解

        随着科技的飞速发展,ai 越来越火,比如平常有问题时,可以询问 ai 给我们解答。越来越多的项目也接入了 ai,智能会话、智能问诊等。那么,我们应该如何在项目中接入 ai 呢?编写一个简单的页面进行对话呢?今天,我们以接入千义通问 api 为例,总结一下实现的基本步骤。

     一:引入依赖

<dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>dashscope-sdk-java</artifactId>
   <version>2.15.2</version>
</dependency>

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.14</version>
</dependency>

     二:编写接口

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 org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

@RestController
@RequestMapping("/demo/ai")
public class ChatController {

    /**
     * 问答内容
     */
    @PostMapping("/queryAnswer")
    public SseEmitter test(@RequestBody QueryVO vo) throws Exception {
        return AiUtils.qwenQuickStart(vo.getQuestion());
    }
}

    三:获取 api key

       登录阿里云控制台,选择大模型进入,根据自己需求选择合适的模型,开通服务。

       1:开通百炼大模型服务

        2:创建 api-key

        3:查看 api-key 列表

      四:调用 api 接口

import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.aigc.generation.models.QwenParam;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.utils.Constants;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * ai 接口调用工具类
 */
public class AiChatUtils {

    private static final ExecutorService executorService = Executors.newFixedThreadPool(10);

    private static String message="您的问题暂时无法回答。";

    /**
     * 调用通义千
     */
    public static SseEmitter queryAnsWer(String chatContent) {
        SseEmitter emitter = new SseEmitter();

        executorService.submit(() -> {
            try {
                // 注意替换 ai key
                Constants.apiKey="your ai key";
                Generation gen = new Generation();
                QwenParam param = QwenParam.builder().model(Generation.Models.QWEN_TURBO).prompt(chatContent)
                        .topP(0.8).build();
                GenerationResult result = gen.call(param);
                message=result.getOutput().getText().toString();

                // 流式发送消息
                for (int i = 0; i < message.length(); i++) {
                    String chunk = String.valueOf(message.charAt(i));
                    emitter.send(SseEmitter.event().data(chunk));
                    Thread.sleep(100); // 模拟处理延迟
                }
                emitter.complete();
            } catch (IOException | InterruptedException e) {
                emitter.completeWithError(e);
            } catch (NoApiKeyException e) {
                throw new RuntimeException(e);
            } catch (InputRequiredException e) {
                throw new RuntimeException(e);
            }
        });
        return emitter;
    }

}

        五:编写 HTML 页面

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>测试 AI</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            background-color: #f4f4f9;
        }

       .chat-container {
            width: 600px;
            height: 600px;
            border: 1px solid #ccc;
            border-radius: 8px;
            overflow: hidden;
            display: flex;
            flex-direction: column;
        }

       .chat-header {
            background-color: #5b8cff;
            color: white;
            text-align: center;
            padding: 10px;
            font-size: 20px;
        }

       .chat-messages {
            flex: 1;
            padding: 20px;
            overflow-y: auto;
            background-color: #fff;
            display: flex;
            flex-direction: column;
        }

       .message {
            margin-bottom: 20px;
            padding: 8px 12px;
            border-radius: 8px;
            max-width: 70%;
        }

       .user-message {
            background-color: #e0f7fa;
            align-self: flex-end;
        }

       .ai-message {
            background-color: #f1f8e9;
            align-self: flex-start;
        }

       .input-container {
            display: flex;
            padding: 10px;
            background-color: #eee;
        }

        #question-input {
            flex: 1;
            padding: 15px;
            border: 1px solid #ccc;
            border-radius: 10px;
            margin-right: 15px;
        }

        #send-button {
            padding: 8px 20px;
            background-color: #2196f3;
            color: #fff;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }
    </style>
</head>

<body>
    <div class="chat-container">
        <div class="chat-header">测试 AI</div>
        <div class="chat-messages" id="chat-messages"></div>
        <div class="input-container">
            <input type="text" id="question-input" placeholder="输入你的问题">
            <button id="send-button">发送</button>
        </div>
    </div>
    <script>
        document.getElementById('send-button').addEventListener('click', async () => {
            const question = document.getElementById('question-input').value;
            if (question.trim() === '') return;

            // 显示用户消息
            const chatMessages = document.getElementById('chat-messages');
            const userMessage = document.createElement('div');
            userMessage.classList.add('message', 'user-message');
            userMessage.textContent = question;
            chatMessages.appendChild(userMessage);

            // 清空输入框
            document.getElementById('question-input').value = '';

            // 创建流式响应的请求
            const response = await fetch('http://localhost:8088/demo/ai/queryAnswer', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Accept': 'text/event-stream'
                },
                body: JSON.stringify({ question })
            });

            const reader = response.body.getReader();
            const decoder = new TextDecoder();
            let aiMessage = document.createElement('div');
            aiMessage.classList.add('message', 'ai-message');
            chatMessages.appendChild(aiMessage);

            while (true) {
                const { done, value } = await reader.read();
                if (done) break;
                const chunk = decoder.decode(value);
                // 去除 data: 前缀
                const lines = chunk.split('\n');
                for (const line of lines) {
                    if (line.startsWith('data:')) {
                        const data = line.replace('data:', '').trim();
                        if (data) {
                            aiMessage.textContent += data;
                        }
                    }
                }
            }
        });
    </script>
</body>

</html>    

     六:进行测试

     七:总结

        以上为接入ai的基本步骤,主要是开通大模型服务和api接口接入,以上实现了一个简单的调用。过程中遇到的主要问题是,先开始返回数据直接将所有的数据全部返回了,这样看起来不太友好。所以采用 SseEmitter 实现服务器发送事件流失响应的,这样看起来更加的友好。


http://www.kler.cn/a/613356.html

相关文章:

  • 基于ssm的养老院综合服务系统
  • 项目-苍穹外卖(十五) Apache ECharts+数据统计
  • Blender绘图——旋转曲线(以LCP与RCP为例)
  • Linux系统编程 | 线程的基本概念
  • FLEXlm如何通过web调用
  • Go服务开发高手课(极客讲堂)
  • 为什么大模型在 OCR 任务上表现不佳?
  • 0.雷达信号
  • 什么是uv 和pip的区别是什么
  • leetcode131-分割回文串
  • 构建大语言模型应用:句子转换器(Sentence Transformers)(第三部分)
  • 手机零售行业的 AI 破局与创新降本实践 | OceanBase DB大咖说
  • 探索:如何构建一个自我的AI辅助的开发环境?
  • 淘宝API+爬虫混合方案:合规采集历史价格与评价数据
  • Axios核心原理
  • 平台清洗行动:AI浏览器用户生存率高出传统方案17倍
  • ffmpeg(1)-图片相关知识
  • uniapp中的本地存储API
  • uniapp自定义圆形滑杆
  • 社区医疗服务可视化系统+论文源码视频演示