1. 项目实战:一个实时协作白板应用的诞生

最近我接了个活儿,要快速搞出一个带实时协作功能的在线白板应用。这玩意儿听起来简单,不就是画个画大家一起看嘛?但真做起来,需求可一点都不“简单”。产品经理的原话是:“要像 Figma 那样丝滑协作,但功能要像 Miro 一样丰富,最好还能支持自定义插件,下周给我看原型。”

得,典型的“既要又要还要”。不过这也正好是个绝佳的测试场,我决定拉上两位最近风头正劲的“AI编程搭档”——GLM4.5 和 DeepSeek 3.1,让它们俩在 Claude Code 这个“竞技场”里,从零开始帮我构建这个项目。我的目标很明确:不光是看谁能写出能跑的代码,更要看谁更能理解复杂需求、设计出合理的架构、写出健壮的代码,以及在调试时能不能给我靠谱的建议。

我设定的这个白板应用核心功能包括:多用户实时同步画布(包括矢量图形、便签、箭头等)、房间管理、操作历史(撤销/重做)、权限控制(查看者、编辑者、管理员),以及一个可扩展的插件系统雏形。技术栈我选了比较主流的:前端用 React + TypeScript 和 Fabric.js 处理画布,后端用 Node.js + Socket.IO 处理实时通信,数据持久化先用 Supabase(PostgreSQL)顶着。

我把这个需求拆解成几个阶段,准备让两个模型分别尝试。第一阶段是需求理解和架构设计。我把上面那段产品经理的“梦话”稍微整理了一下,扔给了 Claude Code 里的 GLM4.5。我给的提示词大概是:“基于以下需求,为一个实时协作在线白板应用设计技术架构和核心数据模型。需求概述:多用户实时同步矢量图形、便签等元素;房间制管理;完整的操作历史栈;角色权限体系;预留插件系统接口。请给出推荐的技术栈、关键模块划分、核心数据表结构(使用 Supabase PostgreSQL)以及实时同步的初步方案。”

GLM4.5 的反应速度确实快,几乎没怎么“思考”就开始输出了。它首先肯定了 React + Fabric.js + Node.js + Socket.IO + Supabase 这个组合的合理性,然后给出了更细致的模块划分:一个独立的 WebSocketService 模块负责连接管理和消息广播,一个 OperationTransformer 模块用 OT(操作转换)算法来解决协同冲突,一个 PluginManager 模块来管理插件的生命周期。数据库方面,它设计了 roomsusersroom_members(关联表,含角色字段)、canvas_elements(用 JSONB 存储元素属性)、operation_logs 这几张核心表,并且特别强调了要在 operation_logs 里记录操作版本号,用于实现可靠的撤销/重做。它还提醒我,OT 算法实现复杂,可以考虑先用简单的“最后写入获胜”加前端防抖来快速实现 MVP,后期再优化。

接着,我换了 DeepSeek 3.1 来回答同一个问题。DeepSeek 3.1 的思考过程在界面上显示得更“绵长”一些,速度上感觉比 GLM4.5 慢了那么一两秒。它给出的方案在技术栈选择上大同小异,但在架构细节上有所不同。它更倾向于使用 CRDT(无冲突复制数据类型)而不是 OT 来实现实时同步,认为 CRDT 在去中心化场景下更鲁棒,并且推荐了 yjs 这个成熟的库。数据库设计上,它把画布元素的历史版本直接存到了 canvas_elements 表里,通过 versionis_current 字段来管理,这样查询历史状态会更直接,但可能增加存储压力。它还额外设计了一个 plugins 表来存储插件元数据和用户配置。

第一回合下来,我的感受是:GLM4.5 更像一个经验丰富的全栈工程师,给出的方案非常务实,直击痛点(快速上线),并且考虑到了实现难度,给出了循序渐进的建议。而 DeepSeek 3.1 则更像一个学院派的研究员,提出的方案(如 CRDT)理论上更优雅、更前沿,但初期实现成本可能更高。两者都很好地理解了需求,但解题思路的差异已经显现。

2. 代码实现与调试:细节见真章

架构定了,接下来就是真刀真枪写代码了。我决定从最核心的“实时同步画布元素”这个功能开始。我给两个模型的提示词更具体了:“现在开始实现前端画布与后端实时同步。前端使用 React (TypeScript) 和 Fabric.js。假设我们已经有了一个 FabricCanvas 组件。请实现:1. 一个自定义 Hook useCanvasSync(roomId),用于建立 WebSocket 连接,并处理画布元素的增删改事件同步。2. 后端(Node.js with Socket.IO)相应的连接处理、广播逻辑。3. 注意处理连接断开重连和消息顺序问题。给出关键代码片段。”

2.1 GLM4.5 的实作体验

