Chat Relay:构建AI聊天界面中继器,统一调用多模型API

发布时间:2026/7/24 7:31:58

Chat Relay:构建AI聊天界面中继器,统一调用多模型API 1. 项目概述一个连接AI聊天界面的“万能中继器”如果你和我一样经常在Cline、RooCode这类AI编程助手和Gemini、ChatGPT、Claude这些网页版AI聊天工具之间切换肯定会遇到一个痛点有些模型没有公开的API或者网页版响应速度、工具调用能力各有千秋没法在一个统一的界面里灵活调用。最近我折腾了一个叫Chat Relay的开源项目它本质上是一个“中继器”能把Cline/RooCode的请求通过一个兼容OpenAI API格式的服务器转发到你的浏览器里去操作那些网页版AI聊天界面再把结果抓回来。这听起来有点“曲线救国”但实测下来对于想用Claude的强工具能力配合Gemini Pro 2.5的深度思考或者单纯想用一个统一接口调用所有AI的场景它是个非常巧妙的解决方案。简单来说它由三部分组成一个你本地运行的、假装自己是OpenAI的API服务器一个安装在Chrome里的浏览器扩展负责在网页上“模拟人工操作”以及一个可选的MCP开发工具服务器。你的Cline/RooCode把请求发给本地API服务器服务器通过WebSocket通知浏览器扩展“去Gemini页面帮我问个问题”扩展自动填好问题、点击发送、抓取AI的回复再一路传回给Cline。整个过程对你使用的AI助手来说是透明的它以为自己只是在调用一个标准的OpenAI接口。2. 核心架构与设计思路拆解2.1 为什么需要这样一个“中继”系统在深入代码之前我们先聊聊为什么会有这个项目。直接原因很明确API的缺失与不均衡。像Google AI Studio、Gemini的某些版本或者一些内测模型并没有提供稳定、公开的API。同时不同模型的网页版在响应速度、上下文长度、工具调用Function Calling能力上差异巨大。Claude的网页版在工具调用上响应极快且准确而Gemini Pro 2.5可能在某些复杂推理上更深入但它的官方API可能有速率限制或者延迟。Chat Relay的设计目标就是打破这些壁垒让你能像搭积木一样在同一个工作流里组合使用不同AI的最佳特性。它的核心设计哲学是“模拟”而非“破解”。它不逆向工程任何服务的后端API而是完全在前端层面模拟一个真实用户的操作打开网页、输入文字、点击按钮、读取回复。这使得它在技术原理上更简单也更依赖于目标网页的DOM结构稳定性。2.2 系统组件深度解析项目采用了清晰的三层架构每一层都有明确的职责和设计考量。1. OpenAI兼容API服务器这是整个系统的“大脑”和“翻译官”。它必须完美扮演一个OpenAI API服务器的角色因为Cline/RooCode这类工具只认这个标准。这意味着它要实现/v1/chat/completions这个核心端点接收格式完全一致的JSON请求包含model,messages,temperature等参数。但它的内部逻辑截然不同它不调用任何AI模型的云端API而是将请求任务派发给已连接的浏览器扩展。设计细节服务器内部维护了一个WebSocket连接池和一个请求映射表。当收到一个HTTP请求时它会生成一个唯一的requestId将请求内容和这个ID通过WebSocket推送给浏览器扩展同时启动一个计时器默认3分钟。如果超时前没收到扩展的回复它会向客户端返回一个超时错误。这种异步、事件驱动的设计是应对网页操作不确定性的关键。2. 浏览器扩展这是系统的“手”和“眼睛”也是最容易出问题的部分。它是一个Chrome扩展以后台脚本background script常驻并通过内容脚本content script注入到目标标签页如chatgpt.com。它的核心挑战在于如何在不同网站千变万化的UI中可靠地找到输入框、发送按钮和回复区域。实操心得项目采用了“提供者Provider”模式为Gemini、AI Studio、ChatGPT、Claude分别编写了独立的Provider类。每个Provider都包含了针对该网站特定的CSS选择器Selector和交互逻辑。例如ChatGptProvider需要找到ChatGPT网页中那个特定的textarea和发送按钮而ClaudeProvider的查找逻辑可能完全不同。当扩展连接到某个标签页时它会根据当前URL自动选择合适的Provider。这种设计极大地提高了系统的可维护性和可扩展性——当某个网站的UI改版时你只需要更新对应的Provider文件即可。3. MCP服务器可选这是一个面向开发者的工具。MCPModel Context Protocol是Anthropic提出的一种协议用于让AI模型更安全、可控地使用工具。这里的MCP服务器可以模拟消息流、测试扩展的抓取逻辑或者作为一个流量监视器帮助你调试整个中继过程。对于普通用户来说它不是必须的但对于想深入了解系统工作原理或进行二次开发的人来说它非常有用。2.3 数据流与容错机制理解数据流是排查问题的关键。一次完整的请求-响应周期如下发起请求Cline发送一个HTTP POST请求到http://localhost:3003/v1/chat/completions。任务分派API服务器生成requestId将请求内容通过WebSocket转发给所有已连接的浏览器扩展。页面操作浏览器扩展接收到任务后激活对应标签页使用Provider的injectMessage方法将文本填入输入框并触发点击事件或按下回车键。响应捕获扩展启动一个“监听器”持续监测回复区域的DOM变化。这里通常采用MutationObserverAPI或者针对流式响应监听特定的DOM节点文本更新。结果回传一旦检测到完整的回复或达到稳定状态扩展将文本内容连同最初的requestId通过WebSocket发回API服务器。格式转换与返回API服务器根据requestId找到对应的HTTP请求上下文将抓取到的纯文本包装成OpenAI API标准格式的JSON响应返回给Cline。避坑指南响应捕获的稳定性这是最容易失败的一环。不同网站的回复加载方式各异有的是一次性吐出有的是流式打字机效果有的在回复末尾会有“重新生成”或“复制”按钮干扰判断。项目的Provider里通常会实现一个waitForCompletion方法它可能包含多重判断等待特定元素出现、等待文本不再变化持续2-3秒、排除掉按钮等非回复文本。在实际使用中如果发现回复抓取不全或提前截断很可能需要调整这个等待逻辑或选择器。3. 详细部署与配置实操纸上得来终觉浅我们一步步把它跑起来。假设你的工作目录是~/projects/。3.1 环境准备与依赖安装首先确保你的系统满足最低要求Node.js: 版本14或以上。推荐使用LTS版本如18.x, 20.x稳定性更好。可以用node -v检查。npm: 通常随Node.js安装。用npm -v检查。Chrome浏览器: 必须是Chrome或基于Chromium的浏览器如Edge、Brave因为扩展是Chrome扩展格式。3.2 API服务器的部署与启动获取代码将项目克隆到本地。cd ~/projects git clone 项目仓库地址 cd chat-relay安装依赖进入API服务器目录并安装所需包。cd api-relay-server npm install这里可能会安装express,ws(WebSocket库),nodemon用于开发热重载等依赖。启动服务器npm start # 或者如果你希望代码改动后自动重启使用 # npx nodemon src/server.js如果一切正常终端会输出服务器启动在http://localhost:3003的信息。请务必记下这个端口号默认3003后续配置全靠它。3.3 浏览器扩展的安装与连接Chrome扩展无法直接安装一个文件夹需要以“开发者模式”加载。打开Chrome在地址栏输入chrome://extensions/并访问。打开右上角的“开发者模式”开关。点击左上角的“加载已解压的扩展程序”按钮。在弹出的文件选择器中导航到本项目下的extension文件夹注意是包含manifest.json的那个目录然后选择。成功后扩展列表里会出现一个名为“Chat Relay”的扩展。确保其开关是打开的。连接扩展与服务器打开你想要使用的AI聊天网页例如https://chatgpt.com。点击浏览器右上角扩展图标可能是个拼图块然后找到Chat Relay。扩展图标可能会显示连接状态。理论上如果API服务器正在运行且扩展配置正确默认就是连接localhost:3003扩展会自动尝试连接。你可以在API服务器的控制台日志中看到类似“Browser extension connected”的消息来确认。3.4 配置Cline或RooCode这是让AI助手“上钩”的关键一步。你需要告诉你的AI助手它的“OpenAI API”其实在我们的中继服务器上。以RooCode为例Cline配置类似打开RooCode的设置通常是Settings或Preferences。找到API配置部分将API Provider从默认的OpenAI改为“OpenAI Compatible”或类似选项不同客户端命名可能略有不同。在Base URL中填入http://localhost:3003/v1。特别注意这里必须是/v1结尾因为OpenAI的接口路径就是/v1/chat/completions我们的服务器也遵循这个约定。API Key可以任意填写比如sk-dummy-key。因为我们的本地服务器为了简化通常不会做真正的密钥验证。但有些严格的客户端可能要求非空填一个任意字符串即可。Model字段这里填写的模型名如gemini-pro,chatgpt-4o,claude-3.5-sonnet并不会直接决定调用哪个后端的哪个模型。这个模型名更像是一个“路由标签”。在我们的API服务器代码中可以配置这个标签与浏览器扩展当前所在网页的对应关系。一种简单的实现是服务器只是把这个模型名原样传递给扩展扩展根据当前激活的标签页网站来决定使用哪个Provider。所以你需要确保你填写的模型名与你在浏览器中打开的网页是匹配的例如填gemini-pro时浏览器要开着Gemini页面。3.5 进行首次测试配置完成后不要急于在Cline/RooCode里进行复杂操作。先用最直接的方法验证整个链路是否通畅。使用curl命令模拟一次API调用curl -X POST http://localhost:3003/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer sk-dummy-key \ -d { model: chatgpt, messages: [ {role: user, content: 请回复‘你好世界’} ], temperature: 0.7, max_tokens: 50 }观察点API服务器终端应该立即打印出收到HTTP请求的日志。浏览器对应的聊天页面如ChatGPT应该自动获得焦点输入框被填入“请回复‘你好世界’”并自动发送。AI网页开始生成回复。浏览器扩展捕获到回复“你好世界”。curl命令窗口几秒到十几秒后你应该会收到一个格式正确的JSON响应其中的content字段就是“你好世界”。如果这个过程顺利完成恭喜你最复杂的部分已经打通了。如果卡在某个环节就需要进入下一章的排查流程。4. 高级配置与管理界面详解项目提供了相当灵活的配置选项和一个强大的管理界面这对于长期稳定使用至关重要。4.1 API服务器核心配置配置文件通常位于api-relay-server/src/server.js或一个独立的config.js中。你可以调整以下参数以适应你的网络环境和使用习惯PORT(默认: 3003): 如果3003端口被占用可以修改为其他端口如3004。记得同步修改Cline/RooCode的Base URL和扩展的连接配置。REQUEST_TIMEOUT(默认: 180000ms即3分钟): 一个请求等待回复的最长时间。对于处理复杂问题可以适当调高比如300000(5分钟)。PING_INTERVAL(默认: 30000ms即30秒): 服务器向WebSocket客户端浏览器扩展发送心跳包的时间间隔用于保持连接活跃。CONNECTION_TIMEOUT(默认: 45000ms即45秒): 如果在这个时间内没有收到客户端的心跳回应服务器会认为连接已断开。网络环境调优建议如果你在远程服务器如云主机上部署API服务器而浏览器扩展在本地网络延迟可能较高。建议将PING_INTERVAL和CONNECTION_TIMEOUT适当调大并确保防火墙开放了WebSocket端口通常是服务器端口。4.2 强大的内置管理界面这是一个非常实用的功能通过访问http://localhost:3003/admin/admin.html即可打开。它分为几个主要区域1. 设置面板在这里你可以动态修改服务器配置而无需重启服务。例如服务器端口运行时修改端口需重启生效。请求超时动态调整REQUEST_TIMEOUT。请求处理策略当多个请求同时到达时是“队列”处理逐个执行还是“丢弃”新请求。对于网页操作建议使用“队列”避免同时向一个聊天窗口发送多条消息导致混乱。自动终止冲突进程一个有用的选项确保端口被占用时能自动清理。2. 实时日志面板这是排查问题的“眼睛”。所有服务器活动包括HTTP请求、WebSocket连接/断开、消息转发、错误信息都会以彩色编码的形式实时显示在这里每2秒自动刷新。信息白色、警告黄色、错误红色一目了然。3. 消息历史面板记录所有经过中继的请求和响应详情。你可以点击任何一条历史记录查看完整的请求体你发送的消息和响应体AI返回的消息。这对于调试回复格式错误或内容丢失非常有用。4. 状态监控面板显示服务器运行时间、当前连接的浏览器扩展数量、WebSocket连接状态等健康指标。4.3 浏览器扩展配置扩展的配置主要在extension/background.js文件中用于定义它如何连接到你的API服务器。serverHost与serverPort: 默认是localhost和3003。如果你将API服务器部署在局域网另一台机器或云上需要将serverHost改为服务器的IP地址或域名。serverProtocol: WebSocket协议ws://或wss://加密。本地环境用ws://。reconnectInterval: 连接失败后的重试间隔。修改这些配置后你需要回到chrome://extensions/页面找到Chat Relay扩展点击“刷新”图标来加载新配置。5. 实战问题排查与经验实录即使按照步骤操作也难免会遇到问题。下面是我在搭建和使用过程中遇到的一些典型问题及解决方法希望能帮你快速排雷。5.1 连接类问题问题1API服务器启动失败提示端口被占用。Error: listen EADDRINUSE: address already in use :::3003排查使用命令lsof -i :3003(Mac/Linux) 或netstat -ano | findstr :3003(Windows) 查看哪个进程占用了3003端口。如果是已知进程如另一个Node应用可以终止它。更简单的方法是直接修改server.js中的PORT为其他未占用端口比如3004并记得更新所有相关配置Cline的Base URL、扩展的serverPort。问题2浏览器扩展图标显示“未连接”或“连接错误”。排查检查API服务器是否运行确认npm start的终端窗口没有报错并且正在运行。检查扩展配置确认extension/background.js中的serverHost和serverPort与API服务器实际地址一致。特别注意如果API服务器在远程localhost必须改为远程IP且要确保远程服务器的防火墙允许该端口的入站连接。检查WebSocket连接在Chrome中按F12打开开发者工具切换到“网络”(Network)标签页筛选“WS”WebSocket。刷新扩展页面或目标聊天页面你应该能看到一个到ws://your-server:port的WebSocket连接。如果连接失败会显示红色错误信息。查看API服务器日志管理界面的日志面板或服务器终端会显示扩展尝试连接的记录和任何错误信息。5.2 请求-响应流程类问题问题3Cline/RooCode发送请求后一直等待超时浏览器没有任何反应。排查确认扩展已注入到正确的标签页打开目标聊天网站如chatgpt.com按F12打开开发者工具在“控制台”(Console)标签页输入chrome.runtime并回车。如果不报错且能显示对象信息说明扩展的内容脚本已成功注入。如果报错尝试重新加载扩展和网页。检查API服务器日志查看是否收到了HTTP POST请求以及是否成功通过WebSocket将任务转发出去。如果日志显示“No connected extensions”说明扩展虽然安装了但WebSocket连接未建立或已断开。检查模型名映射确认Cline请求中model字段的值与扩展中当前激活标签页的网站是否匹配。服务器或扩展的逻辑可能根据这个字段决定是否处理请求。例如请求的model是gemini-pro但当前连接的扩展正在监听一个Claude页面请求可能会被忽略。问题4浏览器页面自动输入了问题并发送但抓取不到回复或者回复不完整。这是最常见的问题根源在于DOM选择器失效或响应捕获逻辑不匹配。排查手动确认页面可正常交互先手动在网页聊天框里发一条消息确保AI能正常回复。排除网站本身服务问题或登录状态失效。检查Provider选择器目标网站的UI可能已经更新。打开extension/providers/目录下对应的JS文件如chatgpt.js。找到getReplyContent或类似的方法里面会有用于查找回复内容的CSS选择器如[data-message-author-roleassistant]。手动测试选择器在收到AI回复的页面上按F12打开开发者工具在“元素”(Elements)面板按CtrlF(Windows) 或CmdF(Mac)粘贴那个CSS选择器看是否能高亮显示正确的回复元素。如果不能说明选择器失效了需要根据新的页面结构更新。调整等待逻辑如果选择器正确但抓取太快或太慢可以修改Provider中的waitForCompletion方法。增加等待稳定时间setTimeout或者添加更多的状态检查如等待“停止生成”按钮出现再抓取。5.3 性能与稳定性优化问题5连续使用一段时间后响应变慢或出现卡顿。排查与优化浏览器内存累积打开的聊天网页标签页过多或长时间不刷新可能导致浏览器内存占用过高。定期关闭不用的标签页或每天重启一次浏览器。API服务器资源检查服务器运行机器的CPU和内存使用情况。如果请求量大Node.js进程可能成为瓶颈。可以考虑使用pm2等进程管理工具来守护和监控Node服务。请求队列堆积如果处理策略是“队列”且某个请求因网页卡住而超时会导致后续请求排队。在管理界面观察请求处理状态必要时可以重启API服务器和浏览器扩展来清空状态。网络波动如果服务器在远程不稳定的网络会导致WebSocket连接频繁断开重连。适当调大PING_INTERVAL和CONNECTION_TIMEOUT并考虑将服务器部署在更稳定的网络环境中。问题6如何同时使用多个不同的AI模型这是Chat Relay的进阶用法。你不能让一个扩展实例同时操作两个不同的网站。但你可以启动多个API服务器实例分别运行在不同的端口如3003给Gemini3004给Claude。安装多个扩展实例需要修改Chrome默认不允许安装两个相同ID的扩展。你需要为第二个扩展创建一个新的项目目录修改其manifest.json中的name和key字段如果需要并修改background.js中的连接端口指向第二个API服务器3004。配置多个AI助手连接在Cline/RooCode中你可以配置多个“自定义API”端点每个指向不同的本地服务器端口并在使用时手动切换。更高级的用法是你可以写一个简单的路由代理根据请求中的model字段将流量转发到不同的后端API服务器上。5.4 安全与合规使用提醒虽然这是一个技术项目但我们必须严肃讨论使用边界。项目README中已经强调了“责任自负”的原则这里我再从实操角度补充几点严格遵守服务条款OpenAI、Google、Anthropic等公司的服务条款通常禁止未经授权的自动化访问、大规模爬取或用于创建替代其服务的产品。Chat Relay用于个人或小团队内部将网页界面作为“桥梁”来连接自己的工具在合理使用频率下模拟人类操作速度风险相对较低。但绝对不要用它来搭建一个对外提供服务的代理或进行高频、批量的自动化请求这几乎肯定会违反条款导致账号被封禁。尊重速率限制网页端虽然没有明确的API速率限制但过快的请求频率会触发风控可能导致验证码、临时封禁甚至永久封号。建议在代码中或在API服务器层加入请求间隔延迟模拟真人打字的思考时间比如每条消息之间随机等待10-30秒。用途正当仅将工具用于学习、研究、个人效率提升等正当目的。不要用于生成垃圾信息、进行欺诈等非法或不道德活动。这个项目像一把精巧的瑞士军刀它通过一种巧妙的方式弥合了工具与资源之间的缝隙。它的价值不在于突破限制而在于创造连接让你手头的工具能发挥出“112”的效能。在使用的过程中保持对技术规则的尊重对服务提供者的感恩才能走得长远。

相关新闻