Hotdry.
application-security

PolyGPT:构建多LLM响应并排对比Web界面的工程实践

用React构建并排多LLM响应界面,支持ChatGPT/Claude/Gemini实时对比,给出API并发、SSE流式与交互参数。

在 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 + 模型动态添加。

  1. 模型配置与状态管理

    • 使用 Zustand 或 Context 维护全局状态:models: [{id: 'gpt4o', apiKey: '', endpoint: 'https://api.openai.com/v1/chat/completions', ...}]
    • 输入框广播:用户 prompt 触发Promise.all(models.map(callAPI)),并发 fetch。
  2. 并发 API 调用参数

    • 超时阈值:signal: AbortSignal.timeout(30000),防卡死。
    • 重试机制:retry: 3,指数退避delay = 1000 * Math.pow(2, attempt)
    • 令牌限制:max_tokens: 4096,平衡成本与完整性。
    • 温度:temperature: 0.7,对比一致性用 0.0。
  3. 流式响应 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)

// api/openai.ts
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 || '';
      }
    }
  }
}

// ModelPanel.tsx
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) { /* error handle */ }
    })();
    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。

资料来源

查看归档