ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Vibe Coding 从 0 到 1 打造 AI 产品:TaoToken 统一 Key 接入 Next.js + Supabase + Vercel 上线一个月复盘

Vibe Coding 从 0 到 1 打造 AI 产品:TaoToken 统一 Key 接入 Next.js + Supabase + Vercel 上线一个月复盘 1. 一个月上线一个 AI 产品我踩过的坑比功能还多Vibe Coding 这个词最近被聊得很多但真正用它从 0 到 1 把一个 AI 产品推到线上、并且跑满一个月的人其实不算多。我用 Next.js 做前端、Supabase 存数据、Vercel 部署AI 能力通过 TaoToken 统一 Key 接入上线一个月后总活跃用户三千出头注册五百多收入为零但订阅和额度机制已经预留好了。这篇文章不聊虚的直接把可复制的config.toml、settings.json骨架、环境变量清单以及这一个月里真正让我卡住的几个问题摊开讲。如果你也在用 Vibe Coding 的方式做 AI 产品或者正准备把 Next.js Supabase Vercel 这套组合跑起来下面这些内容你可以直接抄。核心检索词先摆出来Vibe Coding 是一套用自然语言驱动 AI 写代码的开发方式适合个人开发者和小团队快速验证想法Next.js 负责前端和轻量后端逻辑Supabase 提供认证和数据库Vercel 负责部署TaoToken 则把多家模型的调用收敛成一个 Key 和一条 API 通道省掉到处申请和切换的麻烦。我试过在项目里同时接三家模型结果环境变量、计费口径、报错格式全不一样光对齐就花掉一个周末。后来统一走 TaoToken 的 API 通道配置量直接砍半。下面按实际开发顺序拆开讲。2. 为什么用 TaoToken 统一 Key 接入 AI 能力2.1 多模型切换的真实痛点Vibe Coding 项目里AI 能力通常不止一处文本检查、润色、翻译、标题生成、配图描述每一处对模型的要求都不一样。有的任务要便宜快有的任务要理解力强。如果每个模型单独申请 Key、单独写一套请求封装代码里会散落一堆 base_url 和鉴权逻辑后期换模型等于重写。TaoToken 的做法是把这些收敛成一条通道你拿一个 Key通过统一的 API 地址调用模型名在请求体里指定。对 Next.js 项目来说这意味着只需要维护一份环境变量和一个请求封装函数。2.2 接入前需要准备什么先去官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 注册账号然后在控制台创建 API Key。控制台地址是 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite API Key 管理页在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。API 基础地址是 https://taotoken.net/api 注意这个地址不带 UTM 参数直接写进代码里。注意API Key 只放在服务端环境变量里绝对不要写进前端代码或提交到 Git。Next.js 里只有NEXT_PUBLIC_开头的变量才会暴露到浏览器所以你的 Key 变量名不要加这个前缀。2.3 模型选择建议文本类任务用理解力强的模型配图描述和简单分类用轻量模型。具体模型名以 TaoToken 控制台和接入文档为准文档地址 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。如果你要长期做编码类 Agent可以看 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。3. 可复制的配置骨架3.1 环境变量清单在项目根目录建.env.localVercel 后台也配一份同样的。清单如下# TaoToken 统一接入 TAOTOKEN_API_KEYsk-你的key TAOTOKEN_BASE_URLhttps://taotoken.net/api # Supabase NEXT_PUBLIC_SUPABASE_URLhttps://xxxx.supabase.co NEXT_PUBLIC_SUPABASE_ANON_KEYeyJhbGci... SUPABASE_SERVICE_ROLE_KEYeyJhbGci... # 站点 NEXT_PUBLIC_SITE_URLhttps://yourdomain.comSUPABASE_SERVICE_ROLE_KEY只在服务端用用于额度扣减这类需要绕过 RLS 的操作。NEXT_PUBLIC_开头的两个是给浏览器端 Supabase 客户端用的可以暴露。3.2 config.toml 骨架如果你用支持 TOML 配置的 AI 编码工具可以放一份config.toml在项目根目录把模型和通道固定下来[provider] name taotoken base_url https://taotoken.net/api api_key_env TAOTOKEN_API_KEY [models.default] name 你的默认模型名 max_tokens 4096 temperature 0.7 [models.cheap] name 你的轻量模型名 max_tokens 2048 temperature 0.3 [request] timeout_seconds 60 retry 2这份配置的作用是让 AI 编码工具在生成请求代码时有个统一参照避免它每次自己编一个 base_url 出来。3.3 settings.json 骨架有些工具读settings.json放一份在.vscode/或项目根目录{ ai.provider: taotoken, ai.baseUrl: https://taotoken.net/api, ai.apiKeyEnv: TAOTOKEN_API_KEY, ai.defaultModel: 你的默认模型名, ai.fallbackModel: 你的轻量模型名, ai.maxRetries: 2, ai.timeoutMs: 60000 }3.4 Next.js 里的请求封装在lib/ai.ts里写一个统一调用函数所有 AI 功能都走它const BASE_URL process.env.TAOTOKEN_BASE_URL!; const API_KEY process.env.TAOTOKEN_API_KEY!; export async function callAI( model: string, messages: { role: string; content: string }[], options?: { temperature?: number; maxTokens?: number } ) { const res await fetch(${BASE_URL}/v1/chat/completions, { method: POST, headers: { Content-Type: application/json, Authorization: Bearer ${API_KEY}, }, body: JSON.stringify({ model, messages, temperature: options?.temperature ?? 0.7, max_tokens: options?.maxTokens ?? 4096, }), }); if (!res.ok) { const err await res.text(); throw new Error(AI 请求失败 ${res.status}: ${err}); } const data await res.json(); return data.choices[0].message.content as string; }这个函数放在服务端路由里调用比如app/api/check/route.ts不要在前端组件里直接 fetch否则 Key 会泄露。4. 验证请求与成功结果4.1 先用 curl 打通在终端里跑一条最小请求确认 Key 和通道没问题curl -X POST https://taotoken.net/api/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -d { model: 你的模型名, messages: [{role: user, content: 用一句话解释什么是 Vibe Coding}] }返回里能看到choices[0].message.content就说明通道通了。如果返回 401检查 Key 有没有多余空格返回 404检查 base_url 是不是写成了带路径的完整地址。4.2 在 Next.js 里跑通一次真实调用建一个测试路由app/api/ping/route.tsimport { NextResponse } from next/server; import { callAI } from /lib/ai; export async function GET() { const text await callAI(你的模型名, [ { role: user, content: 回复两个字通了 }, ]); return NextResponse.json({ ok: true, text }); }本地npm run dev后访问http://localhost:3000/api/ping看到{ok:true,text:通了}就说明整条链路打通了。这一步很重要因为 Vercel 上的环境变量和本地是分开的本地通了不代表线上通部署后要再访问一次线上地址确认。4.3 Supabase 侧验证注册用户数、额度消耗这些数据在 Supabase 后台看。建一张usage_logs表记录每次调用create table usage_logs ( id bigint generated by default as identity primary key, user_id uuid references auth.users(id), model text not null, tokens_used int not null default 0, created_at timestamptz default now() );每次callAI成功后插一条记录这样额度机制和用量分析都有数据支撑。上线一个月我就是靠这张表发现英文用户字符额度消耗异常后来把额度从按字符改成按 Token 计算。5. 本篇常见错排查5.1 环境变量在 Vercel 上不生效最常见的原因是本地.env.local改了但 Vercel 后台没同步。Vercel 的环境变量分 Production、Preview、Development 三套只配一套的话预览部署会读不到。改完环境变量必须重新部署才生效热更新不会带上新变量。5.2 前端直接调用导致 Key 泄露如果浏览器控制台里看到请求头带着Authorization: Bearer sk-...说明你把调用写在了客户端组件里。检查文件顶部有没有use client有的话就不能直接读TAOTOKEN_API_KEY。正确做法是前端调自己的/api/xxx路由由服务端路由去调 TaoToken。5.3 上下文污染导致 AI 改错代码这个坑我踩得最狠。项目里堆了一堆 AI 生成的说明文档额度机制从字符改成 Token 后旧文档没删AI 参考到旧文档又把逻辑改回字符计算。解决办法是维护一份ARCHITECTURE.md作为单一信息源每次对话明确让它参考这个文件同时定期清理过期文档。5.4 单文件膨胀到三千行Vibe Coding 很容易让 AI 把所有逻辑塞进一个组件。我的TextEditor.tsx一度超过三千行排查一个 Bug 要读的代码量巨大Token 消耗也高。对策是每完成两三个功能就让 AI 检查文件大小和冗余逻辑把状态管理抽到 Jotai类型定义抽到统一目录。先规划文件结构再让 AI 填代码比事后重构省力得多。5.5 页面 AI 味太重大圆角、渐变按钮、每个图标都配文字标签这是 AI 生成页面的典型特征。想避免的话别跟 AI 说“改好看点”要说具体指令圆角调小、按钮改黑色、去掉图标下方的说明文字。前提是你自己对想要的效果有概念否则 AI 只会给你流行趋势的平均值。6. 上线一个月后的效果验证与下一步一个月的数据摆在这里总活跃三千多注册五百多收入零。曝光量前二十几天每天只有十几到几十最近一周部分页面被索引后涨到每天八百多。宣传上投稿技术周刊带来初期六七百访问技术社区长文和社媒视频各有贡献SEO 方面每个功能做了独立落地页和关键词。验证动作其实就三件事看 Supabase 的注册转化、看usage_logs的模型调用分布、看 Google Analytics 的页面停留。三者对不上就说明某一环有问题比如注册多但调用少可能是引导流程断了。下一步我准备把额度机制和订阅打通模型调用继续走 TaoToken 统一通道省下来的时间用来做功能设计而不是对接。如果你也在做类似的事模型对话调试可以用 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite 接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 长期编码类需求看 Coding Plan。先把 curl 那条命令跑通剩下的就是重复和迭代。
返回列表