Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
S
sl-ai
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
zhouwei
sl-ai
Commits
5e985d57
Commit
5e985d57
authored
Apr 21, 2025
by
zhouwei
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'dev' into 'master'
新增新闻翻译和标签统一接口 See merge request
!8
parents
f8e6cacc
66bdacbf
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
149 additions
and
17 deletions
+149
-17
AIController.java
...java/com/nanyan/securitylink/controller/AIController.java
+5
-0
Choice.java
src/main/java/com/nanyan/securitylink/entity/Choice.java
+1
-1
AIService.java
src/main/java/com/nanyan/securitylink/service/AIService.java
+7
-3
AIServiceImpl.java
...a/com/nanyan/securitylink/service/impl/AIServiceImpl.java
+119
-9
AIResponse.java
src/main/java/com/nanyan/securitylink/vo/AIResponse.java
+3
-2
AnswerVO.java
src/main/java/com/nanyan/securitylink/vo/AnswerVO.java
+11
-0
ResultVO.java
src/main/java/com/nanyan/securitylink/vo/ResultVO.java
+3
-2
No files found.
src/main/java/com/nanyan/securitylink/controller/AIController.java
View file @
5e985d57
...
@@ -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
));
}
}
}
src/main/java/com/nanyan/securitylink/entity/Choice.java
View file @
5e985d57
...
@@ -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
finish
R
eason
;
private
String
finish
_r
eason
;
}
}
src/main/java/com/nanyan/securitylink/service/AIService.java
View file @
5e985d57
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
);
}
}
src/main/java/com/nanyan/securitylink/service/impl/AIServiceImpl.java
View file @
5e985d57
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
();
...
...
src/main/java/com/nanyan/securitylink/vo/AIResponse.java
View file @
5e985d57
...
@@ -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
;
}
}
src/main/java/com/nanyan/securitylink/vo/AnswerVO.java
0 → 100644
View file @
5e985d57
package
com
.
nanyan
.
securitylink
.
vo
;
import
lombok.Data
;
import
java.util.List
;
@Data
public
class
AnswerVO
<
T
>
{
List
<
T
>
result
;
String
finish_reason
;
}
src/main/java/com/nanyan/securitylink/vo/ResultVO.java
View file @
5e985d57
...
@@ -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
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment