/** * 将 v6.1.2.8 的 run_context.json 转换成图结构 */ function convertV8ToGraph(runContext) { const nodes = {}; const edges = []; const iterations = {}; const o = runContext.o || '原始问题'; const rounds = runContext.rounds || []; // 添加原始问题根节点 const rootId = 'root_o'; nodes[rootId] = { type: 'root', query: o, level: 0, relevance_score: 1.0, strategy: '原始问题', iteration: 0, is_terminated: false, no_suggestion_rounds: 0, evaluation_reason: '用户输入的原始问题', is_selected: true }; iterations[0] = [rootId]; // 处理每一轮 rounds.forEach((round, roundIndex) => { if (round.type === 'initialization') { // 初始化阶段:处理 seg_list const roundNum = 0; if (!iterations[roundNum]) iterations[roundNum] = []; round.seg_list.forEach((seg, segIndex) => { const segId = `seg_${seg.text}_${roundNum}`; nodes[segId] = { type: 'seg', query: seg.text, level: 1, relevance_score: seg.score || 0, strategy: '初始分词', iteration: roundNum, is_terminated: false, evaluation_reason: '分词专家分词结果', is_selected: true, parent_query: o }; // 添加边:root -> seg edges.push({ from: rootId, to: segId, edge_type: 'root_to_seg', strategy: '初始分词' }); iterations[roundNum].push(segId); }); // 将 seg 作为第一轮的 q round.q_list_1.forEach((q, qIndex) => { const qId = `q_${q.text}_r1`; const segId = `seg_${q.text}_0`; nodes[qId] = { type: 'q', query: q.text, level: 1, relevance_score: q.score || 0, strategy: '来自分词', iteration: 1, is_terminated: false, evaluation_reason: '初始Query', is_selected: true, parent_query: q.text, from_source: 'seg' }; // 添加边:seg -> q if (nodes[segId]) { edges.push({ from: segId, to: qId, edge_type: 'seg_to_q', strategy: '作为Query' }); } if (!iterations[1]) iterations[1] = []; iterations[1].push(qId); }); } else { // 普通轮次 const roundNum = round.round_num; const nextRoundNum = roundNum + 1; if (!iterations[nextRoundNum]) iterations[nextRoundNum] = []; // 添加本轮的操作步骤节点 const stepNodes = []; // 获取第一个输入Query作为所有操作节点的连接点(代表本轮输入) // 注意:需要从已创建的节点中查找,因为节点ID可能带有index后缀 let firstInputQId = null; if (round.input_q_list && round.input_q_list.length > 0) { const firstInputQ = round.input_q_list[0]; // 尝试查找匹配的节点(考虑可能有index后缀) firstInputQId = Object.keys(nodes).find(id => { const node = nodes[id]; return node.type === 'q' && node.query === firstInputQ.text && node.iteration === roundNum; }); } // 步骤1:请求sug操作节点 if (round.sug_count > 0) { const requestSugId = `operation_request_sug_r${roundNum}`; nodes[requestSugId] = { type: 'operation', query: `步骤1: 请求建议词 (${round.sug_count}个)`, level: roundNum, relevance_score: 0, strategy: '请求建议词', iteration: roundNum, operation_type: 'request_sug', detail: `为${round.input_q_list?.length || 0}个Query请求建议词,获得${round.sug_count}个建议`, is_selected: true }; stepNodes.push(requestSugId); // 平级连接:从第一个输入Query连接 if (firstInputQId && nodes[firstInputQId]) { edges.push({ from: firstInputQId, to: requestSugId, edge_type: 'q_to_operation', strategy: '请求建议词' }); } } // 步骤2:评估sug操作节点 if (round.sug_count > 0) { const evaluateSugId = `operation_evaluate_sug_r${roundNum}`; nodes[evaluateSugId] = { type: 'operation', query: `步骤2: 评估建议词 (高分:${round.high_score_sug_count})`, level: roundNum, relevance_score: 0, strategy: '评估建议词', iteration: roundNum, operation_type: 'evaluate_sug', detail: `评估${round.sug_count}个建议词,${round.high_score_sug_count}个达到阈值`, is_selected: true }; stepNodes.push(evaluateSugId); // 平级连接:从第一个输入Query连接 if (firstInputQId && nodes[firstInputQId]) { edges.push({ from: firstInputQId, to: evaluateSugId, edge_type: 'q_to_operation', strategy: '评估建议词' }); } } // 步骤3:执行搜索操作节点 if (round.search_count > 0) { const searchOpId = `operation_search_r${roundNum}`; nodes[searchOpId] = { type: 'operation', query: `步骤3: 执行搜索 (${round.search_count}次)`, level: roundNum, relevance_score: 0, strategy: '执行搜索', iteration: roundNum, operation_type: 'search', search_count: round.search_count, total_posts: round.total_posts, detail: `搜索${round.search_count}个高分建议词,找到${round.total_posts}个帖子`, is_selected: true }; stepNodes.push(searchOpId); // 平级连接:从第一个输入Query连接 if (firstInputQId && nodes[firstInputQId]) { edges.push({ from: firstInputQId, to: searchOpId, edge_type: 'q_to_operation', strategy: '执行搜索' }); } } // 步骤4:加词操作节点 const addWordCount = round.output_q_list?.filter(q => q.from === 'add').length || 0; if (addWordCount > 0) { const addWordId = `operation_add_word_r${roundNum}`; nodes[addWordId] = { type: 'operation', query: `步骤4: 智能加词 (${addWordCount}个)`, level: roundNum, relevance_score: 0, strategy: '智能加词', iteration: roundNum, operation_type: 'add_word', detail: `为Seed选择词并组合,生成${addWordCount}个新Query`, is_selected: true }; stepNodes.push(addWordId); // 平级连接:从第一个输入Query连接 if (firstInputQId && nodes[firstInputQId]) { edges.push({ from: firstInputQId, to: addWordId, edge_type: 'q_to_operation', strategy: '智能加词' }); } } // 步骤5:筛选高分sug操作节点 const sugCount = round.output_q_list?.filter(q => q.from === 'sug').length || 0; if (sugCount > 0) { const filterSugId = `operation_filter_sug_r${roundNum}`; nodes[filterSugId] = { type: 'operation', query: `步骤5: 筛选高分sug (${sugCount}个)`, level: roundNum, relevance_score: 0, strategy: '筛选高分sug', iteration: roundNum, operation_type: 'filter_sug', detail: `筛选出${sugCount}个分数高于来源Query的建议词`, is_selected: true }; stepNodes.push(filterSugId); // 平级连接:从第一个输入Query连接 if (firstInputQId && nodes[firstInputQId]) { edges.push({ from: firstInputQId, to: filterSugId, edge_type: 'q_to_operation', strategy: '筛选高分sug' }); } } // 将操作节点添加到当前轮次 stepNodes.forEach(nodeId => { if (!iterations[roundNum]) iterations[roundNum] = []; iterations[roundNum].push(nodeId); }); // 处理输出的 q_list if (round.output_q_list) { round.output_q_list.forEach((q, qIndex) => { const qId = `q_${q.text}_r${nextRoundNum}_${qIndex}`; nodes[qId] = { type: 'q', query: q.text, level: nextRoundNum, relevance_score: q.score || 0, strategy: q.from === 'add' ? '加词生成' : q.from === 'sug' ? '建议词' : '未知', iteration: nextRoundNum, is_terminated: false, evaluation_reason: `来源: ${q.from}`, is_selected: true, from_source: q.from }; // 连接到对应的操作节点 if (q.from === 'add') { // 加词生成的Query连接到加词操作节点 const addWordId = `operation_add_word_r${roundNum}`; if (nodes[addWordId]) { edges.push({ from: addWordId, to: qId, edge_type: 'operation_to_q', strategy: '加词生成' }); } } else if (q.from === 'sug') { // sug生成的Query连接到筛选sug操作节点 const filterSugId = `operation_filter_sug_r${roundNum}`; if (nodes[filterSugId]) { edges.push({ from: filterSugId, to: qId, edge_type: 'operation_to_q', strategy: '建议词生成' }); } } iterations[nextRoundNum].push(qId); }); } } }); return { nodes, edges, iterations }; } module.exports = { convertV8ToGraph };