本地运行 Vercel AI SDK 课程
使用本页面在你的电脑上运行 Vercel AI SDK 课程中提取的客户支持代理,用你自己的 OpenAI 密钥和在课程中构建的 Supabase 项目获取答案。一个 Node 服务器运行整个项目:它既提供聊天页面,也回答问题,所以你的密钥始终保存在服务器上,不会流向浏览器。与 Scrimba 编辑器不同的一点是:Node 不会自动读取 .env 文件,所以启动脚本需要一个标志。
你需要先准备什么
安装受支持的 Node.js LTS 版本。推荐使用 Node 24,它包含 npm。
检查两个命令都能正常工作。你的版本号可能不同:
$ node --version
v24.18.0
$ npm --version
11.18.0你还需要三个值:
- 一个 OpenAI API 密钥,来自已设置账单的账户,因为 OpenAI 会为每个答案计费;
- 你的 Supabase 项目 URL,在项目的连接对话框中显示;
- 该项目的密钥,以
sb_secret_开头,位于设置 > API 密钥中。
使用课程中的 Supabase 项目。代理会通过项目的 match_documents 函数搜索存储其中的 Scrimba 帮助文档。如果你不再拥有该项目,服务器启动时仍需要 Supabase URL 和密钥,使用新项目的值也可以。只有 Scrimba 问题才会用到 Supabase,所以一般性问题仍然能通过网络搜索获得答案,而 Scrimba 问题则找不到任何搜索结果。
旧版 service_role 密钥也可用,直到 Supabase 在 2026 年底停用它。参考 Supabase API 密钥。
node --version 和 npm --version 都能打印出版本。然后收集三样东西:你的 OpenAI 密钥、Supabase 项目 URL 和该项目的密钥。 使用你在课程中构建的 Supabase 项目;新项目没有代理可以搜索的文档。
安装依赖包
在提取的文件夹中打开终端,该文件夹包含 package.json 和 server.js,然后安装课程使用的确切版本:
$ cd path-to-your-extracted-project
$ npm ci
added 94 packages, and audited 95 packages in 4snpm 还会报告这些包中存在的一些漏洞。它们不会阻止项目在你的电脑上运行。不要运行 npm audit fix;它会升级课程代码所针对的包。
package.json 的文件夹中运行 npm ci。它会最后报告添加了多少个包。 如果 npm 说需要现有的 package-lock.json 才能安装,说明你在错误的文件夹中。
修改启动脚本
在 Scrimba 中,编辑器将你的密钥交给服务器。在你的电脑上,Node 只在你要求时才读取 .env,而 config.js 如果 OpenAI 密钥缺失会立即停止服务器。打开 package.json 并将启动脚本从:
"start": "node server.js"改为:
"start": "node --env-file=.env server.js"这个标志内置于 Node,所以没有额外的东西需要安装。
package.json 中,按照所示准确添加 --env-file=.env 到启动脚本,然后保存文件。项目中的其他内容都不变。 将你的密钥添加到 .env
在 package.json 旁边创建 .env 文件,包含你的三个值:
OPENAI_API_KEY=your-openai-api-key
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_SERVICE_ROLE_KEY=your-supabase-secret-key
PORT=3000代码仍然使用旧名称 SUPABASE_SERVICE_ROLE_KEY;将你的密钥放在那里,不要重命名任何东西。它必须是密钥或旧版 service_role 密钥,不能是可发布密钥,后者用于浏览器代码,没有服务器需要的访问权限。PORT 是可选的:没有它的话,服务器使用 3000。
在 package.json 旁边创建 .gitignore 并添加:
.env
node_modules/进入 Git 仓库的密钥即使在你删除文件后也会保留在其历史记录中。Git 手册在忽略文件和好习惯中介绍了这个习惯。
将 Supabase 密钥保存在服务器上
你的 Supabase 密钥可以读取和改变数据库中的一切。在这个项目中只有服务器读取它,这是唯一安全的地方:永远不要将它复制到 client.js,也不要提交或分享 .env。
package.json 旁边创建一个名为 .env 的文件,在前三行输入你的值,然后在 .gitignore 中列出 .env,这样 Git 就永远不会保存它。 启动代理并提问
启动服务器:
$ npm start
> start
> node --env-file=.env server.js
Server listening at http://localhost:3000打开 http://localhost:3000,或者你在 .env 中设置的端口。Support AI Chatbot 页面有一个问题输入框和一个提问按钮。提一个关于 Scrimba 的问题,例如如何重置你的密码。当代理工作时,页面显示思考中…,然后显示答案。当答案来自你的 Supabase 文档时,答案下方的查看来源会列出它使用的段落,每个都有相似度分数:OpenAI 和 Supabase 都有效。一般性问题,例如关于新闻的问题,会通过网络搜索得到答案,并列出网页;这只需要 OpenAI。RAG 章节解释了代理为什么在回答前会查找信息。
如果答案显示 I encountered an error while processing your request using tool calling. Please try again later.,页面无法告诉你原因。原因在服务器运行的终端中,在 [ToolBased] Error in RAG process: 这一行下面。
用 Ctrl+C 停止服务器。
npm start,等待 Server listening at http://localhost:3000,然后打开那个地址。提一个关于 Scrimba 的问题并等待答案。 如果答案说遇到了错误,看终端而不是页面。
故障排除
服务器立即停止并显示 Missing OPENAI_API_KEY environment variable: Node 没有加载 .env。检查启动脚本是否说 node --env-file=.env server.js 以及 .env 中的名称是否正确是 OPENAI_API_KEY。SUPABASE_SERVICE_ROLE_KEY is missing or invalid 和 SUPABASE_URL is missing or invalid 对这些名称的意思相同。
node: .env: not found: 启动脚本没问题,但 package.json 旁边没有 .env。检查文件是否名称正确是 .env,而不是 .env.txt。
Invalid supabaseUrl: Must be a valid HTTP or HTTPS URL.: SUPABASE_URL 必须是从连接对话框获取的完整地址,以 https:// 开头。
Error: listen EADDRINUSE: address already in use :::3000: 另一个程序正在使用 3000 端口,通常是这个服务器的另一个终端中的早期运行。用 Ctrl+C 停止它,或在 .env 中设置 PORT=3001,重新启动并打开 http://localhost:3001。
答案说它遇到了错误,终端显示 Incorrect API key provided: OpenAI 拒绝了密钥并返回 401。从你的 OpenAI 账户重新复制密钥,检查它没有被删除,然后重启服务器。
终端显示 You exceeded your current quota: 密钥有效,但 OpenAI 账户没有信用。在你的 OpenAI 账户中添加账单,然后再试一次。
Scrimba 问题得到没有来源的答案,终端显示以 [Tool:KB] Error 开头的一行: OpenAI 有效,但 Supabase 没有返回课程文档。检查 URL 和密钥来自同一项目,密钥是密钥或 service_role 密钥而不是可发布密钥,项目仍然有课程文档和其 match_documents 函数。
终端显示模型 gpt-4o 不可用: OpenAI 在 2027 年 1 月 14 日关闭 gpt-4o,并将 gpt-6-luna 命名为其替代品。将 constants.js 中的 ANSWERING_MODEL 改为 OpenAI 弃用页面上的替代品。保持 EMBEDDING_MODEL_NAME 为 text-embedding-3-small:Supabase 中的文档是用它嵌入的,不同的嵌入模型会找到很差的匹配而不会产生任何错误。
npm start 后立即停止,问题在 package.json 或 .env 中。如果页面用道歉回应,原因在服务器的终端中。 
