Files
沃巴蒂 ff22ed3a8b feat(deepdata): 引入修改密码、文件预览组件与清洗算子增强,deepflow 改名为 deep-flow
本次同步 09-12 至 09-28 的代码变更,主要内容:

新增功能
- 修改密码:后端新增 ChangePasswordRequest DTO 与UserController/UserService
  对应接口,前端新增 ChangePasswordDialog 并在 Header 接入入口
- 文件预览组件重构:file-preview 目录拆分出 VideoPreview(支持 blobUrl 直传)、
  ImagePreview、AudioPreview,index.tsx 统一调度各类型预览器
- 新增 my_ops 算子模块:markitdown_parser、mineru_pdf_parser、text_quality_evaluator
- 新增 tools/minio-file-server MinIO 文件服务

功能增强
- 数据清洗:cleaning_task_service/scheduler/routes 重构,
  data_juicer_executor 与 wrapper 增强,OperatorTable/LogsTable/TaskDetail 同步调整
- 数据标注:annotation sync.py、project.py 接口与schema 更新
- 数据采集、算子市场、首页与菜单路由相关页面调整
- DataJuicer 算子接入(useOperatorOperations、dj_ops_schema)

结构调整
- deepflow/ 更名为 deep-flow/(419 个文件重命名)
- 新增 helm 部署编排、GitHub Actions 之外的自建镜像构建脚本

未纳入本次提交
- scripts-backup/、runtime/python-executor-backup/、components_backup/(备份目录)
- *.backup*、__pycache__ 产物
- zh_core_web_sm-3.8.0-py3-none-any.whl(46MB 构建产物)
- DataX/(内嵌独立仓库,远程亦未收录其源码)
2026-10-03 22:44:56 +08:00

100 lines
4.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -- encoding: utf-8 --
"""
Description: 基于LLM通过用户设置维度和相应描述进行QA对评估
Create: 2023/11/7 9:26
"""
import json
import re
import time
from pathlib import Path
from typing import List, Dict, Any
from loguru import logger
from deepdata.core.base_op import LLM
class QAConditionEvaluator(LLM):
def __init__(self, *args, **kwargs):
super(QAConditionEvaluator, self).__init__(*args, **kwargs)
self.pattern = r'结果[::] ?[YN]'
self.template_path = Path(__file__).parent / "resources/template.txt"
self.examples_path = Path(__file__).parent / "resources/examples.json"
self.task_id = kwargs.get("taskId", "default_id")
self.dimensions = kwargs.get("dimension", [
{
"dimension": "回答是否有针对性",
"description": "回答应对问题中的所有疑问点提供正面、直接的回答,"
"不应引起疑惑。同时,答案不应有任何内容的遗漏,需构成一个完整的陈述。"
},
{
"dimension": "问题是否独立",
"description": "仅分析问题,问题的主体和客体都比较明确,即使有省略,也符合语言习惯。"
"在不需要补充其他信息的情况下不会引起疑惑。"
},
{
"dimension": "语法是否错误",
"description": "问题为疑问句,答案为陈述句; 不存在词语搭配不当的情况;连接词和标点符号不存在错用情况;"
"逻辑混乱的情况不存在;语法结构都正确且完整;"
}
])
self.llm = self.get_llm(*args, **kwargs)
self.prompts = self.build_llm_prompt(*args, **kwargs)
@staticmethod
def _process_examples(dimension_example: List) -> str:
if not dimension_example:
return "\n"
res = "\n以下是一些案例供你参考:"
for single_example in dimension_example:
res += (f"\n问题:{single_example['question']}"
f"\n回答:{single_example['answer']}"
f"\n分析思路:{single_example['evaluate']}"
f"\n结果:{single_example['result']}\n")
return res
def execute(self, sample: Dict[str, Any]) -> Dict[str, Any]:
start = time.time()
qas = json.loads(sample[self.text_key])
single_content_res = []
for qa in qas:
single_qa_res = []
for dimension, prompt in self.prompts.items():
local_result = self._llm_call_parse(qa, prompt, retry=2)
single_qa_res.append({"dimension": dimension, "result": local_result})
qa_response = {"qaId": qa["qaId"], "result": single_qa_res}
single_content_res.append(qa_response)
# 评估结果已保存到文件,标记任务完成
sample[self.text_key] = ""
self.save_sample(single_content_res, sample)
cost_time = time.time() - start
logger.info(f"task id: {self.task_id}, method: QAConditionEvaluator costs {cost_time:.6f} s")
return sample
def build_llm_prompt(self, *args, **kwargs) -> Dict:
templates = self.template_path.read_text(encoding="utf-8")
examples_dict = json.loads(self.examples_path.read_text(encoding="utf-8"))
prompts_dict = {}
for dimension in self.dimensions:
name, des = dimension["dimension"], dimension["description"]
dimension_example = self._process_examples(examples_dict.get(name))
dimension_prompt = templates.format(criterion=des, examples=dimension_example, question="{question}",
answer="{answer}")
prompts_dict[name] = dimension_prompt
return prompts_dict
def _llm_call_parse(self, data: Dict, prompt: str, retry: int = 2):
try:
for _ in range(retry):
response = self.llm(prompt.format(question=data["question"], answer=data["answer"]))
result = re.findall(self.pattern, response)
if result:
return "Y" in result[0]
except RuntimeError as e:
logger.error(f"method: QAConditionEvaluator execution error, cause by {e}")
return False