GLM4.5 生成的 useCanvasSync Hook 结构很清晰。它首先定义了一个 useWebSocket 的基础 Hook 来管理连接状态,然后在 useCanvasSync 中封装了针对画布事件的监听和发射。它处理了 Fabric.js 的 object:addedobject:modifiedobject:removed 事件,将变动的对象序列化后通过 WebSocket 发送。在接收端,它使用了简单的防抖和操作合并,避免高频操作导致的消息风暴。后端代码它给出了一个基本的 Socket.IO 服务器 setup,以及一个 handleCanvasOperation 函数,将接收到的操作广播给房间内的其他用户。

我按照它的代码搭建了环境,跑起来之后,基础同步功能确实有了。但我立刻发现一个问题:当两个用户几乎同时移动同一个图形时,后到的操作会直接覆盖先到的,导致其中一个用户的修改丢失。我把这个现象反馈给了 GLM4.5:“出现了并发修改冲突,后到的操作覆盖了先到的,如何解决?”

GLM4.5 很快回应,承认了之前方案(“最后写入获胜”)的缺陷,并给出了两个优化方向:一是实现一个简单的版本号机制,每个操作带一个递增版本号,前端收到远程操作时,如果其版本号低于本地最新版本,则忽略或尝试合并;二是引入更基础的 OT 逻辑,对于“移动”操作,可以尝试计算向量叠加。它随即提供了一段补充代码,为每个发出的操作附加一个 clientIdvectorClock(一个简单的逻辑时间戳),并在前端接收逻辑里添加了基于时间戳的冲突判断规则。虽然这离完整的 OT/CRDT 还有距离,但确实缓解了最明显的冲突问题,体现了它快速迭代和解决问题的能力。

2.2 DeepSeek 3.1 的实作与“踩坑”

换成 DeepSeek 3.1,我让它基于之前提到的 CRDT 思路来实现同步。它直接推荐了 yjsy-websocket 这一组合。前端代码它生成得很快,展示了如何用 yjs 创建一个共享的 Y.XmlFragment 来存储画布元素的 JSON 表示,并通过 y-websocket 连接到后端。后端代码则异常简洁,几乎就是 y-websocket 服务端的标准配置。

然而,在集成时我遇到了麻烦。首先,Fabric.js 的对象模型和 yjs 的数据结构需要手动做双向绑定,这部分 DeepSeek 3.1 生成的代码比较笼统,我不得不花更多时间去查阅 yjsFabric.js 的文档来补充实现。其次,当我尝试运行后端时,发现它生成的 y-websocket 服务端代码对 Node.js 版本有要求,且与我项目里其他中间件存在兼容性问题,启动报错。我把错误日志贴给它,DeepSeek 3.1 尝试分析了几个可能的原因,比如端口占用、依赖缺失,但给出的解决方案试了都没能立刻解决。最后,我不得不暂时搁置这个方案,回头去调整环境。

在调试环节,DeepSeek 3.1 对于直接粘贴的错误信息分析能力是有的,但有时给出的解决方案不够“接地气”,比如会建议我升级到某个最新的 Beta 版库,而这可能引入不稳定因素。相比之下,当我将同样的环境配置问题抛给 GLM4.5 时,它更倾向于建议我检查当前版本的兼容性,或者提供回退到稳定版本的命令,实操性更强。

在实现“操作历史”(撤销/重做)功能时,两者的差异再次显现。GLM4.5 建议在 useCanvasSync Hook 内部维护两个栈(undoStack/redoStack),记录每次操作前后的元素快照(差异)。而 DeepSeek 3.1 则巧妙地利用了 yjs 的内置能力,指出 yjs 本身就有事务记录,可以通过 Y.UndoManager 轻松实现跨用户的撤销/重做,这是 CRDT 方案的一个天然优势。这让我意识到,在技术选型上,模型的前瞻性建议可能带来长期的收益,尽管初期集成成本更高。

3. 多平台MCP配置:让Claude Code如虎添翼

Claude Code 的强大,一半在于模型本身,另一半在于其 MCP(Model Context Protocol)生态。它能让 AI 直接调用外部工具,比如操作数据库、控制浏览器、读写文件系统,这才是“智能编码助手”超越普通代码补全的关键。但在不同操作系统上配置 MCP,尤其是 Windows,确实有些门道。下面我就以这次项目用到的几个关键 MCP(Supabase, Playwright)为例,分享一下在 Windows、macOS 和 Linux 下的配置经验和避坑点。

3.1 Supabase MCP:你的云端数据库管家

这个项目用了 Supabase,配置对应的 MCP 后,Claude Code 就能直接查看、修改数据库 schema,甚至运行 SQL 查询,效率提升不是一点半点。

macOS/Linux 配置(最顺畅): 在终端里,一行命令基本搞定:

claude mcp add --scope user supabase npx -- @supabase/mcp-server-supabase

