【异常记录Java-20250204】调用讯飞星火AI(Spark lite 版本)Api 授权错误问题处理

embedded/2025/2/6 7:08:58/

问题重现

  • 依赖

    <!--讯飞开放平台sdk-->
    <dependency><groupId>io.github.briqt</groupId><artifactId>xunfei-spark4j</artifactId><version>1.3.0</version>
    </dependency>
    
  • yml配置文件

    # 讯飞Api配置
    xunfei:client:appId: "别只顾着抄,这里要写自己的"apiKey: "别只顾着抄,这里要写自己的"apiSecret: "别只顾着抄,这里要写自己的"
    
  • SparkConfig 配置类

    java">@Configuration
    @ConfigurationProperties(prefix = "xunfei.client")
    @Data
    public class SparkConfig {private String appid;private String apiKey;private String apiSecret;@Beanpublic SparkClient sparkClient() {SparkClient sparkClient = new SparkClient();sparkClient.appid = this.appid;sparkClient.apiKey = this.apiKey;sparkClient.apiSecret = this.apiSecret;return sparkClient;}
    }
    
  • SparkManager 实现类

    java">@Component
    @Slf4j
    public class SparkManager {@Resourceprivate SparkClient sparkClient;/*** AI生成问题的预设条件*/public static final  String PRECONDITION = "" +"你是一名Java程序员\n" +"给我一些软件开发方面的知识\n";public String sendHttpToSpark(final String content){// 消息列表,可以再此列表添加历史对话记录List<SparkMessage> messages = new ArrayList<>();messages.add(SparkMessage.systemContent(PRECONDITION));// 用户输入内容messages.add(SparkMessage.userContent(content));// 构造请求SparkRequest sparkRequest = SparkRequest.builder()// 指定请求版本,lite为V1_5.apiVersion(SparkApiVersion.V1_5).messages(messages)     // 消息列表.build();// 同步调用SparkSyncChatResponse chatResponse = sparkClient.chatSync(sparkRequest);String responseContent = chatResponse.getContent();log.info("spark返回内容:{}",responseContent);return responseContent;}
    }
    

    可以到讯飞星火官网免费领取不限量的免费AI

    在这里插入图片描述

完成以上步骤后,不出意外的话就能正常通过java代码调用Spark lite 的API进行 AI 对话,但遗憾的是出了意外

  • 测试代码
java">@SpringBootTest
public class SparkManagerTest {@Resourceprivate SparkManager sparkManager;private final String userInput = "如何调用api";@Testpublic void testApi(){String result = sparkManager.sendHttpToSpark(userInput);System.out.println(result);}
}
  • 报错截图

在这里插入图片描述

问题处理

一开始我怀疑的是自己的配置出了问题,但CV大法除了CV错地方外,还能怎么错呢?

刚好讯飞星火提供了免费的Spark Lite的同时,还赠送了不少Spark4.0 Uitra的token数,刚好可以拿来做验证

在这里插入图片描述

修改指定请求版本

java">public String sendHttpToSpark(final String content){List<SparkMessage> messages = new ArrayList<>();messages.add(SparkMessage.systemContent(PRECONDITION));messages.add(SparkMessage.userContent(content));SparkRequest sparkRequest = SparkRequest.builder()// 修改指定请求版本为4_0,其对应4.0Ultra.apiVersion(SparkApiVersion.V4_0).messages(messages)    .build();SparkSyncChatResponse chatResponse = sparkClient.chatSync(sparkRequest);String responseContent = chatResponse.getContent();log.info("spark返回内容:{}",responseContent);return responseContent;
}

此时再运行测试代码可正常获取返回内容

在这里插入图片描述

然后看了源码后,也算是找到 Spark Lite 授权错误的原因,API版本枚举类(SparkApiVersion.class)中lite对应的V1_5版本中的domain属性是general 而不是 lite

在这里插入图片描述

为了使用免费版本的AI(仅限学习,经济压力大,学习阶段就搞付费的承受不起),自然得想方法处理。

在这里插入图片描述

需要注意的是,SparkApiVersion类中的构造方法是私有的,无法直接设值,所以我采用的是利用反射去修改值(不推荐,但这不对外,仅是学习AI才使用该方法;如有更好的方法,烦请告知)

编写EnumReflectionUtil工具类,用于修改枚举值

java">public class EnumReflectionUtil {public static void setEnumField(Enum<?> enumConstant, String fieldName, Object newValue) throws Exception {Field field = enumConstant.getClass().getDeclaredField(fieldName);field.setAccessible(true);field.set(enumConstant, newValue);}
}

修改SparkManager类

