12.4
This commit is contained in:
parent
2119f9879d
commit
dc65210f70
@ -215,7 +215,7 @@ def qianwen_long_stream(file_id, user_query, max_retries = 2, backoff_factor = 1
|
||||
else:
|
||||
print(f"查询 '{user_query}' 的所有 {max_retries + 1} 次尝试均失败(429 错误)。")
|
||||
elif error_code == 400 and error_code_string in ['data_inspection_failed', 'ResponseTimeout',
|
||||
'DataInspectionFailed', 'response_timeout']:
|
||||
'DataInspectionFailed', 'response_timeout','RequestTimeOut','request_timeout']:
|
||||
if attempt == 1: # 只重试一次
|
||||
print(f"错误代码为 400 - {error_code_string},将立即重试...")
|
||||
continue # 直接跳到下一次循环(即重试一次)
|
||||
@ -223,7 +223,7 @@ def qianwen_long_stream(file_id, user_query, max_retries = 2, backoff_factor = 1
|
||||
print(f"查询 '{user_query}' 的所有 {max_retries + 1} 次尝试均失败(400 - {error_code_string})。")
|
||||
else:
|
||||
# 对于非 429 和非特定 400 错误,不进行重试,直接抛出异常
|
||||
print(f"遇到非 429 或非 'data_inspection_failed' 的 400 错误(错误代码:{error_code}),不进行重试。")
|
||||
print(f"遇到非 429 或非 'data_inspection_failed...' 的 400 错误(错误代码:{error_code}),不进行重试。")
|
||||
|
||||
# 如果所有尝试都失败了,返回空字符串
|
||||
return ""
|
||||
@ -259,6 +259,8 @@ def qianwen_long_text(file_id, user_query):
|
||||
|
||||
# Return the response content
|
||||
return completion.choices[0].message.content
|
||||
|
||||
#TODO:若采购需求和评分那块响应超时比较多,考虑都改为流式
|
||||
if __name__ == "__main__":
|
||||
# Example file path - replace with your actual file path
|
||||
|
||||
|
@ -1,59 +1,341 @@
|
||||
import json
|
||||
|
||||
from flask_app.货物标.技术参数要求提取后处理函数 import extract_matching_keys
|
||||
|
||||
def extract_matching_keys(data, good_list, special_keys=None, parent_key=''):
|
||||
import re
|
||||
from collections import defaultdict
|
||||
|
||||
def get_suffix(n):
|
||||
"""
|
||||
根据数字n返回对应的字母后缀。
|
||||
1 -> 'a', 2 -> 'b', ..., 26 -> 'z', 27 -> 'aa', 28 -> 'ab', ...
|
||||
"""
|
||||
suffix = ''
|
||||
while n > 0:
|
||||
n, r = divmod(n - 1, 26)
|
||||
suffix = chr(97 + r) + suffix
|
||||
return suffix
|
||||
|
||||
def count_matching_keys(data, patterns, special_keys, counter=None):
|
||||
"""递归统计匹配键的出现次数,仅统计值为列表的键"""
|
||||
if counter is None:
|
||||
counter = defaultdict(int)
|
||||
|
||||
if isinstance(data, dict):
|
||||
for key, value in data.items():
|
||||
clean_key = key.replace(" ", "") # 去除键中的空格
|
||||
if isinstance(value, list):
|
||||
if clean_key not in special_keys and any(pattern.match(clean_key) for pattern in patterns):
|
||||
counter[clean_key] += 1
|
||||
elif isinstance(value, dict):
|
||||
count_matching_keys(value, patterns, special_keys, counter)
|
||||
elif isinstance(data, list):
|
||||
for item in data:
|
||||
if isinstance(item, (dict, list)):
|
||||
count_matching_keys(item, patterns, special_keys, counter)
|
||||
|
||||
return counter
|
||||
|
||||
def process_data(data, patterns, special_keys, key_counter, suffix_map, filtered_data, parent_key):
|
||||
"""递归处理数据并构建结果"""
|
||||
|
||||
def get_suffix_label(key):
|
||||
suffix_map[key] += 1
|
||||
return get_suffix(suffix_map[key])
|
||||
|
||||
if isinstance(data, dict):
|
||||
for key, value in data.items():
|
||||
clean_key = key.replace(" ", "") # 去除键中的空格
|
||||
if isinstance(value, list):
|
||||
# 处理值为列表的键
|
||||
if any(pattern.match(clean_key) for pattern in patterns):
|
||||
# 检查是否以特殊符号开头
|
||||
if clean_key.startswith(('▲', '★','●','■','◆','☆','△','◇','○','□')):
|
||||
symbol = clean_key[0]
|
||||
stripped_key = clean_key[1:]
|
||||
new_key = generate_key(stripped_key, parent_key, key_counter, suffix_map, special_keys)
|
||||
# 将符号添加到每个字符串的开头
|
||||
new_value = [symbol + item for item in value]
|
||||
filtered_data[new_key] = new_value
|
||||
else:
|
||||
new_key = generate_key(clean_key, parent_key, key_counter, suffix_map, special_keys)
|
||||
filtered_data[new_key] = value
|
||||
elif isinstance(value, dict):
|
||||
# 继续递归处理嵌套字典
|
||||
new_parent_key = clean_key if parent_key == '' else f"{parent_key}的{clean_key}"
|
||||
process_data(value, patterns, special_keys, key_counter, suffix_map,
|
||||
filtered_data, new_parent_key)
|
||||
elif isinstance(data, list):
|
||||
for item in data:
|
||||
if isinstance(item, (dict, list)):
|
||||
process_data(item, patterns, special_keys, key_counter, suffix_map,
|
||||
filtered_data, parent_key)
|
||||
|
||||
def generate_key(key, parent_key, key_counter, suffix_map, special_keys):
|
||||
"""生成新的键名"""
|
||||
if key in special_keys and parent_key:
|
||||
return f"{parent_key}的{key}"
|
||||
elif key_counter[key] > 1:
|
||||
suffix = get_suffix(suffix_map[key] + 1)
|
||||
suffix_map[key] += 1
|
||||
return f"{key}-{suffix}"
|
||||
return key
|
||||
|
||||
if special_keys is None:
|
||||
special_keys = ["系统功能"] # 默认值为 ["系统功能"]
|
||||
|
||||
# 去除 good_list 中的空格
|
||||
clean_good_list = [g.replace(" ", "") for g in good_list]
|
||||
|
||||
# 构建匹配的正则表达式
|
||||
patterns = [re.compile(r'^' + re.escape(g) + r'(?:-\d+)?$') for g in clean_good_list]
|
||||
|
||||
# 先统计所有匹配键的出现次数,仅统计值为列表的键
|
||||
key_counter = count_matching_keys(data, patterns, special_keys)
|
||||
|
||||
# 初始化后缀映射
|
||||
suffix_map = {key: 0 for key, count in key_counter.items() if count > 1}
|
||||
|
||||
# 用于存储最终结果
|
||||
filtered_data = {}
|
||||
|
||||
# 递归处理数据
|
||||
process_data(data, patterns, special_keys, key_counter, suffix_map, filtered_data, parent_key)
|
||||
|
||||
return filtered_data
|
||||
|
||||
def test_extract_matching_keys():
|
||||
# 定义测试数据
|
||||
data = {
|
||||
"fruits": ["apple", "banana"],
|
||||
"fruits-1": ["orange"],
|
||||
"vegetables": ["carrot"],
|
||||
"系统功能": ["feature1"], # 特殊键,应被特殊处理或排除
|
||||
"grains": {
|
||||
"whole": ["rice", "wheat"],
|
||||
"whole-1": ["barley"],
|
||||
"refined": ["white rice"]
|
||||
"采购需求": {
|
||||
"显示系统": {
|
||||
"系统功能":["1","2"],
|
||||
"★LED全彩显示屏": [
|
||||
"1、显示尺寸:6m±0.3(W)× 1.5m±0.2(H),单屏分辨率≥3744 × 1040;",
|
||||
"2 、像素间距≤1.53mm;",
|
||||
"3 、亮度≥450nits, 色温: 3000-15000K 可调, 对比度: 5000:1;",
|
||||
"4 、峰值功耗≤440W, 平均功耗≤146W, 带有智能(黑屏) 节电功 能, 开启智能节电功能比没开启节能 40%以上;",
|
||||
"5 、水平可视角度≥160 ° , 垂直可视角度≥140 ° ;",
|
||||
"6 、亮度均匀性≥97%, 刷新率≥3840 Hz , 发光点中心距偏差<3%;",
|
||||
"7 、色域覆盖率≥100%, 低亮高灰: 100%亮度时, 16 bits 灰度,20% 亮度时, 12bits 灰度;",
|
||||
"8 、铝底壳材质, 无风扇散热结构;",
|
||||
"9 、模组电源接口采用4P 接插头, 免工具维护, 同时有防呆设计, 预防接错电源线短路而导致的烧毁模组行为,采用集成 HUB 接收卡 控制, 支持通讯状态监控;",
|
||||
"10 、冗余备份, 支持双电网供电, 当其中一路交流电网跳闸后, 另 外一路电网继续供电, 实现不间断供电, 支持热备份, 当其中一块 电源失效后, 另一块电源继续工作, 从而实现不间断供电;",
|
||||
"11 、屏体发光模组采用 4.5 VDC 的安全电压供电;",
|
||||
"12 、彩色信号处理位数≥16bit;",
|
||||
"13 、具备故障自诊及排查功能;",
|
||||
"14 、 图像有降噪 、增强 、运动补偿 、色坐标变换处理 、钝 化处理无 几何失真和线性失真现象 、消除鬼影拖尾, 无“毛毛虫 ”“鬼影 ” 跟随现象;",
|
||||
"15 、防护等级符合 IP6X, 显示屏具有防潮 、防尘 、防腐蚀 、防电磁 干扰 、防静电等功能, 并具有过流、短路 、过压 、欠压保护等功能;",
|
||||
"16 、工作噪音声压等级一米处≤7.8 dB (A),盐雾符合 10 级要求, PCB 阻燃等级达到 UL 94 V-0 级要求, 通过 9 级烈度地震模拟实验。"
|
||||
],
|
||||
"☆钢结构底座及铝型材支架": [
|
||||
"1 、主体钢架结构及定制型材;",
|
||||
"2 、确保楼层承受力许可,按需加固楼层地面;",
|
||||
"3 、钢结构。"
|
||||
],
|
||||
"电缆及信号线缆": [
|
||||
"1 、配套所需控制网线 、高清视频线缆 、 电源线缆等适配。"
|
||||
],
|
||||
"控制终端": [
|
||||
"1 、处理器: 八核心 16 线程;",
|
||||
"2 、显卡: 8G/DDR6/PCI Express 4.0 16X;",
|
||||
"3 、 内存: ≥8G DDR4 内存;",
|
||||
"4 、硬盘: SSD 固态硬盘(容量≥480G);",
|
||||
"5 、接口: 音频/网络/HDMI 接口/9 针串口;",
|
||||
"6 、显示器: 21.5 英寸。"
|
||||
]
|
||||
},
|
||||
"misc": {
|
||||
"fruits": ["strawberry"],
|
||||
"fruits-1": ["blueberry"],
|
||||
"系统 功能": ["feature2"], # 特殊键,带空格
|
||||
"dairy": ["milk", "cheese"]
|
||||
"摄像系统": {
|
||||
"系统功能": ["a", "b"],
|
||||
"★高清摄像机": [
|
||||
"1 、成像器件: 1/2.8 Exmor CMOS;",
|
||||
"2 、镜头: 30 倍光学(f=4.3mm to 129mm );",
|
||||
"3 、水平视角: 63.7 ° ;",
|
||||
"4、视频输出格式:1080P/60,1 080P/50,1080P/30,1080P/25,1080i/60, 720p/60;",
|
||||
"5 、视频输出: 3G-SDI, HDMI, CVBS,IP (可同步输出 );",
|
||||
"6 、真双输出: IP 和 SDI 视频格式可以独立设置;",
|
||||
"7 、控制方式: RS232 / RS422 / RS485, IP/Onvif/Visca-over-IP, IP 控制软件, 红外遥控器;",
|
||||
"8 、IP 最高 1080p60, 支持 H.264/H.265/MJPEG;",
|
||||
"9 、支持 Tally 灯;",
|
||||
"10 、支持独立 PoE+(IEEE 802.3 at) 和 DC 12V 电源;",
|
||||
"11 、扩展存储: Micro SD,最高支持 128GB。"
|
||||
],
|
||||
"摄像机三脚架": [
|
||||
"1 、铝合金材质, 承重 2-10Kg;",
|
||||
"2 、满足高清摄像机承重 、尺寸要求。"
|
||||
]
|
||||
},
|
||||
"beverages": {
|
||||
"alcoholic": {
|
||||
"beer": ["lager", "ale"],
|
||||
"wine": ["red", "white"]
|
||||
},
|
||||
"non-alcoholic": ["juice", "soda"]
|
||||
"视频处理系统": {
|
||||
"★高清视频拼控矩阵(16*16)": [
|
||||
"1 、8U 切换主箱体, 支持输入 13 槽, 输出 4.5 槽, 支持 8 路高分采集, 支持冗余电源, 标配 1 个电源模块; 本项目配置输入接 口 16 路和 1 张字幕卡, 输出接口 16 路;",
|
||||
"2 、设备应为纯硬件 FPGA 架构, CrossPoint 全总线交换技术, 背板 等效带宽;",
|
||||
"3 、单张板卡支持 4 通道输入或输出, 紧凑型机箱,模拟视频单板卡 支持 16 路同时输入, 单卡支持 2 种信号源任意组合;",
|
||||
"4、输入输出板卡可热插拔,输入板卡热插拔恢复时间 <2s,输出板 卡热插拔恢复时间<8s;",
|
||||
"5 、开机时间≤10s, 启动电源至输出最总画面的时间间隔;",
|
||||
"6 、平均故障时间间隔 ( MTBF ) 不小于 96000 小时, 保证设备能够 稳定运行;",
|
||||
"7 、最大单机背板信号处理带宽不小于 720Gbps;",
|
||||
"8、对各个输入通道采用纯硬件处理技术,采用独享带宽方式为每个 输入通道分配带宽, 切换过程中对其他信号无影响, 实现了对输入 通道的实时处理;",
|
||||
"9、支持集中采集 DVI、VGA、CVBS、HDBaseT、HDMI、SDI、YPbPr 、 光纤等 2K 信号,Dual-link DVI、HDMI 1.4、DisplayPort 等 4K 信号;",
|
||||
"10 、支持 DVI 、HDBaseT 、HDMI 、SDI 、光纤 、CVBS 、Ypbp r 等常见的 2K 信号输出, Dual-link DVI 、HDMI 1.4 等 4K 信号输出;",
|
||||
"11、设备可实现任意一路画面的任意比例缩放、漫游、 跨屏 、叠加、 开窗;",
|
||||
"12 、设备支持图像无缝实时切换功能, 无缝切换时间<20 ms ;",
|
||||
"13 、支持场景保存及快速调用, 支持场景轮巡, 适应于不同的应用 场景;",
|
||||
"14 、支持信号源预监功能, 支持浏览所有输入信号源的实时预览画 面;",
|
||||
"15 、支持大屏图像回显, 可显示整面拼接墙的显示图像;",
|
||||
"16 、支持设置拼接屏的拼缝补偿, 可精确到 1 个像素;",
|
||||
"17 、支持 RRTA 分辨率实时全兼容技术, 单台 设备应支持同时控制 4 组不同分辨率的大屏幕显示;",
|
||||
"18 、设备具备静态底图功能, 设备支持超大分辨率底图显示, 横纵 分辨率最大 65535 像素。"
|
||||
],
|
||||
"分量信号接口器": [
|
||||
"用于现有视频会议专业对接高清矩阵接口器"
|
||||
],
|
||||
"高清四画面分割器": [
|
||||
"画面预览使用, 具有画中画 、独立单画面放大功能。"
|
||||
]
|
||||
},
|
||||
"snacks": [
|
||||
{
|
||||
"chips": ["potato", "tortilla"],
|
||||
"nuts": ["almonds", "cashews"]
|
||||
},
|
||||
{
|
||||
"chips-1": ["kettle", "baked"],
|
||||
"candies": ["chocolate", "gummy"]
|
||||
}
|
||||
]
|
||||
"发言系统": {
|
||||
"数字会议发言主机": [
|
||||
"1 、标准挂载单元数量: 4 路总线接口, 单路可连接 32 个 , 最多系统可挂载 128 个会议单元, 且最远线路长度可高达 100 米;",
|
||||
"2、主机面板彩屏显示系统菜单,通过设置可设 定 1/2/4/6 发言数量;",
|
||||
"3 、支持先入先出模式, 后入后出模式, 限制模式, 电脑/主席允许 模式, 自由讨论模式;",
|
||||
"4 、可直接控制最多三个摄像球, 完成视频会议功能;",
|
||||
"5、多种输入输出接口主输入、卡座输入和前置输出、辅助输出及录音输出接口;",
|
||||
"6 、带有 RS 232 视频控制输出 口, 可以直接输出派尔高-P, 派尔高 -D, VISCA 控制协议, 控制最大 3 个摄像机, 完成摄像自动跟踪;",
|
||||
"7 、 内置 4 切 1 视频切换器, 用于摄像机的视频 接连;",
|
||||
"8 、可以响应处理话筒的会议中服务的请求;",
|
||||
"9 、 内置签到表决功能, 可以配合话筒进行签到表决;",
|
||||
"10 、 内置 DSP 自适应音频处理器,可以最大可能的抑制声回输。"
|
||||
],
|
||||
"方形短杆代表话筒": [
|
||||
"1 、超大静音开关设计;",
|
||||
"2 、会议操作系统,全新的触摸操控技术, 2.8 英寸的彩色触摸屏幕;",
|
||||
"3 、超短全金属短咪杆设计;",
|
||||
"4 、高灵敏度咪芯设计,拾音距离≥80 cm ;",
|
||||
"5 、红色雾面指示灯设计, 指示发言状态;",
|
||||
"6 、支持视像跟踪;",
|
||||
"7、配合主机, 可以实现先入先出,后入后出, 限制模式,主席允许模式, 自由讨论模式;",
|
||||
"8、话筒的身份可以自行设定,可以通过主机设置改变话筒身份,在 代表, 主席, VIP 自由切换, 让使用更灵活多样, 满足 高端需求;",
|
||||
"9 、长距离传输对音质不会有影响; 具备超强的抗手机 RF 干扰性。"
|
||||
],
|
||||
"专用连接线缆": [
|
||||
"主机与话筒专用连接线缆, 长度≥30m。"
|
||||
],
|
||||
"手持无线话筒": [
|
||||
"1 、含一台接收机, 两个无线手持话筒发射器;",
|
||||
"2 、频率响应: 50Hz-18KHz;",
|
||||
"3 、有效使用距离≥100 米;",
|
||||
"4 、信噪比≥105dB(1KHz-A);",
|
||||
"5 、灵敏度: -105dBm(12dB S/N AD)。"
|
||||
]
|
||||
},
|
||||
"视频会议系统": {
|
||||
"▲多点控制器": [
|
||||
"1 、遵循 H.323 、H.320 、SIP 标准协议;",
|
||||
"2 、支持 H.265, H.264 HP, H.264 编解码标准。",
|
||||
"3 、支持不低于 25 分屏高清多画面;",
|
||||
"4 、最大线路速率: 8M;",
|
||||
"5、视频抗丢包能力:支持高至 60%丢包率情况下 , 图像流畅无马赛克;音频抗 IP 网络丢包能力:支持高至 75%丢包 率情况下,声音清晰流畅; 会议抗 IP 网络丢包能力:支持高至 70%丢包率情况下,会 议仍可正常召开。 以上 5 项参数需提供第三方检测机构检验 报告。"
|
||||
],
|
||||
"★多串口控制服务器": [
|
||||
"1 、具有高速数据处理能力, 内嵌高速嵌入式 CPU ;",
|
||||
"2 、提供 16 路一控多 、多控一;",
|
||||
"3 、具有多种转发机制, 支持 IP 、串口间双向转发机制;",
|
||||
"4、控制会议矩阵、会议摄像机外围设备串口设备,实现对会议系统设备的控制;"
|
||||
],
|
||||
"★综合会议管理调度平台": [
|
||||
"1、含硬件终端和视频会议专用软件,用于控制会议、矩阵、会议摄像机,实现与省厅 、 随州市综合会议管理调度平台对接 、融合, 互联互通;",
|
||||
"2 、统一调度管理平台, 根据业务需要, 可互为控制 、互为 备份;",
|
||||
"3、可以与原有的主控平台互为操作、实现控制备份,保证会议正常召开, 需在设计方案中详细阐明如何实现;",
|
||||
"4、实现对会议设备的整合控制,采用一键拖拉式操作,软件界面友好 、操作管理简易 、直观;",
|
||||
"5 、可在综合会议管理平台实现四画面预览各分会场及中心视频信 号;",
|
||||
"6 、提供软件著作权证书。"
|
||||
],
|
||||
"65寸电视机移动推车(9楼)": [
|
||||
"1 、全钢结构, 满足 70 寸电视承重安装要求;",
|
||||
"2 、承载: 200Kg;",
|
||||
"3 、轮子带自锁刹车功能。"
|
||||
],
|
||||
"65寸液晶电视机(分会场)": [
|
||||
"1 、屏幕尺寸: 65 英寸; 含挂架及安装;",
|
||||
"2 、背光类型: LED;",
|
||||
"3 、屏幕分辨率: 超高清 4K (3840 ×2 160);",
|
||||
"4 、支持 HDR 显示;",
|
||||
"5 、CPU: Cortex A55 四核;",
|
||||
"6 、接口: USB2.0 ×2 、HDMI2.0 ×2;",
|
||||
"7 、 网络连接方式: 无线/网线。"
|
||||
],
|
||||
"控制平板及软件": [
|
||||
"10.2 寸无线触摸屏, 含控制软件, 实现远程一键式控制 、视频会议调度。"
|
||||
],
|
||||
"鹅颈话筒": [
|
||||
"1 、采样率: 48kHz;",
|
||||
"2 、频响: 20Hz – 20kHz;",
|
||||
"3 、灵敏度: 38 ±2dB;",
|
||||
"4 、拾音距离: 20-50CM;含接头 、线缆, 线缆 长度≥3.5m;",
|
||||
"5 、支持终端远程供电, 无需外接电源。"
|
||||
]
|
||||
},
|
||||
"辅助系统": {
|
||||
"时序电源": [
|
||||
"1、具有 12 路 1KW 电源;",
|
||||
"2、具有电压表指示, 支持串口控制;",
|
||||
"3、采用触点闭合控制功能;",
|
||||
"4、具有过压 、过流保护。"
|
||||
],
|
||||
"多媒体地插盒": [
|
||||
"1 、具有至少 1 路 HDMI 、 1 路电源 、2 路网络接口模块;",
|
||||
"2 、采用优质接插件。"
|
||||
],
|
||||
"线材辅料": [
|
||||
"采用专用线材 、材料 、接口 、各种辅料等。"
|
||||
],
|
||||
"墙体拆除及修复": [
|
||||
"对大屏安装区域墙体 、天花进行拆除及修复。"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
good_list = ["fruits", "vegetables", "grains", "chips"]
|
||||
}
|
||||
good_list = [
|
||||
"★LED全彩显示屏",
|
||||
"控制盒及电源",
|
||||
"大屏播控系统",
|
||||
"配电柜(含PLC)",
|
||||
"☆钢结构底座及铝型材支架",
|
||||
"电缆及信号线缆",
|
||||
"控制终端",
|
||||
"50寸液晶电视机",
|
||||
"50寸电视机地面推车",
|
||||
"高清监视器",
|
||||
"★高清摄像机",
|
||||
"摄像机三脚架",
|
||||
"摄像机壁装架",
|
||||
"摄像机控制键盘",
|
||||
"★高清视频拼控矩阵(16*16)",
|
||||
"分量信号接口器",
|
||||
"高清四画面分割器",
|
||||
"数字会议发言主机",
|
||||
"方形短杆代表话筒",
|
||||
"专用连接线缆",
|
||||
"手持无线话筒",
|
||||
"▲多点控制器",
|
||||
"★多串口控制服务器",
|
||||
"★综合会议管理调度平台",
|
||||
"★高清会议终端(主会场)",
|
||||
"★高清会议终端(分会场)",
|
||||
"65寸电视机移动推车(9楼)",
|
||||
"65寸液晶电视机(分会场)",
|
||||
"控制平板及软件",
|
||||
"鹅颈话筒",
|
||||
"时序电源",
|
||||
"多媒体地插盒",
|
||||
"线材辅料",
|
||||
"墙体拆除及修复",
|
||||
"系统功能"
|
||||
]
|
||||
|
||||
special_keys = ["系统功能", "dairy"] # 假设 'dairy' 也是特殊键
|
||||
|
||||
# 预期输出
|
||||
expected_output = {
|
||||
"fruits-a": ["apple", "banana"],
|
||||
"fruits-b": ["orange"],
|
||||
"vegetables": ["carrot"],
|
||||
"grains-a": ["rice", "wheat"],
|
||||
"grains-b": ["barley"],
|
||||
"grains": {"refined": ["white rice"]},
|
||||
"misc": {}, # 'fruits' and 'fruits-1' inside 'misc' should be processed
|
||||
"chips-a": ["potato", "tortilla"],
|
||||
"chips-b": ["kettle", "baked"]
|
||||
}
|
||||
|
||||
# 注意:根据您的函数逻辑,特殊键会被排除,且嵌套的 'fruits' 会被处理
|
||||
# 这里我们需要根据函数实际行为调整预期输出
|
||||
@ -65,27 +347,14 @@ def test_extract_matching_keys():
|
||||
# 'dairy' 是特殊键,应被排除
|
||||
# '系统功能' 和 '系统 功能' 是特殊键,应被排除
|
||||
|
||||
expected_output_correct = {
|
||||
"fruits-a": ["apple", "banana"],
|
||||
"fruits-b": ["orange"],
|
||||
"vegetables": ["carrot"],
|
||||
"grains-a": ["rice", "wheat"],
|
||||
"grains-b": ["barley"],
|
||||
"chips-a": ["potato", "tortilla"],
|
||||
"chips-b": ["kettle", "baked"]
|
||||
}
|
||||
|
||||
# 运行函数
|
||||
result = extract_matching_keys(data, good_list, special_keys)
|
||||
|
||||
# 打印结果
|
||||
print("测试用例: 提取匹配键并处理各种情况")
|
||||
print("输入数据:", data)
|
||||
print("good_list:", good_list)
|
||||
print("special_keys:", special_keys)
|
||||
print("\n预期输出:", expected_output_correct)
|
||||
print("实际输出:", result)
|
||||
print("\n测试通过:", result == expected_output_correct)
|
||||
print("实际输出:", json.dumps(result,ensure_ascii=False,indent=4))
|
||||
|
||||
# 运行测试
|
||||
if __name__ == "__main__":
|
||||
|
@ -285,70 +285,14 @@ def combine_and_update_results(original_data, updates):
|
||||
|
||||
return original_data
|
||||
|
||||
#文件内容以markdown格式组织,其中表格部分(若有)以html语法组织,
|
||||
def get_technical_requirements(file_path,invalid_path,processed_filepath):
|
||||
# docx_file_path=pdf2docx(file_path)
|
||||
file_id=upload_file(file_path) #目前传入的为docx文档
|
||||
first_query_template="该文件是否说明了采购需求,即需要采购哪些货物?如果有,请回答'是',否则,回答'否'" #防止截取失败
|
||||
judge_res=qianwen_long(file_id,first_query_template)
|
||||
prompt_template1 = '''
|
||||
任务:解析采购文件,提取采购需求,并以JSON格式返回。
|
||||
|
||||
要求与指南:
|
||||
1. 精准定位:请运用文档理解能力,找到文件中的采购需求部分,若有采购清单,请直接根据采购清单上的货物(或系统)名称给出结果;若未出现采购清单,则从表格或文字中摘取采购信息
|
||||
2. 采购目标:采购种类通常有硬件(如设备、货物)和软件(如系统软件、应用APP),一次采购活动可以同时包含这两种类型。
|
||||
3. 系统归属:一些采购活动可能将采购目标划分为若干系统和货物,每个系统可能包含若干货物,则将这些货物名称作为该系统的二级键;系统可以只包含总体'系统功能'而无货物。
|
||||
4. 软件需求:对于软件应用或系统软件需求,仅需列出系统模块构成(若有),并作为系统键值的一部分,无需在模块下再细分功能。
|
||||
5. 系统功能:若采购的某系统提及总体系统功能,则在系统值中添加'系统功能'二级键,不展开具体内容。
|
||||
6. 完整性:确保不遗漏系统内的货物,也不添加未提及的内容,若采购清单之外有额外的货物采购要求,且该货物暂未提取至JSON回答中,请将这些货物名称也包含进来。
|
||||
|
||||
输出格式:
|
||||
1.JSON格式,最外层键名为'采购需求'。
|
||||
2.层次关系用嵌套键值对表示。
|
||||
3.嵌套键名为系统或货物或模块名称,与原文保持一致。
|
||||
4.最内层键值应为空列表[]。
|
||||
5.不包含'说明'、'规格'、'技术参数'等列内容,仅返回采购的货物或系统或模块名称。
|
||||
|
||||
特殊情况处理:
|
||||
同一层级(如同一系统中)下同名但采购要求不同的货物,以'货物名-编号'区分,编号从1递增。例如若同层级下存在两种型号的交换机,那么命名分别是'交换机-1'和'交换机-2',以规避重复键名;否则无需在名称后添加编号。
|
||||
|
||||
{{
|
||||
"采购需求": {{
|
||||
"交换机-1": [],
|
||||
"交换机-2": [],
|
||||
"门禁管理系统": {{
|
||||
"系统功能":[]
|
||||
}},
|
||||
"交通监控视频子系统": {{
|
||||
"系统功能": [],
|
||||
"高清视频抓拍像机": [],
|
||||
"补光灯": []
|
||||
}},
|
||||
"LED全彩显示屏": []
|
||||
// 其他系统和货物
|
||||
}}
|
||||
}}
|
||||
示例输出2,系统软件采购:
|
||||
{{
|
||||
"采购需求": {{
|
||||
"信息管理系统": {{
|
||||
"通用模块":[],
|
||||
"用户管理":[]
|
||||
}},
|
||||
"信息检索系统": {{
|
||||
"系统功能":[],
|
||||
"权限管理模块":[]
|
||||
}},
|
||||
"XX小程序":[],
|
||||
"数据分析中心":[]
|
||||
}}
|
||||
}}
|
||||
|
||||
注意事项:
|
||||
1.严格按照上述要求执行,确保输出准确性和规范性。
|
||||
2.如有任何疑问或不确定内容,请保留原文描述,必要时使用'未知'标注。
|
||||
'''
|
||||
prompt_template2 = '''
|
||||
def generate_prompt(judge_res, full_text=None):
|
||||
"""
|
||||
获取需要采购的货物名称
|
||||
根据 `judge_res` 和 `full_text` 动态生成 prompt。
|
||||
如果 `judge_res` 包含 '否',则不添加文件内容部分。
|
||||
如果 `judge_res` 不包含 '否' 且有 `full_text`,则添加文件内容部分。
|
||||
"""
|
||||
base_prompt = '''
|
||||
任务:你负责解析采购文件,提取采购需求,并以JSON格式返回,不要遗漏该项目需要采购的货物(或系统)。
|
||||
|
||||
要求与指南:
|
||||
@ -360,7 +304,8 @@ def get_technical_requirements(file_path,invalid_path,processed_filepath):
|
||||
6. 完整性:确保不遗漏系统内的货物,也不添加未提及的内容。若'采购清单'中未提取的货物(或系统)名称在形如'主要设备功能指标'的标题下有详细参数指标要求,请将该货物名也添加至返回中。
|
||||
|
||||
特殊情况:
|
||||
若采购的货物或系统或模块名称前存在三角▲、五角★,注意是名称前而非具体的技术参数或采购要求前,在返回名称时请保留前面的▲或★符号,如'★高清摄像机'。
|
||||
1.若采购的货物或系统或模块名称前存在三角▲,△、五角★,☆,注意是名称前而非具体的技术参数或采购要求前,在返回名称时请保留前面的▲,△或★,☆符号,如'★高清摄像机'。
|
||||
2.若同一层级(如同一系统中)下存在同名但采购要求不同的货物,请以'货物名-编号'区分,编号从1递增,例如若同层级下存在两种型号的交换机,那么命名分别是'交换机-1'和'交换机-2',以规避重复键名;否则无需在名称后添加编号。
|
||||
|
||||
输出格式:
|
||||
1.JSON格式,最外层键名为'采购需求'。
|
||||
@ -368,9 +313,6 @@ def get_technical_requirements(file_path,invalid_path,processed_filepath):
|
||||
3.嵌套键名为系统或货物或模块名称,与原文保持一致。
|
||||
4.最内层键值应为空列表[]。
|
||||
|
||||
特殊情况处理:
|
||||
若同一层级(如同一系统中)下存在同名但采购要求不同的货物,请以'货物名-编号'区分,编号从1递增,例如若同层级下存在两种型号的交换机,那么命名分别是'交换机-1'和'交换机-2',以规避重复键名;否则无需在名称后添加编号。
|
||||
|
||||
示例输出1,普通系统、货物类采购:
|
||||
{{
|
||||
"采购需求": {{
|
||||
@ -404,23 +346,31 @@ def get_technical_requirements(file_path,invalid_path,processed_filepath):
|
||||
//其他系统
|
||||
}}
|
||||
}}
|
||||
|
||||
文件内容:{full_text}
|
||||
|
||||
注意事项:
|
||||
1.严格按照上述要求执行,确保输出准确性和规范性。
|
||||
'''
|
||||
if '否' not in judge_res and full_text:
|
||||
# 添加文件内容部分
|
||||
base_prompt += f"\n文件内容:\n{full_text}\n"
|
||||
base_prompt += "\n注意事项:\n1.严格按照上述要求执行,确保输出准确性和规范性。\n"
|
||||
return base_prompt
|
||||
|
||||
#文件内容以markdown格式组织,其中表格部分(若有)以html语法组织,
|
||||
def get_technical_requirements(file_path,invalid_path,processed_filepath):
|
||||
# docx_file_path=pdf2docx(file_path)
|
||||
file_id=upload_file(file_path) #目前传入的为docx文档
|
||||
first_query_template="该文件是否说明了采购需求,即需要采购哪些货物?如果有,请回答'是',否则,回答'否'" #防止截取失败
|
||||
judge_res=qianwen_long(file_id,first_query_template)
|
||||
if '否' in judge_res:
|
||||
print("no!调用invalid_path")
|
||||
file_id=upload_file(invalid_path)
|
||||
model_res=qianwen_long(file_id,prompt_template1)
|
||||
user_query = generate_prompt(judge_res)
|
||||
model_res=qianwen_long(file_id,user_query)
|
||||
print(model_res)
|
||||
else:
|
||||
# processed_filepath = convert_pdf_to_markdown(file_path) # 转markdown格式
|
||||
# processed_filepath=r"C:\Users\Administrator\Desktop\货物标\extract_files\107国道.txt"
|
||||
user_query=generate_full_user_query(processed_filepath,prompt_template2)
|
||||
full_text = read_txt_to_string(processed_filepath)
|
||||
user_query=generate_prompt(judge_res,full_text)
|
||||
model_res=doubao_model(user_query)
|
||||
# model_res = qianwen_long(file_id,prompt_template1)
|
||||
print(model_res)
|
||||
cleaned_res = clean_json_string(model_res) #转字典
|
||||
processed_data=truncate_system_keys(cleaned_res['采购需求'])
|
||||
@ -523,7 +473,6 @@ def get_technical_requirements(file_path,invalid_path,processed_filepath):
|
||||
# 更新原始采购需求字典
|
||||
final_res=combine_and_update_results(modified_data, technical_requirements_combined_res)
|
||||
ffinal_res=all_postprocess(final_res)
|
||||
# final_res = postprocess(cleaned_res)
|
||||
ffinal_res["货物列表"] = good_list
|
||||
# 输出最终的 JSON 字符串
|
||||
return {"采购需求":ffinal_res}
|
||||
|
Loading…
x
Reference in New Issue
Block a user