Java对接科大讯飞星火大模型V2.0实战
Java对接讯飞认知大模型教程,先注册账号领取免费测试额度
获取个人免费额度
个人免费 购买 星火认知大模型V2.0
获取秘钥
平台地址: 讯飞开放平台
pom.xml 文件
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.java-websocket</groupId> <artifactId>Java-WebSocket</artifactId> <version>1.3.8</version> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.16</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.67</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>
核心调用类
package com.xunfei; import cn.hutool.core.codec.Base64; import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DateUtil; import cn.hutool.crypto.SecureUtil; import cn.hutool.crypto.digest.HMac; import com.alibaba.fastjson.JSONObject; import com.xunfei.domain.RoleContent; import com.xunfei.domain.request.Request; import com.xunfei.domain.request.header.Header; import com.xunfei.domain.request.parameter.Chat; import com.xunfei.domain.request.parameter.Parameter; import com.xunfei.domain.request.payload.Message; import com.xunfei.domain.request.payload.Payload; import com.xunfei.domain.response.payload.Text; import com.xunfei.domain.response.Result; import org.java_websocket.client.WebSocketClient; import org.java_websocket.handshake.ServerHandshake; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.util.UriComponentsBuilder; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.*; import java.util.stream.Collectors; /** * 讯飞大模型测试类 * * @author Linzj * @date 2023/10/19/019 16:25 */ public class XunFeiBigModelMain { private static final Logger log = LoggerFactory.getLogger(XunFeiBigModelMain.class); /** * 请求地址 */ private static final String HOST_URL = "https://spark-api.xf-yun.com/v2.1/chat"; /** * v2版本 */ private static final String DOMAIN_2 = "generalv2"; /** * APPID */ private static final String APPID = "填你自己的"; /** * APISecret */ private static final String API_SECRET = "填你自己的"; /** * APIKey */ private static final String API_KEY = "填你自己的"; /** * user表示是用户的问题 */ private static final String ROLE_USER = "user"; /** * assistant表示AI的回复 */ private static final String ROLE_ASSISTANT = "assistant"; /** * 接口响应内容集合 */ private static final LinkedList<Result> RESULT_LINKED_LIST = new LinkedList<>(); /** * 对话历史存储集合 */ public static List<RoleContent> historyList = new LinkedList<>(); public static void main(String[] args) throws MalformedURLException, URISyntaxException { System.out.println("您好,这里是星火认知大模型,请问有什么可以帮您的吗?"); while (true) { Scanner scanner = new Scanner(System.in); String content = scanner.nextLine(); // 如果键入“结束对话”,则跳出循环,终止程序 if (Objects.equals(content, "结束对话")) { System.out.println("好的,再见!"); break; } System.out.println("我:" + content); websocketClient(getAuthUrl(), createReqParams(content)); } } /** * websocket 连接 * * @param authUrl 鉴权地址 * @param reqParams 请求参数 * @throws URISyntaxException 异常 */ private static void websocketClient(String authUrl, String reqParams) throws URISyntaxException { String url = authUrl.replace("http://", "ws://").replace("https://", "wss://"); URI uri = new URI(url); WebSocketClient webSocketClient = new WebSocketClient(uri) { @Override public void onOpen(ServerHandshake serverHandshake) { RESULT_LINKED_LIST.clear(); send(reqParams); } @Override public void onMessage(String s) { // 错误码,0表示正常 final int successCode = 0; // 会话状态,2代表最后一个结果 final int lastStatus = 2; Result result = JSONObject.parseObject(s, Result.class); com.xunfei.domain.response.header.Header header = result.getHeader(); if (Objects.equals(successCode, header.getCode())) { RESULT_LINKED_LIST.add(result); } else { log.error("大模型接口响应异常,错误码:{},sid:{}", header.getCode(), header.getSid()); } // 如果是最后的结果,整合答复数据打印出来 if (Objects.equals(lastStatus, header.getStatus())) { printReply(); } } @Override public void onClose(int i, String s, boolean b) { // log.info("WebSocket连接已关闭,原因:{},状态码:{},是否远程关闭:{}", i, s, b); } @Override public void onError(Exception e) { log.error("大模型接口调用发生异常,异常原因:{},异常位置:{}", e.getMessage(), e.getStackTrace()[0]); } }; webSocketClient.connect(); } /** * 生成请求参数 * * @param content 对话内容 * @return 请求参数 */ public static String createReqParams(String content) { // 组装接口请求参数 Header header = new Header(); header.setAppId(APPID); Chat chat = new Chat(); chat.setDomain(DOMAIN_2); Parameter parameter = new Parameter(); parameter.setChat(chat); Message message = new Message(); if (historyList.isEmpty()) { com.xunfei.domain.request.payload.Text text = new com.xunfei.domain.request.payload.Text(); text.setRole(ROLE_USER); text.setContent(content); message.setText(Collections.singletonList(text)); // 添加历史对话集合 RoleContent roleContent = new RoleContent(); roleContent.setRole(ROLE_USER); roleContent.setContent(content); historyList.add(roleContent); } else { // 添加历史对话集合 RoleContent roleContent = new RoleContent(); roleContent.setRole(ROLE_USER); roleContent.setContent(content); historyList.add(roleContent); delHistory(); List<com.xunfei.domain.request.payload.Text> textList = historyList.stream() .map(item -> { com.xunfei.domain.request.payload.Text text = new com.xunfei.domain.request.payload.Text(); text.setContent(item.getContent()); text.setRole(item.getRole()); return text; }) .collect(Collectors.toList()); message.setText(textList); } Payload payload = new Payload(); payload.setMessage(message); Request request = new Request(); request.setHeader(header); request.setParameter(parameter); request.setPayload(payload); return JSONObject.toJSONString(request); } /** * URL鉴权 * * @return 请求url * @throws MalformedURLException 异常 */ private static String getAuthUrl() throws MalformedURLException { String date = DateUtil.format(new Date(), DatePattern.HTTP_DATETIME_FORMAT); URL url = new URL(HOST_URL); String preStr = "host: " + url.getHost() + "\n" + "date: " + date + "\n" + "GET " + url.getPath() + " HTTP/1.1"; HMac hMac = SecureUtil.hmacSha256(API_SECRET.getBytes(StandardCharsets.UTF_8)); byte[] digest = hMac.digest(preStr); String signature = Base64.encode(digest); String authorizationOrigin = String.format("api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"", API_KEY, "hmac-sha256", "host date request-line", signature); String authorization = Base64.encode(authorizationOrigin); return UriComponentsBuilder.fromUriString(HOST_URL) .queryParam("authorization", authorization) .queryParam("date", date) .queryParam("host", url.getHost()).toUriString(); } /** * 如果历史数据太大,将前面的历史数据清除一些 */ public static void delHistory() { // 由于历史记录最大上线1.2W左右,如果最大值,删除前面的数据 final int maxLength = 12000; Iterator<RoleContent> iterator = historyList.iterator(); while (iterator.hasNext()) { iterator.next(); int historyLength = historyList.stream() .map(RoleContent::getContent) .collect(Collectors.joining()).length(); if (historyLength > maxLength) { iterator.remove(); } else { break; } } } /** * 打印星火认知大模型回复内容 */ private static void printReply() { String content = RESULT_LINKED_LIST.stream() .map(item -> item.getPayload().getChoices().getText()) .flatMap(Collection::stream) .map(Text::getContent) .collect(Collectors.joining()); RoleContent roleContent = new RoleContent(); roleContent.setRole(ROLE_ASSISTANT); roleContent.setContent(content); historyList.add(roleContent); System.out.println("星火认知大模型:" + content); } }
相关文档
其他一些实体类就不详细写了,文末有项目地址,可以自行获取,或者照着官方文档自己写一下
最终效果
对接完成,全部代码已提交至Gitee 讯飞大模型
本文作者:启航黑珍珠号
本文链接:https://www.cnblogs.com/Linzj5950/p/17777153.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步