运行后,它会引导你打开浏览器进行 OAuth 授权,授权完成后,服务就自动配置好了。全局安装或者用 npx 临时运行都可以,非常方便。

Windows 配置(坑点所在): 在 Windows 上,如果你直接运行上述命令,很可能会卡住或者报错,提示找不到命令或权限问题。根本原因在于 Windows 下命令行环境(特别是 PowerShell 或旧版 CMD)对路径和脚本执行策略的处理方式与 Unix 系不同。

可靠的方法是使用 Node.js 的绝对路径来启动 MCP 服务器:

  1. 首先,全局安装 Supabase MCP 服务器:npm install -g @supabase/mcp-server-supabase
  2. 找到你的 node.exe 和全局 npm 模块的安装路径。如果你用 nvm-windows 管理 Node,路径可能像 C:\nvm\v20.11.0\node.exeC:\Users\[你的用户名]\AppData\Roaming\npm\node_modules\@supabase\mcp-server-supabase\dist\transports\stdio.js
  3. 使用完整的路径执行安装命令,并设置必要的环境变量(如 Supabase 的访问令牌):
    claude mcp add --scope user supabase "C:\nvm\v20.11.0\node.exe" -e SUPABASE_ACCESS_TOKEN=sbp_your_token_here -- "C:\Users\Aitrainee\AppData\Roaming\npm\node_modules\@supabase\mcp-server-supabase\dist\transports\stdio.js"
    
    关键就在于这个格式:claude mcp add --scope user <server-name> "<node-path>" [环境变量] -- "<server-script-path>"

配置成功后,你可以在 C:\Users\[你的用户名]\.claude.json 文件里看到新增的 mcpServers 配置。以后迁移到新机器,直接复制这个配置文件过去就行,省时省力。

3.2 Playwright MCP:自动化测试与爬取的利器

Playwright MCP 可以让 Claude Code 控制浏览器,自动完成点击、填写表单、截图等操作。这在做前端功能测试或者需要从网页抓取数据来辅助编码时特别有用。

macOS/Linux 配置: 同样相对简单:

claude mcp add --scope user playwright npx -- @playwright/mcp

首次运行会提示你安装 Playwright 的浏览器驱动,按照提示操作即可。

Windows 配置: 步骤和 Supabase 类似,但 Playwright 本身对浏览器环境的依赖更强。

  1. 全局安装:npm install -g @playwright/mcp
  2. 同样需要找到绝对路径进行安装:
    claude mcp add --scope user playwright-mcp "C:\nvm\v20.11.0\node.exe" -- "C:\Users\Aitrainee\AppData\Roaming\npm\node_modules\@playwright\mcp\cli.js"
    
  3. 安装后,非常重要的一步:你需要手动运行一次 playwright install 来确保所需的 Chromium、Firefox 等浏览器核心被下载到系统上,否则 MCP 调用时会失败。

通用避坑指南:

  • 权限问题:在 Windows 上,始终以管理员身份运行终端(PowerShell 或 Windows Terminal)来进行 MCP 安装操作,可以避免很多因权限导致的路径访问错误。
  • 环境变量:如果 MCP 服务需要 API Key 等环境变量(如 Supabase 的 SUPABASE_ACCESS_TOKEN),务必在 claude mcp add 命令中通过 -e KEY=VALUE 的形式传入,而不是依赖系统环境变量,这样更可靠。
  • 检查连接:安装完成后,在 Claude Code 里输入 /mcp 命令,可以列出所有已连接的 MCP 服务器,确认状态是否为 “✅ Connected”。
  • 项目级与用户级--scope user 是配置在用户全局,所有项目可用。你也可以在项目根目录下使用 --scope project 配置仅本项目使用的 MCP,实现环境隔离。

4. 免费/低成本模型接入方案:拓宽选择面

虽然 Claude Code 默认使用 Anthropic 的模型,但其开放架构允许我们接入其他模型,这对于想体验不同模型能力或控制成本的开发者来说是个福音。主要有两种主流方法:官方接口和第三方路由工具。

4.1 官方接口直连(最稳定)

这是最直接、通常也是最稳定的方式。一些国产大模型平台提供了与 Anthropic API 兼容的接口。你只需要在启动 Claude Code 前,设置两个环境变量即可。

以接入智谱 AI(GLM-4.5)为例:

  • Windows (CMD):
    set ANTHROPIC_BASE_URL=https://open.bigmodel.cn/api/anthropic
    set ANTHROPIC_API_KEY=你的智谱API_KEY
    claude --dangerously-skip-permissions
    
  • Windows (PowerShell):
    $env:ANTHROPIC_BASE_URL="https://open.bigmodel.cn/api/anthropic"
    $env:ANTHROPIC_API_KEY="你的智谱API_KEY"
    claude --dangerously-skip-permissions
    
  • macOS / Linux (Bash/Zsh):
    export ANTHROPIC_BASE_URL=https://open.bigmodel.cn/api/anthropic
    export ANTHROPIC_API_KEY=你的智谱API_KEY
    claude --dangerously-skip-permissions
    

