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

news/2025/2/9 14:13:51/

问题重现

  • 依赖

    <!--讯飞开放平台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/news/1570591.html

相关文章

一种基于Leaflet.Legend的图例动态更新方法

目录 前言 一、场景再现 1、需求描述 2、核心方法介绍 3、存在的问题 二、问题解决 1、重复解决办法 2、图例不展示解决办法 3、成果展示 三、总结 前言 在当今数字化时代&#xff0c;地理信息系统&#xff08;GIS&#xff09;技术已经广泛应用于各个领域&#xff0c;…

【共享文件夹】使用Samba服务可在Ubuntu和Windows系统之间共享一个实际的文件夹

目标&#xff1a;在Ubuntu和Windows系统之间共享一个实际的文件夹&#xff0c;并能够共同编辑其中的文件 安装Samba创建共享文件夹配置Samba设置Samba密码重启Samba服务以应用更改&#xff1a;在Windows中访问共享文件夹如果客户机无法访问 Samba 服务器&#xff0c;解决方法①…

以太网总线多功能数据采集卡,16路2M同步模拟量采集卡 NET9784A/B

#阿尔泰科技# 型号&#xff1a;NET9784/(A/B) 概述&#xff1a; NET9784、NET9784A、NET9784B 是同一系列以太网总线的多功能同步数据采集卡。该系列板 卡支持 16 路差分模拟输入通道&#xff0c;16bit ADC 分辨率&#xff0c;提供 2MS/s、1MS/s、500KS/s 三种采样率可选 型&…

阿里云 | DeepSeek人工智能大模型安装部署

ModelScope是阿里云人工智能大模型开源社区 ModelScope网络链接地址 https://www.modelscope.cn DeepSeek模型库网络链接地址 https://www.modelscope.cn/organization/deepseek-ai 如上所示&#xff0c;在阿里云人工智能大模型开源社区ModelScope中&#xff0c;使用阿里云…

【C语言】C语言经典面试题详解

文章目录 引言1. 指针与数组1.1 指针与数组的区别1.2 指针数组与数组指针 2. 内存管理2.1 malloc与free2.2 内存泄漏与悬空指针 3. 函数指针3.1 函数指针的定义与使用3.2 回调函数 4. 结构体与联合体4.1 结构体的内存对齐4.2 联合体的使用场景4.3 位段 5. 预处理器与宏5.1 宏定…

Android开发获取缓存,删除缓存

Android开发获取缓存&#xff0c;删除缓存 app设置中往往有清理缓存的功能。会显示当前缓存时多少&#xff0c;然后可以点击清理缓存 直接上代码&#xff1a; object CacheHelper {/*** 获取缓存大小* param context* return* throws Exception*/JvmStaticfun getTotalCache…

【CUDA】常量内存

目录 一、认识常量内存 二、使用常量内存实现1D模板 三、与只读缓存比较 一、认识常量内存 常量内存对内核代码而言是只读的&#xff0c;但它对主机而言即是可读的又是可写的。常量内存位于设备的DRAM上&#xff08;和全局内存一样&#xff09;。有一个专用的片上缓存&…

设计模式-生产者消费者模型

阻塞队列&#xff1a; 在介绍生产消费者模型之前&#xff0c;我们先认识一下阻塞队列。 阻塞队列是一种支持阻塞操作的队列&#xff0c;常用于生产者消费者模型&#xff0c;它提供了线程安全的队列操作&#xff0c;并且在队列为空或满时&#xff0c;能够阻塞等待&#xff0c;…