尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

OmniRoute Playground Studio 深度解析:一站式 AI 网关测试工作台的前端架构与源码实现

OmniRoute Playground Studio 深度解析:一站式 AI 网关测试工作台的前端架构与源码实现 OmniRoute Playground Studio 深度解析一站式 AI 网关测试工作台的前端架构与源码实现【免费下载链接】OmniRouteNever stop coding. Free MIT AI gateway: one endpoint, 352 providers (150 free), 1200 models Kimi, Claude, GPT, Gemini, GLM, DeepSeek, MiniMax. Works with Claude Code, Codex, Cursor, OpenCode, Cline Copilot. Quota-aware auto-fallback, RTKCaveman compression saves 15-95% tokens, MCP/A2A, Desktop/PWA. Built by 550 contributors项目地址: https://gitcode.com/GitHub_Trending/om/OmniRoutePlayground Studio 是 OmniRoute 在/dashboard/playground提供的统一 AI 测试工作台将原先基于 Monaco 的单一编辑器升级为集 Chat对话、Compare多模型对比、API原生端点调试、Build工具调用与结构化输出于一体的四标签页工作空间并配有一个全局共享的 Config 配置面板。本文以 docs/frameworks/PLAYGROUND_STUDIO.md 为核心骨架结合仓库内的实际组件与后端路由源码为你拆解其架构设计、各标签页职责、状态管理与底层请求链路帮助你理解如何把这个“代理网关调试面板”应用到自己的模型评测、Prompt 调优与 API 接入验证流程中。功能定位Playground Studio —— 面向/dashboard/playground的统一 AI 测试工作空间。状态自 OmniRoute v3.8.6 起随版本发布持续迭代至今。一、整体布局Shell 四标签页 共享配置面板Playground Studio 用一个PlaygroundStudioShell 组件替换了旧版page.tsx的扁平结构内部编排四个标签页与一个始终可见的右侧配置面板。顶层布局示意如下┌ Playground ──────────────────────────────────────────────────────────┐ │ [ Chat] [⚖ Compare] [{} API] [ Build] 142↑ 38↓ · $0.002 /│ ├──────────────────────────────────────────┬───────────────────────────┤ │ {active tab content} │ ─ Config │ │ │ Endpoint [chat ∨] │ │ │ Model [gpt-4o ∨] │ │ │ System [textarea] │ │ │ Temp ▕▕▔▔ 0.7 │ │ │ Presets [▾ load][save] │ │ │ [✨ Improve prompt] │ └──────────────────────────────────────────┴───────────────────────────┘1.1 Shell 组件与标签路由PlaygroundStudio.tsx/dashboard/playground/PlaygroundStudio.tsx) 是整个工作台的编排核心它的关键职责包括维护当前激活标签通过resolveTab(searchParams.get(tab))解析 URL 上的?tabchat|compare|api|build查询参数实现标签页深链deep-link并通过manualTab状态支持页面内手动切换持有全局共享的configState包括 endpoint、baseUrl、model、systemPrompt 与 params作为ConfigState一路向下注入各标签页见下方源码片段因此切换标签不会丢失配置管理全局指标状态metrics由 ChatTab 上报的StreamMetrics汇总到顶栏的 Token/Cost 计数器展示通过 Next.jsdynamic()懒加载体积较大的标签ChatTab、ApiTab、BuildTab均以{ ssr: false }方式导入CompareTab则直接静态导入用于降低首屏包体积并避免 Monaco 等重组件在 SSR 阶段被执行。// PlaygroundStudio.tsx节选 const ChatTab dynamic(() import(./components/tabs/ChatTab), { ssr: false }); const ApiTab dynamic(() import(./components/tabs/ApiTab), { ssr: false }); const BuildTab dynamic(() import(./components/tabs/BuildTab), { ssr: false });1.2 初始配置默认值Shell 中定义的初始配置INITIAL_CONFIG即用户首次打开时的面板状态字段默认值说明endpointchat.completions对应/v1/chat/completionsbaseUrlwindow.location.origin非浏览器环境回退到http://localhost:20128网关监听地址本地开发默认端口 20128model空字符串由 Config 面板根据已选 Provider 自动挑选可用模型systemPromptYou are a helpful assistant.注入所有标签页的系统提示词const INITIAL_CONFIG: ConfigState { endpoint: chat.completions, baseUrl: typeof window ! undefined ? window.location.origin : http://localhost:20128, model: , systemPrompt: You are a helpful assistant., params: DEFAULT_PARAMS, };二、四大标签页从对话到结构化输出的完整评测闭环2.1 Chat Tab —— 多轮流式对话工作台ChatTab.tsx/dashboard/playground/components/tabs/ChatTab.tsx) 由旧版ChatPlayground.tsx演进而来定位是多轮、带指标的可对话工作台核心能力包括完整 Markdown 渲染助手回复经 MarkdownMessage.tsx/dashboard/playground/components/MarkdownMessage.tsx) 渲染支持代码块、表格、列表、链接共享 System Prompt请求体构造时从共享配置configState.systemPrompt读取并前置为system消息buildApiMessages会把历史中的 system 去重后再拼接每条消息的 Token/成本统计通过useStreamMetrics计算 prompt completion tokens并借助 TokenCostCounter.tsx/dashboard/playground/components/TokenCostCounter.tsx) 展示在每条 assistant 消息下方重新生成Regenerate与清空Clear重新生成会定位最后一条 assistant 消息截断其后上下文后用同样参数重跑发送过程中可随时 StopAbortController 中止参数组装buildRequestBody只把偏离默认值的参数写入请求体如temperature ! 1.0才带上并在模型支持思考能力时由buildReasoningRequestFields追加effort/thinking字段发送目标默认对chat.completions端点发起POST /v1/chat/completions的 SSE 流式请求对于非 chat 端点则通过 chatTabEndpointRequest.ts/dashboard/playground/components/tabs/chatTabEndpointRequest.ts) 构造对应的请求体与格式化响应这意味着 Chat 标签不只局限在纯对话场景。2.2 Compare Tab —— 网关的“杀手级”多模型并行对比作为代理型 AI 网关Playground Studio 最具辨识度的差异化能力是Compare 标签页把同一个 Prompt 同时发给最多 4 个模型并排观察各自的流式输出与实时性能指标。实现位于 CompareTab.tsx/dashboard/playground/components/tabs/CompareTab.tsx)最多 4 列MAX_COLUMNS 4每列独立从/v1/chat/completions拉流每列有独立的AbortController因此支持单列取消、移除或全局Cancel all添加模型列通过 Add model按钮或直接按CmdK / CtrlK快捷键聚焦模型名输入框Enter 确认新列默认继承 Config 面板当前模型Run all ▶ 并行触发runAll()先cancelAll()清理在途请求再以Promise.allSettled(columns.map(col streamColumn(col)))一次性派发所有流——这正是“必须并行”语义的代码级保证。若把流式启动写成串行 await就会退化为顺序请求详见文末 TroubleshootingSSE 解析使用原生fetchReadableStream而非 EventSource逐行读取data:前缀的 SSE 分块直到[DONE]从首块开始记录 TTFT渲染节流为避免高频 chunk 触发数百次重渲染Compare 列通过requestAnimationFrame累积单帧内的增量并一次性setColumns刷入 UIpushChunk实现每列实时指标CompareColumn.tsx/dashboard/playground/components/CompareColumn.tsx) 与 ProviderMetrics.tsx/dashboard/playground/components/ProviderMetrics.tsx) 展示 TTFT、TPS、token 数与估算成本指标由非 React 的命令式ColumnMetricsTracker类挂在 ref 上采集规避了在异步回调中使用 Hooks 的规则问题。需要注意Compare 标签的指标同样标注为“client-side estimate”客户端估算D12即从浏览器收到第一个 SSE chunk 的时刻起算并非网关侧的服务器计时。2.3 API Tab —— 为高级用户保留的 Monaco 编辑器对需要手写请求、精确控制每个字段的开发者API Tab 完整保留了原始 Monaco 编辑体验封装为 ApiTab.tsx/dashboard/playground/components/tabs/ApiTab.tsx)覆盖多类端点按文档记录内置约 10 个端点chat completions、completions、embeddings、images、audio、speech、transcriptions、moderations、rerank、search 等多模态文件上传与SSE 流式实时输出通过dynamic(..., { ssr: false })懒加载规避 Monaco 在 SSR 下无法渲染的问题这正是后面 Troubleshooting 表中“编辑器空白”症状的根因与解法。需要补充的仓库现状是供 Chat/Compare/Build 及“导出代码”共享的PlaygroundEndpoint联合类型已扩展为13 个成员见 codeExport.ts 中的类型定义与 D4-rev2 注释即chat.completions、responses、completions、embeddings、images、audio.transcriptions、audio.speech、video、music、moderations、rerank、search、web.fetch。它们通过endpointToPath()映射为/v1/chat/completions、/v1/responses、/v1/videos/generations、/v1/web/fetch等实际路由共享 Config 面板的 Endpoint 下拉即列出这些选项。API Tab 因其历史渊源仍保留自己的一套端点体系不与上述联合类型直接耦合。2.4 Build Tab —— 工具调用与结构化输出面向 Function Calling 与结构化输出的测试需求BuildTab.tsx/dashboard/playground/components/tabs/BuildTab.tsx) 聚合了两个编辑器ToolsBuilder.tsx/dashboard/playground/components/tabs/BuildTab.tsx) 依赖的 ToolsBuilder.tsx/dashboard/playground/components/ToolsBuilder.tsx)同目录另有 BuildTab 引用以可视方式增删改tools[]每个工具自带 JSON Schema 参数编辑器并通过 Zod 的ToolDefinitionSchema即时校验参数合法性StructuredOutputEditor.tsx/dashboard/playground/components/StructuredOutputEditor.tsx)可切换 JSON 模式并编辑 JSON Schema作为response_format发送前用StructuredOutputSchema校验。最终请求发往/v1/chat/completions请求体携带tools[]与/或response_format。该 Tab 上方还提供与之联动的 useToolsBuilder.ts/dashboard/playground/hooks/useToolsBuilder.ts) 与 useStructuredOutput.ts/dashboard/playground/hooks/useStructuredOutput.ts) Hooks 作为状态管理入口。三、共享 Config 面板所有标签页的“单一事实来源”StudioConfigPane.tsx/dashboard/playground/components/StudioConfigPane.tsx) 是位于右侧、可折叠collapsed 后收成一条设置图标栏的共享配置区。所有字段的配置状态都提升到PlaygroundStudio再向下派发给各标签页因此修改一次即可作用于 Chat / Compare / Build / API。字段组件说明与取值范围Endpointselect选项与PlaygroundEndpoint联合类型一致逐项显示对应 HTTP 路径如chat.completions — /v1/chat/completionsProviderselect选择 Provider 后按命名空间过滤模型目录内置 Provider 用连接 id兼容型连接按modelPrefix过滤如openai/、anthropic/、claude-code/前缀变更会清空已选模型并自动挑选默认模型Modelinput/select当模型目录较大时提供搜索框过滤输入时始终把当前已选模型保留在列表避免选中项被悄悄换掉模型目录为空时退化为自由文本输入System prompttextarea注入所有标签页的 system 消息ParametersParamSliders.tsx/dashboard/playground/components/ParamSliders.tsx)滑块调节 temperature / max_tokens / top_p / presence frequency penalty另有 seed、stop sequences 输入与 JSON mode 开关见下表默认值Reasoning ControlsReasoningControls.tsx/dashboard/playground/components/ReasoningControls.tsx)仅当所选模型目录的/models能力标记显示支持supportsThinking/effort_tiers时才渲染思考档位见reasoningControlUtils.tsPresetsPresetPicker.tsx/dashboard/playground/components/PresetPicker.tsx)命名配置快照的保存 / 载入持久化到 SQLiteImprove promptImprovePromptButton.tsx/dashboard/playground/components/ImprovePromptButton.tsx)打开“将消耗配额”确认弹窗调用/api/playground/improve-prompt3.1 参数滑块默认值与范围DEFAULT_PARAMS与各滑块的 min/max/step 定义在 ParamSliders.tsx/dashboard/playground/components/ParamSliders.tsx)整理如下参数默认值范围 / 说明temperature1.00–2步长 0.01max_tokens10241–32768整数top_p1.00–1步长 0.01presence_penalty0-2–2步长 0.01frequency_penalty0-2–2步长 0.01seednull数字输入留空为 null不带入请求体stop空字符串逗号分隔的停止序列文本带空格 / 换行则按需在构造层展开jsonModefalse开启后请求体附加response_format: { type: json_object }effort/thinking/ false推理控制参数effort: 表示“不设置”不写入请求体3.2 与模型目录catalog的联动Config 面板不是孤立的自由表单它通过 modelSelection.ts/dashboard/playground/components/modelSelection.ts) 的filterModelsByQuery、resolveModelFilterKey、pickDefaultModel与后台模型目录联动选择 Provider → 按命名空间解析模型目录 → 自动挑选第一个可用模型作为默认避免“模型为空导致 Chat 报 Set a model”的常见陷阱。四、顶栏标签切换、实时 Token/成本与代码导出StudioTopBar.tsx/dashboard/playground/components/StudioTopBar.tsx) 承载三件事标签切换器以roletablist语义化结构渲染四个标签按钮便于无障碍访问TokenCostCounter.tsx/dashboard/playground/components/TokenCostCounter.tsx)实时展示本次会话的 token 升降↑/↓与累计估算成本——数据源为PlaygroundStudio中由 ChatTab 上报的StreamMetrics导出代码按钮/打开 ExportCodeModal.tsx/dashboard/playground/components/ExportCodeModal.tsx)。顶栏展示示意来自文档142↑ 38↓ · $0.002 /其中 142/38 为进出 token$0.002 为估算成本。五、Export Code把当前状态一键导出为 curl / Python / TypeScript5.1 生成器与占位符约定codeExport.ts 是整个代码导出能力的核心它根据当前PlaygroundStateendpoint、baseUrl、model、systemPrompt、messages/prompt、params、tools、stream 等生成三种语言的请求示例curlAuthorization: Bearer $OMNIROUTE_API_KEYContent-Type: application/json并把格式化后的请求体以注释形式附在尾部便于阅读Pythonrequests通过os.environ[OMNIROUTE_API_KEY]读取密钥TypeScriptfetch通过process.env.OMNIROUTE_API_KEY读取密钥。导出的代码里API Key 位置永远使用占位符$OMNIROUTE_API_KEY常量API_KEY_PLACEHOLDER绝不内嵌真实密钥文档约定 D11。如果你看到导出代码中出现MISSING_API_KEY之类字样说明该处未走codeExport.ts的占位符逻辑属于异常路径。// codeExport.ts节选 export const API_KEY_PLACEHOLDER $OMNIROUTE_API_KEY; // chat.completions → /v1/chat/completions export function endpointToPath(endpoint: PlaygroundEndpoint): string { /* ... */ }5.2 请求体按端点差异化构造buildBody()会根据端点为不同 API 生成不同结构的 body例如端点关键字段默认模型兜底chat.completionsmessagessystem usergpt-4o-miniresponsesinputinstructionssystemgpt-4o-minicompletionspromptgpt-3.5-turbo-instructembeddingsinputtext-embedding-3-smallimagespromptsizedall-e-3audio.speechinputvoicetts-1rerankquerydocumentstop_nrerank-english-v3.0searchquery 可选provider/search_type/max_results—web.fetchurl 可选providerfirecrawl 等/format/depth—注audio.transcriptions实际需要 multipart/form-data代码中以 JSON 形式注释示意真实使用需按该端点协议构造多部分请求体。这套导出能力同时被 Search Tools Studio 复用是 Playground 与其他框架页共享的底层工具见 codeExport.ts 注释及 SEARCH_TOOLS_STUDIO.md。六、Prompt Improver用模型改进你的 System / User Prompt6.1 调用链路配置面板中的✨ Improve prompt按钮触发一条完整的“模型改写提示词”链路ImprovePromptButton → useImprovePrompt (hook) → POST /api/playground/improve-prompt { system, prompt, model, tone } → 后端用 buildImproveChatBody() 拼装 meta-prompt 请求 → 内部调用 POST /v1/chat/completions网关回环 → 返回 { improvedSystem?, improvedPrompt?, tokensIn, tokensOut } → UI 将 improvedSystem 写回 Config 的 system prompt improvedPrompt 写回 Chat Tab 当前输入框6.2 请求契约与固定 Meta-Prompt请求体由 promptImprover.ts 中的ImprovePromptRequestSchemaZod校验{ system?: string; // 最多 50_000 字符与 prompt 至少一个非空 prompt?: string; // 最多 50_000 字符 model: string; // 必填用户在 Config 面板选的模型 tone: concise | detailed; // 默认 concise }改写请求内置固定的元提示词META_SYSTEM_PROMPT文档注明 D8实现受 Anthropic Console Prompt Improver 启发改动需经编排方批准要求改写模型输出只有改写后的文本不加解释与 markdown 包裹当同时提供 system 与 prompt 时以SYSTEM/PROMPT标记分行返回。拼接为实际的 chat 请求时使用temperature: 0.3、max_tokens: 2048、stream: false。响应解析parseImprovedContent具备容错设计当返回值不含标记符时若只传了 system 则整体作为improvedSystem只传了 prompt 则整体作为improvedPrompt两者都传时回退为improvedPrompt。6.3 配额提示由于该功能会真实消耗一个模型调用前端在弹窗中会明确警告“将消耗配额”用户确认后才发请求——这与 OmniRoute 以配额为中心的网关理念一致。七、Presets把一整套配置存为可复用快照7.1 存储模型与 CRUDPresetPicker.tsx/dashboard/playground/components/PresetPicker.tsx) 通过usePresets调用/api/playground/presets/*把“命名配置快照”持久化在 SQLite 的playground_presets表迁移脚本 084_playground_presets.sql服务启动时会自动执行迁移或通过npm run db:migrate手动执行CREATE TABLE IF NOT EXISTS playground_presets ( id TEXT PRIMARY KEY, name TEXT NOT NULL, endpoint TEXT NOT NULL, model TEXT NOT NULL, system TEXT, params_json TEXT NOT NULL DEFAULT {}, created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP );每个 preset 保存name、endpoint、model、system、params_json与created_at即一次完整的 Config 状态快照。按文档所述CRUD 语义为GET列表、POST创建、GET /:id单查不存在返回 404、PUT /:id局部更新、DELETE /:id返回 204。7.2 后端路由实现要点以 presets/route.ts 为例实现遵循了几条项目内“硬性规则”所有 DB 访问经 src/lib/db/playgroundPresets.ts 模块禁止在路由中裸写 SQL请求体用 Zod 校验PlaygroundPresetCreateSchema校验失败返回 400 并给出首个问题的path: message所有错误统一走buildErrorBody()含消息净化sanitizeErrorMessage避免把内部异常细节泄露到响应中可选鉴权当携带 API Key 时必须有效isValidApiKeydashboard 会话经requireManagementAuth认可只有当REQUIRE_API_KEY开启时匿名请求才被强制拒绝——默认匿名可用保留旧版行为。八、Stream Metrics客户端感知的流式性能指标8.1 纯函数计算层streamMetrics.ts 是不依赖 React 的纯函数模块computeMetrics()接收四类时间戳与 token 计数输出标准StreamMetrics输入含义startedAt请求派发时刻msfirstChunkAt收到第一个 SSE chunk 的时刻msfinishedAt流结束时刻mstokensIn/tokensOut输入 / 输出 token 数pricing可选的客户端价格estimated: true输出指标计算方式ttftMs首 Token 延迟firstChunkAt - startedAttotalMs总耗时finishedAt - startedAttps每秒 TokentokensOut / (totalMs / 1000)costUsd估算成本(tokensIn × inUsdPer1k tokensOut × outUsdPer1k) / 1000四个时刻均未发生则对应指标为null如首块未到则 TTFT 为 nullUI 按需判空。8.2 React Hook 封装useStreamMetrics.ts/dashboard/playground/hooks/useStreamMetrics.ts) 提供start()→onFirstChunk()→onChunk(n)→finish(usage?)的生命周期接口start()记录请求发出时刻并重置状态onFirstChunk()只记录一次首块时刻重复调用被守卫随后立刻用computeMetrics刷新onChunk(n)只累加refs中的 tokensOut不触发 setState以避免每 chunk 一次重渲染造成 UI 抖动finish(usage?)若上游 SSE 尾部携带usageprompt_tokens/completion_tokens则以它覆盖累加值得到精确 token 数再统一计算并刷新指标reset()清空计时器与指标。Compare 标签同样遵循这套生命周期但以非 Hooks 的ColumnMetricsTracker类实现原因是流式回调运行在异步上下文直接调用带 React 状态的 Hook 会违反 Rules of Hooks。8.3 定价的来源与边界务必注意客户端成本估算依赖 types.ts 中静态内联的MODEL_PRICING_TABLE其中每个条目都带label: (estimated)例如模型in$/1k tokensout$/1k tokensgpt-4o0.00250.01gpt-4o-mini0.000150.0006claude-sonnet-4-60.0030.015claude-haiku-4-50.00080.004gemini-2.0-flash0.00010.0004deepseek-chat0.000140.00028源码注释明确写着DO NOT use for billing不得用于计费价格仅“近似于 2025 年的估算值”真实计费请以网关的/api/usage与上游用量为准。查询不到价格的模型会返回null此时 UI 相应地把成本显示为“不可估算”而非错误地按零计费。九、后端路由总览Playground Studio 的持久化与外部能力全部走网关自有 Next.js API 路由汇总如下MethodPathHandler 行为POST/api/playground/improve-promptZod 校验ImprovePromptRequestSchema内部以 meta-prompt 调用/v1/chat/completions返回改进后的 system/prompt 与 token 用量GET/api/playground/presets返回{ presets, total }支持offset/limit分页POST/api/playground/presets创建 preset用PlaygroundPresetCreateSchema校验成功返回 201GET/api/playground/presets/:id返回单个 preset不存在则 404PUT/api/playground/presets/:id局部更新DELETE/api/playground/presets/:id成功返回 204鉴权策略为“可选”客户端携带 API Key 时必须有效dashboard 会话cookie/session可作为替代凭证仅在REQUIRE_API_KEY开启时才对匿名请求返回 401。所有错误路径经buildErrorBody()统一封装并做消息净化对应项目 Hard Rule #12并且路由会附带 CORS 头以支持跨域调用。improve-prompt 路由还有一个值得注意的实现细节它以环境变量回环到网关自身——baseUrl OMNIROUTE_BASE_URL ?? http://127.0.0.1:${PORT ?? 20128}再请求${baseUrl}/v1/chat/completions把用户请求原样转换为一次带配额消耗的真实网关调用这也解释了为什么“Improve prompt 需要先在 Config 中填写模型”。十、关键源码文件索引以下路径可以帮助你按图索骥地深入阅读实现相对路径职责src/app/(dashboard)/dashboard/playground/PlaygroundStudio.tsx/dashboard/playground/PlaygroundStudio.tsx)Shell 组件与标签编排、共享状态src/app/(dashboard)/dashboard/playground/components/StudioTopBar.tsx/dashboard/playground/components/StudioTopBar.tsx)顶栏标签切换 计数器 导出按钮src/app/(dashboard)/dashboard/playground/components/StudioConfigPane.tsx/dashboard/playground/components/StudioConfigPane.tsx)共享配置面板src/app/(dashboard)/dashboard/playground/components/ParamSliders.tsx/dashboard/playground/components/ParamSliders.tsx)采样参数滑块与默认值src/app/(dashboard)/dashboard/playground/components/PresetPicker.tsx/dashboard/playground/components/PresetPicker.tsx)预设保存 / 载入src/app/(dashboard)/dashboard/playground/components/ImprovePromptButton.tsx/dashboard/playground/components/ImprovePromptButton.tsx)提示词改进入口src/app/(dashboard)/dashboard/playground/components/tabs/ChatTab.tsx/dashboard/playground/components/tabs/ChatTab.tsx)Chat 工作台src/app/(dashboard)/dashboard/playground/components/tabs/CompareTab.tsx/dashboard/playground/components/tabs/CompareTab.tsx)多模型并行对比src/app/(dashboard)/dashboard/playground/components/tabs/ApiTab.tsx/dashboard/playground/components/tabs/ApiTab.tsx)Monaco 编辑器保留src/app/(dashboard)/dashboard/playground/components/tabs/BuildTab.tsx/dashboard/playground/components/tabs/BuildTab.tsx)工具调用 结构化输出src/app/(dashboard)/dashboard/playground/components/ExportCodeModal.tsx/dashboard/playground/components/ExportCodeModal.tsx)代码导出弹窗src/app/(dashboard)/dashboard/playground/components/ProviderMetrics.tsx/dashboard/playground/components/ProviderMetrics.tsx)TTFT / TPS 展示src/app/(dashboard)/dashboard/playground/hooks/useStreamMetrics.ts/dashboard/playground/hooks/useStreamMetrics.ts)客户端流式指标 Hooksrc/app/(dashboard)/dashboard/playground/hooks/usePresets.ts/dashboard/playground/hooks/usePresets.ts)Presets CRUD Hooksrc/app/(dashboard)/dashboard/playground/hooks/useImprovePrompt.ts/dashboard/playground/hooks/useImprovePrompt.ts)提示词改进 Hooksrc/lib/playground/codeExport.tscurl / Python / TS 生成器src/lib/playground/promptImprover.tsMeta-prompt 构造与响应解析src/lib/playground/streamMetrics.ts指标纯函数计算src/lib/playground/types.ts类型重导出 静态定价表src/lib/db/playgroundPresets.tsPresets DB 模块src/app/api/playground/improve-prompt/route.ts提示词改进 REST 路由src/app/api/playground/presets/route.tsPresets 列表 创建src/app/api/playground/presets/[id]/route.tsPresets 单查 / 更新 / 删除src/lib/db/migrations/084_playground_presets.sqlPresets 表迁移脚本十一、常见问题排查症状原因修复方式API 标签页 Monaco 不渲染SSR 阶段加载了 Monaco确认ApiTab使用dynamic(..., { ssr: false })懒加载Compare 各列串行拉流而非并行Promise.all用法有误如先 await 再循环所有列的流启动必须一次性派发在同一个Promise.all/Promise.allSettled调用内参考runAll()实现指标显示null的 TTFT首块处理函数未接线检查 SSE 读取循环中是否调用了useStreamMetrics.onFirstChunk()或 Compare 的tracker.onFirstChunk()且仅应在收到首个含内容 chunk 时调用Preset 无法持久化DB 迁移未执行运行npm run db:migrate或重启服务迁移会在启动时自动执行Improve prompt 返回 502Config 面板未填写模型先在 Config 中填写模型名该请求会真实消耗一次模型调用与配额导出代码出现MISSING_API_KEY占位符未被正确注入codeExport.ts始终使用API_KEY_PLACEHOLDER $OMNIROUTE_API_KEY检查导出是否走了该生成器结语Playground Studio 的价值在于它把“网关能力验证”从散落的手写请求收敛为一条完整的产品化流水线Chat 用于对话与多轮调优Compare 用同一个 Prompt 横向对比多个模型的输出与 TTFT/TPSAPI 覆盖从对话到重排、搜索、网页抓取甚至音视频生成的全端点调试Build 则直击工具调用与结构化输出这两个 Agent 开发核心场景。而贯穿全流程的共享 Config、可持久化 Presets、带配额提示的 Prompt Improver、客户端估算指标与一键代码导出构成了一个可复现、可对比、可分享的评测闭环。对普通用户而言它是快速试用 352 网关背后模型与路由能力的入口对开发者而言它也是一份“如何为 AI 代理网关构建多标签页测试工作台”的可直接阅读的端到端参考实现相关并行对比范式亦可对照 SEARCH_TOOLS_STUDIO.md 中的工具化探索。使用前请留意所有耗时与成本指标均为浏览器侧的客户端估算值费用口径请以网关/api/usage为准。【免费下载链接】OmniRouteNever stop coding. Free MIT AI gateway: one endpoint, 352 providers (150 free), 1200 models Kimi, Claude, GPT, Gemini, GLM, DeepSeek, MiniMax. Works with Claude Code, Codex, Cursor, OpenCode, Cline Copilot. Quota-aware auto-fallback, RTKCaveman compression saves 15-95% tokens, MCP/A2A, Desktop/PWA. Built by 550 contributors项目地址: https://gitcode.com/GitHub_Trending/om/OmniRoute创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表