在AI时代,多模型并行对比已成为开发者与研究者的刚需。传统方式需多标签切换,效率低下且易遗漏细节。构建一个Web界面,实现单次输入多模型并发查询、响应并排实时展示,能显著提升对比效率。本文聚焦单一技术点:基于开源PolyGPT的React前端工程实践,提供可落地组件、参数阈值与优化清单。
多LLM对比的核心价值与痛点
观点先行:side-by-side界面不仅是UI优化,更是工程化决策工具。证据显示,在复杂查询中,不同模型如GPT-4o在创造性、Claude-3.5在逻辑严谨性、Gemini-1.5在多模态、Perplexity在搜索事实上的差异,可通过并排直观量化,帮助选型或融合输出。
痛点包括:API调用异步不齐、流式响应同步难、交互续问碎片化。PolyGPT验证了纯前端方案的可行性,无需后端,浏览器直连各厂商API,隐私私有。
PolyGPT架构剖析:React + 并发 + SSE
PolyGPT核心是React单页应用(SPA)。布局采用CSS Grid/Flexbox实现响应式并排面板,每模型一列,支持4+模型动态添加。
-
模型配置与状态管理:
- 使用Zustand或Context维护全局状态:
models: [{id: 'gpt4o', apiKey: '', endpoint: 'https://api.openai.com/v1/chat/completions', ...}]。
- 输入框广播:用户prompt触发
Promise.all(models.map(callAPI)),并发fetch。
-
并发API调用参数:
- 超时阈值:
signal: AbortSignal.timeout(30000),防卡死。
- 重试机制:
retry: 3,指数退避delay = 1000 * Math.pow(2, attempt)。
- 令牌限制:
max_tokens: 4096,平衡成本与完整性。
- 温度:
temperature: 0.7,对比一致性用0.0。
-
流式响应SSE实现:
- 各厂商API支持stream=true,返回SSE格式。
- 前端用
EventSource或fetch+ReadableStream解析delta内容。
- 同步更新:React useEffect监听,追加到各面板的
responseChunks[],用dangerouslySetInnerHTML渲染Markdown。
- 关键参数:
bufferSize: 1024,防DOM频繁重绘;flushInterval: 50ms,实时感强。
证据:GitHub repo中,src/lib/api.ts封装了OpenAI/Anthropic/Google/Perplexity适配器,统一streamResponse(prompt)接口。
自建工程落地清单
以下是完整组件与参数清单,直接fork PolyGPT或从零搭建:
组件结构
App/
├── ModelSelector/ # 下拉选模型,输入API Key
├── PromptInput/ # Textarea + Send按钮
├── ResponsePanels/ # Grid容器,子组件ModelPanel
│ └── ModelPanel/ # 单模型:Header(模型名/加载/错误)+ Content(流式文本)
├── History/ # 会话列表,支持续问
└── Settings/ # 全局温度/令牌/主题
关键代码框架(TypeScript)
export async function* streamOpenAI(prompt: string, apiKey: string) {
const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ model: 'gpt-4o', messages: [{role: 'user', content: prompt}], stream: true }),
signal: AbortSignal.timeout(30000)
});
const reader = response.body.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = new TextDecoder().decode(value);
for (const line of chunk.split('\n')) {
if (line.startsWith('data: ')) {
const data = line.slice(6);
if (data === '[DONE]') break;
const parsed = JSON.parse(data);
yield parsed.choices[0].delta.content || '';
}
}
}
}
const ModelPanel = ({ model, prompt }) => {
const [response, setResponse] = useState('');
useEffect(() => {
let isCancelled = false;
(async () => {
try {
for await (const chunk of streamOpenAI(prompt, model.apiKey)) {
if (isCancelled) break;
setResponse(prev => prev + chunk);
}
} catch (e) { }
})();
return () => { isCancelled = true; };
}, [prompt]);
return <div className="panel">{response}</div>;
};
优化参数与监控点
- 性能阈值:面板高度自适应
max-h-96 overflow-auto;加载spinner阈值>500ms显示。
- 错误处理:统一ErrorBoundary,捕获401(无key)/429(限流),弹窗提示
retryAfter: response.headers.get('retry-after')。
- 交互扩展:点击面板复制/续问
newPrompt = old + '\n继续:';融合按钮,POST到自定义后端合并。
- 成本追踪:本地累加
usage: parsed.usage.total_tokens,阈值警报>1000 tokens/query。
- PWA支持:manifest.json + serviceWorker,离线缓存配置页。
部署:Vite build后Vercel一键,环境变量存API keys(客户端暴露,适合个人)。
风险与回滚
限流风险:fallback到缓存历史。浏览器兼容:polyfill AbortController。回滚:单模型降级。
此方案参数化强,扩展到10模型仅改配置。实践证明,构建周期<1天,日常对比效率提升5x。
资料来源: