import { useState } from "react"; import type { Dataset } from "@/pages/DataManagement/dataset.model"; import { Steps, Card, Select, Input, Checkbox, Button, Badge, Divider, Radio, Form, message, } from "antd"; import { Eye, Trash2, Settings, ArrowLeft, ArrowRight, Play, Edit, Copy, Save, RefreshCw, ChevronDown, ChevronRight, Search, CheckCircle, Code, X, MoreHorizontal, Activity, MessageSquare, Brain, } from "lucide-react"; import { Link, useNavigate } from "react-router"; import DevelopmentInProgress from "@/components/DevelopmentInProgress"; const { TextArea } = Input; export default function SynthesisTaskCreate() { return ; const navigate = useNavigate(); const [form] = Form.useForm(); const [searchQuery, setSearchQuery] = useState(""); const [createStep, setCreateStep] = useState(1); const [selectedFiles, setSelectedFiles] = useState([]); const [datasets] = useState([]); const [files] = useState([]); const [selectedSynthesisTypes, setSelectedSynthesisTypes] = useState< string[] >(["qa_judge"]); const [showDebugCard, setShowDebugCard] = useState(false); const [debugStepId, setDebugStepId] = useState(null); const [expandedTypes, setExpandedTypes] = useState([ "qa", "distillation", ]); // 表单数据 const [formValues, setFormValues] = useState({ name: "", sourceDataset: "", targetCount: 1000, description: "", executionMode: "immediate", scheduleStrategy: "", outputPath: "", enableQualityCheck: false, enableNotification: false, }); const synthesisTypes = [ { id: "qa", name: "生成问答对", icon: MessageSquare, count: 14, expanded: true, description: "基于文本生成各类问答对", children: [ { id: "qa_judge", name: "文字生成问答对_判断题", count: 1, description: "生成判断题形式的问答对", }, { id: "qa_choice", name: "文字生成问答对_选择题", count: 0, description: "生成多选题形式的问答对", }, { id: "qa_fill", name: "文字生成问答对_填空题", count: 0, description: "生成填空题形式的问答对", }, { id: "qa_short", name: "相关文本描述问答对_金融领域", count: 0, description: "金融领域的专业问答对", }, ], }, { id: "distillation", name: "生成蒸馏", icon: Brain, count: 6, expanded: true, description: "知识蒸馏数据生成", children: [ { id: "dist_text", name: "相关文本生成蒸馏", count: 0, description: "基于文本的知识蒸馏", }, { id: "dist_qa", name: "问答数据", count: 0, description: "问答形式的蒸馏数据", }, { id: "dist_instruct", name: "相关指令生成蒸馏问题_few-shot", count: 0, description: "Few-shot指令蒸馏", }, { id: "dist_summary", name: "问答数据为基础蒸馏", count: 0, description: "基于问答数据的蒸馏", }, { id: "dist_reasoning", name: "问答数据为基础高质量", count: 0, description: "高质量推理数据蒸馏", }, ], }, ]; const toggleTypeExpansion = (typeId: string) => { setExpandedTypes((prev) => prev.includes(typeId) ? prev.filter((id) => id !== typeId) : [...prev, typeId] ); }; const handleSynthesisTypeSelect = (typeId: string) => { setSelectedSynthesisTypes((prev) => { if (prev.includes(typeId)) { return prev.filter((id) => id !== typeId); } else { return [...prev, typeId]; } }); }; const handleValuesChange = (_, allValues) => { setFormValues({ ...formValues, ...allValues }); }; const handleSelectAllFiles = () => { const filteredFiles = files.filter((file) => file.name.toLowerCase().includes(searchQuery.toLowerCase()) ); if (selectedFiles.length === filteredFiles.length) { setSelectedFiles([]); } else { setSelectedFiles(filteredFiles.map((file) => file.id)); } }; const handleRemoveSelectedFile = (fileId: string) => { setSelectedFiles(selectedFiles.filter((id) => id !== fileId)); }; const handleCreateTask = async () => { try { const values = await form.validateFields(); if ( !values.name || !values.sourceDataset || selectedFiles.length === 0 || selectedSynthesisTypes.length === 0 || !values.outputPath || !values.targetCount || (values.executionMode === "scheduled" && !values.scheduleStrategy) ) { message.error("请填写所有必填项"); return; } const newTask: SynthesisTask = { id: Date.now(), name: values.name, type: selectedSynthesisTypes[0].includes("qa") ? "qa" : "distillation", status: values.executionMode === "immediate" ? "pending" : "paused", progress: 0, sourceDataset: values.sourceDataset, targetCount: values.targetCount, generatedCount: 0, createdAt: new Date().toISOString().split("T")[0], template: "自动生成模板", estimatedTime: "预计 30 分钟", }; setTasks([newTask, ...tasks]); setShowCreateTask(false); setCreateStep(1); // Reset form form.resetFields(); setSelectedFiles([]); // Auto-start simulation if immediate execution if (values.executionMode === "immediate") { setTimeout(() => { setTasks((prev) => prev.map((task) => task.id === newTask.id ? { ...task, status: "running" } : task ) ); const interval = setInterval(() => { setTasks((prev) => prev.map((task) => { if (task.id === newTask.id && task.status === "running") { const newProgress = Math.min( task.progress + Math.random() * 8 + 2, 100 ); const isCompleted = newProgress >= 100; return { ...task, progress: newProgress, generatedCount: Math.floor( (newProgress / 100) * task.targetCount ), status: isCompleted ? "completed" : "running", estimatedTime: isCompleted ? "已完成" : `剩余 ${Math.ceil((100 - newProgress) / 10)} 分钟`, }; } return task; }) ); }, 1000); setTimeout(() => clearInterval(interval), 12000); }, 1000); } } catch { // 校验失败 } }; const renderCreateTaskPage = () => { if (createStep === 1) { return ( 基本信息 ({ label: ( {dataset.name} {dataset.type} • {dataset.total}条 • {dataset.size} ), value: dataset.id, }))} /> {form.getFieldValue("sourceDataset") && ( 选择文件 {/* 文件选择区域 */} setSearchQuery(e.target.value)} /> {selectedFiles.length === files.filter((file) => file.name .toLowerCase() .includes(searchQuery.toLowerCase()) ).length ? "取消全选" : "全选"} {files .filter((file) => file.name .toLowerCase() .includes(searchQuery.toLowerCase()) ) .map((file) => ( { if (e.target.checked) { setSelectedFiles([ ...selectedFiles, file.id, ]); } else { setSelectedFiles( selectedFiles.filter( (id) => id !== file.id ) ); } }} /> {file.name} {file.size} • {file.type} ))} {/* 已选文件列表 */} 已选文件 {selectedFiles.length === 0 ? ( 暂未选择文件 ) : ( selectedFiles.map((fileId) => { const file = files.find((f) => f.id === fileId); if (!file) return null; return ( {file.name} {file.size} • {file.type} handleRemoveSelectedFile(fileId)} className="p-1 h-6 w-6 hover:bg-blue-100" > ); }) )} )} 任务配置 {form.getFieldValue("executionMode") === "scheduled" && ( )} 指定合成结果的存储位置,支持本地路径和云存储路径 启用质量检查(对合成结果进行自动质量评估) 发送完成通知(任务完成后发送邮件或消息通知) navigate("/data/synthesis/task")}> 取消 { form .validateFields() .then(() => setCreateStep(2)) .catch(() => {}); }} disabled={ !form.getFieldValue("name") || !form.getFieldValue("sourceDataset") || selectedFiles.length === 0 || !form.getFieldValue("targetCount") } > 下一步 ); } if (createStep === 2) { return ( {/* 左侧合成指令 */} 合成指令 {synthesisTypes.map((type) => { return ( toggleTypeExpansion(type.id)} > {expandedTypes.includes(type.id) ? ( ) : ( )} {type.name}({type.count}) {expandedTypes.includes(type.id) && ( {type.children.map((child) => ( handleSynthesisTypeSelect(child.id) } > handleSynthesisTypeSelect(child.id) } /> {child.name} ({child.count}) ))} )} ); })} {/* 右侧合成编排 */} 合成步骤编排({selectedSynthesisTypes.length}) 选择合成模板 启用调测 {/* 开始节点 */} 开 开始 {/* 合成步骤 */} {selectedSynthesisTypes.map((typeId, index) => { const typeInfo = synthesisTypes .flatMap((t) => t.children) .find((c) => c.id === typeId); if (!typeInfo) return null; return ( {index + 1} {typeInfo.name} 该任务为从用户提供的参考文本中抽取出一个判断题,同时输出正确答案。 模型 配置参数 { setDebugStepId(typeId); setShowDebugCard(true); }} > 配置参数 指令 该任务为从用户提供的参考文本中抽取出一个判断题,同时输出正确答案。 输入变量 text 参考文本 输出变量 answer 回答 question 问题 ); })} {/* 结束节点 */} 结 结束 setCreateStep(1)} className="px-4 py-2 text-sm" type="default" > 上一步 创建任务 {/* Debug Card */} {showDebugCard && debugStepId && ( 流程调测 -{" "} { synthesisTypes .flatMap((t) => t.children) .find((c) => c.id === debugStepId)?.name } { setShowDebugCard(false); setDebugStepId(null); }} className="hover:bg-white" > {/* Left Panel - Configuration */} 参数配置 模型选择 Temperature 0.0-2.0 Max Tokens Top P 0.0-1.0 Frequency Penalty -2.0-2.0 Presence Penalty -2.0-2.0 指令模板 系统指令 用户指令模板 输入变量 text 输出变量 question answer explanation {/* Right Panel - Testing */} 调测验证 测试输入 开始调测 重置 调测输出 判断题: 人工智能是计算机科学的一个分支。 答案: 对 解释: 根据文本内容,人工智能确实是计算机科学的一个分支,这是文本中明确提到的信息。 响应时间 1.2秒 Token消耗 156 tokens 成功率 100% 质量评分 95分 批量测试 测试样本数量 开始批量测试 批量测试结果 成功样本: 9/10 平均质量: 92分 平均耗时: 1.4秒 总消耗: 1,420 tokens 保存配置 { setShowDebugCard(false); setDebugStepId(null); }} className="text-sm" > 取消 应用配置 )} ); } }; return ( {/* Header */} 创建合成任务 {renderCreateTaskPage()} ); }
{file.name}
{file.size} • {file.type}
指定合成结果的存储位置,支持本地路径和云存储路径