Repository navigation
Expand file tree
/
Copy pathLLM_tool.py
More file actions
354 lines (334 loc) · 15.8 KB
/
Copy pathLLM_tool.py
File metadata and controls
354 lines (334 loc) · 15.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
from __future__ import annotations
from typing import Any
from openai import OpenAI
from prompts import *
import json
import re
from typing import List, Dict, Any
GRAPH_FIELD_SEP = "<SEP>"
class LLMHandler:
def __init__(self):
self.client = OpenAI(api_key="sk-4c48568e7bcb45b386cda7f51f58386a", base_url="https://api.deepseek.com")
# self.client = OpenAI(api_key="sk-hjexxiqvkahyxeznmxskiqhwxvjanwdsfodxrtuvcntzqjio", base_url="https://api.siliconflow.cn")
def entity_extraction(self, text):
# 调用大模型进行实体提取
response = self.client.chat.completions.create(
# model="deepseek-ai/DeepSeek-V3",
model="deepseek-chat",
messages=[
{
"role": "system",
"content": ENTITY_EXTRACTION.format(
language="中文",
examples="\n".join([example for example in ENTITY_EXTRACTION_EXAMPLES
])
)},
{
"role": "user",
"content": """
#############################
---真实数据---
######################
Entity_types(实体类型):[{entity_types}]
Text(文本):'''
{input_text}
'''""".format(
entity_types=DEFAULT_ENTITY_TYPES,
input_text=text,
)
}
],
temperature=0.0,
stream=False,
)
# print(ENTITY_EXTRACTION.format(
# language="中文",
# tuple_delimiter= DEFAULT_TUPLE_DELIMITER,
# record_delimiter=DEFAULT_RECORD_DELIMITER,
# completion_delimiter=DEFAULT_COMPLETION_DELIMITER,
# examples="\n".join([example for example in ENTITY_EXTRACTION_EXAMPLES
# ]))
# )
return response.choices[0].message.content
def entity_continue_extraction(self, text, first_extraction_result):
# 调用大模型进行实体继续提取
response = self.client.chat.completions.create(
# model="deepseek-ai/DeepSeek-V3",
model="deepseek-chat",
messages=[
{
"role": "system",
"content": ENTITY_EXTRACTION.format(
language="中文",
tuple_delimiter= DEFAULT_TUPLE_DELIMITER,
record_delimiter=DEFAULT_RECORD_DELIMITER,
completion_delimiter=DEFAULT_COMPLETION_DELIMITER,
examples="\n".join([example for example in ENTITY_EXTRACTION_EXAMPLES
])
)
},
{
"role": "user",
"content": """ #############################
---真实数据---
######################
Entity_types(实体类型):[{entity_types}]
Text(文本):
{input_text}
######################
Output(输出):""".format(
entity_types=DEFAULT_ENTITY_TYPES,
input_text=text,
)
},
{
"role": "assistant",
"content": first_extraction_result
},
{
"role": "user",
"content": entity_continue_extraction.format(
language="中文",
tuple_delimiter= DEFAULT_TUPLE_DELIMITER,
record_delimiter=DEFAULT_RECORD_DELIMITER,
completion_delimiter=DEFAULT_COMPLETION_DELIMITER,
entity_types=DEFAULT_ENTITY_TYPES
) + text
}
],
temperature=0.0,
stream=False,
)
return response.choices[0].message.content
def entity_if_loop_extraction(self, text, first_extraction_result, second_extraction_result):
# 调用大模型进行实体循环提取判断
response = self.client.chat.completions.create(
# model="deepseek-ai/DeepSeek-V3",
model="deepseek-chat",
messages=[
{
"role": "system",
"content": ENTITY_EXTRACTION.format(
language="中文",
tuple_delimiter= DEFAULT_TUPLE_DELIMITER,
record_delimiter=DEFAULT_RECORD_DELIMITER,
completion_delimiter=DEFAULT_COMPLETION_DELIMITER,
examples="\n".join([example for example in ENTITY_EXTRACTION_EXAMPLES
]) + text
)
},
{
"role": "user",
"content": """ #############################
---真实数据---
######################
Entity_types(实体类型):[{entity_types}]
Text(文本):
{input_text}
######################
Output(输出):""".format(
entity_types=DEFAULT_ENTITY_TYPES,
input_text=text,
)
},
{
"role": "assistant",
"content": first_extraction_result
},
{
"role": "user",
"content": entity_continue_extraction.format(
language="中文",
tuple_delimiter= DEFAULT_TUPLE_DELIMITER,
record_delimiter=DEFAULT_RECORD_DELIMITER,
completion_delimiter=DEFAULT_COMPLETION_DELIMITER,
entity_types=DEFAULT_ENTITY_TYPES
)
},
{
"role": "assistant",
"content": second_extraction_result
},
{
"role": "user",
"content": entity_if_loop_extraction.format(
language="中文",
)
}
],
temperature=0.0,
stream=False,
)
return response.choices[0].message.content
def get_second_extraction_result(self, text):
"""
执行两次实体提取并返回第二次的结果
Args:
text: 输入文本
Returns:
第二次实体提取的结果
"""
# 第一次提取
first_result = self.entity_extraction(text)
# 第二次提取
second_result = self.entity_continue_extraction(text, first_result)
print(second_result)
# 尝试从三重引号中提取JSON
json_match = re.search(r"```(?:json)?(.*?)```", second_result, re.DOTALL)
if json_match:
# 从三重引号中提取内容
json_str = json_match.group(1).strip()
try:
return json.loads(json_str)
except json.JSONDecodeError:
print("无法解析提取的JSON内容,尝试直接解析整个响应")
# 如果没有三重引号或解析失败,尝试直接解析整个内容
try:
return json.loads(second_result)
except json.JSONDecodeError:
print("无法直接解析响应为JSON,返回空结果")
return {"entities": [], "relations": [], "content_keywords": []}
# return second_result
def keywords_extraction(self, query):
"""
从查询中提取关键词
Args:
query: 查询文本
Returns:
关键词列表
"""
# 调用大模型进行关键词提取
# print(KEYWORDS_EXTRACTION_EXAMPLES)
content = KEYWORDS_EXTRACTION.format(examples="\n".join(KEYWORDS_EXTRACTION_EXAMPLES))
response = self.client.chat.completions.create(
# model="deepseek-ai/DeepSeek-V3",
model="deepseek-chat",
messages=[
{"role": "system","content": content},
{"role": "user",
"content": f"""
---实际数据---
当前查询:{query}
输出:"""
}
],
temperature=0.3,
stream=False,
)
result = response.choices[0].message.content
print("关键词生成结果---------------------\n\n",result)
json_match = re.search(r"```(?:json)?(.*?)```", result, re.DOTALL)
if json_match:
# 从三重引号中提取内容
json_str = json_match.group(1).strip()
try:
return json.loads(json_str)
except json.JSONDecodeError:
print("无法解析提取的JSON内容,尝试直接解析整个响应")
# 如果没有三重引号或解析失败,尝试直接解析整个内容
try:
return json.loads(result)
except json.JSONDecodeError:
print("无法直接解析响应为JSON,返回空结果")
return {"high_level_keywords": [], "low_level_keywords": []}
def naive_rag_response(self, query, content_data):
"""
使用Naive RAG方法生成响应
Args:
query: 查询文本
knowledge_base: 知识库
Returns:
生成的响应文本
"""
# 提取关键词
response = self.client.chat.completions.create(
# model="deepseek-ai/DeepSeek-V3",
model="deepseek-chat",
messages=[
{
"role": "system",
"content": NAIVE_RAG_RESPONSE.format(
content_data=content_data
)
},
{
"role": "user",
"content": f"用户问题为:{query}"
}
],
temperature=0.3,
)
return response.choices[0].message.content
def mix_rag_response(self, query, vector_context, kg_context):
"""
使用混合RAG方法生成响应
Args:
query: 查询文本
vector_context: 向量上下文
kg_context: 知识图谱上下文
Returns:
生成的响应文本
"""
# 调用大模型进行混合RAG
response = self.client.chat.completions.create(
# model="deepseek-ai/DeepSeek-V3",
model="deepseek-chat",
messages=[
{
"role": "system",
"content": MIX_RAG_RESPONSE.format(
vector_context=vector_context,
kg_context=kg_context
)
},
{
"role": "user",
"content": f"用户问题为:{query}"
}
],
temperature=0.3,
)
# return response.choices[0].message.content
response = response.choices[0].message.content
# print("混合环境下的回答:",response)
json_match = re.search(r"```(?:json)?(.*?)```", response, re.DOTALL)
if json_match:
# 从三重引号中提取内容
json_str = json_match.group(1).strip()
try:
return json.loads(json_str)
except json.JSONDecodeError:
print("无法解析提取的JSON内容,尝试直接解析整个响应")
# 如果没有三重引号或解析失败,尝试直接解析整个内容
try:
return json.loads(response)
except json.JSONDecodeError:
print("无法直接解析响应为JSON,返回空结果")
return {"question": "", "keyword": "", "answer": ""}
if __name__ == "__main__":
# 初始化LLM工具
llm_tool = LLMHandler()
# 测试文本
test_text = """
这是关于3D编程模型创新设计专项赛的相关信息:\
#三、选拔赛参与办法1.选拔赛报名。参加活动的青少年通过访问“人工智能创新挑战赛”网站https://aiic.china61.org.cn/,在首页点击“选拔赛报名”进行在线报名,详细登记相关信息和报名赛项、组别。\
2.参加选拔赛。根据各地区报名实际情况,本赛项选拔赛为线上选拔赛,线上申报参赛作品,并由专家对作品进行盲评的形式举办。3.报名时间:2024年4月15日-5月15日,选拔赛时间为2024年5月16日-7月1日(具体时间另行通知)。\
参加选拔赛的青少年需通过“人工智能创新挑战赛”网站点击“参加选拔赛”链接,选择“3D编程模型创新设计专项赛”了解选拔赛详细信息。\
4.主办单位将根据线上选拔赛的成绩,甄选部分优秀选手入围全国挑战赛决赛。5.选拔赛成绩可以在2024年7月15日后,登录“人工智能创新挑战赛”网站进行查询,入围决赛的选手可以参加全国决赛。\
#四、选拔赛规则#(一)线上选拔赛规则#1.线上选拔赛简介线上选拔赛以线上申报参赛作品,并由专家对作品进行盲评的形式举办。参加活动的青少年需通过“人工智能创新挑战赛”网站点击“参加选拔赛”链接,选择“3D编程模型创新设计专项赛”并凭报名信息进入线上竞赛系统参赛。\
参赛学生团队使用三维编程设计平台,融合编程语言、计算算法,结合所在学段组别对应参赛命题,将作品可编辑程序源代码文件、作品设计说明文件(PPT格式)等上传至赛事网站进行参赛。#2.选拔赛参赛命题(1)小学低年级组、小学高年级组、初中组参赛命题:运用算法知识和编程逻辑设计三维模型设计作品“伞”。\
(2)高中组、中职职高组参赛。运用三角函数、阵列、立体几何等算法知识,设计“波浪线形”栅栏设计作品(参考如下图)#3.线上选拔赛流程线上选拔赛分为报名阶段、作品上传阶段、作品评审阶段。具体比赛日期详见后续通知。阶段环节报名阶段参赛学生自行组队,在赛事平台上完成个人信息注册与组队报名。\
作品上传阶段参赛学生需在该阶段,根据作品设计主题,按照赛事平台要求完成作品可编辑程序源代码文件、作品设计说明文件(PPT格式)的上传。参赛学生提交作品将由专家评审委员会进行作品作品评审阶段评审,并甄选出部分优秀参赛学生入围全国挑战赛。
"""
# 测试实体提取
print("=== 测试实体提取 ===")
extraction_result = llm_tool.entity_extraction(test_text)
print("提取结果:\n", extraction_result)
# 测试继续提取
print("\n=== 测试继续提取 ===")
continue_result = llm_tool.entity_continue_extraction(test_text,extraction_result)
print("继续提取结果:\n", continue_result)
# 测试是否需要继续提取
print("\n=== 测试是否需要继续提取 ===")
if_loop_result = llm_tool.entity_if_loop_extraction(test_text,extraction_result,continue_result)
print("是否需要继续提取:", if_loop_result)