欢迎光临
我们一直在努力

OpenMAIC 运行踩坑与经验


tags:

  • OpenMAIC
  • Next.js
  • 部署
  • 排错
    created: 2026-09-10
    project: G:\\vibing\\OpenMAIC-main

OpenMAIC 运行踩坑与经验

本文记录把 OpenMAIC(Next.js 16 多智能体互动课堂)从源码跑到可用、以及打包分发、部署过程中实际遇到的问题、根因和解决办法。
在这里插入图片描述

一、环境与版本

项目版本 / 要求
操作系统 Windows(开发),Linux + 宝塔(Nginx / Docker 部署)
Node.js v22.19.0(engines 要求 >= 22.19.0)
包管理器 pnpm 10.28.0(packageManager 声明,不要用 npm 安装)
Next.js 16.2.11(Turbopack)
React 19.2.3
TypeScript 5.9.3
关键依赖 tailwindcss 4.3.3、@langchain/core 1.2.9、@types/node 22.20.1

启动命令:

pnpm install # 首次安装,会执行 postinstall 构建全部 workspace 包
pnpm dev # 开发模式,默认 3000 端口被占用时自动改用 3001
pnpm build # 生产构建(会做完整 TypeScript 类型检查)
pnpm start # 生产模式启动

[!warning] 用 pnpm,不要用 npm
项目是 pnpm workspace,postinstall 里用的是 pnpm run build,而且锁文件是 pnpm-lock.yaml。
npm install 不会正确构建 @openmaic/* 子包,后续必然报模块找不到。
npm run build 只是执行脚本本身没问题,但依赖必须由 pnpm 安装。


二、问题速查表

症状根因解决
启动后访问页面 500,Missing field 'negated' on ScannerOptions.sources 锁文件把 tailwindcss 4.0.0 与 4.3.3 的 oxide 扫描器混装 pnpm update -D tailwindcss @tailwindcss/postcss 统一到 4.3.3
CSS 错误修完仍然报旧路径 @tailwindcss+postcss@4.0.0 旧版本目录被运行中的 dev server 锁住未清理 + Turbopack 缓存 停服务 → 删 .next 和残留 .pnpm 目录 → 重启
Module not found: Can't resolve '@langchain/core/utils/uuid' @langchain/core 1.1.16 太旧,langgraph-checkpoint@1.1.5 需要 ^1.1.48 pnpm update @langchain/core(升到 1.2.9)
npm run build 报 Type 'Buffer' is not assignable to 'BinaryLike' @types/node 锁在 20.0.0,与 TypeScript 5.9 不兼容 package.json 改 "@types/node": "^22" 后 pnpm update @types/node
找不到 @openmaic/renderer / @openmaic/editor 的模块 两个 workspace 包缺少 dist 构建产物 pnpm –filter @openmaic/renderer run build、pnpm –filter @openmaic/editor run build
端口 3000 打不开,日志提示改用 3001 3000 被本机其他程序(grafana)占用 用日志里的端口访问;部署时让应用只监听 127.0.0.1:3000
页面能打开,但生成课程/语音失败 .env.local 没有配置任何 LLM 服务商 Key 从 .env.example 复制并至少填一个 *_API_KEY
想用小米 MiMo TTS,填自定义 TTS 却调不通 MiMo TTS 走 /v1/chat/completions + audio 参数,不是 /v1/audio/speech 源码内新增原生 xiaomi-tts provider(见第四节)
日志里 instrumentation.ts: A Node.js API is used 警告 Edge Runtime 检查提示,非致命 忽略,不影响启动和功能

三、问题详解

3.1 工作区包缺少 dist 产物

现象:启动或构建时报找不到 @openmaic/renderer、@openmaic/editor 的模块(它们的 main 指向 dist/…)。

原因:这两个包在 postinstall 里构建,如果安装过程被中断(或只跑了部分脚本),dist 就不存在。

解决:

pnpm —filter @openmaic/renderer run build
pnpm —filter @openmaic/editor run build

随后确认 packages/@openmaic/<包名>/dist 存在即可。之后正常 pnpm install 会自动完成这一步。


3.2 Tailwind 版本错配导致页面 500

现象:首页首次编译直接 500,日志:

Error evaluating Node.js code
Error: Missing field `negated` on ScannerOptions.sources
at …/@tailwindcss+postcss@4.0.0/…/dist/index.js

根因:锁文件里 @tailwindcss/postcss@4.0.0 被解析成依赖 @tailwindcss/node@4.3.3、@tailwindcss/oxide@4.3.3,4.0.0 的 JS 与 4.3.3 的原生扫描器 API 不匹配。

解决:

pnpm update –D tailwindcss @tailwindcss/postcss # 统一到 4.3.3

后续坑:更新完仍然报 @tailwindcss+postcss@4.0.0 的路径。原因是 dev server 还在运行,Windows 下旧目录被文件锁住删不掉,加上 Turbopack 的 .next 缓存仍指向旧路径。

# 先停掉 pnpm dev,再执行:
node –e "const fs=require('fs'); for (const p of ['.next','node_modules/.pnpm/@tailwindcss+postcss@4.0.0']) { if (fs.existsSync(p)) { fs.rmSync(p,{recursive:true,force:true}); console.log('removed',p); } }"
pnpm dev

经验:更新/删除依赖前先停 dev server;改完依赖后清一次 .next 最省事。


3.3 @langchain/core/utils/uuid 找不到

现象:访问 /api/chat 或执行 next build 时:

Module not found: Can't resolve '@langchain/core/utils/uuid'
./node_modules/.pnpm/@langchain+langgraph-checkpoint@1.1.5_@langchain+core@1.1.16/…

根因:langgraph-checkpoint@1.1.5 的 peer 依赖是 @langchain/core@^1.1.48,但锁文件把 core 固定在 1.1.16,该版本没有导出 utils/uuid。

解决:

pnpm update @langchain/core # 1.1.16 -> 1.2.9

验证:

node –e "import('@langchain/core/utils/uuid').then(m=>console.log('ok',typeof m.v5,typeof m.v6))"

再清一次 .next 缓存并重启。修复后 POST /api/chat 返回 400(参数校验)而不是 500(模块缺失),说明路由编译通过。


3.4 npm run build 的 Buffer 类型错误(重点)

现象:npm run build 在 TypeScript 阶段失败:

./app/api/materials/route.ts:341:48
Type error: Argument of type 'Buffer' is not assignable to parameter of type 'BinaryLike'.
Type 'Buffer' is not assignable to type 'Uint8Array<ArrayBufferLike> | DataView<ArrayBufferLike>'.
Type 'SharedArrayBuffer' is missing the following properties from type 'ArrayBuffer': …

类似错误全项目有几百处(凡是把 Buffer 传给 createHash、fs.writeFile、Blob、Response 的地方)。

根因:@types/node 被锁在 20.0.0(很旧的版本),与 TypeScript 5.9 的 TypedArray/Buffer 类型定义不兼容。next dev 不做类型检查所以察觉不到,next build 会做全量类型检查直接失败。

解决:

  • package.json 开发依赖改为:
  • "@types/node": "^22"

  • 升级依赖:
  • pnpm update @types/node # 20.0.0 -> 22.20.1

  • 验证(全量类型检查 0 错误 + 生产构建成功):
  • pnpm exec tsc —noEmit –p tsconfig.json
    pnpm build

    结果:修复前 tsc 有 370+ 处 Buffer 相关错误,修复后 0 错误;pnpm build 完整通过(编译成功、TypeScript 通过、52 个页面/接口全部生成)。

    [!tip] 判断技巧
    只要看到 Type 'Buffer' is not assignable to … 且伴随 SharedArrayBuffer is missing …,基本就是 @types/node 与 TypeScript 版本不匹配,而不是业务代码写错。


    3.5 端口占用

    本机 3000 端口被 grafana 常驻占用,Next.js 会自动改用 3001,日志里会明确写:

    ⚠ Port 3000 is in use by process xxxx, using available port 3001 instead.

    排查与验证:

    Get-NetTCPConnection –LocalPort 3000 –State Listen | Select-Object LocalPort,OwningProcess
    (Invoke-WebRequest –Uri http://localhost:3001 –UseBasicParsing).StatusCode

    部署到服务器时建议把容器/进程端口绑定为 127.0.0.1:3000,对外只通过 Nginx 暴露 80/443。


    3.6 .env.local 配置

    copy .env.example .env.local

    • 所有变量都“可选”,但至少要有一个 LLM 服务商 Key,否则界面能开、生成课程必失败。
    • 建议同时指定 DEFAULT_MODEL=provider:model,例如 openai:gpt-5.5。
    • 共享部署建议设置 ACCESS_CODE 做站点级密码保护。
    • 改完 .env.local 建议重启 pnpm dev / pnpm build 后再访问。

    各服务商 Key 与 TTS/ASR 是分开的变量族:

    能力变量前缀示例
    LLM 对话 OPENAI_API_KEY、DEEPSEEK_API_KEY、XIAOMI_API_KEY …
    TTS 语音合成 TTS_XIAOMI_API_KEY、TTS_MINIMAX_API_KEY …
    ASR 语音识别 ASR_OPENAI_API_KEY、ASR_FUNASR_BASE_URL …

    四、小米 MiMo TTS 接入经验

    4.1 关键结论:MiMo TTS 不是 OpenAI 的 /audio/speech

    官方接口形态(https://mimo.mi.com/docs):

    • 请求:POST https://api.xiaomimimo.com/v1/chat/completions
    • 认证头:api-key: $MIMO_API_KEY(OpenAI SDK 的 Authorization: Bearer 同样可用)
    • 待合成文本放在 role: "assistant" 的 message 里(不是 user)
    • 音频参数:"audio": { "format": "wav", "voice": "mimo_default" }
    • 返回:base64 音频在 choices[0].message.audio.data

    模型:mimo-v2.5-tts(预置音色)、mimo-v2.5-tts-voicedesign(文本设计音色)、mimo-v2.5-tts-voiceclone(音色复刻)。

    预置音色: mimo_default、冰糖、茉莉、苏打、白桦、Mia、Chloe、Milo、Dean。

    因此:OpenMAIC 里“添加自定义语音合成(OpenAI 兼容)”按钮只支持 /audio/speech,对 MiMo 无效,必须写原生 provider。

    4.2 新增原生 provider 的改动点

    文件改动
    lib/audio/types.ts BuiltInTTSProviderId 增加 'xiaomi-tts'
    lib/audio/constants.ts 注册 provider(模型 mimo-v2.5-tts、9 个音色、默认值、图标)
    lib/audio/tts-providers.ts 新增 generateXiaomiMiMoTTS():chat/completions + audio 参数 + base64 解码
    lib/server/provider-config.ts 环境变量映射 TTS_XIAOMI / TTS_MIMO → xiaomi-tts
    lib/audio/provider-display.ts、lib/store/settings.ts、components/settings/tts-settings.tsx 显示名、默认配置、接口路径提示
    lib/i18n/locales/*.json(12 个) 新增 providerXiaomiTTS 文案
    .env.example / .env.local 新增 TTS_XIAOMI_API_KEY、TTS_XIAOMI_BASE_URL 说明

    4.3 配置与验证

    TTS_XIAOMI_API_KEY=你的MiMo密钥
    TTS_XIAOMI_BASE_URL=https://api.xiaomimimo.com/v1

    # Token Plan 区域端点(按需替换):
    # TTS_XIAOMI_BASE_URL=https://token-plan-cn.xiaomimimo.com/v1
    # TTS_XIAOMI_BASE_URL=https://token-plan-sgp.xiaomimimo.com/v1
    # TTS_XIAOMI_BASE_URL=https://token-plan-ams.xiaomimimo.com/v1

    TTS_MIMO_* 是 TTS_XIAOMI_* 的别名,两者等价。

    验证:重启 → 设置 → 语音合成 → 选 “Xiaomi MiMo TTS” → 选音色 → 点试听。

    [!note] 注意
    已为对话模型配置的 XIAOMI_API_KEY 不会自动用于语音合成,必须单独配置 TTS_XIAOMI_API_KEY。


    五、复制项目给别人(不带密钥)

    复制时排除个人密钥与运行期数据:

    robocopy "G:\\vibing\\OpenMAIC-main" "G:\\vibing\\OpenMAIC-copy" /E `
    /XD node_modules .next .codegraph data dist `
    /XF .env.local .env.*.local *.tsbuildinfo

    排除项原因
    .env.local 含 API Key
    data/ 运行期产生的本地数据
    node_modules、.next、dist、*.tsbuildinfo 构建产物/缓存,对方重新安装即可

    复制后校验没有残留密钥(把 $key 换成你的 key 值,或从 .env.local 读取):

    rg –l –F —hidden —no-ignore $key "G:\\vibing\\OpenMAIC-copy"

    无输出即安全;最后打包 Compress-Archive 成 zip,并附上一份安装说明(.env.example 必须保留)。


    六、部署要点(宝塔 + Nginx / Docker)

    两套方案共用同一个架构:应用只监听 127.0.0.1:3000,Nginx 负责 80/443 与 SSL。

    6.1 Docker 方案

    cd /www/wwwroot/openmaic
    cp .env.example .env.local

    # 国内网络加速
    ALPINE_MIRROR=mirrors.tuna.tsinghua.edu.cn \\
    NPM_REGISTRY=https://registry.npmmirror.com \\
    docker compose up -d –build

    curl http://127.0.0.1:3000/api/health

    • 建议把 docker-compose.yml 的端口改为 '127.0.0.1:3000:3000',避免 3000 直接暴露公网。
    • 需要服务端持久化(课程/会话入库)时加 –profile server-persistence,并在构建时传入 NEXT_PUBLIC_PERSISTENCE=1 与一致的 NEXT_PUBLIC_PERSISTENCE_TOKEN(编译期开关,写进浏览器 bundle)。
    • 需要 MP4 导出时加 –profile video-export,该服务含 Chromium + FFmpeg,内存需要 ≥ 8GB,否则会自动降级为下载 ZIP。

    [!warning] 持久化鉴权
    项目内置的是开发级 token 认证,NEXT_PUBLIC_PERSISTENCE_TOKEN 会暴露在前端 JS 中,拿到即可读写所有学习者数据。只适合可信网络 + ACCESS_CODE 的单用户部署;公开多用户必须自行替换为真正的会话鉴权。

    6.2 Nginx + Node(不用 Docker)

    cd /www/wwwroot/openmaic
    node -v # 必须 >= 22.19
    npm i -g pnpm@10
    pnpm install
    NODE_OPTIONS=–max-old-space-size=3072 pnpm build
    pnpm start

    用 pm2 守护:

    npm i -g pm2
    pm2 start pnpm –name openmaic — start
    pm2 save && pm2 startup

    6.3 Nginx 反代配置要点

    server_name maic.example.com;
    client_max_body_size 200m; # 上传课程材料

    location / {
    proxy_pass http://127.0.0.1:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade"; # WebSocket / SSE 必需
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_read_timeout 300s;
    proxy_send_timeout 300s;
    proxy_buffering off; # 流式输出必需
    }

    安全组/防火墙只放行 80、443。


    七、常用命令速查

    # 启动 / 构建
    pnpm dev
    pnpm build
    pnpm start

    # 类型检查与 i18n 校验
    pnpm exec tsc —noEmit –p tsconfig.json
    node scripts/check-i18n-keys.mjs

    # 单独构建 workspace 包
    pnpm —filter @openmaic/renderer run build
    pnpm —filter @openmaic/editor run build

    # 清理缓存(先停 dev server)
    node –e "require('fs').rmSync('.next',{recursive:true,force:true})"

    # 健康检查
    (Invoke-WebRequest http://localhost:3001/api/health –UseBasicParsing).Content


    在这里插入图片描述

    八、经验总结

  • 先 pnpm install 再启动;postinstall 会构建全部子包,中断了就用 pnpm –filter <包> run build 补。
  • pnpm-lock 是唯一依赖真相;不要用 npm 安装,不要手工改 node_modules 里的版本号。
  • 改依赖前先停 dev server,改完清一次 .next,能避开 Windows 文件锁和 Turbopack 陈旧缓存这两类“假故障”。
  • dev 不查类型、build 才查类型;本地能跑不代表 pnpm build 能过,交付前一定跑一次完整构建。
  • 报错先看进程与端口(Port … in use),再看依赖树,最后才怀疑业务代码。
  • 区分编译期与运行时环境变量:NEXT_PUBLIC_* 在构建时写进前端 bundle,改完必须重新 build,只改 .env.local 不生效。
  • 第三方能力要核对真实协议:MiMo TTS 表面是“OpenAI 兼容”,实际走 chat/completions 的 audio 通道,套用通用 TTS 适配器必然失败。
    在这里插入图片描述
  • 赞(0)
    未经允许不得转载:171主机测评 » OpenMAIC 运行踩坑与经验
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址