import React, { useState } from 'react'; import { Send, Upload, RotateCcw, Bookmark, History, Sparkles, BookOpen, Brain, GitCompare, ChevronDown, ChevronRight, MessageSquare, FileText, CheckCircle, AlertCircle, } from 'lucide-react'; import { useTheme } from '../contexts/ThemeContext'; import { PageType } from '../components/Sidebar'; type QAMode = 'single-round' | 'multi-round' | 'deep-search'; type CompareMode = 'compare-off' | 'compare-on'; type ViewMode = 'single' | 'compare'; interface Message { id: string; role: 'user' | 'assistant'; content: string; timestamp: Date; sources?: SourceItem[]; } interface SourceItem { title: string; type: string; snippet: string; } interface CompareResult { leftMode: QAMode; rightMode: QAMode; leftContent: string; rightContent: string; sources: { left: SourceItem[]; right: SourceItem[]; }; differences?: { consensus: string; differences: string; leftAdvantage: string; rightAdvantage: string; }; } const GeneralQA: React.FC<{ onNavigate: (page: PageType) => void }> = ({ onNavigate }) => { const { theme } = useTheme(); const isDark = theme === 'dark'; // 状态管理 const [viewMode, setViewMode] = useState('single'); const [qaMode, setQaMode] = useState('single-round'); const [compareLeftMode, setCompareLeftMode] = useState('single-round'); const [compareRightMode, setCompareRightMode] = useState('deep-search'); // 知识范围 const [knowledgeScope, setKnowledgeScope] = useState<'all' | 'specific-kb' | 'specific-domain'>('all'); // 回答偏好 const [answerStyle, setAnswerStyle] = useState<'concise' | 'detailed'>('detailed'); const [showSources, setShowSources] = useState(true); const [showProcess, setShowProcess] = useState(false); const [autoSummary, setAutoSummary] = useState(false); // 对比设置 const [compareLayout, setCompareLayout] = useState<'horizontal' | 'vertical'>('horizontal'); const [autoSummarizeDiff, setAutoSummarizeDiff] = useState(true); const [recommendBetter, setRecommendBetter] = useState(true); // 消息和结果 const [messages, setMessages] = useState([]); const [inputValue, setInputValue] = useState(''); const [isLoading, setIsLoading] = useState(false); const [compareResult, setCompareResult] = useState(null); // 检索过程展示 const [searchProcess, setSearchProcess] = useState({ currentMode: '单轮RAG', rounds: 1, hits: 5, queryRewrite: '', }); // 示例消息 const sampleMessages: Message[] = [ { id: '1', role: 'user', content: 'RAG技术的工作原理是什么?', timestamp: new Date(), }, { id: '2', role: 'assistant', content: 'RAG(检索增强生成)技术的工作原理主要包括以下几个步骤:\n\n1. **检索阶段**:系统首先将用户问题转换为查询向量,在知识库中进行相似度搜索,返回最相关的文档片段。\n\n2. **增强阶段**:将检索到的相关文档与原始问题组合,形成增强后的提示词上下文。\n\n3. **生成阶段**:将增强后的提示词发送给大语言模型,生成最终回答。\n\n这种方式可以有效解决LLM知识过时、幻觉等问题,提升回答的准确性和可信度。', timestamp: new Date(), sources: [ { title: 'RAG技术白皮书', type: 'PDF', snippet: 'RAG是一种结合检索和生成的技术架构...' }, { title: 'LLM应用实践', type: '文档', snippet: '检索增强生成可以有效提升回答质量...' }, ], }, ]; const handleSend = () => { if (!inputValue.trim()) return; setIsLoading(true); // 模拟发送消息 const userMessage: Message = { id: Date.now().toString(), role: 'user', content: inputValue, timestamp: new Date(), }; setMessages([...messages, userMessage]); setInputValue(''); // 模拟AI响应 setTimeout(() => { setMessages(prev => [...prev, ...sampleMessages]); setIsLoading(false); setSearchProcess({ currentMode: qaMode === 'single-round' ? '单轮RAG' : qaMode === 'multi-round' ? '多轮RAG' : '深度检索', rounds: qaMode === 'multi-round' ? 3 : 1, hits: 5, queryRewrite: qaMode === 'deep-search' ? '原问题→分解子问题→独立检索→综合回答' : '', }); }, 1500); }; const handleCompare = () => { if (!inputValue.trim()) return; setIsLoading(true); // 模拟对比结果 setTimeout(() => { setCompareResult({ leftMode: compareLeftMode, rightMode: compareRightMode, leftContent: '单轮RAG回答:直接检索并生成答案,响应速度快,但可能遗漏跨文档的关联信息。适用于简单事实查询。', rightContent: '深度检索回答:通过问题分解、多轮检索和综合分析,提供更全面的答案。包含详细的推理过程和更多的引用来源。', sources: { left: [ { title: 'RAG基础教程', type: '文档', snippet: '单轮RAG是最基础的检索增强方式...' }, ], right: [ { title: '高级RAG技术', type: '论文', snippet: '深度检索通过query改写和迭代优化...' }, { title: 'RAG最佳实践', type: '指南', snippet: '多阶段检索可以显著提升召回率...' }, ], }, differences: { consensus: '两种方式都使用向量检索技术,都能引用原始文档', differences: '深度检索采用多轮查询改写,覆盖更全面', leftAdvantage: '响应更快,资源消耗更低', rightAdvantage: '答案更完整,引用更充分', }, }); setIsLoading(false); }, 2000); }; const handleSaveRecord = () => { alert('问答记录已保存'); }; const handleCollect = () => { alert('已添加到收藏'); }; const handleKeyDown = (e: React.KeyboardEvent) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); if (viewMode === 'compare') { handleCompare(); } else { handleSend(); } } }; // 获取模式标签 const getModeLabel = (mode: QAMode) => { switch (mode) { case 'single-round': return '单轮RAG'; case 'multi-round': return '多轮RAG'; case 'deep-search': return '深度检索'; } }; return (
{/* 顶部模式栏 */}

通用问答

支持单轮RAG、多轮RAG、深度检索及结果对比
{/* 模式切换按钮 */}
{/* 主体内容区 */}
{/* 左侧参数区 */}
{viewMode === 'single' ? ( <> {/* 问答模式选择 */}

问答模式

{[ { value: 'single-round', label: '单轮RAG', icon: Sparkles, desc: '快速直接' }, { value: 'multi-round', label: '多轮RAG', icon: Brain, desc: '深入理解' }, { value: 'deep-search', label: '深度检索', icon: BookOpen, desc: '全面分析' }, ].map((mode) => ( ))}
) : ( <> {/* 对比模式设置 */}

对比模式设置

{/* 左侧模式 */}
VS
{/* 右侧模式 */}
{/* 对比布局 */}

对比布局

)} {/* 知识范围 */}

知识范围

{[ { value: 'all', label: '全部知识源' }, { value: 'specific-kb', label: '指定知识库' }, { value: 'specific-domain', label: '指定资源域' }, ].map((option) => (
{/* 回答偏好 */}

回答偏好

{/* 对比设置 - 仅对比模式 */} {viewMode === 'compare' && (

对比设置

)}
{/* 中间结果区 */}
{viewMode === 'single' ? ( <> {/* 聊天消息区 */}
{messages.length === 0 ? (

开始你的问答

输入问题,获取基于知识库的智能回答

) : ( messages.map((msg) => (
{/* 用户消息 */}
{msg.role === 'assistant' && (
)}

{msg.content}

{msg.role === 'user' && (
)}
{/* 来源信息 */} {msg.role === 'assistant' && msg.sources && showSources && (

引用来源

{msg.sources.map((source, idx) => (
{source.title} {source.type}

{source.snippet}

))}
)}
)) )} {isLoading && (
)}
) : ( <> {/* 对比结果区 */}
{compareResult ? ( compareLayout === 'horizontal' ? (
{/* 左侧结果 */}
{getModeLabel(compareResult.leftMode)}

{compareResult.leftContent}

{/* 左侧来源 */}

引用来源

{compareResult.sources.left.map((source, idx) => (
{source.title}
))}
{/* 右侧结果 */}
{getModeLabel(compareResult.rightMode)}

{compareResult.rightContent}

{/* 右侧来源 */}

引用来源

{compareResult.sources.right.map((source, idx) => (
{source.title}
))}
) : (
{/* 上方结果 */}
{getModeLabel(compareResult.leftMode)}

{compareResult.leftContent}

{/* 下方结果 */}
{getModeLabel(compareResult.rightMode)}

{compareResult.rightContent}

) ) : (

对比模式

输入问题,对比不同模式的回答效果

)}
)} {/* 底部输入区 */}