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
e3e37317
Commit
e3e37317
authored
Apr 29, 2025
by
zhouwei
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'dev' into 'master'
Dev See merge request
!10
parents
bfcdbc5d
8202f94f
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
272 additions
and
167 deletions
+272
-167
AIController.java
...java/com/nanyan/securitylink/controller/AIController.java
+16
-4
AIService.java
src/main/java/com/nanyan/securitylink/service/AIService.java
+4
-0
AIServiceImpl.java
...a/com/nanyan/securitylink/service/impl/AIServiceImpl.java
+252
-163
No files found.
src/main/java/com/nanyan/securitylink/controller/AIController.java
View file @
e3e37317
package
com
.
nanyan
.
securitylink
.
controller
;
package
com
.
nanyan
.
securitylink
.
controller
;
import
com.alibaba.fastjson.JSONObject
;
import
com.nanyan.securitylink.dto.AIRequestDTO
;
import
com.nanyan.securitylink.dto.AIRequestDTO
;
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.CodeVO
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.PostMapping
;
import
org.springframework.web.bind.annotation.PostMapping
;
import
org.springframework.web.bind.annotation.RequestBody
;
import
org.springframework.web.bind.annotation.RequestBody
;
...
@@ -14,20 +16,30 @@ public class AIController {
...
@@ -14,20 +16,30 @@ public class AIController {
@Autowired
@Autowired
AIService
aiService
;
AIService
aiService
;
@PostMapping
(
"/translate"
)
@PostMapping
(
"/translate"
)
public
Response
<
AIResponse
>
translate
(
@RequestBody
AIRequestDTO
AIRequestDTO
)
{
public
Response
<
AIResponse
<
String
>
>
translate
(
@RequestBody
AIRequestDTO
AIRequestDTO
)
{
return
Response
.
SUCCESS
(
aiService
.
translate
(
AIRequestDTO
));
return
Response
.
SUCCESS
(
aiService
.
translate
(
AIRequestDTO
));
}
}
@PostMapping
(
"/news/tag"
)
@PostMapping
(
"/news/tag"
)
public
Response
<
AIResponse
>
newsTag
(
@RequestBody
AIRequestDTO
AIRequestDTO
)
{
public
Response
<
AIResponse
<
CodeVO
>
>
newsTag
(
@RequestBody
AIRequestDTO
AIRequestDTO
)
{
return
Response
.
SUCCESS
(
aiService
.
newsTags
(
AIRequestDTO
));
return
Response
.
SUCCESS
(
aiService
.
newsTags
(
AIRequestDTO
));
}
}
@PostMapping
(
"/natural/disaster/tag"
)
@PostMapping
(
"/natural/disaster/tag"
)
public
Response
<
AIResponse
>
naturalDisasterTag
(
@RequestBody
AIRequestDTO
AIRequestDTO
)
{
public
Response
<
AIResponse
<
CodeVO
>
>
naturalDisasterTag
(
@RequestBody
AIRequestDTO
AIRequestDTO
)
{
return
Response
.
SUCCESS
(
aiService
.
naturalDisasterTag
(
AIRequestDTO
));
return
Response
.
SUCCESS
(
aiService
.
naturalDisasterTag
(
AIRequestDTO
));
}
}
@PostMapping
(
"/news/tag/translate"
)
@PostMapping
(
"/news/tag/translate"
)
public
Response
<
AIResponse
>
newsTagAndTranslate
(
@RequestBody
AIRequestDTO
AIRequestDTO
)
{
public
Response
<
AIResponse
<
JSONObject
>
>
newsTagAndTranslate
(
@RequestBody
AIRequestDTO
AIRequestDTO
)
{
return
Response
.
SUCCESS
(
aiService
.
newsTagAndTranslate
(
AIRequestDTO
));
return
Response
.
SUCCESS
(
aiService
.
newsTagAndTranslate
(
AIRequestDTO
));
}
}
@PostMapping
(
"/urgent/notice"
)
public
Response
<
AIResponse
<
JSONObject
>>
dealUrgentNotice
(
@RequestBody
AIRequestDTO
AIRequestDTO
)
{
return
Response
.
SUCCESS
(
aiService
.
dealUrgentNotice
(
AIRequestDTO
));
}
@PostMapping
(
"/news/country/city"
)
public
Response
<
AIResponse
<
JSONObject
>>
collectNewsCountryAndCity
(
@RequestBody
AIRequestDTO
AIRequestDTO
)
{
return
Response
.
SUCCESS
(
aiService
.
collectNewsCountryAndCity
(
AIRequestDTO
));
}
}
}
src/main/java/com/nanyan/securitylink/service/AIService.java
View file @
e3e37317
...
@@ -12,4 +12,8 @@ public interface AIService {
...
@@ -12,4 +12,8 @@ public interface AIService {
AIResponse
<
CodeVO
>
naturalDisasterTag
(
AIRequestDTO
aiRequestDTO
);
AIResponse
<
CodeVO
>
naturalDisasterTag
(
AIRequestDTO
aiRequestDTO
);
AIResponse
<
JSONObject
>
newsTagAndTranslate
(
AIRequestDTO
aiRequestDTO
);
AIResponse
<
JSONObject
>
newsTagAndTranslate
(
AIRequestDTO
aiRequestDTO
);
AIResponse
<
JSONObject
>
dealUrgentNotice
(
AIRequestDTO
aiRequestDTO
);
AIResponse
<
JSONObject
>
collectNewsCountryAndCity
(
AIRequestDTO
aiRequestDTO
);
}
}
src/main/java/com/nanyan/securitylink/service/impl/AIServiceImpl.java
View file @
e3e37317
...
@@ -169,7 +169,43 @@ public class AIServiceImpl implements AIService {
...
@@ -169,7 +169,43 @@ public class AIServiceImpl implements AIService {
public
AIResponse
<
CodeVO
>
newsTags
(
AIRequestDTO
aiRequestDTO
)
{
public
AIResponse
<
CodeVO
>
newsTags
(
AIRequestDTO
aiRequestDTO
)
{
ChatInputData
chatInputData
=
new
ChatInputData
();
ChatInputData
chatInputData
=
new
ChatInputData
();
buildNewsTag
(
chatInputData
,
aiRequestDTO
);
String
systemPrompt
=
"```xml\n"
+
"<instruction>\n"
+
"对新闻内容进行标签分类,仅当标签评分达到或超过80分时才应用该标签。可选的标签包括:枪击,抢劫,事故爆炸,恐怖袭击,纵火,大规模伤亡事件,人质事件,毒气泄漏,生物危害,交通事故,建筑物倒塌,食品安全事件,社会冲突,群体性事件,环境污染,抗议示威,集体维权,活动失控骚乱,地域冲突,性别冲突,宗教冲突,民族冲突,阶级冲突,食物中毒,地震,火山爆发,山体滑坡,泥石流,雪崩,水坝决口,水坝溃坝,台风/飓风,龙卷风,暴雨,洪水,寒潮,高温热浪,干旱,沙尘暴,冻雨,冰雹,雷暴,大风,山林火灾,冰川融化,海啸,霾,化学品泄漏,核事故,矿难,油轮泄漏,火灾,工业污染,工业事故,传染病爆发,公共卫生事件,持刀伤人,恐怖爆炸,暴力冲突,战争,游行抗议,其他。\n"
+
"\n"
+
"<instructions>\n"
+
"1. 仔细阅读新闻内容,理解其核心事件和背景。\n"
+
"2. 根据新闻内容,评估每个标签的适用性,并为每个标签打分(0-100分)。\n"
+
"3. 仅选择评分达到或超过80分的标签作为最终标签。\n"
+
"4. 如果新闻内容与任何标签的匹配度均低于80分,则输出“其他”。\n"
+
"5. 确保输出结果不包含任何XML标签,仅列出适用的标签名称,多个标签用逗号分隔。\n"
+
"6. 如果新闻内容涉及多个高评分标签,则按相关性从高到低排序。\n"
+
"\n"
+
"<examples>\n"
+
"<example>\n"
+
"输入:某市发生一起持枪抢劫银行事件,造成3人死亡,5人受伤。\n"
+
"输出:枪击, 抢劫, 大规模伤亡事件\n"
+
"</example>\n"
+
"\n"
+
"<example>\n"
+
"输入:某工厂发生化学气体泄漏,导致附近居民出现中毒症状。\n"
+
"输出:毒气泄漏\n"
+
"</example>\n"
+
"\n"
+
"<example>\n"
+
"输入:某地区因土地纠纷引发大规模抗议活动,警方与示威者发生冲突。\n"
+
"输出:社会冲突, 群体性事件\n"
+
"</example>\n"
+
"\n"
+
"<note>\n"
+
"1. 标签评分必须严格遵循80分的阈值,低于80分的标签不得使用。\n"
+
"2. 确保标签的准确性和相关性,避免过度标记或遗漏重要标签。\n"
+
"3. 对于模糊或不确定的内容,优先选择最相关的标签,避免猜测。\n"
+
"4. 输出结果必须简洁明了,仅包含适用的标签名称。\n"
+
"</note>\n"
+
"</instruction>\n"
+
"```"
;
buildChatInputData
(
chatInputData
,
aiRequestDTO
.
getInputs
().
getMsg_info
(),
systemPrompt
);
String
apiKey
=
getModelApiKey
();
String
apiKey
=
getModelApiKey
();
ChatCompletionResponse
chatCompletionResponse
=
aiRequest
(
chatInputData
,
apiKey
);
ChatCompletionResponse
chatCompletionResponse
=
aiRequest
(
chatInputData
,
apiKey
);
...
@@ -201,7 +237,43 @@ public class AIServiceImpl implements AIService {
...
@@ -201,7 +237,43 @@ public class AIServiceImpl implements AIService {
@Override
@Override
public
AIResponse
<
CodeVO
>
naturalDisasterTag
(
AIRequestDTO
aiRequestDTO
)
{
public
AIResponse
<
CodeVO
>
naturalDisasterTag
(
AIRequestDTO
aiRequestDTO
)
{
ChatInputData
chatInputData
=
new
ChatInputData
();
ChatInputData
chatInputData
=
new
ChatInputData
();
buildNaturalDisasterTag
(
chatInputData
,
aiRequestDTO
);
String
systemPrompt
=
"```xml\n"
+
"<instruction>\n"
+
"根据给定的天气预警信息,打上相应的标签。标签列表包括:大风,雷暴,霾,冻雨,地震,火山爆发,海啸,台风/飓风,龙卷风,洪水,干旱,山体滑坡,泥石流,雪崩,森林火灾,冰川融化,沙尘暴,高温热浪,寒潮,暴雨,工业事故,交通事故,火灾,爆炸,核事故,化学品泄漏,油轮泄漏,矿难,食物中毒,公共卫生事件,建筑物倒塌,恐怖袭击,水坝溃坝,游行抗议,冰雹。\n"
+
"\n"
+
"<instructions>\n"
+
"1. 仔细阅读输入的天气预警信息,理解其描述的具体事件或现象。\n"
+
"2. 根据预警信息的内容,从提供的标签列表中选择最匹配的一个或多个标签。\n"
+
"3. 确保所选标签与预警信息描述的事件或现象完全一致,避免无关标签。\n"
+
"4. 如果预警信息描述的事件或现象不在标签列表中,则忽略该信息或选择最接近的标签。\n"
+
"5. 输出时仅列出匹配的标签,不要包含任何额外的解释或XML标签。\n"
+
"6. 如果预警信息包含多个事件或现象,请为每个事件或现象分别打上对应的标签。\n"
+
"\n"
+
"<examples>\n"
+
"<example>\n"
+
"输入:今日预计有强风,风速可达10级以上,请市民注意防范。\n"
+
"输出:大风\n"
+
"</example>\n"
+
"\n"
+
"<example>\n"
+
"输入:受台风影响,沿海地区将出现暴雨和大风天气,局部地区可能有洪水。\n"
+
"输出:台风/飓风,暴雨,洪水\n"
+
"</example>\n"
+
"\n"
+
"<example>\n"
+
"输入:某化工厂发生泄漏事故,导致周边空气质量下降,建议居民关闭门窗。\n"
+
"输出:化学品泄漏,工业事故\n"
+
"</example>\n"
+
"\n"
+
"<notes>\n"
+
"1. 标签之间用逗号分隔,不要使用空格或其他符号。\n"
+
"2. 如果预警信息描述的事件或现象与多个标签相关,请列出所有相关标签。\n"
+
"3. 确保标签的准确性,避免主观判断或猜测。\n"
+
"4. 输出格式应简洁明了,仅包含标签名称。\n"
+
"</notes>\n"
+
"</instruction>\n"
+
"```"
;
buildChatInputData
(
chatInputData
,
aiRequestDTO
.
getInputs
().
getWarn_info
(),
systemPrompt
);
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
()))
{
...
@@ -232,7 +304,37 @@ public class AIServiceImpl implements AIService {
...
@@ -232,7 +304,37 @@ public class AIServiceImpl implements AIService {
@Override
@Override
public
AIResponse
<
JSONObject
>
newsTagAndTranslate
(
AIRequestDTO
aiRequestDTO
)
{
public
AIResponse
<
JSONObject
>
newsTagAndTranslate
(
AIRequestDTO
aiRequestDTO
)
{
ChatInputData
chatInputData
=
new
ChatInputData
();
ChatInputData
chatInputData
=
new
ChatInputData
();
buildNewsTagAndTranslate
(
chatInputData
,
aiRequestDTO
);
String
systemPrompt
=
"```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"
+
"```"
;
buildChatInputData
(
chatInputData
,
aiRequestDTO
.
getInputs
().
getMsg_info
(),
systemPrompt
);
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
()))
{
...
@@ -273,15 +375,146 @@ public class AIServiceImpl implements AIService {
...
@@ -273,15 +375,146 @@ public class AIServiceImpl implements AIService {
return
null
;
return
null
;
}
}
private
void
buildNewsTagAndTranslate
(
ChatInputData
chatInputData
,
AIRequestDTO
aiRequestDTO
)
{
@Override
setModel
(
chatInputData
);
public
AIResponse
<
JSONObject
>
dealUrgentNotice
(
AIRequestDTO
aiRequestDTO
)
{
chatInputData
.
setStream
(
false
);
ChatInputData
chatInputData
=
new
ChatInputData
();
List
<
Message
>
messages
=
new
ArrayList
<>();
String
systemPrompt
=
"```xml\n"
+
chatInputData
.
setMessages
(
messages
);
"<instruction>\n"
+
Message
systemRole
=
getSystemMessageForNewsTagAndTranslate
();
"根据给定的多条JSON格式的文旅部及外交部紧急通知消息,每条消息包含id、title和content字段。你需要完成以下任务:\n"
+
messages
.
add
(
systemRole
);
"\n"
+
Message
userRole
=
getUserMessageForNewsTagAndTranslate
(
aiRequestDTO
);
"1. 紧急程度判断:根据title和content的内容,按照以下标准判断紧急程度:\n"
+
messages
.
add
(
userRole
);
" - 极高:存在致命威胁且需强制撤离\n"
+
" - 高:存在重大安全威胁需规避行程\n"
+
" - 中:局部或特定风险需加强防范\n"
+
" - 低:常规安全提醒\n"
+
" - 极低:日常注意事项\n"
+
"\n"
+
"2. 区域判断:判断消息描述的是境内还是境外(相对中国而言):\n"
+
" - 境内:描述中国国内的情况\n"
+
" - 境外:描述中国以外国家或地区的情况\n"
+
"\n"
+
"3. 地理位置提取:从内容中提取描述的国家和城市:\n"
+
" - 国家:必须提取,如果是境内则为\"中国\"\n"
+
" - 城市:尽可能提取,无法提取则输出\"\",多个城市以英文,分割\n"
+
"\n"
+
"4. 输出格式要求:\n"
+
" - 保持原始id不变\n"
+
" - 新增字段:\n"
+
" * level:表示紧急程度\n"
+
" * area:表示境内/境外\n"
+
" * country:表示国家\n"
+
" * city:表示城市\n"
+
" - 输出为JSON数组格式\n"
+
" - 不要包含任何XML标签\n"
+
"\n"
+
"处理步骤:\n"
+
"1. 仔细阅读每条消息的title和content\n"
+
"2. 根据内容严重性判断紧急程度\n"
+
"3. 判断是否涉及中国境内\n"
+
"4. 提取明确提到的国家和城市\n"
+
"5. 按照要求格式组织输出\n"
+
"\n"
+
"注意事项:\n"
+
"- 城市提取要准确,不确定时留空\n"
+
"- 紧急程度判断要严格遵循标准\n"
+
"- 确保输出是标准JSON格式\n"
+
"</instruction>\n"
+
"\n"
+
"<examples>\n"
+
"示例1:\n"
+
"输入:\n"
+
"[\n"
+
" {\n"
+
" \"id\": 1,\n"
+
" \"title\": \"关于暂勿前往XX国的紧急提醒\",\n"
+
" \"content\": \"近期XX国发生武装冲突,已造成多人伤亡,建议中国公民暂勿前往。特别提醒在X市的中国公民尽快撤离。\"\n"
+
" }\n"
+
"]\n"
+
"输出:\n"
+
"[\n"
+
" {\n"
+
" \"id\": 1,\n"
+
" \"level\": \"极高\",\n"
+
" \"area\": \"境外\",\n"
+
" \"country\": \"XX国\",\n"
+
" \"city\": \"X市\"\n"
+
" }\n"
+
"]\n"
+
"</instruction>\n"
+
"```"
;
buildChatInputData
(
chatInputData
,
aiRequestDTO
.
getInputs
().
getMsg_info
(),
systemPrompt
);
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
();
aiResponse
.
setFinish_reason
(
chatCompletionResponse
.
getChoices
().
get
(
0
).
getFinish_reason
());
if
(
StringUtils
.
isNotEmpty
(
content
)){
content
=
content
.
replaceAll
(
"```json"
,
""
).
replaceAll
(
"```"
,
""
);
List
<
JSONObject
>
jsonObjects
=
JSONArray
.
parseArray
(
content
,
JSONObject
.
class
);
ResultVO
<
JSONObject
>
outputs
=
new
ResultVO
<>();
outputs
.
setResult
(
jsonObjects
);
aiResponse
.
setOutputs
(
outputs
);
}
return
aiResponse
;
}
return
null
;
}
@Override
public
AIResponse
<
JSONObject
>
collectNewsCountryAndCity
(
AIRequestDTO
aiRequestDTO
)
{
ChatInputData
chatInputData
=
new
ChatInputData
();
String
systemPrompt
=
"```xml\n"
+
"<instruction>\n"
+
"你是一个专业的地理信息分析师,请严格遵循以下步骤处理新闻文本:\n"
+
"\n"
+
"1. 仔细阅读新闻正文内容,忽略所有非事件描述的信息(如媒体机构、记者信息等)\n"
+
"2. 定位事件直接关联的具体地理位置:\n"
+
" - 优先提取明确提及的规范国家名称和城市名称\n"
+
" - 城市必须能明确归属于国家行政体系\n"
+
"3. 处理模糊表述:\n"
+
" - 对\"某国\"\"该地区\"等表述,需结合上下文地理特征、政治背景推断\n"
+
" - 非中文表述需翻译为中文规范名称\n"
+
"4. 输出规范:\n"
+
" - 仅返回标准JSON格式:{\"country\": \"国家\", \"city\": \"城市\"}\n"
+
" - 无地理信息时返回:{\"country\": \"\", \"city\": \"\"}\n"
+
" - 禁止包含任何解释性文字或XML标签\n"
+
"5. 验证逻辑:\n"
+
" - 确保城市隶属于国家(如东京属于日本)\n"
+
" - 拒绝推测性结论,必须有文本依据\n"
+
"\n"
+
"注意事项:\n"
+
"- 国家城市名称必须使用新闻原文中的语言版本\n"
+
"- 不存在的行政关系需视为无效信息(如\"巴黎属于德国\")\n"
+
"- 多地点新闻只提取核心事件发生地\n"
+
"\n"
+
"<additional_rules>\n"
+
"1. 国家城市名称标准化:\n"
+
" - 优先使用主权国家名称(如\"中国\"而非\"中国大陆\")\n"
;
buildChatInputData
(
chatInputData
,
aiRequestDTO
.
getInputs
().
getMsg_info
(),
systemPrompt
);
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
();
aiResponse
.
setFinish_reason
(
chatCompletionResponse
.
getChoices
().
get
(
0
).
getFinish_reason
());
if
(
StringUtils
.
isNotEmpty
(
content
)){
if
(
content
.
contains
(
"</think>"
)){
content
=
content
.
split
(
"</think>"
,
-
1
)[
1
];
}
content
=
content
.
replaceAll
(
"```json"
,
""
).
replaceAll
(
"```"
,
""
).
replaceAll
(
"\n"
,
""
);
JSONObject
jsonObject
=
JSONObject
.
parseObject
(
content
);
List
<
JSONObject
>
jsonObjects
=
new
ArrayList
<>();
jsonObjects
.
add
(
jsonObject
);
ResultVO
<
JSONObject
>
outputs
=
new
ResultVO
<>();
outputs
.
setResult
(
jsonObjects
);
aiResponse
.
setOutputs
(
outputs
);
}
return
aiResponse
;
}
return
null
;
}
}
private
String
getModelApiKey
()
{
private
String
getModelApiKey
()
{
...
@@ -293,17 +526,6 @@ public class AIServiceImpl implements AIService {
...
@@ -293,17 +526,6 @@ public class AIServiceImpl implements AIService {
return
apiKey
;
return
apiKey
;
}
}
private
void
buildNaturalDisasterTag
(
ChatInputData
chatInputData
,
AIRequestDTO
aiRequestDTO
)
{
setModel
(
chatInputData
);
chatInputData
.
setStream
(
false
);
List
<
Message
>
messages
=
new
ArrayList
<>();
chatInputData
.
setMessages
(
messages
);
Message
systemRole
=
getSystemMessageForNatureDisaster
();
messages
.
add
(
systemRole
);
Message
userRole
=
getUserMessageForNaturalDisasterTag
(
aiRequestDTO
);
messages
.
add
(
userRole
);
}
private
static
void
setModel
(
ChatInputData
chatInputData
)
{
private
static
void
setModel
(
ChatInputData
chatInputData
)
{
UserHeader
userHeader
=
UserThreadLocal
.
get
();
UserHeader
userHeader
=
UserThreadLocal
.
get
();
if
(
StringUtils
.
isNotEmpty
(
userHeader
.
getModel
())){
if
(
StringUtils
.
isNotEmpty
(
userHeader
.
getModel
())){
...
@@ -313,14 +535,14 @@ public class AIServiceImpl implements AIService {
...
@@ -313,14 +535,14 @@ public class AIServiceImpl implements AIService {
}
}
}
}
private
void
build
NewsTag
(
ChatInputData
chatInputData
,
AIRequestDTO
AIRequestDTO
)
{
private
void
build
ChatInputData
(
ChatInputData
chatInputData
,
String
userMsg
,
String
systemPrompt
)
{
setModel
(
chatInputData
);
setModel
(
chatInputData
);
chatInputData
.
setStream
(
false
);
chatInputData
.
setStream
(
false
);
List
<
Message
>
messages
=
new
ArrayList
<>();
List
<
Message
>
messages
=
new
ArrayList
<>();
chatInputData
.
setMessages
(
messages
);
chatInputData
.
setMessages
(
messages
);
Message
systemRole
=
getSystemMessage
ForNewsTag
(
);
Message
systemRole
=
getSystemMessage
(
systemPrompt
);
messages
.
add
(
systemRole
);
messages
.
add
(
systemRole
);
Message
userRole
=
getUserMessage
ForNewsTag
(
AIRequestDTO
);
Message
userRole
=
getUserMessage
(
userMsg
);
messages
.
add
(
userRole
);
messages
.
add
(
userRole
);
}
}
...
@@ -369,153 +591,20 @@ public class AIServiceImpl implements AIService {
...
@@ -369,153 +591,20 @@ public class AIServiceImpl implements AIService {
return
systemRole
;
return
systemRole
;
}
}
private
static
Message
getUserMessageForNewsTagAndTranslate
(
AIRequestDTO
AIRequestDTO
)
{
private
static
Message
getUserMessage
(
String
content
)
{
Message
userRole
=
new
Message
();
userRole
.
setRole
(
"user"
);
userRole
.
setContent
(
AIRequestDTO
.
getInputs
().
getMsg_info
());
return
userRole
;
}
private
static
Message
getUserMessageForNaturalDisasterTag
(
AIRequestDTO
AIRequestDTO
)
{
Message
userRole
=
new
Message
();
Message
userRole
=
new
Message
();
userRole
.
setRole
(
"user"
);
userRole
.
setRole
(
"user"
);
userRole
.
setContent
(
AIRequestDTO
.
getInputs
().
getWarn_info
());
userRole
.
setContent
(
content
);
return
userRole
;
}
private
static
Message
getUserMessageForNewsTag
(
AIRequestDTO
AIRequestDTO
)
{
Message
userRole
=
new
Message
();
userRole
.
setRole
(
"user"
);
userRole
.
setContent
(
AIRequestDTO
.
getInputs
().
getMsg_info
());
return
userRole
;
return
userRole
;
}
}
@NotNull
@NotNull
private
static
Message
getSystemMessage
ForNewsTagAndTranslate
(
)
{
private
static
Message
getSystemMessage
(
String
prompt
)
{
Message
systemRole
=
new
Message
();
Message
systemRole
=
new
Message
();
systemRole
.
setRole
(
"system"
);
systemRole
.
setRole
(
"system"
);
systemRole
.
setContent
(
"```xml\n"
+
systemRole
.
setContent
(
prompt
);
"<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
;
return
systemRole
;
}
}
@NotNull
private
static
Message
getSystemMessageForNatureDisaster
()
{
Message
systemRole
=
new
Message
();
systemRole
.
setRole
(
"system"
);
systemRole
.
setContent
(
"```xml\n"
+
"<instruction>\n"
+
"根据给定的天气预警信息,打上相应的标签。标签列表包括:大风,雷暴,霾,冻雨,地震,火山爆发,海啸,台风/飓风,龙卷风,洪水,干旱,山体滑坡,泥石流,雪崩,森林火灾,冰川融化,沙尘暴,高温热浪,寒潮,暴雨,工业事故,交通事故,火灾,爆炸,核事故,化学品泄漏,油轮泄漏,矿难,食物中毒,公共卫生事件,建筑物倒塌,恐怖袭击,水坝溃坝,游行抗议,冰雹。\n"
+
"\n"
+
"<instructions>\n"
+
"1. 仔细阅读输入的天气预警信息,理解其描述的具体事件或现象。\n"
+
"2. 根据预警信息的内容,从提供的标签列表中选择最匹配的一个或多个标签。\n"
+
"3. 确保所选标签与预警信息描述的事件或现象完全一致,避免无关标签。\n"
+
"4. 如果预警信息描述的事件或现象不在标签列表中,则忽略该信息或选择最接近的标签。\n"
+
"5. 输出时仅列出匹配的标签,不要包含任何额外的解释或XML标签。\n"
+
"6. 如果预警信息包含多个事件或现象,请为每个事件或现象分别打上对应的标签。\n"
+
"\n"
+
"<examples>\n"
+
"<example>\n"
+
"输入:今日预计有强风,风速可达10级以上,请市民注意防范。\n"
+
"输出:大风\n"
+
"</example>\n"
+
"\n"
+
"<example>\n"
+
"输入:受台风影响,沿海地区将出现暴雨和大风天气,局部地区可能有洪水。\n"
+
"输出:台风/飓风,暴雨,洪水\n"
+
"</example>\n"
+
"\n"
+
"<example>\n"
+
"输入:某化工厂发生泄漏事故,导致周边空气质量下降,建议居民关闭门窗。\n"
+
"输出:化学品泄漏,工业事故\n"
+
"</example>\n"
+
"\n"
+
"<notes>\n"
+
"1. 标签之间用逗号分隔,不要使用空格或其他符号。\n"
+
"2. 如果预警信息描述的事件或现象与多个标签相关,请列出所有相关标签。\n"
+
"3. 确保标签的准确性,避免主观判断或猜测。\n"
+
"4. 输出格式应简洁明了,仅包含标签名称。\n"
+
"</notes>\n"
+
"</instruction>\n"
+
"```"
);
return
systemRole
;
}
@NotNull
private
static
Message
getSystemMessageForNewsTag
()
{
Message
systemRole
=
new
Message
();
systemRole
.
setRole
(
"system"
);
systemRole
.
setContent
(
"```xml\n"
+
"<instruction>\n"
+
"对新闻内容进行标签分类,仅当标签评分达到或超过80分时才应用该标签。可选的标签包括:枪击,抢劫,事故爆炸,恐怖袭击,纵火,大规模伤亡事件,人质事件,毒气泄漏,生物危害,交通事故,建筑物倒塌,食品安全事件,社会冲突,群体性事件,环境污染,抗议示威,集体维权,活动失控骚乱,地域冲突,性别冲突,宗教冲突,民族冲突,阶级冲突,食物中毒,地震,火山爆发,山体滑坡,泥石流,雪崩,水坝决口,水坝溃坝,台风/飓风,龙卷风,暴雨,洪水,寒潮,高温热浪,干旱,沙尘暴,冻雨,冰雹,雷暴,大风,山林火灾,冰川融化,海啸,霾,化学品泄漏,核事故,矿难,油轮泄漏,火灾,工业污染,工业事故,传染病爆发,公共卫生事件,持刀伤人,恐怖爆炸,暴力冲突,战争,游行抗议,其他。\n"
+
"\n"
+
"<instructions>\n"
+
"1. 仔细阅读新闻内容,理解其核心事件和背景。\n"
+
"2. 根据新闻内容,评估每个标签的适用性,并为每个标签打分(0-100分)。\n"
+
"3. 仅选择评分达到或超过80分的标签作为最终标签。\n"
+
"4. 如果新闻内容与任何标签的匹配度均低于80分,则输出“其他”。\n"
+
"5. 确保输出结果不包含任何XML标签,仅列出适用的标签名称,多个标签用逗号分隔。\n"
+
"6. 如果新闻内容涉及多个高评分标签,则按相关性从高到低排序。\n"
+
"\n"
+
"<examples>\n"
+
"<example>\n"
+
"输入:某市发生一起持枪抢劫银行事件,造成3人死亡,5人受伤。\n"
+
"输出:枪击, 抢劫, 大规模伤亡事件\n"
+
"</example>\n"
+
"\n"
+
"<example>\n"
+
"输入:某工厂发生化学气体泄漏,导致附近居民出现中毒症状。\n"
+
"输出:毒气泄漏\n"
+
"</example>\n"
+
"\n"
+
"<example>\n"
+
"输入:某地区因土地纠纷引发大规模抗议活动,警方与示威者发生冲突。\n"
+
"输出:社会冲突, 群体性事件\n"
+
"</example>\n"
+
"\n"
+
"<note>\n"
+
"1. 标签评分必须严格遵循80分的阈值,低于80分的标签不得使用。\n"
+
"2. 确保标签的准确性和相关性,避免过度标记或遗漏重要标签。\n"
+
"3. 对于模糊或不确定的内容,优先选择最相关的标签,避免猜测。\n"
+
"4. 输出结果必须简洁明了,仅包含适用的标签名称。\n"
+
"</note>\n"
+
"</instruction>\n"
+
"```"
);
return
systemRole
;
}
private
HttpEntity
getHeader
(
String
token
)
{
private
HttpEntity
getHeader
(
String
token
)
{
HttpHeaders
httpHeaders
=
new
HttpHeaders
();
HttpHeaders
httpHeaders
=
new
HttpHeaders
();
httpHeaders
.
set
(
"Content-Type"
,
"application/json"
);
httpHeaders
.
set
(
"Content-Type"
,
"application/json"
);
...
...
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