Commit 5e985d57 authored by zhouwei's avatar zhouwei

Merge branch 'dev' into 'master'

新增新闻翻译和标签统一接口

See merge request !8
parents f8e6cacc 66bdacbf
...@@ -25,4 +25,9 @@ public class AIController { ...@@ -25,4 +25,9 @@ public class AIController {
public Response<AIResponse> naturalDisasterTag(@RequestBody AIRequestDTO AIRequestDTO) { public Response<AIResponse> naturalDisasterTag(@RequestBody AIRequestDTO AIRequestDTO) {
return Response.SUCCESS(aiService.naturalDisasterTag(AIRequestDTO)); return Response.SUCCESS(aiService.naturalDisasterTag(AIRequestDTO));
} }
@PostMapping("/news/tag/translate")
public Response<AIResponse> newsTagAndTranslate(@RequestBody AIRequestDTO AIRequestDTO) {
return Response.SUCCESS(aiService.newsTagAndTranslate(AIRequestDTO));
}
} }
...@@ -7,5 +7,5 @@ public class Choice { ...@@ -7,5 +7,5 @@ public class Choice {
private int index; private int index;
private Message message; private Message message;
private Object logprobs; // logprobs is null in the JSON private Object logprobs; // logprobs is null in the JSON
private String finishReason; private String finish_reason;
} }
package com.nanyan.securitylink.service; package com.nanyan.securitylink.service;
import com.alibaba.fastjson.JSONObject;
import com.nanyan.securitylink.dto.AIRequestDTO; import com.nanyan.securitylink.dto.AIRequestDTO;
import com.nanyan.securitylink.vo.AIResponse; import com.nanyan.securitylink.vo.AIResponse;
import com.nanyan.securitylink.vo.CodeVO;
public interface AIService { public interface AIService {
AIResponse translate(AIRequestDTO AIRequestDTO); AIResponse<String> translate(AIRequestDTO AIRequestDTO);
AIResponse newsTags(AIRequestDTO AIRequestDTO); AIResponse<CodeVO> newsTags(AIRequestDTO AIRequestDTO);
AIResponse naturalDisasterTag(AIRequestDTO aiRequestDTO); AIResponse<CodeVO> naturalDisasterTag(AIRequestDTO aiRequestDTO);
AIResponse<JSONObject> newsTagAndTranslate(AIRequestDTO aiRequestDTO);
} }
package com.nanyan.securitylink.service.impl; package com.nanyan.securitylink.service.impl;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
...@@ -10,6 +11,7 @@ import com.nanyan.securitylink.entity.*; ...@@ -10,6 +11,7 @@ import com.nanyan.securitylink.entity.*;
import com.nanyan.securitylink.execption.BaseException; import com.nanyan.securitylink.execption.BaseException;
import com.nanyan.securitylink.service.AIService; import com.nanyan.securitylink.service.AIService;
import com.nanyan.securitylink.vo.AIResponse; import com.nanyan.securitylink.vo.AIResponse;
import com.nanyan.securitylink.vo.AnswerVO;
import com.nanyan.securitylink.vo.CodeVO; import com.nanyan.securitylink.vo.CodeVO;
import com.nanyan.securitylink.vo.ResultVO; import com.nanyan.securitylink.vo.ResultVO;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
...@@ -40,6 +42,7 @@ public class AIServiceImpl implements AIService { ...@@ -40,6 +42,7 @@ public class AIServiceImpl implements AIService {
private static final Map<String, String> NATURAL_DISASTER_LABEL_MAP = new HashMap<>(); private static final Map<String, String> NATURAL_DISASTER_LABEL_MAP = new HashMap<>();
static { static {
NEWS_LABEL_MAP.put("其他","TagOther");
NEWS_LABEL_MAP.put("枪击","TagShooting"); NEWS_LABEL_MAP.put("枪击","TagShooting");
NEWS_LABEL_MAP.put("抢劫","TagRobbery"); NEWS_LABEL_MAP.put("抢劫","TagRobbery");
NEWS_LABEL_MAP.put("事故爆炸","TagExplosion"); NEWS_LABEL_MAP.put("事故爆炸","TagExplosion");
...@@ -145,7 +148,7 @@ public class AIServiceImpl implements AIService { ...@@ -145,7 +148,7 @@ public class AIServiceImpl implements AIService {
private final static String DEEP_SEEK_URL = "https://ark.cn-beijing.volces.com/api/v3/chat/completions"; private final static String DEEP_SEEK_URL = "https://ark.cn-beijing.volces.com/api/v3/chat/completions";
@Override @Override
public AIResponse translate(AIRequestDTO AIRequestDTO) { public AIResponse<String> translate(AIRequestDTO AIRequestDTO) {
ChatInputData chatInputData = new ChatInputData(); ChatInputData chatInputData = new ChatInputData();
buildTranslate(chatInputData, AIRequestDTO); buildTranslate(chatInputData, AIRequestDTO);
...@@ -153,14 +156,17 @@ public class AIServiceImpl implements AIService { ...@@ -153,14 +156,17 @@ public class AIServiceImpl implements AIService {
ChatCompletionResponse chatCompletionResponse = aiRequest(chatInputData, apiKey); ChatCompletionResponse chatCompletionResponse = aiRequest(chatInputData, apiKey);
if (CollectionUtils.isNotEmpty(chatCompletionResponse.getChoices())) { if (CollectionUtils.isNotEmpty(chatCompletionResponse.getChoices())) {
AIResponse aiResponse = new AIResponse(); AIResponse<String> aiResponse = new AIResponse<>();
aiResponse.setAnswer(chatCompletionResponse.getChoices().get(0).getMessage().getContent()); aiResponse.setFinish_reason(chatCompletionResponse.getChoices().get(0).getFinish_reason());
String content = chatCompletionResponse.getChoices().get(0).getMessage().getContent();
content = content.replaceAll("```json","").replaceAll("```", "");
aiResponse.setAnswer(content);
return aiResponse; return aiResponse;
} }
return null; return null;
} }
public AIResponse newsTags(AIRequestDTO aiRequestDTO) { public AIResponse<CodeVO> newsTags(AIRequestDTO aiRequestDTO) {
ChatInputData chatInputData = new ChatInputData(); ChatInputData chatInputData = new ChatInputData();
buildNewsTag(chatInputData, aiRequestDTO); buildNewsTag(chatInputData, aiRequestDTO);
...@@ -168,12 +174,14 @@ public class AIServiceImpl implements AIService { ...@@ -168,12 +174,14 @@ public class AIServiceImpl implements AIService {
ChatCompletionResponse chatCompletionResponse = aiRequest(chatInputData, apiKey); ChatCompletionResponse chatCompletionResponse = aiRequest(chatInputData, apiKey);
if (CollectionUtils.isNotEmpty(chatCompletionResponse.getChoices())) { if (CollectionUtils.isNotEmpty(chatCompletionResponse.getChoices())) {
AIResponse aiResponse = new AIResponse(); AIResponse<CodeVO> aiResponse = new AIResponse<>();
String content = chatCompletionResponse.getChoices().get(0).getMessage().getContent(); String content = chatCompletionResponse.getChoices().get(0).getMessage().getContent();
aiResponse.setFinish_reason(chatCompletionResponse.getChoices().get(0).getFinish_reason());
if(StringUtils.isNotEmpty(content)){ if(StringUtils.isNotEmpty(content)){
content = content.replaceAll("```json","").replaceAll("```", "");
String[] split = content.split(",", -1); String[] split = content.split(",", -1);
List<CodeVO> result = new ArrayList<>(); List<CodeVO> result = new ArrayList<>();
ResultVO outputs = new ResultVO(); ResultVO<CodeVO> outputs = new ResultVO<>();
outputs.setResult(result); outputs.setResult(result);
aiResponse.setOutputs(outputs); aiResponse.setOutputs(outputs);
for (String s : split) { for (String s : split) {
...@@ -191,18 +199,20 @@ public class AIServiceImpl implements AIService { ...@@ -191,18 +199,20 @@ public class AIServiceImpl implements AIService {
} }
@Override @Override
public AIResponse naturalDisasterTag(AIRequestDTO aiRequestDTO) { public AIResponse<CodeVO> naturalDisasterTag(AIRequestDTO aiRequestDTO) {
ChatInputData chatInputData = new ChatInputData(); ChatInputData chatInputData = new ChatInputData();
buildNaturalDisasterTag(chatInputData, aiRequestDTO); buildNaturalDisasterTag(chatInputData, aiRequestDTO);
String apiKey = getModelApiKey(); String apiKey = getModelApiKey();
ChatCompletionResponse chatCompletionResponse = aiRequest(chatInputData, apiKey); ChatCompletionResponse chatCompletionResponse = aiRequest(chatInputData, apiKey);
if (CollectionUtils.isNotEmpty(chatCompletionResponse.getChoices())) { if (CollectionUtils.isNotEmpty(chatCompletionResponse.getChoices())) {
AIResponse aiResponse = new AIResponse(); AIResponse<CodeVO> aiResponse = new AIResponse<>();
String content = chatCompletionResponse.getChoices().get(0).getMessage().getContent(); String content = chatCompletionResponse.getChoices().get(0).getMessage().getContent();
aiResponse.setFinish_reason(chatCompletionResponse.getChoices().get(0).getFinish_reason());
if(StringUtils.isNotEmpty(content)){ if(StringUtils.isNotEmpty(content)){
content = content.replaceAll("```json","").replaceAll("```", "");
String[] split = content.split(",", -1); String[] split = content.split(",", -1);
List<CodeVO> result = new ArrayList<>(); List<CodeVO> result = new ArrayList<>();
ResultVO outputs = new ResultVO(); ResultVO<CodeVO> outputs = new ResultVO<>();
outputs.setResult(result); outputs.setResult(result);
aiResponse.setOutputs(outputs); aiResponse.setOutputs(outputs);
for (String s : split) { for (String s : split) {
...@@ -219,6 +229,61 @@ public class AIServiceImpl implements AIService { ...@@ -219,6 +229,61 @@ public class AIServiceImpl implements AIService {
return null; return null;
} }
@Override
public AIResponse<JSONObject> newsTagAndTranslate(AIRequestDTO aiRequestDTO) {
ChatInputData chatInputData = new ChatInputData();
buildNewsTagAndTranslate(chatInputData, aiRequestDTO);
String apiKey = getModelApiKey();
ChatCompletionResponse chatCompletionResponse = aiRequest(chatInputData, apiKey);
if (CollectionUtils.isNotEmpty(chatCompletionResponse.getChoices())) {
AIResponse<JSONObject> aiResponse = new AIResponse<>();
String content = chatCompletionResponse.getChoices().get(0).getMessage().getContent();
if(StringUtils.isNotEmpty(content)){
content = content.replaceAll("```json","").replaceAll("```", "");
JSONArray objects = JSONArray.parseArray(content);
ArrayList<JSONObject> jsonObjects = new ArrayList<>();
for (int i = 0; i < objects.size(); i++) {
JSONObject jsonObject = objects.getJSONObject(i);
jsonObjects.add(jsonObject);
if(jsonObject.containsKey("news_tag")){
List<CodeVO> codes = new ArrayList<>();
JSONArray newsTags = jsonObject.getJSONArray("news_tag");
for (int j = 0; j < newsTags.size(); j++) {
String newsTag = newsTags.getString(j);
if(NEWS_LABEL_MAP.containsKey(newsTag)){
String c = NEWS_LABEL_MAP.get(newsTag);
CodeVO code = new CodeVO();
code.setCode(c);
code.setName(newsTag);
codes.add(code);
}
}
jsonObject.put("news_tag", JSONObject.toJSON(codes));
}
}
ResultVO<JSONObject> outputs = new ResultVO<>();
AnswerVO<JSONObject> answer = new AnswerVO<>();
answer.setResult(jsonObjects);
answer.setFinish_reason(chatCompletionResponse.getChoices().get(0).getFinish_reason());
outputs.setAnswer(answer);
aiResponse.setOutputs(outputs);
}
return aiResponse;
}
return null;
}
private void buildNewsTagAndTranslate(ChatInputData chatInputData, AIRequestDTO aiRequestDTO) {
setModel(chatInputData);
chatInputData.setStream(false);
List<Message> messages = new ArrayList<>();
chatInputData.setMessages(messages);
Message systemRole = getSystemMessageForNewsTagAndTranslate();
messages.add(systemRole);
Message userRole = getUserMessageForNewsTagAndTranslate(aiRequestDTO);
messages.add(userRole);
}
private String getModelApiKey() { private String getModelApiKey() {
UserHeader userHeader = UserThreadLocal.get(); UserHeader userHeader = UserThreadLocal.get();
String apiKey = appConfig.getApiTranslateKey(); String apiKey = appConfig.getApiTranslateKey();
...@@ -304,6 +369,13 @@ public class AIServiceImpl implements AIService { ...@@ -304,6 +369,13 @@ public class AIServiceImpl implements AIService {
return systemRole; return systemRole;
} }
private static Message getUserMessageForNewsTagAndTranslate(AIRequestDTO AIRequestDTO) {
Message userRole = new Message();
userRole.setRole("user");
userRole.setContent(AIRequestDTO.getInputs().getMsg_info());
return userRole;
}
private static Message getUserMessageForNaturalDisasterTag(AIRequestDTO AIRequestDTO) { private static Message getUserMessageForNaturalDisasterTag(AIRequestDTO AIRequestDTO) {
Message userRole = new Message(); Message userRole = new Message();
userRole.setRole("user"); userRole.setRole("user");
...@@ -318,6 +390,44 @@ public class AIServiceImpl implements AIService { ...@@ -318,6 +390,44 @@ public class AIServiceImpl implements AIService {
return userRole; return userRole;
} }
@NotNull
private static Message getSystemMessageForNewsTagAndTranslate() {
Message systemRole = new Message();
systemRole.setRole("system");
systemRole.setContent("```xml\n" +
"<instruction>\n" +
"同时对多条新闻内容进行打上新闻标签分类和翻译成指定语言,仅当新闻标签评分达到或超过80分时才应用新闻标签,翻译必须进行,每条数据都唯一标识ID。输入为JSON数组,输出也为JSON数组。具体要求如下:\n" +
"\n" +
"1. **输入格式**: \n" +
" - 输入是一个JSON数组,每个对象包含以下字段: \n" +
" - `content`:新闻内容文本 \n" +
" - `id`:唯一标识ID \n" +
" - `language`:目标翻译语言 \n" +
"\n" +
"2. **输出格式**: \n" +
" - 输出是一个JSON数组,每个对象包含以下字段:\n" +
" - `content`:翻译后的新闻内容 \n" +
" - `id`:与输入相同的唯一标识ID \n" +
" - `language`:目标翻译语言 \n" +
" - `news_tag`:新闻标签列表(仅当评分≥80分时应用) \n" +
"\n" +
"3. **标签分类规则**: \n" +
" - 新闻标签的评分范围为0-100分,仅当评分≥80分时才将标签添加到输出中。 \n" +
" - 翻译必须执行,无论标签评分如何。 \n" +
"\n" +
"4. **标签列表**: \n" +
" - 人为灾害标签包括:枪击,抢劫,事故爆炸,恐怖袭击,纵火,大规模伤亡事件,人质事件,毒气泄漏,生物危害,交通事故,建筑物倒塌,食品安全事件,社会冲突,群体性事件,环境污染,抗议示威,集体维权,活动失控骚乱,地域冲突,性别冲突,宗教冲突,民族冲突,阶级冲突,食物中毒,地震,火山爆发,山体滑坡,泥石流,雪崩,水坝决口,水坝溃坝,台风/飓风,龙卷风,暴雨,洪水,寒潮,高温热浪,干旱,沙尘暴,冻雨,冰雹,雷暴,大风,山林火灾,冰川融化,海啸,霾,化学品泄漏,核事故,矿难,油轮泄漏,火灾,工业污染,工业事故,传染病爆发,公共卫生事件,持刀伤人,恐怖爆炸,暴力冲突,战争,游行抗议,其他。\n" +
"\n" +
"5. **注意事项**: \n" +
" - 输出中不得包含任何XML标签。 \n" +
" - 确保每条数据的唯一标识ID与输入一致。 \n" +
" - 如果新闻内容无法分类或评分低于80分,则输出“其他”。\n" +
"</instruction>\n" +
"```"
);
return systemRole;
}
@NotNull @NotNull
private static Message getSystemMessageForNatureDisaster() { private static Message getSystemMessageForNatureDisaster() {
Message systemRole = new Message(); Message systemRole = new Message();
......
...@@ -3,13 +3,14 @@ package com.nanyan.securitylink.vo; ...@@ -3,13 +3,14 @@ package com.nanyan.securitylink.vo;
import lombok.Data; import lombok.Data;
@Data @Data
public class AIResponse { public class AIResponse<T> {
private String event; private String event;
private String task_id; private String task_id;
private String id; private String id;
private String message_id; private String message_id;
private String mode; private String mode;
private String answer; private String answer;
private ResultVO outputs; private ResultVO<T> outputs;
private long created_at; private long created_at;
private String finish_reason;
} }
package com.nanyan.securitylink.vo;
import lombok.Data;
import java.util.List;
@Data
public class AnswerVO<T> {
List<T> result;
String finish_reason;
}
...@@ -5,6 +5,7 @@ import lombok.Data; ...@@ -5,6 +5,7 @@ import lombok.Data;
import java.util.List; import java.util.List;
@Data @Data
public class ResultVO { public class ResultVO<T> {
List<CodeVO> result; List<T> result;
AnswerVO<T> answer;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment