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

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

问题重现

  • 依赖

    <!--讯飞开放平台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 配置类

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

    @Component
    @Slf4j
    public class SparkManager {
        @Resource
        private 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 对话,但遗憾的是出了意外

  • 测试代码
@SpringBootTest
public class SparkManagerTest {

    @Resource
    private SparkManager sparkManager;

    private final String userInput = "如何调用api";

    @Test
    public void testApi(){
        String result = sparkManager.sendHttpToSpark(userInput);
        System.out.println(result);
    }
}
  • 报错截图

在这里插入图片描述

问题处理

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

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

在这里插入图片描述

修改指定请求版本

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工具类,用于修改枚举值

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类

@Component
@Slf4j
public class SparkManager {
    @Resource
    private SparkClient sparkClient;

    @PostConstruct
    public 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.kler.cn/a/532836.html

相关文章:

  • 蓝桥与力扣刷题(141 环形链表)
  • Vim的基础命令
  • Linux网络 | 进入数据链路层,学习相关协议与概念
  • 记忆化搜索和动态规划 --最长回文子串为例
  • 【产品经理学习案例——AI翻译棒出海业务】
  • makailio-alias_db模块详解
  • 电子电器架构 --- 电子电气架构设计要求与发展方向
  • 【怎么用系列】短视频戒除—1—对推荐算法进行干扰
  • 2.6学习记录
  • 结合深度学习、自然语言处理(NLP)与多准则决策的三阶段技术框架,旨在实现从消费者情感分析到个性化决策
  • Autosar-以太网是怎么运行的?(原理部分)
  • Node.js 调用 DeepSeek API 完整指南
  • java使用pcap4j进行报文发送和接收
  • Go语言指针的解引用和间接引用
  • 深入理解Node.js_架构与最佳实践
  • static成员变量的本质?静态变量?静态类有什么意义?全局变量?类函数?
  • DeepSeek最新图像模型Janus-Pro论文阅读
  • 落地 dnn对象检测
  • 【BUUCTF杂项题】面具下的flag
  • MTGNN论文解读
  • Electron使用WebAssembly实现CRC-8 MAXIM校验
  • CompletableFuture
  • 2. 【.NET Aspire 从入门到实战】--理论入门与环境搭建--.NET Aspire 概览
  • Docker使用指南(一)——镜像相关操作详解(实战案例教学,适合小白跟学)
  • C 语言 | 入门 | 先导课程
  • asp.netcore 有关jwt的依赖包介绍