以接入 DeepSeek 为例: DeepSeek 也提供了官方兼容接口,只需将 ANTHROPIC_BASE_URL 替换为 https://api.deepseek.com/v1,并将 ANTHROPIC_API_KEY 设置为你的 DeepSeek API Key 即可。

这种方式的优点是延迟低、稳定性高,完全遵循官方协议。缺点是你需要分别注册这些平台并管理各自的 API Key 和计费。像智谱AI经常有优惠活动,比如我之前遇到的20元包月活动,对于重度测试者来说非常划算。

4.2 使用 Claude Code Router(灵活路由)

如果你觉得管理多个环境变量麻烦,或者想在一个界面里灵活切换不同模型,甚至使用一些提供免费额度的聚合平台,那么 claude-code-router 这个开源项目就是为你准备的。

安装与启动:

  1. 首先确保已安装 Claude Code:npm install -g @anthropic-ai/claude-code
  2. 安装路由工具:npm install -g @musistudio/claude-code-router
  3. 启动路由服务:ccr code --dangerously-skip-permissions--dangerously-skip-permissions 参数是为了避免每次操作都请求权限,提升流畅度。

启动后,打开浏览器访问 http://127.0.0.1:3456/ui/,你会看到一个配置界面。在这里,你可以添加多个模型供应商。

配置模型供应商:

  1. 点击“添加供应商”,名称可以自定,比如“智谱GLM”。
  2. 在“供应商URL”中,填入对应平台的API端点,如智谱的 https://open.bigmodel.cn/api/anthropic
  3. 在“API密钥”填入你的Key。
  4. 最关键的一步:在“供应商转换器”中,选择 “Anthropic”。这是因为 Claude Code Router 会将请求转换成对应平台能识别的 Anthropic 兼容格式。
  5. 模型名称填写平台支持的模型名,如 glm-4-plusdeepseek-chat

你可以重复这个过程,添加 DeepSeek、OpenRouter、SiliconFlow(硅基流动)等多个供应商。OpenRouter 和 SiliconFlow 这类聚合平台 often 提供一些免费的模型额度,非常适合初学者尝鲜。例如,SiliconFlow 注册就赠送额度(国内版约15元,国际版1美元),足够进行大量基础测试。

路由规则与使用: 在配置页面的“Claude Code 路由”部分,你可以设置不同功能(如“代码补全”、“对话”、“长文本分析”)默认使用哪个供应商的哪个模型。配置完成后,点击“保存并重启路由”。

以后启动 Claude Code 时,就不再需要设置复杂的环境变量了,直接运行 ccr code 即可。所有的模型调用都会通过路由服务转发,你可以在 Web 界面中随时监控调用情况和切换模型。这种方法把复杂的配置图形化了,并且能轻松实现模型的混合使用(比如用 GLM4.5 写代码,用 DeepSeek 3.1 来审查逻辑),大大提升了灵活性和便利性。

注意事项:

  • 通过路由工具调用免费或聚合平台的模型时,可能会遇到速率限制或上下文长度限制。如果任务过于复杂,有时会收到“红温”(请求被限制)的报错。官方直连方案通常更稳定。
  • 路由服务依赖于你启动的 ccr code 终端窗口,关闭该窗口服务即停止。不需要使用时,直接关闭窗口即可,不要按 Ctrl+C 在终端内中断,以免有后台进程未正确退出。

经过这一轮从架构设计、编码调试到环境配置、模型接入的完整实战,我对 GLM4.5 和 DeepSeek 3.1 在 Claude Code 中的表现有了更立体的认识。GLM4.5 像一位敏捷的实战派,反应迅速,解决方案务实,在快速迭代和解决具体 bug 时表现突出,尤其适合需要快速出活、明确目标的开发场景。DeepSeek 3.1 则像一位深思熟虑的架构师,倾向于提供更理论化、更前沿的解决方案,在问题分析和提出创新思路方面有优势,但在具体实现和调试的“最后一公里”上,有时需要开发者更多的引导和手动介入。

选择哪一个,很大程度上取决于你的工作流和个人偏好。如果你追求效率和开箱即用的体验,GLM4.5 是更稳妥的选择。如果你乐于探索新技术方案,并愿意花时间深入调试,DeepSeek 3.1 可能会带来更多惊喜。至于我,在这个白板项目后续的插件系统开发中,我可能会让它们俩“轮流值班”,用 GLM4.5 快速搭建框架和实现基础功能,再用 DeepSeek 3.1 来评审代码、思考更优的数据流设计。工具嘛,用得趁手才是关键。

更多推荐