java">@Component
@Slf4j
public class SparkManager {@Resourceprivate SparkClient sparkClient;@PostConstructpublic void init(){try {// 修改 V1_5 的版本信息EnumReflectionUtil.setEnumField(SparkApiVersion.V1_5, "version", "v1.1");EnumReflectionUtil.setEnumField(SparkApiVersion.V1_5, "url", "https://spark-api.xf-yun.com/v1.1/chat");EnumReflectionUtil.setEnumField(SparkApiVersion.V1_5, "domain", "lite");} catch (Exception e) {log.error("尝试修改枚举字段异常:", e);}}/*** AI生成问题的预设条件*/public static final  String PRECONDITION = "" +"你是一名Java程序员\n" +"给我一些软件开发方面的知识\n";public String sendHttpToSpark(final String content){// 消息列表,可以再此列表添加历史对话记录List<SparkMessage> messages = new ArrayList<>();messages.add(SparkMessage.systemContent(PRECONDITION));// 用户输入内容messages.add(SparkMessage.userContent(content));// 构造请求SparkRequest sparkRequest = SparkRequest.builder()// 此时SparkApiVersion.V1_5的内容为修改后的内容.apiVersion(SparkApiVersion.V1_5).messages(messages)     // 消息列表.build();// 同步调用SparkSyncChatResponse chatResponse = sparkClient.chatSync(sparkRequest);String responseContent = chatResponse.getContent();log.info("spark返回内容:{}",responseContent);return responseContent;}
}

此时再运行测试代码可正常获取返回内容,且增加的是Spark Lite的token数而非Spark4.0的,说明调用的是Spark Lite 无误

在这里插入图片描述


http://www.ppmy.cn/embedded/159962.html

相关文章

Vue和Java使用AES加密传输

背景&#xff1a;Vue对参数进行加密&#xff0c;对响应进行解密。Java对参数进行解密&#xff0c;对响应进行解密。不拦截文件上传类请求、GET请求。 【1】前端配置 安装crypto npm install crypto-js编写加解密工具类encrypt.js import CryptoJS from crypto-jsconst KEY …

vim-plug的自动安装与基本使用介绍

vim-plug介绍 Vim-plug 是一个轻量级的 Vim 插件管理器&#xff0c;它允许你轻松地管理 Vim 插件的安装、更新和卸载。相较于其他插件管理器&#xff0c;vim-plug 的优点是简单易用&#xff0c;速度较快&#xff0c;而且支持懒加载插件&#xff08;即按需加载&#xff09; 自动…

3.【BUUCTF】XSS-Lab1

进入题目页面如下 好好好&#xff0c;提示点击图片&#xff0c;点进去页面如下&#xff0c;且url中有传参&#xff0c;有注入点 发现题目给出了源码 查看得到本题的源码 分析一下代码 <!DOCTYPE html><!--STATUS OK--> <!-- 声明文档类型为 HTML5&#xff0c;告…

基于 docker 的mysql 5.7 主主集群搭建

创建挂载目录和配置文件 主节点1 mkdir -p /mysql_master_1/mysql/log mkdir -p /mysql_master_1/mysql/data mkdir -p /mysql_master_1/mysql/conf vim /mysql_master_1/mysql/conf/my.cnf[mysqld] datadir/var/lib/mysql #MySQL 数据库文件存放路径 server_id 1 #指定数据…

React组件中的列表渲染与分隔符处理技巧

React组件中的列表渲染与分隔符处理技巧 摘要问题背景解决方案分析方案一&#xff1a;数组拼接法方案二&#xff1a;Fragment组件方案三&#xff1a;动态生成key 关键技术点1. key的使用原则2. Fragment组件3. 性能优化 实战演练挑战1&#xff1a;动态分隔符样式挑战2&#xff…

SQL中的三值逻辑和NULL

在SQL中&#xff0c;三值逻辑是一个重要概念&#xff0c;它的存在主要是由于 NULL 值的引入。NULL 代表未知值&#xff0c;它既不是空字符串&#xff0c;也不是数字 0&#xff0c;而是一个特殊的标记&#xff0c;表示数据缺失或不可用。 目录 SQL的三值逻辑 NULL的特性 NULL…

【单层神经网络】softmax回归的从零开始实现(图像分类)

softmax回归 该回归分析为后续的多层感知机做铺垫 基本概念 softmax回归用于离散模型预测&#xff08;分类问题&#xff0c;含标签&#xff09; softmax运算本质上是对网络的多个输出进行了归一化&#xff0c;使结果有一个统一的判断标准&#xff0c;不必纠结为什么要这么算…

Java NIO详解

一、NIO简介 NIO 中的 N 可以理解为 Non-blocking&#xff0c;不单纯是 New&#xff0c;是解决高并发、I/O高性能的有效方式。 Java NIO 是Java1.4之后推出来的一套IO接口&#xff0c;NIO提供了一种完全不同的操作方式&#xff0c; NIO支持面向缓冲区的、基于通道的IO操作。 …