新增同义词词典支持,优化IntentRecognition类以加载jieba自定义词典和同义词字典,调整关键词提取流程,简化日志记录,更新PromptTemplates以规范同义词处理规则。

This commit is contained in:
2025-07-31 09:23:27 +08:00
parent 728262cc65
commit 6a72233a97
3 changed files with 297 additions and 63 deletions
+237
View File
@@ -0,0 +1,237 @@
主材价格
设备价格
单条设置
储能预规
砂子
中砂
造价2016
机械进出场费
√标记
建安
Q/GDW11338-2014
Q/GDW 11338-2023
未能成功匹配的数据
2013年版导则
非标准清单
连接
表七
场地征用费表
预规2018版
单个基础用量
主材的规格型号
挖方量
GT7-23
消材暂估价
招标代理费计算
534号文
标底
最高投标限价
招标控制价
控制价
2014线路清单专业
技经指标
初步设计清单库
施工图设计清单库
灌注桩直径
电力清单2021规范
电力清单16版
OPPC
修订批注
删除修改记录
修订记录
取消工程密码
调整依据
材料
机械
整套系统调试
消材
辅材
计价材料
电力建设工程常用设备材料价格信息
承包人报价浮动率
报价浮动率
国网电定34号文
国网14规范
国网2014规范
QGDW 11337-2014
国网23规范
国网2023规范
QGDW 11337-2023 输变电工程工程量清单计价规范
表头属性
DL/T 5745-2021
DL/T 5745-2016
合价小数位数
清单规范使用指南
主网预算第四册
2018版定额使用指南
人材机结算价调整系数设置
总承包服务费
装材费
主材费
未计价材料费
查询
显示零费用项目
显示零工程量清单
显示零消耗量
显示空特征值
配网预规
财资【2022】136号文
【2023】9号文
20kv及以下配网工程
配网工程
空项目划分输出
可研估算
初步设计概算
检修预规
电力设备检修工程
设备检修工程
编码顺序显示
迁改工程_其他费用导则
技改工程
程序启动失败
清标软件
青海清标软件2017
自动更新
注释名称
标注名称
用户定义组合件
物料清册
标准物资模板
定额[2023]26号文
软件崩溃
商品混凝土价差调整
封面
签字审批
编制说明
表二乙
表三甲
表三乙
配电网工程预算编制与计算规定
供货单位
文件夹路径
预规2022版
一批工程录入
2022年版配网定额
表五
表三取费明细
重置模板
恢复默认取费表
恢复初始
输出文件格式
批量设置行高
南网规约接口
价款调整
软件操作手册
表三工程量合并排序
增加索道级数
Excel价格库
Excel库
市场价系数调整
红色三角号标记
编码重复
首页
主页
西藏预规2023版
选择报表
降低层级按钮
商品砼
商混
小数位数设置
数量精度设置
工程量精度设置窗口
工程量小数位数设置
取消密码
查看取费过程
表二甲
表四
其他费用明细
总费用表
表一
人工材料机械
人工/材料/机械
工程量转换系数
贷款利率
年度贷款比例
金额显示单位
报表单位
上级消耗量
补充人材机资源
加密锁
回存资源按钮
保存资源
调整计算式
计算式编辑器
加减乘除
费用项四则运算
新增子级
添加子项费用
162号文
编制期价差
价差
人材机价差
云账户
报表编辑
计价依据
造价文件编制基准规范
一笔性清单费用
一次性费用
独立费用
包干费用
工程量录入界面
建筑工程界面
安装工程界面
添加定额
添加主材
添加设备
含税价格
含税
不含税价格
除税价
设置颜色标记
增值税率
导出版
补充主材
计算基数
费用基数
物料单重
批量查询物料信息价
1980号文
人工展放
人工展放引绳
技术经济参数
地方信息价
通用设计
复用清单
刷新组价
TBS
挖孔桩基础
掏挖基础
组件参数库
自定义组件库
构件库
工程税金
运输距离
工地运输距离
输电线路工程
反查资源
红色三角形标志
红色三角号标记
充盈量
工程项目限价
清单控制价
投标限价
装材
主材
未计价材料
招标人采购
甲方供应
业主供应
乙方供应
投标人采购
刷新清单顺序码
技改预规
取费模板
其他费用模版
工程费用模版
Excel物料表
+53 -42
View File
@@ -80,8 +80,49 @@ class AsyncIntentRecognizer:
# 加载软件词条名称库
self._soft_wiki_library = self._load_soft_wiki_library()
# 异步检索器将在create方法中初始化
self._noun_retriever = None
# self._noun_retriever = None
# 初始化jieba自定义词典
self._init_jieba_dict()
self._synonymous_dict=self._init_synonymous_dict()
def _init_jieba_dict(self):
"""初始化jieba自定义词典"""
try:
current_dir = os.path.dirname(os.path.abspath(__file__))
dict_path = os.path.join(current_dir, "..", "..", "data", "nouns", "all_synonymous_jieba.txt")
# 检查字典文件是否存在
if os.path.exists(dict_path):
jieba.load_userdict(dict_path)
logging.info("成功加载jieba自定义词典")
else:
logging.warning(f"自定义词典文件不存在: {dict_path}")
except Exception as e:
logging.error(f"加载jieba自定义词典失败: {e}")
def _init_synonymous_dict(self):
"""加载同义词,key是同义词 val:是对应名词"""
try:
current_dir = os.path.dirname(os.path.abspath(__file__))
dict_path = os.path.join(current_dir, "..", "..", "data", "nouns", "merged_nouns.json")
# 检查字典文件是否存在
synonymous_dict={}
if os.path.exists(dict_path):
with open(dict_path, "r", encoding="utf-8") as f:
data = json.load(f)
for cur_data in data:
synonymous=cur_data["synonymous"]
name=cur_data["name"]
for cur_synonymous in synonymous:
synonymous_dict[cur_synonymous]=name
else:
logging.warning(f"名词库文件不存在: {dict_path}")
return synonymous_dict
except Exception as e:
logging.error(f"加载名词库文件失败: {e}")
return {}
def _load_soft_wiki_library(self):
"""
加载软件wiki库
@@ -105,7 +146,7 @@ class AsyncIntentRecognizer:
"""
instance = cls()
# 异步初始化名词检索器
instance._noun_retriever = await AsyncProfessionalNounRetriever.create()
# instance._noun_retriever = await AsyncProfessionalNounRetriever.create()
return instance
def _load_suffix_keywords(self, filepath: str = None) -> List[str]:
@@ -277,7 +318,7 @@ class AsyncIntentRecognizer:
"""
start_time = time.time()
query_keys=[]
# 步骤1: 使用LLM提取查询中的关键词
# 步骤1: 提取查询中的关键词
try:
llm_start_time = time.time()
extracted_terms = await self._extract_keywords_async(query, use_jieba)
@@ -289,44 +330,14 @@ class AsyncIntentRecognizer:
raise RuntimeError(f"异步LLM关键词提取失败: {e}") from e
matched_terms = [] # 存储匹配到的Term对象
# 步骤2: 使用向量检索找到相似的专业名词
try:
vector_start_time = time.time()
# 创建并行任务列表
async def process_single_keyword(current_key: str) -> List[Term]:
"""处理单个关键词的向量检索和重排序"""
vector_results = await self._noun_retriever.query_async(current_key, top_k=5, use_intersection=False)
current_key_terms = set()
# 添加向量检索结果
for result in vector_results:
if isinstance(result.get('synonymous', []), str):
result['synonymous'] = result['synonymous'].split(';')
term = Term(
name=result.get('name'),
synonymous=result.get('synonymous', []),
description=result.get('description', '')
)
current_key_terms.add(term)
if len(current_key_terms) > 0:
reranked_terms = await self._rerank_matched_terms_async(current_key, current_key_terms)
return reranked_terms
return []
# 并行处理所有关键词
keyword_tasks = [process_single_keyword(current_key) for current_key in query_keys]
keyword_results = await asyncio.gather(*keyword_tasks)
# 合并所有结果
for result in keyword_results:
if len(result) > 0:
matched_terms.extend(result)
vector_end_time = time.time()
vector_time = vector_end_time - vector_start_time
except Exception as e:
raise RuntimeError(f"异步向量检索关键词时出错: {e}") from e
# 查找同义词
for cur_key in query_keys:
if cur_key not in self._synonymous_dict:
continue
name = self._synonymous_dict[cur_key]
matched_terms.append(Term(name=name,synonymous=[cur_key],description=""))
# 提取所有Term对象的名称并排序
# 将set类型的matched_terms转换为TermList类型
term_list = TermList(terms=list(matched_terms))
@@ -334,7 +345,7 @@ class AsyncIntentRecognizer:
total_time = end_time - start_time
# 输出整合的时间日志
logging.info(f"异步关键词匹配耗时统计 - 总耗时: {total_time:.2f}, 问题关键词提取: {llm_time:.2f}秒, 向量检索+重排序: {vector_time:.2f}")
logging.info(f"异步关键词匹配耗时统计 - 总耗时: {total_time:.2f}")
return term_list, query_keys
+7 -21
View File
@@ -172,29 +172,22 @@ query_rewrite_prompt = """
query_rewrite_prompt_pro="""
# 电力造价问答优化工程师(精简版)
# 问答优化工程师
**角色**:基于历史对话和术语库重构问题,提升知识库检索准确率。
**最高准则**
1、保持问题核心意图,但允许在指代消除、背景继承下添加隐含功能词。
2. 所有新增内容必须源于历史对话或聊天背景,禁止捏造。
3. 归一化替换需严格全词匹配:查询中的词必须与术语库同义词完全一致(不区分大小写)。部分匹配(如子字符串)或不匹配,保留原词
禁止部分匹配或子字符串替换。仅当提问中的词 **完全等于** 术语库同义词(大小写不敏感)时方可替换,否则保留原词。
- 错误示例:`文件` ≠ `文件夹路径`(因`文件`是`文件夹路径`的子字符串,禁止替换)。
3. 归一化替换需严格全词匹配:查询中的词必须与术语库同义词完全一致(不区分大小写)。部分匹配(如子字符串)或不匹配,保留原词
## 核心原则
1. **指代消除 → 当指示代词(""/"")出现时,强制继承历史对话的最新核心主题(如功能或任务),并应用到当前主体。**
2. 背景继承 → 补充历史对话和聊天背景中的隐含信息(包括主题和功能)。
3. 术语规范 → 归一化标准词并【】标记。提问中出现的同义词(synonymous)替换为标准词(name)
3. 术语规范 → 提问中出现的同义词(synonymous)替换为标准词(name)并【】标记
4. 语义保真 → 保持问题核心意图,但允许在指代消除、背景继承下添加隐含功能词。
## 归一化替换规则
1. 必须严格全词匹配同义词(即synonymous全词出现在query中)
“错误示例:
- query:文件 !=> 文件夹路径(‘文件’不全等于‘文件夹路径’,部分匹配不替换)。
- query:费率查询 !=> 精准查询(‘费率查询’不全等于‘关键词查询’,不替换)。
**仅当全词匹配时替换**:如query:直接费率(全词匹配‘直接费率’)==> 固定费率。”
2. 只有当问题中的词与术语库中某一项的同义词列表中的某个词完全相同时,才替换为对应的标准词
1. 只有当问题中的词与术语库中某一项的同义词列表中的某个词完全相同时,才替换为对应的标准词
## 处理流程
@@ -211,11 +204,6 @@ query_rewrite_prompt_pro="""
<history>
{chat_history}
</history>
- 当前聊天背景:
<conversation_background>
{context}
</conversation_background>
### 二、重构决策树
```mermaid
@@ -227,7 +215,7 @@ graph TD
E --> F[执行重构]
D -- 否 --> F
F --> G[补充缺失背景]
G --> H[同义词替换+【】标记]
G --> H[同义词替换]
H --> I[保留原生专业术语]
B -- 否 --> I
```
@@ -235,9 +223,8 @@ graph TD
### 三、重构优先级
1. **指代消除 → 当指示代词出现时,优先继承历史对话的核心主题(如功能词),并替换当前问题的动词部分。**
2. 背景继承 → 历史对话中确定的背景信息需要保留。
3. 术语处理 → 同义词转标准词 + 【】标记
4. 同义词转标准词 → 将提问中出现的同义词(synonymous)替换为对应标准词(name)
5. 结构优化 → 保持原问题的5W2H特征,指代消除、背景继承下允许微调意图。
3. 同义词转标准词 → 将提问中出现的同义词(synonymous)替换为对应标准词(name) 并使用【】标记
4. 结构优化 → 保持原问题的5W2H特征,指代消除、背景继承下允许微调意图。
## 输出规范
{output_format}
@@ -246,7 +233,6 @@ graph TD
- [] **主题是否合理继承?**(当有代词时,历史主题必须注入)
- [] 核心诉求是否保留?
- [] 背景信息是否合理补充?
- [] 术语标记是否完整【】?
- [] 语句是否自然流畅?
- [] 避免补充无关信息
"""