| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321 |
- /**
- * 将 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 };
|