sxwz2.0/src/main/java/com/kexue/skills/service/impl/SkillGenServiceImpl.java
wangzhiwei 3df611f809 feat(content): 添加从目录导入Excel功能并优化内容管理
- 新增从指定目录批量导入Excel数据到CmsContent的功能
- 添加ImportPathDto请求参数实体类
- 实现importFromPath方法支持目录遍历和文件批量导入
- 添加truncateTable方法用于清空表数据
- 优化Excel导入逻辑增加异常处理和空值检查
- 调整批量处理大小从100改为10
- 更新审核状态和发布状态的描述文案
- 修复分享次数和官方标识字段的默认值设置
- 将Servlet API从javax迁移到jakarta
- 更新README.md完善项目文档
- 优化技能解析逻辑支持多层级目录结构
- 修复AI模型生成中的标签选择和参数验证问题
2026-03-23 11:38:20 +08:00

585 lines
29 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.kexue.skills.service.impl;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.kexue.skills.common.Assert;
import com.kexue.skills.common.util.HttpUtil;
import com.kexue.skills.config.DeepSeekConfig;
import com.kexue.skills.config.GlmConfig;
import com.kexue.skills.entity.CmsContent;
import com.kexue.skills.entity.CmsTag;
import com.kexue.skills.entity.dto.CmsTagDto;
import com.kexue.skills.entity.request.SkillAnalyzeRequest;
import com.kexue.skills.entity.request.SkillGenRequest;
import com.kexue.skills.entity.request.SkillPreGenRequest;
import com.kexue.skills.entity.request.SkillRequest;
import com.kexue.skills.entity.response.SkillResponse;
import com.kexue.skills.exception.BizException;
import com.kexue.skills.mapper.CmsContentMapper;
import com.kexue.skills.service.CmsTagService;
import com.kexue.skills.service.SkillGenService;
import com.kexue.skills.utils.EscapeCharacterUtils;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.File;
import java.io.FileOutputStream;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
/**
* 技能生成服务实现
*
* @author 维哥
* @since 2026-01-28
*/
@Slf4j
@Service
public class SkillGenServiceImpl implements SkillGenService {
@Autowired
private DeepSeekConfig deepSeekConfig;
@Autowired
private GlmConfig glmConfig;
@Autowired
private CmsTagService cmsTagService;
@Resource
private CmsContentMapper cmsContentMapper;
/**
* 生成技能
*
* @param request 生成请求
* @return 生成结果
*/
@Override
public SkillResponse preGenerate(SkillPreGenRequest request) {
log.info("生成技能请求: {}", request);
String url = deepSeekConfig.getBaseUrl() + "/v1/chat/completions";
// 从数据库中读取cms_tag表的标签信息
CmsTagDto tagDto = new CmsTagDto();
tagDto.setDeleteFlag(0);
tagDto.setStatus(1);
List<CmsTag> tags = cmsTagService.getList(tagDto);
// 将标签名称拼接成逗号分隔的字符串
StringBuilder tagsList = new StringBuilder();
for (int i = 0; i < tags.size(); i++) {
CmsTag tag = tags.get(i);
tagsList.append(tag.getTagId()+"."+tag.getTagName());
if (i < tags.size() - 1) {
tagsList.append("");
}
}
SkillRequest skillRequest = new SkillRequest(true, deepSeekConfig.getChat().getModel(),
deepSeekConfig.getChat().getTemperature(), deepSeekConfig.getChat().getMaxTokens(),
request.getPrompt(), tagsList.toString());
String deepseekResponse = "";
try {
// 发送HTTP请求到deepseek API
deepseekResponse = HttpUtil.sendPostRequest(url, skillRequest, deepSeekConfig.getApiKey(), null);
log.info("Deepseek API响应: {}", deepseekResponse);
// 解析deepseek返回结果
JSONObject responseJson = JSON.parseObject(deepseekResponse);
List<JSONObject> choices = responseJson.getJSONArray("choices").toJavaList(JSONObject.class);
if (choices != null && !choices.isEmpty()) {
// 获取最新的choice这里是第一个因为只有一个
JSONObject latestChoice = choices.get(0);
JSONObject message = latestChoice.getJSONObject("message");
String content = message.getString("content");
// 解析content中的JSON
JSONObject skillJson = JSON.parseObject(content);
SkillResponse skillResponse = new SkillResponse();
skillResponse.setName(skillJson.getString("name"));
skillResponse.setDescription(skillJson.getString("description"));
skillResponse.setTags(skillJson.getJSONArray("tags").toJavaList(String.class));
log.info("解析技能响应: {}", skillResponse);
return skillResponse;
}
} catch (Exception e) {
log.error("调用Deepseek API失败: {}", e.getMessage(), e);
throw new BizException("调用Deepseek API失败:"+ e.getMessage()+" Deepseek API响应:"+ deepseekResponse);
}
return null;
}
@Override
public SkillResponse preGenerateV2(SkillPreGenRequest request) {
log.info("生成技能请求V2: {}", request);
String url = glmConfig.getBaseUrl() + "/chat/completions";
String apiKey = glmConfig.getApiKey();
String model = glmConfig.getChat().getModel();
double temperature = glmConfig.getChat().getTemperature();
int maxTokens = glmConfig.getChat().getMaxTokens();
// 从数据库中读取cms_tag表的标签信息
CmsTagDto tagDto = new CmsTagDto();
tagDto.setDeleteFlag(0);
tagDto.setStatus(1);
List<CmsTag> tags = cmsTagService.getList(tagDto);
// 将标签名称拼接成逗号分隔的字符串
StringBuilder tagsList = new StringBuilder();
for (int i = 0; i < tags.size(); i++) {
CmsTag tag = tags.get(i);
tagsList.append(tag.getTagId()+"."+tag.getTagName());
if (i < tags.size() - 1) {
tagsList.append("");
}
}
// 构建系统消息内容
String systemContent = "你是一个专业的AI技能设计助手。请根据agent skills撰写规范按照用户提出的主题描述及参考文件生成这个skill的名称、描述并从以下标签列表中选择至少3个标签\"" + tagsList.toString() + "\"tags只需要返回序号数组并简述这个skill的具体价值点。输出json格式仅输出以上所提到的名称、描述、标签、价值点节点名称分别为name、description、tags、value_point节点内容以中文形式返回。请严格按照指定的JSON格式输出仅包含要求的字段以中文形式返回。";
// 准备文件URL列表
List<String> fileUrls = new ArrayList<>();
if (request.getFileUrl() != null && !request.getFileUrl().isEmpty()) {
fileUrls.add(request.getFileUrl());
}
if (request.getFileUrls() != null && !request.getFileUrls().isEmpty()) {
fileUrls.addAll(request.getFileUrls());
}
// 创建技能请求
SkillRequest skillRequest = new SkillRequest(model, systemContent, request.getPrompt(), fileUrls, temperature, maxTokens);
String response = "";
try {
// 发送HTTP请求到API
response = HttpUtil.sendPostRequest(url, skillRequest, apiKey, null);
log.info("API响应: {}", response);
// 解析返回结果
JSONObject responseJson = JSON.parseObject(response);
List<JSONObject> choices = responseJson.getJSONArray("choices").toJavaList(JSONObject.class);
if (choices != null && !choices.isEmpty()) {
// 获取最新的choice这里是第一个因为只有一个
JSONObject latestChoice = choices.get(0);
JSONObject message = latestChoice.getJSONObject("message");
String content = message.getString("content");
// 解析content中的JSON
JSONObject skillJson = JSON.parseObject(content);
SkillResponse skillResponse = new SkillResponse();
skillResponse.setName(skillJson.getString("name"));
skillResponse.setDescription(skillJson.getString("description"));
skillResponse.setTags(skillJson.getJSONArray("tags").toJavaList(String.class));
skillResponse.setSummary(skillJson.getString("value_point"));
log.info("解析技能响应: {}", skillResponse);
return skillResponse;
}
} catch (Exception e) {
log.error("调用API失败: {}", e.getMessage(), e);
throw new BizException("调用Deepseek API失败:"+ e.getMessage()+" Deepseek API响应:"+ response);
}
return null;
}
@Override
public CmsContent generate(SkillGenRequest request) {
log.info("生成技能请求: {}", request);
// 参数验证,确保每个参数都必须传递
Assert.notEmpty(request.getName(), "技能名称不能为空");
Assert.notEmpty(request.getDescription(), "技能描述不能为空");
Assert.notEmpty(request.getTags(), "技能标签不能为空");
Assert.notEmpty(request.getRequirement(), "技能摘要不能为空");
String url = deepSeekConfig.getBaseUrl() + "/v1/chat/completions";
// 从数据库中读取cms_tag表的标签信息
CmsTagDto tagDto = new CmsTagDto();
tagDto.setDeleteFlag(0);
tagDto.setStatus(1);
List<CmsTag> tags = cmsTagService.getList(tagDto);
List<String> tags1 = request.getTags();
// 将标签名称拼接成逗号分隔的字符串
StringBuilder tagsList = new StringBuilder();
String defaultIcon = "";
for (int i = 0; i < tags.size(); i++) {
CmsTag tag = tags.get(i);
if (tags1.contains(tag.getTagId()+"")) {
if (StringUtil.isEmpty(defaultIcon)){
defaultIcon = tag.getIcon();
}
tagsList.append(tag.getTagName());
if (i < tags.size() - 1) {
tagsList.append("");
}
}
}
String systemContent = "你是一个专业的AI技能设计助手。请基于用户提供的Skill名称、描述、标签按照skills目录结构输出完整的skills内容包括skills.md本体内容、scripts目录中的脚本等并打包成一个YAML文件技能包。请严格遵循以下规范1. 包含必需的文件和目录2. 多行内容使用 | 字面块3. 内容从行首开始4. 空目录用 children: [] 表示5. 文件内容要实际有用6.输出一个完整的YAML文档概要含核心属性name、version、description、author、created、tags 等,其中 structure 为核心节点,用于描述 skill 包的文件目录结构structure 下的每个节点均含基础属性name、type、path、format、descriptioncontent 和 children 为互选属性,由 type 决定type 为 file 时,展示文件具体内容在 content 字段,必须保证content内容的缩进为2个字符type 为 directory 时,展示子目录 / 文件节点在 children [] 数组中,无需其他额外说明。";
String userContent = "请根据以下Skill信息生成skills.md文档内容Skill名称SKILL_NAME,Skill描述DESCRIPTION,Skill标签TAGS 摘要SUMMARY。";
userContent = userContent.replace("SKILL_NAME", request.getName()).replace("DESCRIPTION", request.getDescription()).replace("TAGS", tagsList.toString()).replace("SUMMARY", request.getRequirement());
SkillRequest skillRequest = new SkillRequest(true, deepSeekConfig.getChat().getModel(),systemContent,userContent,deepSeekConfig.getChat().getTemperature(), 8192,"text");
String deepseekResponse = "";
try {
// 发送HTTP请求到deepseek API
deepseekResponse = HttpUtil.sendPostRequest(url, skillRequest, deepSeekConfig.getApiKey(), null);
log.info("Deepseek API响应: {}", deepseekResponse);
JSONObject responseJson = JSON.parseObject(deepseekResponse);
String content = responseJson.getJSONArray("choices").toJavaList(JSONObject.class).get(0).getJSONObject("message").getString("content");
content = EscapeCharacterUtils.removeEscapeCharacters( content);//去除转义字符
CmsContent cmsContent = getCmsContent(request, content, StpUtil.getLoginIdAsLong(),defaultIcon);
List<CmsTag> list = tags.stream().filter(tag -> tag.getTagId() == Long.parseLong(cmsContent.getTags().split(",")[0])).toList();
if (CollectionUtil.isNotEmpty( list)){
cmsContent.setIcon(list.get(0).getIcon());
}
// 保存到数据库
cmsContentMapper.insert(cmsContent);
return cmsContent;
} catch (Exception e) {
log.error("调用Deepseek API失败: {}", e.getMessage(), e);
throw new BizException("调用Deepseek API失败:"+ e.getMessage()+" Deepseek API响应:"+ deepseekResponse);
}
}
private CmsContent getCmsContent(SkillGenRequest request, String CmsContent,Long userId,String defaultIcon){
CmsContent cmsContent = new CmsContent();
cmsContent.setTitle(request.getName());
cmsContent.setDescription(request.getDescription());
cmsContent.setContent(CmsContent);
cmsContent.setTags(request.getTags().stream().map(String::valueOf).collect(Collectors.joining(",")));
cmsContent.setIsPaid(0);//免费
cmsContent.setIsOfficial(false);
cmsContent.setPublishStatus(1);
cmsContent.setAuthorId(userId);
cmsContent.setAuthorName(null);
cmsContent.setAuditStatus(1);
cmsContent.setViewCount(0);
cmsContent.setCommentCount(0);
cmsContent.setRequiredPoints(0);
cmsContent.setSupportPointsPay(0);
cmsContent.setPrice(new BigDecimal(0));
cmsContent.setLikeCount(0);
cmsContent.setShareCount(0);
cmsContent.setCreateTime(new Date());
cmsContent.setUpdateTime(new Date());
cmsContent.setContentType(1);
cmsContent.setCreateBy(userId+"");
cmsContent.setUpdateBy(userId+"");
cmsContent.setDeleteFlag(0);
cmsContent.setIcon(defaultIcon);
cmsContent.setRequirement(request.getRequirement());
cmsContent.setIntroduce(request.getIntroduce());
return cmsContent;
}
/**
* 分析技能
*
* @param request 分析请求
* @return 分析结果
*/
@Override
public String analyzeSkill(SkillAnalyzeRequest request) {
log.info("分析技能请求: {}", request);
// 这里可以实现技能分析逻辑
// 不需要数据库操作,直接返回结果
return "技能分析成功: " + request.getSkillId();
}
@Override
public String genIntroduce(String content) {
log.info("生成技能介绍请求: {}", content);
String url = deepSeekConfig.getBaseUrl() + "/v1/chat/completions";
String systemContent = "你是一个专业的AI技能设计助手。我会给你提供一个完整的skill的内容请你帮我总结出skill的作用能够解决的问题输出一段描述文本";
SkillRequest skillRequest = new SkillRequest(true, deepSeekConfig.getChat().getModel(), systemContent, content, 0.3, 500, "text");
String deepseekResponse = "";
try {
// 发送HTTP请求到deepseek API
deepseekResponse = HttpUtil.sendPostRequest(url, skillRequest, deepSeekConfig.getApiKey(), null);
log.info("Deepseek API响应: {}", deepseekResponse);
// 解析返回结果
JSONObject responseJson = JSON.parseObject(deepseekResponse);
List<JSONObject> choices = responseJson.getJSONArray("choices").toJavaList(JSONObject.class);
if (choices != null && !choices.isEmpty()) {
JSONObject latestChoice = choices.get(0);
JSONObject message = latestChoice.getJSONObject("message");
return EscapeCharacterUtils.removeEscapeCharacters( message.getString("content"));//去除转义字符
}
} catch (Exception e) {
log.error("调用Deepseek API失败: {}", e.getMessage(), e);
throw new BizException("调用Deepseek API失败:"+ e.getMessage()+" Deepseek API响应:"+ deepseekResponse);
}
return null;
}
@Override
public CmsContent uploadSkill(String skillUrl) {
log.info("上传技能压缩包请求: {}", skillUrl);
String url = deepSeekConfig.getBaseUrl() + "/v1/chat/completions";
// 从数据库中读取cms_tag表的标签信息
CmsTagDto tagDto = new CmsTagDto();
tagDto.setDeleteFlag(0);
tagDto.setStatus(1);
List<CmsTag> tags = cmsTagService.getList(tagDto);
// 将标签名称拼接成逗号分隔的字符串
StringBuilder tagsList = new StringBuilder();
for (int i = 0; i < tags.size(); i++) {
CmsTag tag = tags.get(i);
tagsList.append(tag.getTagId()+"."+tag.getTagName());
if (i < tags.size() - 1) {
tagsList.append("");
}
}
// 构建系统消息内容
String systemContent = """
你是一位专业的AI技能包解析助手需完成以下任务
1. 我会提供一个技能包压缩包格式包含zip/rar的URL你需解析该压缩包根目录下的SKILL.md文件; 或者提供一个在线的SKILL.md文件的url
2. 基于SKILL.md内容提炼出
- skill的核心标题name
- skill的核心描述description
- 详细功能介绍introduce
- 从指定标签列表中选取至少3个适配标签tagList标签范围TAG_LIST
- 选择标签的时候只需要输出对应的标签编号
3. 生成content字段基于技能包的名称、描述、标签按照skills目录结构输出完整的技能包YAML内容包含skills.md本体、scripts目录脚本等需遵循以下严格规范
- 包含技能包必需的文件和目录;
- 多行内容使用「|」字面块表示;
- 所有内容从行首开始,无前置空格;
- 空目录标注为「children: []」;
- 文件内容需具备实际使用价值;
- YAML文档需完整核心概要包含name、version、description、author、created、tags等属性
- 核心节点为structure用于描述技能包文件目录结构structure下每个节点需包含基础属性name、type、path、format、descriptioncontent和children为互选属性type为file时content字段填写文件内容type为directory时children数组填写子目录/文件节点)。
请将最终结果以JSON格式输出JSON结构必须包含name(技能名称),description技能描述、introduce功能介绍、tagList标签列表、content完整YAML格式技能包内容无需额外说明仅输出符合要求的JSON内容。
""";
systemContent = systemContent.replace("TAG_LIST", tagsList.toString());
// 构建用户消息内容
String userContent = skillUrl;
// 创建技能请求
SkillRequest skillRequest = new SkillRequest(true, deepSeekConfig.getChat().getModel(), systemContent, userContent, 0.5, 8192, "json_object");
String deepseekResponse = "";
try {
// 发送HTTP请求到DeepSeek API
deepseekResponse = HttpUtil.sendPostRequest(url, skillRequest, deepSeekConfig.getApiKey(), null);
log.info("Deepseek API响应: {}", deepseekResponse);
// 解析返回结果
JSONObject responseJson = JSON.parseObject(deepseekResponse);
List<JSONObject> choices = responseJson.getJSONArray("choices").toJavaList(JSONObject.class);
if (choices != null && !choices.isEmpty()) {
// 获取最新的choice
JSONObject latestChoice = choices.get(0);
JSONObject message = latestChoice.getJSONObject("message");
String content = message.getString("content");
// 解析content中的JSON
JSONObject skillJson = JSON.parseObject(content);
// 构建技能生成请求
SkillGenRequest request = new SkillGenRequest();
request.setName(skillJson.getString("name"));
request.setDescription(skillJson.getString("description"));
request.setIntroduce(skillJson.getString("introduce"));
request.setTags(skillJson.getJSONArray("tagList").toJavaList(String.class));
// 生成CmsContent对象
CmsContent cmsContent = getCmsContent(request, skillJson.getString("content"), StpUtil.getLoginIdAsLong(), "");
List<CmsTag> list = tags.stream().filter(tag -> tag.getTagId() == Long.parseLong(cmsContent.getTags().split(",")[0])).toList();
if (CollectionUtil.isNotEmpty( list)){
cmsContent.setIcon(list.get(0).getIcon());
}
// 保存到数据库
// cmsContentMapper.insert(cmsContent);
return cmsContent;
}
} catch (Exception e) {
log.error("调用Deepseek API失败: {}", e.getMessage(), e);
throw new BizException("调用Deepseek API失败:"+ e.getMessage()+" Deepseek API响应:"+ deepseekResponse);
}
return null;
}
@Override
public CmsContent uploadSkillV2(byte[] fileBytes, String fileName) {
log.info("上传本地技能压缩包请求: {}", fileName);
try {
// 创建临时文件
String fileExtension = "";
if (fileName.contains(".")) {
int dotIndex = fileName.lastIndexOf(".");
if (dotIndex != -1) {
fileExtension = fileName.substring(dotIndex);
}
}
File tempFile = File.createTempFile("skill", fileExtension);
try (FileOutputStream fos = new FileOutputStream(tempFile)) {
fos.write(fileBytes);
}
// 生成默认参数
String author = StpUtil.getLoginIdAsString();
// 从文件名中提取技能名称
String defaultSkillName = fileName;
if (fileName.contains(".")) {
int dotIndex = fileName.lastIndexOf(".");
if (dotIndex != -1) {
defaultSkillName = fileName.substring(0, dotIndex);
}
}
// 1. 提取压缩包中的skillMdText
Map<String, Object> skillInfo = com.kexue.skills.common.util.SkillZipParser.extractSkillMdText(tempFile.getAbsolutePath(), defaultSkillName);
String skillMdText = (String) skillInfo.get("skillMdText");
// 从数据库中读取cms_tag表的标签信息
CmsTagDto tagDto = new CmsTagDto();
tagDto.setDeleteFlag(0);
tagDto.setStatus(1);
List<CmsTag> tags = cmsTagService.getList(tagDto);
// 2. 解析skillMdText获取SkillGenRequest
SkillGenRequest request = null;
if (skillMdText != null && !skillMdText.isEmpty()) {
request = parseSkillMdText(skillMdText, tags);
} else {
// 如果没有找到md文件使用默认值
request = new SkillGenRequest();
request.setName(defaultSkillName);
request.setDescription("未知");
request.setIntroduce("未知");
request.setTags(Arrays.asList("1001", "1000"));
}
// 3. 使用SkillGenRequest中的信息生成yaml
String yamlContent = com.kexue.skills.common.util.SkillZipParser.generateYamlFromSkillInfo(
tempFile.getAbsolutePath(),
author,
request.getName(),
request.getDescription(),
request.getTags()
);
log.info("解析出skill 压缩包内容:{}", yamlContent);
// 4. 生成CmsContent对象
CmsContent cmsContent = getCmsContent(request, yamlContent, StpUtil.getLoginIdAsLong(), "");
if (Objects.nonNull(cmsContent.getTags())) {
String s = cmsContent.getTags().split(",")[0];
long l = 1000;// 默认值
try {
l = Long.parseLong(s);
} catch (NumberFormatException e) {
// 异常是因为大模型返回的tag带中文了忽略
}
long finalL = l;
List<CmsTag> list = tags.stream().filter(tag -> tag.getTagId() == finalL).toList();
if (CollectionUtil.isNotEmpty(list)){
cmsContent.setIcon(list.get(0).getIcon());
}
}
// 删除临时文件
tempFile.delete();
return cmsContent;
} catch (Exception e) {
log.error("上传本地技能压缩包失败: {}", e.getMessage(), e);
throw new BizException("上传本地技能压缩包失败:" + e.getMessage());
}
}
public SkillGenRequest parseSkillMdText(String skillMdText,List<CmsTag> tags) {
String url = deepSeekConfig.getBaseUrl() + "/v1/chat/completions";
// 将标签名称拼接成逗号分隔的字符串
StringBuilder tagsList = new StringBuilder();
for (int i = 0; i < tags.size(); i++) {
CmsTag tag = tags.get(i);
tagsList.append(tag.getTagId()+"."+tag.getTagName());
if (i < tags.size() - 1) {
tagsList.append("");
}
}
// 构建系统消息内容
String systemContent = """
你是一位专业的AI技能包解析助手需完成以下任务
1. 我会提供一个技能包压缩包SKILL.md文件的具体内容
2. 基于SKILL.md内容提炼出
- skill的核心标题name
- skill的核心描述description
- 详细功能介绍introduce
- 从指定标签列表中选取至少3个适配标签tagList标签范围TAG_LIST
- 选择标签的时候只需要输出对应的标签编号,特别注意:只需要标签编号
请将最终结果以JSON格式输出JSON结构必须包含name(技能名称),description技能描述、introduce功能介绍、tagList标签列表无需额外说明仅输出符合要求的JSON内容。
""";
systemContent = systemContent.replace("TAG_LIST", tagsList.toString());
// 创建技能请求
SkillRequest skillRequest = new SkillRequest(true, deepSeekConfig.getChat().getModel(), systemContent, skillMdText, 0.5, 8192, "json_object");
String deepseekResponse = "";
try {
// 发送HTTP请求到DeepSeek API
deepseekResponse = HttpUtil.sendPostRequest(url, skillRequest, deepSeekConfig.getApiKey(), null);
log.info("Deepseek API响应: {}", deepseekResponse);
// 解析返回结果
JSONObject responseJson = JSON.parseObject(deepseekResponse);
List<JSONObject> choices = responseJson.getJSONArray("choices").toJavaList(JSONObject.class);
if (choices != null && !choices.isEmpty()) {
// 获取最新的choice
JSONObject latestChoice = choices.get(0);
JSONObject message = latestChoice.getJSONObject("message");
String content = message.getString("content");
// 解析content中的JSON
JSONObject skillJson = JSON.parseObject(content);
// 构建技能生成请求
SkillGenRequest request = new SkillGenRequest();
request.setName(skillJson.getString("name"));
request.setDescription(skillJson.getString("description"));
request.setIntroduce(skillJson.getString("introduce"));
// 处理tagList可能不存在的情况
if (skillJson.containsKey("tagList")) {
request.setTags(skillJson.getJSONArray("tagList").toJavaList(String.class));
} else {
request.setTags(Arrays.asList("1001", "1002"));
}
return request;
}
} catch (Exception e) {
log.error("调用Deepseek API失败: {}", e.getMessage(), e);
throw new BizException("调用Deepseek API失败:"+ e.getMessage()+" Deepseek API响应:"+ deepseekResponse);
}
return null;
}
}