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

问题重现

  • 依赖

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

    yaml 复制代码
    # 讯飞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;
    
        @Bean
        public 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 {
        @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 对话,但遗憾的是出了意外

  • 测试代码
java 复制代码
@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数,刚好可以拿来做验证

修改指定请求版本

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 {
    @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 无误

相关推荐
IT毕设梦工厂3 小时前
计算机毕业设计选题推荐:基于大数据的城市噪音数据分析与可视化|毕业设计选题|计算机毕设|选题推荐|毕设指导|项目定制|源码|高质量项目
大数据·信息可视化·数据分析·spark·毕业设计·课程设计·数据可视化
素男3 小时前
叫沉默的,和叫留白的——一次改名记
人工智能·agent·self-becoming·ai长期记忆·ai自我介绍
ym hyd 1113 小时前
慢性病精细化管理平台源码 Java+SpringBoot+Vue3 前后分离
java·vue.js·spring boot·毕设
IT古董3 小时前
《FDE前沿部署工程师实战教程》23 - Enterprise AI Event Bus:事件驱动、消息队列与AI工作流自动触发
大数据·数据库·人工智能
枫叶丹43 小时前
AI 的记忆不是数据库:长期个性化如何避免过期与污染
人工智能·chatgpt·开源·agent·codex
程序猿乐锅3 小时前
【黑马点评 | 第七篇】Redis 分布式锁的两种实现
java·数据库·redis·分布式·spring·缓存
阿尔法工场研究院3 小时前
宇树们不想重蹈新造车的覆辙
大数据·人工智能·科技·机器人
SL_staff3 小时前
JVS私有化交付为何敢承诺100%源码开放与无兜底风险?
java·低代码·全栈
程序员JerrySUN3 小时前
Jetson边缘嵌入式实战课程第四讲:用 Yocto 定制 Jetson 系统,从开发走向产品化
arm开发·人工智能·安全·计算机视觉·目标跟踪
这张生成的图像能检测吗3 小时前
(论文速读)DI-CDM:微调条件扩散模型在结构健康监测中的损伤成像
人工智能·lora·扩散模型·高分辨率成像·结构健康监测