11.20 修改bug
This commit is contained in:
parent
63476636b7
commit
6dd1e02290
@ -29,4 +29,4 @@ ENV ALIBABA_CLOUD_ACCESS_KEY_SECRET=88oyw7LniqV8i0SnOuSFS5lprfrPtw
|
|||||||
EXPOSE 5000
|
EXPOSE 5000
|
||||||
|
|
||||||
# 在容器启动时运行你的应用
|
# 在容器启动时运行你的应用
|
||||||
CMD ["python", "flask_app/main/start_up.py"]
|
CMD ["python", "flask_app/start_up.py"]
|
||||||
|
@ -69,7 +69,7 @@ def extract_business_requirements(data):
|
|||||||
counter += 1
|
counter += 1
|
||||||
|
|
||||||
business_requirements_string = json.dumps(new_data, ensure_ascii=False, indent=4)
|
business_requirements_string = json.dumps(new_data, ensure_ascii=False, indent=4)
|
||||||
print(business_requirements_string)
|
# print(business_requirements_string)
|
||||||
prompt_template1 = """请帮我从以下文本中摘取商务要求部分,并将信息重新组织,外键名为'商务要求',键值为字符串列表,其中每个字符串为一条商务要求,去除开头的序号(若有)。
|
prompt_template1 = """请帮我从以下文本中摘取商务要求部分,并将信息重新组织,外键名为'商务要求',键值为字符串列表,其中每个字符串为一条商务要求,去除开头的序号(若有)。
|
||||||
#角色
|
#角色
|
||||||
你是一个专业的招投标业务专家,擅长从招标文件中总结商务要求的部分,并逐条列出,作为编写商务要求偏离表的前置准备。
|
你是一个专业的招投标业务专家,擅长从招标文件中总结商务要求的部分,并逐条列出,作为编写商务要求偏离表的前置准备。
|
||||||
@ -415,7 +415,7 @@ def outer_post_processing(combined_data, includes, good_list):
|
|||||||
extracted_info = {}
|
extracted_info = {}
|
||||||
|
|
||||||
# 初始化采购要求的技术要求
|
# 初始化采购要求的技术要求
|
||||||
procurement_reqs = ""
|
tech_deviation = ""
|
||||||
zige_info=""
|
zige_info=""
|
||||||
fuhe_info=""
|
fuhe_info=""
|
||||||
|
|
||||||
@ -430,10 +430,10 @@ def outer_post_processing(combined_data, includes, good_list):
|
|||||||
tech_requirements = get_nested(base_info, ["采购要求", "采购需求"], {})
|
tech_requirements = get_nested(base_info, ["采购要求", "采购需求"], {})
|
||||||
|
|
||||||
if tech_requirements:
|
if tech_requirements:
|
||||||
procurement_reqs = extract_matching_keys(tech_requirements, good_list)
|
tech_deviation = extract_matching_keys(tech_requirements, good_list)
|
||||||
else:
|
else:
|
||||||
# 如果 '技术要求' 不存在或为空,可以根据需要设置默认值
|
# 如果 '技术要求' 不存在或为空,可以根据需要设置默认值
|
||||||
procurement_reqs = "未提供"
|
tech_deviation = "未提供"
|
||||||
|
|
||||||
if "资格审查" in includes:
|
if "资格审查" in includes:
|
||||||
zige_review = combined_data.get("资格审查", {})
|
zige_review = combined_data.get("资格审查", {})
|
||||||
@ -452,9 +452,9 @@ def outer_post_processing(combined_data, includes, good_list):
|
|||||||
}, ensure_ascii=False, indent=4)
|
}, ensure_ascii=False, indent=4)
|
||||||
except KeyError as e:
|
except KeyError as e:
|
||||||
print(f"缺少关键字: {e}")
|
print(f"缺少关键字: {e}")
|
||||||
# tech_star_deviation=get_tech_star_deviation(json.dumps(procurement_reqs,ensure_ascii=False,indent=4))
|
tech_star_deviation=get_tech_star_deviation(json.dumps(tech_deviation,ensure_ascii=False,indent=4))
|
||||||
# business_req_deviation = extract_business_requirements(get_nested(combined_data, ['基础信息'], {}))
|
business_deviation,business_star_deviation = extract_business_requirements(get_nested(combined_data, ['基础信息'], {}))
|
||||||
# zige_deviation,fuhe_deviation=extract_zige_deviation_table(zige_info,fuhe_info)
|
zige_deviation,fuhe_deviation=extract_zige_deviation_table(zige_info,fuhe_info)
|
||||||
|
|
||||||
# 遍历原始字典的每一个键值对
|
# 遍历原始字典的每一个键值对
|
||||||
for key, value in combined_data.items():
|
for key, value in combined_data.items():
|
||||||
@ -473,7 +473,7 @@ def outer_post_processing(combined_data, includes, good_list):
|
|||||||
if not processed_data["其他"]:
|
if not processed_data["其他"]:
|
||||||
del processed_data["其他"]
|
del processed_data["其他"]
|
||||||
|
|
||||||
return processed_data, extracted_info, procurement_reqs
|
return processed_data, extracted_info, tech_deviation,tech_star_deviation,business_deviation,business_star_deviation,zige_deviation,fuhe_deviation
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -130,13 +130,13 @@ def rag_assistant(knowledge_name):
|
|||||||
#TODO:http格式,有bug还没修改
|
#TODO:http格式,有bug还没修改
|
||||||
def create_assistant(knowledge_name):
|
def create_assistant(knowledge_name):
|
||||||
"""
|
"""
|
||||||
Create an assistant using DashScope API via HTTP request based on the provided knowledge name.
|
Create an assistant using DashScope routes via HTTP request based on the provided knowledge name.
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
knowledge_name (str): The name of the knowledge base to associate with the assistant.
|
knowledge_name (str): The name of the knowledge base to associate with the assistant.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
dict: Response from the API containing assistant details.
|
dict: Response from the routes containing assistant details.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
ValueError: If the DASHSCOPE_API_KEY environment variable is not set.
|
ValueError: If the DASHSCOPE_API_KEY environment variable is not set.
|
||||||
@ -150,12 +150,12 @@ def create_assistant(knowledge_name):
|
|||||||
print(f"Error retrieving pipeline ID for knowledge '{knowledge_name}': {e}")
|
print(f"Error retrieving pipeline ID for knowledge '{knowledge_name}': {e}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Step 2: Fetch the API Key from Environment Variables
|
# Step 2: Fetch the routes Key from Environment Variables
|
||||||
api_key = os.getenv("DASHSCOPE_API_KEY")
|
api_key = os.getenv("DASHSCOPE_API_KEY")
|
||||||
if not api_key:
|
if not api_key:
|
||||||
raise ValueError("DASHSCOPE_API_KEY environment variable is not set.")
|
raise ValueError("DASHSCOPE_API_KEY environment variable is not set.")
|
||||||
|
|
||||||
# Step 3: Define the API Endpoint and Headers
|
# Step 3: Define the routes Endpoint and Headers
|
||||||
url = 'https://dashscope.aliyuncs.com/api/v1/assistants'
|
url = 'https://dashscope.aliyuncs.com/api/v1/assistants'
|
||||||
headers = {
|
headers = {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
@ -258,7 +258,7 @@ def multi_threading(queries, knowledge_name="", file_id="", llm_type=1):
|
|||||||
result_queue = queue.Queue()
|
result_queue = queue.Queue()
|
||||||
max_retries = 2 # 设置最大重试次数
|
max_retries = 2 # 设置最大重试次数
|
||||||
# 使用 ThreadPoolExecutor 管理线程
|
# 使用 ThreadPoolExecutor 管理线程
|
||||||
with concurrent.futures.ThreadPoolExecutor(max_workers=60) as executor:
|
with concurrent.futures.ThreadPoolExecutor(max_workers=30) as executor:
|
||||||
# 逐个提交任务,每提交一个任务后休眠1秒
|
# 逐个提交任务,每提交一个任务后休眠1秒
|
||||||
future_to_query = {}
|
future_to_query = {}
|
||||||
for index, query in enumerate(queries):
|
for index, query in enumerate(queries):
|
||||||
|
@ -39,17 +39,16 @@ def get_technical_requirements_main(file_path,file_type,unique_id,output_folder)
|
|||||||
# file_id=upload_file(truncate_file)
|
# file_id=upload_file(truncate_file)
|
||||||
final_res=get_technical_requirements(truncate_file,pdf_path)
|
final_res=get_technical_requirements(truncate_file,pdf_path)
|
||||||
# 安全地提取 "技术要求" 内部的字典内容
|
# 安全地提取 "技术要求" 内部的字典内容
|
||||||
if isinstance(final_res, dict) and '技术要求' in final_res and isinstance(final_res['技术要求'], dict):
|
if isinstance(final_res, dict) and '采购需求' in final_res and isinstance(final_res['采购需求'], dict):
|
||||||
technical_requirements = final_res['技术要求']
|
technical_requirements = final_res['采购需求']
|
||||||
good_list = technical_requirements.pop('货物列表', []) # 如果 '货物列表' 不存在,返回 []
|
good_list = technical_requirements.pop('货物列表', []) # 如果 '货物列表' 不存在,返回 []
|
||||||
print(good_list)
|
|
||||||
logger.info("Collected good_list from the processing function: %s", good_list)
|
logger.info("Collected good_list from the processing function: %s", good_list)
|
||||||
return extract_matching_keys(technical_requirements,good_list)
|
return extract_matching_keys(technical_requirements,good_list)
|
||||||
else:
|
else:
|
||||||
return final_res
|
return final_res
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
file_path="C:\\Users\\Administrator\\Desktop\\货物标\\zbfiles\\包头市公安支队机动车查验监管系统招标文201907.pdf"
|
file_path=r"C:\Users\Administrator\Desktop\货物标\zbfiles\2-招标文件(广水市教育局封闭管理).pdf"
|
||||||
file_type=2
|
file_type=2
|
||||||
output_folder = "C:\\Users\\Administrator\\Desktop\\fsdownload\\45f650ce-e519-457b-9ad6-5840e2ede539\\tmp"
|
output_folder = r"C:\Users\Administrator\Desktop\fsdownload\39b0c3b4-1807-456c-8330-c5c7d1b7a2ca\tmp"
|
||||||
res=get_technical_requirements_main(file_path,file_type,"123",output_folder)
|
res=get_technical_requirements_main(file_path,file_type,"123",output_folder)
|
||||||
print(json.dumps(res,ensure_ascii=False,indent=4))
|
print(json.dumps(res,ensure_ascii=False,indent=4))
|
||||||
|
@ -81,7 +81,7 @@ def qianwen_long_text(file_id, user_query):
|
|||||||
return completion.choices[0].message.content
|
return completion.choices[0].message.content
|
||||||
|
|
||||||
def qianwen_long_stream(file_id, user_query):
|
def qianwen_long_stream(file_id, user_query):
|
||||||
print("调用 qianwen-long text...")
|
print("调用 qianwen-long stream...")
|
||||||
"""
|
"""
|
||||||
使用之前上传的文件,根据用户查询生成响应,并实时显示流式输出。
|
使用之前上传的文件,根据用户查询生成响应,并实时显示流式输出。
|
||||||
"""
|
"""
|
||||||
@ -93,7 +93,7 @@ def qianwen_long_stream(file_id, user_query):
|
|||||||
# 生成基于文件ID的响应
|
# 生成基于文件ID的响应
|
||||||
completion = client.chat.completions.create(
|
completion = client.chat.completions.create(
|
||||||
model="qwen-long",
|
model="qwen-long",
|
||||||
temperature=0.5,
|
temperature=0.4,
|
||||||
messages=[
|
messages=[
|
||||||
{
|
{
|
||||||
'role': 'system',
|
'role': 'system',
|
||||||
|
@ -28,7 +28,7 @@ def delete_index(client: bailian20231229Client, workspace_id: str, index_id: str
|
|||||||
headers = {}
|
headers = {}
|
||||||
try:
|
try:
|
||||||
response = client.delete_index_with_options(workspace_id, delete_index_request, headers, runtime)
|
response = client.delete_index_with_options(workspace_id, delete_index_request, headers, runtime)
|
||||||
print("API Response:", response)
|
print("routes Response:", response)
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
print(error.message)
|
print(error.message)
|
||||||
print(error.data.get("Recommend"))
|
print(error.data.get("Recommend"))
|
||||||
@ -42,7 +42,7 @@ async def delete_index_async(client: bailian20231229Client, workspace_id: str, i
|
|||||||
headers = {}
|
headers = {}
|
||||||
try:
|
try:
|
||||||
response = await client.delete_index_with_options_async(workspace_id, delete_index_request, headers, runtime)
|
response = await client.delete_index_with_options_async(workspace_id, delete_index_request, headers, runtime)
|
||||||
print("API Response:", response)
|
print("routes Response:", response)
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
print(error.message)
|
print(error.message)
|
||||||
print(error.data.get("Recommend"))
|
print(error.data.get("Recommend"))
|
||||||
|
@ -22,7 +22,7 @@ def query():
|
|||||||
id='docmind-20241008-24363df30d274863894f037dbb7244e8'
|
id='docmind-20241008-24363df30d274863894f037dbb7244e8'
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
# 复制代码运行请自行打印 API 的返回值
|
# 复制代码运行请自行打印 routes 的返回值
|
||||||
response = client.query_doc_parser_status(request)
|
response = client.query_doc_parser_status(request)
|
||||||
# API返回值格式层级为 body -> data -> 具体属性。可根据业务需要打印相应的结果。获取属性值均以小写开头
|
# API返回值格式层级为 body -> data -> 具体属性。可根据业务需要打印相应的结果。获取属性值均以小写开头
|
||||||
# 获取返回结果。建议先把response.body.data转成json,然后再从json里面取具体需要的值。
|
# 获取返回结果。建议先把response.body.data转成json,然后再从json里面取具体需要的值。
|
||||||
|
@ -29,7 +29,7 @@ def submit_file():
|
|||||||
)
|
)
|
||||||
runtime = util_models.RuntimeOptions()
|
runtime = util_models.RuntimeOptions()
|
||||||
try:
|
try:
|
||||||
# 复制代码运行请自行打印 API 的返回值
|
# 复制代码运行请自行打印 routes 的返回值
|
||||||
response = client.submit_doc_parser_job_advance(request, runtime)
|
response = client.submit_doc_parser_job_advance(request, runtime)
|
||||||
# API返回值格式层级为 body -> data -> 具体属性。可根据业务需要打印相应的结果。如下示例为打印返回的业务id格式
|
# API返回值格式层级为 body -> data -> 具体属性。可根据业务需要打印相应的结果。如下示例为打印返回的业务id格式
|
||||||
# 获取属性值均以小写开头,
|
# 获取属性值均以小写开头,
|
||||||
|
@ -24,7 +24,7 @@ def query():
|
|||||||
layout_num=0
|
layout_num=0
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
# 复制代码运行请自行打印 API 的返回值
|
# 复制代码运行请自行打印 routes 的返回值
|
||||||
response = client.get_doc_parser_result(request)
|
response = client.get_doc_parser_result(request)
|
||||||
# API返回值格式层级为 body -> data -> 具体属性。可根据业务需要打印相应的结果。获取属性值均以小写开头
|
# API返回值格式层级为 body -> data -> 具体属性。可根据业务需要打印相应的结果。获取属性值均以小写开头
|
||||||
# 获取返回结果。建议先把response.body.data转成json,然后再从json里面取具体需要的值。
|
# 获取返回结果。建议先把response.body.data转成json,然后再从json里面取具体需要的值。
|
||||||
|
@ -4,7 +4,7 @@ import os
|
|||||||
|
|
||||||
def convert_pdf_to_word(file_path, output_dir, output_format='docx'):
|
def convert_pdf_to_word(file_path, output_dir, output_format='docx'):
|
||||||
"""
|
"""
|
||||||
Converts a PDF file to a Word document using a specified API.
|
Converts a PDF file to a Word document using a specified routes.
|
||||||
|
|
||||||
:param file_path: Path to the PDF file to convert.
|
:param file_path: Path to the PDF file to convert.
|
||||||
:param output_dir: Directory to save the converted Word document.
|
:param output_dir: Directory to save the converted Word document.
|
||||||
|
@ -403,17 +403,70 @@ def process_and_stream(file_url, zb_type):
|
|||||||
output_json_path = os.path.join(output_folder, 'final_result.json')
|
output_json_path = os.path.join(output_folder, 'final_result.json')
|
||||||
extracted_info_path = os.path.join(output_folder, 'extracted_result.json')
|
extracted_info_path = os.path.join(output_folder, 'extracted_result.json')
|
||||||
includes = ["基础信息", "资格审查", "商务评分", "技术评分", "无效标与废标项", "投标文件要求", "开评定标流程"]
|
includes = ["基础信息", "资格审查", "商务评分", "技术评分", "无效标与废标项", "投标文件要求", "开评定标流程"]
|
||||||
final_result, extracted_info, procurement_reqs = outer_post_processing(combined_data, includes, good_list)
|
final_result, extracted_info,tech_deviation,tech_star_deviation,business_deviation,business_star_deviation,zige_deviation,fuhe_deviation = outer_post_processing(combined_data, includes, good_list)
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
f"Procurement requirements extracted: {json.dumps(procurement_reqs, ensure_ascii=False, indent=4)}") # 添加日志记录
|
f"技术偏离表: {json.dumps(tech_deviation, ensure_ascii=False, indent=4)}"
|
||||||
|
) # 添加日志记录
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
f"技术偏离表带星: {json.dumps(tech_star_deviation, ensure_ascii=False, indent=4)}"
|
||||||
|
) # 添加日志记录
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
f"商务偏离表: {json.dumps(business_deviation, ensure_ascii=False, indent=4)}"
|
||||||
|
) # 添加日志记录
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
f"商务偏离表带星: {json.dumps(business_star_deviation, ensure_ascii=False, indent=4)}"
|
||||||
|
) # 添加日志记录
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
f"资格检查偏离表: {json.dumps(zige_deviation, ensure_ascii=False, indent=4)}"
|
||||||
|
) # 添加日志记录
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
f"符合性检查偏离表: {json.dumps(fuhe_deviation, ensure_ascii=False, indent=4)}"
|
||||||
|
) # 添加日志记录
|
||||||
|
|
||||||
|
|
||||||
# 采购需求
|
# 采购需求
|
||||||
procurement_reqs_response = {
|
tech_deviation_response = {
|
||||||
'message': 'procurement_reqs',
|
'message': 'procurement_reqs',
|
||||||
'filename': os.path.basename(downloaded_filepath),
|
'filename': os.path.basename(downloaded_filepath),
|
||||||
'data': json.dumps(procurement_reqs, ensure_ascii=False)
|
'data': json.dumps(tech_deviation, ensure_ascii=False)
|
||||||
}
|
}
|
||||||
yield f"data: {json.dumps(procurement_reqs_response, ensure_ascii=False)}\n\n"
|
tech_deviation_star_response = {
|
||||||
|
'message': 'jishu_star_deviation',
|
||||||
|
'filename': filename,
|
||||||
|
'data': json.dumps(tech_star_deviation, ensure_ascii=False)
|
||||||
|
}
|
||||||
|
zige_deviation_response = {
|
||||||
|
'message': 'zige_deviation',
|
||||||
|
'filename': filename,
|
||||||
|
'data': json.dumps(zige_deviation, ensure_ascii=False)
|
||||||
|
}
|
||||||
|
fuhe_deviation_response = {
|
||||||
|
'message': 'fuhe_deviation',
|
||||||
|
'filename': filename,
|
||||||
|
'data': json.dumps(fuhe_deviation, ensure_ascii=False)
|
||||||
|
}
|
||||||
|
shangwu_deviation_response = {
|
||||||
|
'message': 'shangwu_deviation',
|
||||||
|
'filename': filename,
|
||||||
|
'data': json.dumps(business_deviation, ensure_ascii=False)
|
||||||
|
}
|
||||||
|
shangwu_star_deviation_response = {
|
||||||
|
'message': 'shangwu_star_deviation',
|
||||||
|
'filename': filename,
|
||||||
|
'data': json.dumps(business_star_deviation, ensure_ascii=False)
|
||||||
|
}
|
||||||
|
yield f"data: {json.dumps(tech_deviation_response, ensure_ascii=False)}\n\n"
|
||||||
|
yield f"data: {json.dumps(tech_deviation_star_response, ensure_ascii=False)}\n\n"
|
||||||
|
yield f"data: {json.dumps(zige_deviation_response, ensure_ascii=False)}\n\n"
|
||||||
|
yield f"data: {json.dumps(fuhe_deviation_response, ensure_ascii=False)}\n\n"
|
||||||
|
yield f"data: {json.dumps(shangwu_deviation_response, ensure_ascii=False)}\n\n"
|
||||||
|
yield f"data: {json.dumps(shangwu_star_deviation_response, ensure_ascii=False)}\n\n"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(extracted_info_path, 'w', encoding='utf-8') as json_file:
|
with open(extracted_info_path, 'w', encoding='utf-8') as json_file:
|
||||||
@ -579,12 +632,11 @@ def test_process_and_stream():
|
|||||||
"数量": "500立方米",
|
"数量": "500立方米",
|
||||||
"规格": "C30"
|
"规格": "C30"
|
||||||
}
|
}
|
||||||
procurement_reqs_response = {
|
tech_deviation_response = {
|
||||||
'message': 'procurement_reqs',
|
'message': 'procurement_reqs',
|
||||||
'filename': filename,
|
'filename': filename,
|
||||||
'data': json.dumps(procurement_reqs, ensure_ascii=False)
|
'data': json.dumps(procurement_reqs, ensure_ascii=False)
|
||||||
}
|
}
|
||||||
yield f"data: {json.dumps(procurement_reqs_response, ensure_ascii=False)}\n\n"
|
|
||||||
|
|
||||||
zige_deviation_table = {
|
zige_deviation_table = {
|
||||||
"资格性检查": ["具有独立承担民事责任的能力;", "具有良好的商业信誉和健全的财务会计制度;",
|
"资格性检查": ["具有独立承担民事责任的能力;", "具有良好的商业信誉和健全的财务会计制度;",
|
||||||
@ -641,11 +693,14 @@ def test_process_and_stream():
|
|||||||
'filename': filename,
|
'filename': filename,
|
||||||
'data': json.dumps(jishu_star_deviation_table, ensure_ascii=False)
|
'data': json.dumps(jishu_star_deviation_table, ensure_ascii=False)
|
||||||
}
|
}
|
||||||
|
|
||||||
yield f"data:{json.dumps(zige_deviation_response, ensure_ascii=False)}\n\n"
|
yield f"data:{json.dumps(zige_deviation_response, ensure_ascii=False)}\n\n"
|
||||||
yield f"data:{json.dumps(fuhe_deviation_response, ensure_ascii=False)}\n\n"
|
yield f"data:{json.dumps(fuhe_deviation_response, ensure_ascii=False)}\n\n"
|
||||||
yield f"data:{json.dumps(shangwu_deviation_response, ensure_ascii=False)}\n\n"
|
yield f"data:{json.dumps(shangwu_deviation_response, ensure_ascii=False)}\n\n"
|
||||||
yield f"data:{json.dumps(shangwu_star_deviation_response, ensure_ascii=False)}\n\n"
|
yield f"data:{json.dumps(shangwu_star_deviation_response, ensure_ascii=False)}\n\n"
|
||||||
yield f"data:{json.dumps(jishu_star_deviation_response, ensure_ascii=False)}\n\n"
|
yield f"data:{json.dumps(jishu_star_deviation_response, ensure_ascii=False)}\n\n"
|
||||||
|
yield f"data: {json.dumps(tech_deviation_response, ensure_ascii=False)}\n\n"
|
||||||
|
|
||||||
|
|
||||||
# 发送完整的大字典
|
# 发送完整的大字典
|
||||||
complete_response = {
|
complete_response = {
|
@ -10,55 +10,83 @@ from flask_app.货物标.截取pdf货物标版 import extract_common_header, cle
|
|||||||
#正则表达式判断原文中是否有商务、服务、其他要求
|
#正则表达式判断原文中是否有商务、服务、其他要求
|
||||||
def find_exists(truncate_file, required_keys):
|
def find_exists(truncate_file, required_keys):
|
||||||
if not truncate_file:
|
if not truncate_file:
|
||||||
return ["技术要求","商务要求", "服务要求", "其他要求"]
|
return ["技术要求", "商务要求", "服务要求", "其他要求"]
|
||||||
common_header = extract_common_header(truncate_file)
|
|
||||||
|
common_header = extract_common_header(truncate_file) # 假设该函数已定义
|
||||||
pdf_document = PdfReader(truncate_file)
|
pdf_document = PdfReader(truncate_file)
|
||||||
text = ""
|
|
||||||
|
|
||||||
|
# 定义正则模式
|
||||||
begin_pattern = re.compile(
|
begin_pattern = re.compile(
|
||||||
r'^第[一二三四五六七八九十百千]+(?:章|部分).*?(?:服务|项目|商务|技术).*?要求|'
|
r'(?:^第[一二三四五六七八九十百千]+(?:章|部分)\s*' # 匹配“第X章”或“第X部分”
|
||||||
r'^第[一二三四五六七八九十百千]+(?:章|部分).*?(?:采购|技术标准).*|'
|
r'[\u4e00-\u9fff、()()]*?' # 匹配允许的字符
|
||||||
r'^[一二三四五六七八九十百千]+、\s*采购清单', re.MULTILINE)
|
r'(?:(?:服务|项目|商务|技术)[\u4e00-\u9fff、()()]*?要求|' # 匹配“服务”、“项目”、“商务”或“技术”后跟“要求”
|
||||||
|
r'(?:采购|需求)[\u4e00-\u9fff、()()]*?)' # 匹配“采购”或“需求”
|
||||||
|
r'\s*$|' # 匹配行尾
|
||||||
|
r'^第[一二三四五六七八九十百千]+(?:章|部分)(?!.*说明).*?' # 匹配“第X章”后带“采购内容”等,排除“说明”
|
||||||
|
r'(?:采购内容|采购要求|需求).*|' # 匹配“采购内容”或“采购要求”关键词
|
||||||
|
r'^[一二三四五六七八九十百千]+、\s*采购清单)' # 匹配“一、采购清单”
|
||||||
|
r'\s*$', # 匹配行尾
|
||||||
|
re.MULTILINE
|
||||||
|
)
|
||||||
end_pattern = re.compile(
|
end_pattern = re.compile(
|
||||||
r'^第[一二三四五六七八九十百千]+(?:章|部分)\s*[\u4e00-\u9fff]+', re.MULTILINE)
|
r'第[一二三四五六七八九1-9]+(?:章|部分)\s*[\u4e00-\u9fff、()()]+\s*$', re.MULTILINE)
|
||||||
|
|
||||||
|
# 遍历所有页面,拼接全文
|
||||||
|
text = ""
|
||||||
for page in pdf_document.pages:
|
for page in pdf_document.pages:
|
||||||
page_text = page.extract_text() or ""
|
page_text = page.extract_text() or ""
|
||||||
cleaned_text = clean_page_content(page_text, common_header)
|
cleaned_text = clean_page_content(page_text, common_header)
|
||||||
text += cleaned_text + '\n'
|
text += cleaned_text + "\n"
|
||||||
|
|
||||||
|
# 匹配起始位置
|
||||||
start_match = re.search(begin_pattern, text)
|
start_match = re.search(begin_pattern, text)
|
||||||
if not start_match:
|
if not start_match:
|
||||||
|
print("未找到开始模式")
|
||||||
return []
|
return []
|
||||||
|
|
||||||
start_index = start_match.end()
|
start_index = start_match.end()
|
||||||
end_match = re.search(end_pattern, text[start_index:])
|
|
||||||
|
|
||||||
|
# 匹配结束位置
|
||||||
|
end_match = re.search(end_pattern, text[start_index:])
|
||||||
if end_match:
|
if end_match:
|
||||||
end_index = start_index + end_match.start()
|
end_index = start_index + end_match.start()
|
||||||
relevant_text = text[start_index:end_index]
|
relevant_text = text[start_index:end_index]
|
||||||
else:
|
else:
|
||||||
relevant_text = text[start_index:]
|
relevant_text = text[start_index:]
|
||||||
relevant_text=re.sub(r'\s+', '', relevant_text) #删除换行符 空格
|
|
||||||
# print(relevant_text)
|
# 保留换行,避免结构丢失
|
||||||
# Custom logic for "服务要求"
|
relevant_text = re.sub(r'\s+', ' ', relevant_text)
|
||||||
|
# print(f"提取的内容范围:\n{relevant_text}")
|
||||||
|
|
||||||
|
# 匹配所需的要求
|
||||||
matched_requirements = []
|
matched_requirements = []
|
||||||
punctuation = r"[,。?!、;:,.?!]*"
|
punctuation = r"[,。?!、;:,.?!]*"
|
||||||
for req in required_keys:
|
for req in required_keys:
|
||||||
if re.search(re.escape(req), relevant_text):
|
# required_keys 中的元素本身已包含 \s*,直接作为正则模式
|
||||||
if req == "服务要求":
|
if re.search(req, relevant_text):
|
||||||
|
if req == "服\s*务\s*要\s*求":
|
||||||
# 提取所有包含"服务要求"的行
|
# 提取所有包含"服务要求"的行
|
||||||
lines = [line for line in relevant_text.split('\n') if req in line]
|
lines = [line for line in relevant_text.split('\n') if re.search(req, line)]
|
||||||
# 检查是否存在'技术'紧跟在'服务要求'前面(中间只有标点,标点是可选的)
|
# 检查是否存在'技术'紧跟在'服务要求'前面(中间只有标点,标点是可选的)
|
||||||
pattern = r'技术\s*' + punctuation + re.escape(req)
|
pattern = "技\s*术" + punctuation + req
|
||||||
# 如果存在'技术'紧跟'服务要求'并且中间仅有标点(可选),则不添加该要求
|
if any(re.search(pattern, line) for line in lines):
|
||||||
if not any(re.search(pattern, line) for line in lines):
|
# 如果存在'技术'紧跟'服务要求',添加"技术、服务要求"
|
||||||
|
if "技\s*术\s*、\s*服\s*务\s*要\s*求" not in matched_requirements:
|
||||||
|
matched_requirements.append("技\s*术\s*、\s*服\s*务\s*要\s*求")
|
||||||
|
else:
|
||||||
|
# 如果不存在'技术'紧跟'服务要求',正常添加"服务要求"
|
||||||
matched_requirements.append(req)
|
matched_requirements.append(req)
|
||||||
else:
|
else:
|
||||||
matched_requirements.append(req)
|
matched_requirements.append(req)
|
||||||
|
|
||||||
return matched_requirements
|
# 去除 \s*,仅返回原始关键词
|
||||||
|
clean_requirements = [re.sub(r'\\s\*', '', req) for req in matched_requirements]
|
||||||
|
|
||||||
|
# 判断互斥关系:如果有"技术、服务要求",删除"技术要求"和"服务要求"
|
||||||
|
if "技术、服务要求" in clean_requirements:
|
||||||
|
clean_requirements = [req for req in clean_requirements if req not in ["技术要求", "服务要求"]]
|
||||||
|
|
||||||
|
return clean_requirements
|
||||||
|
|
||||||
def generate_queries(truncate_file, required_keys):
|
def generate_queries(truncate_file, required_keys):
|
||||||
key_list = find_exists(truncate_file, required_keys)
|
key_list = find_exists(truncate_file, required_keys)
|
||||||
@ -74,24 +102,116 @@ def generate_queries(truncate_file, required_keys):
|
|||||||
# print(query_base)
|
# print(query_base)
|
||||||
return queries
|
return queries
|
||||||
|
|
||||||
|
def generate_user_query_template(required_keys):
|
||||||
|
import textwrap
|
||||||
|
import json
|
||||||
|
|
||||||
|
# 定义所有可能的键
|
||||||
|
all_possible_keys = ["技术要求", "服务要求", "商务要求", "其他要求", "技术、服务要求"]
|
||||||
|
|
||||||
|
# 定义每个键对应的示例内容
|
||||||
|
example_content1 = {
|
||||||
|
"技术要求": ["相关技术要求以及服务要求1", "相关技术要求以及服务要求2"],
|
||||||
|
"服务要求": ["服务要求1", "服务要求2"],
|
||||||
|
"商务要求": {
|
||||||
|
"★产品质保期": ["所投 LED 整屏不低于 3 年,健身器材整套不低于 2 年"],
|
||||||
|
"售后服务方案": ["包含产品配送、安装保障方案"]
|
||||||
|
},
|
||||||
|
"其他要求": {
|
||||||
|
"子因素名1": ["关于项目采购的其他要求1...", "关于项目采购的其他要求2..."],
|
||||||
|
"子因素名2": ["关于项目采购的其他要求3...", "关于项目采购的其他要求4..."]
|
||||||
|
},
|
||||||
|
"技术、服务要求": ["相关技术、服务要求内容1", "相关技术、服务要求内容2"]
|
||||||
|
}
|
||||||
|
|
||||||
|
example_content2 = {
|
||||||
|
"技术要求": {
|
||||||
|
"子因素名1": ["相关技术要求1", "相关技术要求2"],
|
||||||
|
"子因素名2": ["相关技术要求3"]
|
||||||
|
},
|
||||||
|
"服务要求": {
|
||||||
|
"子因素名1": ["相关服务要求1", "相关服务要求2"],
|
||||||
|
"子因素名2": ["相关服务要求3", "相关服务要求4"]
|
||||||
|
},
|
||||||
|
"商务要求": ["所投 LED 整屏不低于 3 年,健身器材整套不低于 2 年", "包含产品配送、安装保障方案"],
|
||||||
|
"其他要求": ["关于项目采购的其他要求1..."],
|
||||||
|
"技术、服务要求": {
|
||||||
|
"子因素名1": ["相关技术、服务要求内容1"],
|
||||||
|
"子因素名2": ["相关技术、服务要求内容2", "相关技术、服务要求内容3"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# 将 required_keys 转换为集合以便于操作
|
||||||
|
keys = set(required_keys)
|
||||||
|
|
||||||
|
# 处理互斥关系:如果 "技术要求" 和 "服务要求" 同时存在,则移除 "技术、服务要求"
|
||||||
|
if "技术要求" in keys and "服务要求" in keys:
|
||||||
|
keys.discard("技术、服务要求")
|
||||||
|
# 如果 "技术、服务要求" 存在,则移除 "技术要求" 和 "服务要求"
|
||||||
|
elif "技术、服务要求" in keys:
|
||||||
|
keys.discard("技术要求")
|
||||||
|
keys.discard("服务要求")
|
||||||
|
|
||||||
|
# 确保 keys 中只包含允许的键
|
||||||
|
keys = keys.intersection(all_possible_keys)
|
||||||
|
|
||||||
|
# 按照预定义的顺序排序键,以保持一致性
|
||||||
|
sorted_keys = [key for key in all_possible_keys if key in keys]
|
||||||
|
|
||||||
|
# 如果没有任何键被选中,返回一个默认的模板或抛出异常
|
||||||
|
if not sorted_keys:
|
||||||
|
raise ValueError("required_keys 中没有有效的键。")
|
||||||
|
|
||||||
|
# 生成提示部分,根据 sorted_keys 动态构建
|
||||||
|
keys_str = '、'.join(sorted_keys)
|
||||||
|
outer_keys_str = ', '.join([f"'{key}'" for key in sorted_keys])
|
||||||
|
|
||||||
|
# 使用三引号定义多行字符串,便于编辑和维护
|
||||||
|
prompt_instruction = textwrap.dedent(f"""请你根据该货物类招标文件中的采购要求部分内容,请告诉我该项目采购的{keys_str}分别是什么,请以json格式返回结果,默认情况下外层键名是{outer_keys_str},键值为字符串列表,每个字符串表示具体的一条要求,内容需要与原文保持一致,不可擅自总结删减。
|
||||||
|
|
||||||
|
要求与指南:
|
||||||
|
1. 默认情况无需嵌套,键值为字符串列表;若存在嵌套结构,嵌套键名是原文中该要求下相应子标题,最多一层嵌套。
|
||||||
|
2. JSON 的结构要求:
|
||||||
|
- 外层键名为 {outer_keys_str} 中的各项。
|
||||||
|
- 每个外层键对应的值可以是:
|
||||||
|
a. 一个对象(字典),其键为子因素名,值为字符串列表。
|
||||||
|
b. 一个字符串列表,表示具体的一条条要求。若只有一条要求,也用字符串列表表示。
|
||||||
|
- 最多只允许一层嵌套。
|
||||||
|
3. 请优先定位正文部分的大标题'xx要求',在其之后提取'xx要求'相关内容,由于要求的位置比较集中,请尽量避免在全文各处寻找。
|
||||||
|
4. 在提取技术要求或技术、服务要求时(若有),你无需从采购清单或表格中提取货物名以及参数要求,你仅需定位到原文中相应位置(正文部分、而非表格中)并提取正文内容,通常一类要求写在一块大标题下,否则,键值为空列表。
|
||||||
|
5. 若无相关要求,键值为[]
|
||||||
|
""")
|
||||||
|
|
||||||
|
# 过滤 example_content1 和 example_content2 以仅包含 sorted_keys
|
||||||
|
def filter_content(example_content, keys):
|
||||||
|
return {k: v for k, v in example_content.items() if k in keys}
|
||||||
|
|
||||||
|
filtered_example_content1 = filter_content(example_content1, sorted_keys)
|
||||||
|
filtered_example_content2 = filter_content(example_content2, sorted_keys)
|
||||||
|
|
||||||
|
# 将过滤后的示例转换为格式化的 JSON 字符串
|
||||||
|
json_example1_str = json.dumps(filtered_example_content1, indent=4, ensure_ascii=False)
|
||||||
|
json_example2_str = json.dumps(filtered_example_content2, indent=4, ensure_ascii=False)
|
||||||
|
|
||||||
|
# 完整的用户查询模板,包含两份示例输出
|
||||||
|
user_query_template = f"""
|
||||||
|
{prompt_instruction}
|
||||||
|
以下为示例输出,仅供格式参考:
|
||||||
|
示例 1:
|
||||||
|
{json_example1_str}
|
||||||
|
示例 2:
|
||||||
|
{json_example2_str}
|
||||||
|
"""
|
||||||
|
|
||||||
|
return user_query_template
|
||||||
|
|
||||||
def get_business_requirements(procurement_path):
|
def get_business_requirements(procurement_path):
|
||||||
file_id=upload_file(procurement_path)
|
file_id=upload_file(procurement_path)
|
||||||
# required_keys = ["技术要求","商务要求", "服务要求", "其他要求"]
|
required_keys = ["技\s*术\s*要\s*求","商\s*务\s*要\s*求", "服\s*务\s*要\s*求", "其\s*他\s*要\s*求"]
|
||||||
# queries = generate_queries(truncate_file, required_keys)
|
contained_keys=find_exists(procurement_path,required_keys)
|
||||||
#一起问了,效率慢点,但内容准
|
print(contained_keys)
|
||||||
user_query="""
|
# queries = generate_queries(truncate_file, contained_keys)
|
||||||
请你根据该货物类招标文件中的采购要求部分内容,请告诉我文档中技术要求、服务要求、商务要求、其他要求分别是什么,注意事项:在提取技术要求和服务要求的时候,你无需从采购清单或表格中提取货物名以及参数要求,你仅需定位到原文中相应位置(正文部分、而非表格中)并提取原文内容,通常一类要求写在一块大标题下。请以json格式返回结果,可以用嵌套键值对的形式组织回答,默认情况下外层键名是'技术要求','服务要求','商务要求','其他要求',嵌套键名是原文中的相应子标题或者是你对相关子要求的总结,而键值需要与原文保持一致,不可擅自总结删减。
|
user_query=generate_user_query_template(contained_keys)
|
||||||
以下是你需要考虑的特殊情况:如果原文中技术要求与服务要求在一块,那么你应该用外键'技术、服务要求'替换默认外键'技术要求'和'服务要求';若相关要求不存在,对应的键值设为'未知'。以下为示例输出,仅供格式参考:
|
|
||||||
{
|
|
||||||
"技术、服务要求":"相关技术要求以及服务要求",
|
|
||||||
"商务要求":{
|
|
||||||
"★产品质保期":"所投 LED 整屏不低于 3 年,健身器材整套不低于 2 年",
|
|
||||||
"售后服务方案":"包含产品配送、安装保障方案"
|
|
||||||
},
|
|
||||||
"其他要求":"未知"
|
|
||||||
}"""
|
|
||||||
|
|
||||||
business_requirements=qianwen_long_stream(file_id,user_query)
|
business_requirements=qianwen_long_stream(file_id,user_query)
|
||||||
# Combine and fill missing keys with default values
|
# Combine and fill missing keys with default values
|
||||||
final_res = clean_json_string(business_requirements)
|
final_res = clean_json_string(business_requirements)
|
||||||
@ -101,7 +221,7 @@ def get_business_requirements(procurement_path):
|
|||||||
#TODO:改为先判断,再摘取
|
#TODO:改为先判断,再摘取
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# truncate_file = "C:\\Users\\Administrator\\Desktop\\fsdownload\\e4be098d-b378-4126-9c32-a742b237b3b1\\ztbfile_procurement.docx"
|
# truncate_file = "C:\\Users\\Administrator\\Desktop\\fsdownload\\e4be098d-b378-4126-9c32-a742b237b3b1\\ztbfile_procurement.docx"
|
||||||
truncate_file="D:\\flask_project\\flask_app\\static\\output\\output1\\55dc56f0-f7fe-4734-95a3-867df3456d49\\招招招标文件(一中多媒体报告厅教学设备)_procurement.docx"
|
truncate_file=r"C:\Users\Administrator\Desktop\货物标\output1\2-招标文件(广水市教育局封闭管理)_procurement.pdf"
|
||||||
file_id = upload_file(truncate_file)
|
# file_id = upload_file(truncate_file)
|
||||||
res=get_business_requirements(truncate_file)
|
res=get_business_requirements(truncate_file)
|
||||||
print(json.dumps(res, ensure_ascii=False, indent=4))
|
print(json.dumps(res, ensure_ascii=False, indent=4))
|
||||||
|
@ -354,11 +354,12 @@ def get_technical_requirements(file_path,invalid_path):
|
|||||||
ffinal_res = postprocess(cleaned_res)
|
ffinal_res = postprocess(cleaned_res)
|
||||||
else:
|
else:
|
||||||
# user_query_template = "请你根据该货物标中采购要求部分的内容,请你给出\"{}\"的技术参数(或采购要求),请以json格式返回结果,外层键名为\"{}\", 键值对中的键是你对该要求的总结,而值需要完全与原文保持一致,不可擅自总结删减。"
|
# user_query_template = "请你根据该货物标中采购要求部分的内容,请你给出\"{}\"的技术参数(或采购要求),请以json格式返回结果,外层键名为\"{}\", 键值对中的键是你对该要求的总结,而值需要完全与原文保持一致,不可擅自总结删减。"
|
||||||
user_query_template = """请根据以下货物标中采购要求部分的内容,为\"{}\"生成技术参数(或采购要求)。请以 JSON 格式返回结果,外层键名为\"{}\",最内层键值为一个列表,列表中包含若干描述\"{}\"的技术参数(或采购要求)的字符串,内容需与原文一致,即若技术参数前存在序号也要保留,但不可擅自增添或删减。
|
user_query_template = """请根据货物标中采购要求部分的内容,告诉我\"{}\"的技术参数或采购要求是什么。请以 JSON 格式返回结果,键名为\"{}\",键值为一个列表,列表中包含若干描述\"{}\"的技术参数或采购要求的字符串,内容需与原文一致,即若技术参数前存在序号也要保留,但不可擅自增添或删减。
|
||||||
要求与指南:
|
要求与指南:
|
||||||
1. 如果该货物没有相关采购要求或技术参数要求,键值应为空列表。
|
1. 如果该货物没有相关采购要求或技术参数要求,键值应为空列表。
|
||||||
2. 如果存在嵌套结构,且原文为Markdown 的表格语法,如'摄像机|有效像素|≥900W像素', 请不要返回该Markdown语法,而是使用冒号':'将相关信息拼接在一起,生成一条完整且清晰的技术参数(或采购要求)描述,作为列表中的一个字符串。如"摄像机:有效像素:≥900W像素"。
|
2. 如果存在嵌套结构,且原文为Markdown 的表格语法,如'摄像机|有效像素|≥900W像素', 请不要返回该Markdown语法,而是使用冒号':'将相关信息拼接在一起,生成一条完整且清晰的技术参数(或采购要求)描述,作为列表中的一个字符串。如"摄像机:有效像素:≥900W像素"。
|
||||||
3. 字符串中的内容为具体的技术参数要求或采购要求,请不要返回诸如'(1)高清录像功能'这种标题性质且不能体现要求的内容。
|
3. 字符串中的内容为具体的技术参数要求或采购要求,请不要返回诸如'(1)高清录像功能'这种标题性质且不能体现要求的内容。
|
||||||
|
4. 你的键值应该全面,对于同一个单元格内的数据,尽量全面,不要遗漏。
|
||||||
|
|
||||||
### 示例输出1如下:
|
### 示例输出1如下:
|
||||||
{{
|
{{
|
||||||
@ -368,23 +369,23 @@ def get_technical_requirements(file_path,invalid_path):
|
|||||||
]
|
]
|
||||||
}}
|
}}
|
||||||
|
|
||||||
### 示例输出2如下:
|
### 示例输出2如下(包含嵌套结构):
|
||||||
{{
|
{{
|
||||||
"摄像机": [
|
"摄像机": [
|
||||||
"摄像机:有效像素:≥900W像素",
|
"摄像机:有效像素:≥900W像素",
|
||||||
"摄像机:最低照度:彩色≤0.001lx",
|
"摄像机:最低照度:彩色≤0.001lx",
|
||||||
"协议:API 接口开放:具备;支持标准 ONVIF 协议与第三方厂家设备进行互联;支持 GB/T28181;应提供 SDK"
|
"协议:routes 接口开放:具备;支持标准 ONVIF 协议与第三方厂家设备进行互联;支持 GB/T28181;应提供 SDK"
|
||||||
]
|
]
|
||||||
}}
|
}}
|
||||||
"""
|
"""
|
||||||
user_query_template_two="""请根据以下货物标中采购要求部分的内容,为\"{}\"生成技术参数(或采购要求)。由于该货物存在多种不同的采购要求或技术参数,请逐一列出,并以 JSON 格式返回结果。请以'货物名-编号'区分多种型号,编号为从 1 开始的自然数,依次递增,即第一个键名为\"{}-1\", 键值为一个列表,列表中包含若干描述\"{}\"的技术参数(或采购要求)的字符串,需与原文完全一致,即若技术参数前存在序号也要保留,但不可擅自增添或删减。
|
user_query_template_two="""请根据货物标中采购要求部分的内容,告诉我\"{}\"的技术参数或采购要求是什么。由于该货物存在多种不同的采购要求或技术参数,请逐一列出,并以 JSON 格式返回结果。请以'货物名-编号'区分多种型号,编号为从 1 开始的自然数,依次递增,即第一个键名为\"{}-1\", 键值为一个列表,列表中包含若干描述\"{}\"的技术参数(或采购要求)的字符串,需与原文完全一致,即若技术参数前存在序号也要保留,但不可擅自增添或删减。
|
||||||
请注意以下特殊情况:
|
请注意以下特殊情况:
|
||||||
要求与指南:
|
要求与指南:
|
||||||
1. 如果该货物没有相关采购要求或技术参数要求,键值应为空列表。
|
1. 如果该货物没有相关采购要求或技术参数要求,键值应为空列表。
|
||||||
2. 如果存在嵌套结构,且原文为Markdown 的表格语法,如'摄像机|有效像素|≥900W像素', 请不要返回该Markdown语法,而是使用冒号':'将相关信息拼接在一起,生成一条完整且清晰的技术参数(或采购要求)描述,作为列表中的一个字符串。如"摄像机:有效像素:≥900W像素"。
|
2. 如果存在嵌套结构,且原文为Markdown 的表格语法,如'摄像机|有效像素|≥900W像素', 请不要返回该Markdown语法,而是使用冒号':'将相关信息拼接在一起,生成一条完整且清晰的技术参数(或采购要求)描述,作为列表中的一个字符串。如"摄像机:有效像素:≥900W像素"。
|
||||||
3. 字符串中的内容为具体的技术参数要求或采购要求,请不要返回诸如'(1)高清录像功能'这种标题性质且不能体现要求的内容。
|
3. 字符串中的内容为具体的技术参数要求或采购要求,请不要返回诸如'(1)高清录像功能'这种标题性质且不能体现要求的内容。
|
||||||
|
|
||||||
### 示例输出,参考1如下:
|
### 示例输出1如下:
|
||||||
{{
|
{{
|
||||||
"交换机-1": [
|
"交换机-1": [
|
||||||
"1、支持固化千兆电口≥8 个,固化千兆光口≥2 个,桌面型设备;",
|
"1、支持固化千兆电口≥8 个,固化千兆光口≥2 个,桌面型设备;",
|
||||||
@ -396,12 +397,12 @@ def get_technical_requirements(file_path,invalid_path):
|
|||||||
]
|
]
|
||||||
}}
|
}}
|
||||||
|
|
||||||
### 示例输出,参考2如下(包含嵌套结构):
|
### 示例输出2如下(包含嵌套结构):
|
||||||
{{
|
{{
|
||||||
"摄像机-1": [
|
"摄像机-1": [
|
||||||
"摄像机:有效像素:≥900W像素",
|
"摄像机:有效像素:≥900W像素",
|
||||||
"摄像机:最低照度:彩色≤0.001lx",
|
"摄像机:最低照度:彩色≤0.001lx",
|
||||||
"协议:API 接口开放:具备;支持标准 ONVIF 协议与第三方厂家设备进行互联;支持 GB/T28181;应提供 SDK"
|
"协议:routes 接口开放:具备;支持标准 ONVIF 协议与第三方厂家设备进行互联;支持 GB/T28181;应提供 SDK"
|
||||||
],
|
],
|
||||||
"摄像机-2": [
|
"摄像机-2": [
|
||||||
"支持夜视", "支持云存储"
|
"支持夜视", "支持云存储"
|
||||||
@ -431,6 +432,7 @@ def get_technical_requirements(file_path,invalid_path):
|
|||||||
# 打印结果
|
# 打印结果
|
||||||
for question, response in results:
|
for question, response in results:
|
||||||
technical_requirements.append(response)
|
technical_requirements.append(response)
|
||||||
|
# print(response)
|
||||||
technical_requirements_combined_res = combine_json_results(technical_requirements)
|
technical_requirements_combined_res = combine_json_results(technical_requirements)
|
||||||
|
|
||||||
"""根据所有键是否已添加处理技术要求"""
|
"""根据所有键是否已添加处理技术要求"""
|
||||||
@ -440,7 +442,7 @@ def get_technical_requirements(file_path,invalid_path):
|
|||||||
# final_res = postprocess(cleaned_res)
|
# final_res = postprocess(cleaned_res)
|
||||||
ffinal_res["货物列表"] = good_list
|
ffinal_res["货物列表"] = good_list
|
||||||
# 输出最终的 JSON 字符串
|
# 输出最终的 JSON 字符串
|
||||||
return {"采购需求": ffinal_res}
|
return {"采购需求":ffinal_res}
|
||||||
|
|
||||||
def test_all_files_in_folder(input_folder, output_folder):
|
def test_all_files_in_folder(input_folder, output_folder):
|
||||||
# 确保输出文件夹存在
|
# 确保输出文件夹存在
|
||||||
|
@ -111,11 +111,19 @@ def postprocess(data):
|
|||||||
# 递归处理顶层数据
|
# 递归处理顶层数据
|
||||||
return {key: convert_dict(val) if isinstance(val, dict) else val for key, val in data.items()}
|
return {key: convert_dict(val) if isinstance(val, dict) else val for key, val in data.items()}
|
||||||
|
|
||||||
|
|
||||||
def all_postprocess(data):
|
def all_postprocess(data):
|
||||||
temp=restructure_data(data)
|
temp = restructure_data(data)
|
||||||
processed_data = {}
|
|
||||||
for key, value_list in temp.items():
|
def recursive_process(item):
|
||||||
processed_data[key] = remove_common_prefixes(value_list)
|
if isinstance(item, dict):
|
||||||
|
return {k: recursive_process(v) for k, v in item.items()}
|
||||||
|
elif isinstance(item, list):
|
||||||
|
return remove_common_prefixes(item)
|
||||||
|
else:
|
||||||
|
return item
|
||||||
|
|
||||||
|
processed_data = recursive_process(temp)
|
||||||
return processed_data
|
return processed_data
|
||||||
def detect_depth(data):
|
def detect_depth(data):
|
||||||
"""
|
"""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user