1. 项目概述:从“想法”到“产品”的极限挑战
最近在AI圈子里,GLM-5的“全栈长任务”能力被讨论得沸沸扬扬。简单来说,它不再是一个只能回答单轮问题的聊天机器人,而是能像一个真正的工程师一样,理解一个复杂的、多步骤的项目需求,然后自主规划、拆解任务,并调用各种工具(比如写代码、调用API、处理文件)去一步步完成它。这听起来就像是给了一个“AI全栈工程师”。于是,一个大胆的想法冒了出来:如果让GLM-5去复刻一个像TikTok视频生成这样的复杂SaaS(软件即服务)应用,从零开始,它能做到什么程度?需要多久?
这个项目的核心,就是一次极限压力测试。我们不依赖任何现成的、封装好的视频生成API服务,而是要求AI从最基础的环境搭建开始,理解前后端分离的架构,设计数据库,编写核心的视频处理逻辑,并最终打包成一个可运行的、具备基本用户交互界面的Web应用。目标是在3小时内,见证一个从“一句话需求”到“可运行原型”的完整诞生过程。这不仅仅是测试GLM-5的代码能力,更是对其项目规划、架构设计、多工具协同和长上下文记忆能力的全面考验。对于开发者而言,这个过程本身就是一个绝佳的“全栈项目快速启动”实战教程,你能清晰地看到一个现代SaaS应用是如何被一步步构建出来的。
2. 技术栈选型与架构设计思路
面对“复刻TikTok视频生成SaaS”这样一个宏大的目标,第一步不是埋头写代码,而是进行冷静的技术选型和架构设计。这决定了项目的可行性、开发效率以及最终成品的质量。GLM-5在这个环节展现出了令人印象深刻的“工程思维”。
2.1 为什么选择Next.js + FastAPI组合?
这是整个项目的技术基石。选择它们,是基于对项目需求、开发效率和生态成熟度的综合考量。
前端:Next.js 是必然之选。对于一个SaaS应用,尤其是内容生成类应用,用户体验和性能至关重要。Next.js基于React,提供了开箱即用的服务端渲染(SSR)和静态站点生成(SSG)能力。这意味着我们的应用首页可以极快地加载,对搜索引擎友好,同时也为后续可能的复杂交互(如视频预览、用户仪表盘)提供了强大的框架支持。它的App Router模式让基于文件系统的路由变得异常清晰,Server Actions功能则允许我们在服务端直接执行函数,简化了API调用逻辑,非常适合与后端FastAPI进行高效对接。更重要的是,Next.js的生态极其丰富,部署到Vercel等平台几乎是一键完成,这完美契合了我们“快速验证、快速上线”的SaaS理念。
后端:FastAPI 是Python后端的最优解。视频生成涉及大量的文件I/O、异步任务处理和机器学习模型调用(尽管本项目初期可能用模拟逻辑)。FastAPI凭借其现代、快速(高性能)、易于学习的特点脱颖而出。它基于Python类型提示,能自动生成交互式API文档(Swagger UI),这极大地提升了前后端联调的效率。对于需要处理长时间运行任务(如视频合成)的场景,FastAPI对async/await的原生支持非常优雅,可以方便地集成Celery或RQ等任务队列,实现异步任务处理,避免阻塞主请求。此外,Python在AI/ML和数据处理领域的庞大库生态(如Pillow, OpenCV, MoviePy),使得在FastAPI中集成未来的真实视频生成逻辑会非常顺畅。
数据库:PostgreSQL + Prisma。我们需要存储用户信息、生成任务状态、视频元数据等。PostgreSQL作为功能强大的开源关系型数据库,可靠性高,且支持JSON字段,适合存储一些灵活的结构化数据(如视频的生成参数)。为了提升开发效率,我们选择Prisma作为ORM(对象关系映射)。Prisma具有极佳的类型安全性和直观的数据模型定义方式,其自动生成的客户端让数据库操作变得像调用本地函数一样简单,并且完美支持TypeScript(Next.js)和Python(通过第三方适配器或直接使用SQL),保持了技术栈的一致性。
整体架构:清晰的前后端分离。前端Next.js应用运行在用户浏览器和Vercel服务器上,通过RESTful API或GraphQL与后端FastAPI服务通信。FastAPI服务负责核心业务逻辑:接收前端的视频生成请求,管理任务队列,调用(模拟或真实的)视频处理引擎,并将处理结果(视频文件URL、任务状态)更新到数据库。数据库由PostgreSQL实例托管,所有服务通过Prisma Client进行访问。这种分离架构职责清晰,便于独立开发和扩展。
2.2 核心功能模块拆解
GLM-5将庞大的“视频生成SaaS”需求,拆解成了几个可并行或串行开发的核心模块,这是项目能快速推进的关键:
- 用户认证与授权模块:实现用户注册、登录(含JWT令牌签发与验证)、会话管理。这是SaaS的基石。
- 视频生成任务管理模块:这是核心业务模块。包括:
- 任务创建:接收用户输入(如文案、图片、音乐选择、风格参数)。
- 任务队列:将生成任务放入后台队列,立即返回任务ID,实现异步处理。
- 任务状态查询:提供API供前端轮询或通过WebSocket推送任务进度。
- 结果存储与返回:任务完成后,将生成的视频文件上传至对象存储(如AWS S3、Cloudflare R2或MinIO),并将可访问的URL存入数据库。
- 视频处理引擎(模拟)模块:在3小时极限挑战中,实现真实的AI视频生成不现实。因此,我们构建一个“模拟引擎”。它不会真正进行AI合成,而是根据输入参数,模拟处理时间,并最终返回一个预设的或简单生成的示例视频(例如,将多张图片拼接成幻灯片视频,并加上背景音乐)。这个模块保留了真实引擎的接口,未来可以无缝替换。
- 前端交互界面模块:
- 任务创建页面:表单供用户输入文案、上传素材、选择风格。
- 任务仪表盘:展示用户的历史生成任务列表及其状态(排队中、处理中、完成、失败)。
- 视频播放器:用于播放已完成的视频。
3. 实战开发:3小时极限流水线
有了清晰的蓝图,接下来就是分秒必争的实战。我们按照模块划分,并行推进开发。
3.1 第一阶段:项目初始化与基础框架搭建(约30分钟)
这个阶段的目标是建立起项目骨架,确保开发环境畅通。
后端(FastAPI)初始化:
# 创建项目目录并进入 mkdir tiktok-saas-backend && cd tiktok-saas-backend # 创建虚拟环境 python -m venv venv # 激活虚拟环境 (Windows: venv\Scripts\activate) source venv/bin/activate # 安装核心依赖 pip install fastapi uvicorn sqlalchemy psycopg2-binary pydantic python-jose[cryptography] passlib[bcrypt] python-multipart # 初始化项目结构 mkdir app cd app mkdir api models schemas core services utils touch __init__.py main.py在main.py中,快速搭建一个最简单的FastAPI应用,并连接数据库。使用Pydantic定义清晰的数据验证模型(Schemas),使用SQLAlchemy定义数据库模型(Models)。同时,在core目录下配置数据库连接、安全(JWT)等核心设置。
前端(Next.js)初始化:
# 使用Next.js官方脚手架创建项目,选择TypeScript和Tailwind CSS npx create-next-app@latest tiktok-saas-frontend --typescript --tailwind --app cd tiktok-saas-frontend # 安装必要的UI库和HTTP客户端(这里以shadcn/ui和axios为例) npm install axios npx shadcn@latest init # 按提示初始化,选择部分组件如button, card, input等初始化后,立即配置API基础URL(指向本地FastAPI服务),并规划出主要的页面路由:/(首页/登录),/dashboard(仪表盘),/create(创建任务)。
数据库初始化:使用Docker快速启动一个PostgreSQL实例。
docker run --name tiktok-saas-db -e POSTGRES_PASSWORD=yourpassword -p 5432:5432 -d postgres:15然后,使用Prisma初始化数据模型。在前后端项目中分别定义Prisma Schema,或共享一个Schema。运行prisma generate创建客户端,并执行prisma db push将模型同步到数据库。
实操心得:环境配置一步到位在极限开发中,环境问题是最大的“时间杀手”。我习惯在项目根目录创建
docker-compose.yml,把数据库、Redis(用于任务队列)等服务都定义好,一行docker-compose up -d就能拉起所有依赖。另外,将requirements.txt和package.json的依赖尽量写准确,避免后续频繁调整。
3.2 第二阶段:核心业务逻辑实现(约90分钟)
这是最核心、最耗时的阶段,需要前后端紧密配合。
后端核心实现:
- 用户认证(
app/api/auth.py):实现/auth/register和/auth/login端点。登录成功后,使用python-jose库生成JWT令牌返回给前端。创建一个依赖项(Dependency)来验证后续请求中的JWT令牌。 - 任务模型与CRUD(
app/models/task.py,app/api/tasks.py):定义Task模型,包含id,user_id,status(pending,processing,completed,failed),parameters(JSON字段存储用户输入),result_url等字段。实现任务的创建、列表查询、状态查询等API。 - 模拟视频处理引擎(
app/services/video_engine.py):import asyncio import random from datetime import datetime from pathlib import Path class MockVideoEngine: async def generate_video(self, task_id: int, parameters: dict) -> str: """模拟视频生成过程""" # 1. 模拟处理时间,比如5-15秒 process_time = random.randint(5, 15) await asyncio.sleep(process_time) # 2. 模拟成功或失败(比如10%的失败率) if random.random() < 0.1: raise Exception("Mock engine failed randomly") # 3. 生成一个模拟的视频文件(这里简单复制一个预设文件,或使用MoviePy生成一个简单视频) # 假设我们有一个预设的output.mp4在assets目录 import shutil output_dir = Path(f"./storage/videos/{task_id}") output_dir.mkdir(parents=True, exist_ok=True) output_path = output_dir / "output.mp4" # shutil.copy("./assets/sample.mp4", output_path) # 复制样本 # 更真实的模拟:用MoviePy根据parameters生成一个简单幻灯片 # from moviepy.editor import ImageSequenceClip, AudioFileClip, concatenate_videoclips # ... 生成逻辑 ... # 4. 返回模拟的视频存储路径(在实际中,这里应上传到对象存储并返回URL) mock_url = f"/storage/videos/{task_id}/output.mp4" return mock_url - 异步任务队列集成:为了不阻塞API响应,当用户创建任务时,API只负责将任务信息存入数据库(状态为
pending),然后立即向一个任务队列(如Celery,或更轻量的RQ)发送一个消息。一个独立的Worker进程会监听这个队列,收到消息后调用MockVideoEngine.generate_video(),并在完成后更新数据库中的任务状态和result_url。在3小时挑战中,我们可以先用一个简单的后台线程池或asyncio.create_task来模拟,但架构上为真正的队列留好接口。
前端核心实现:
- 状态管理:使用React Context或Zustand这样的轻量级状态库,来管理用户的登录状态和JWT令牌。
- API服务封装(
lib/api.ts):使用Axios创建预配置的HTTP客户端,自动在请求头中附加JWT令牌,并统一处理错误响应。 - 任务创建页面(
app/create/page.tsx):构建一个表单,包含文案输入框、素材上传区域(使用input type=file)、风格选择下拉框等。表单提交时,调用后端的任务创建API。 - 任务仪表盘(
app/dashboard/page.tsx):- 使用
useEffect和setInterval或更优的setTimeout递归,定期轮询/api/tasks接口,获取用户的任务列表。 - 将任务以卡片形式展示,清晰显示状态(用不同颜色的Badge组件)。对于“处理中”的任务,可以显示一个进度条动画(虽然是模拟的,但能提升用户体验)。
- 为“已完成”的任务提供视频播放组件(使用HTML5
video标签或第三方播放器)。
- 使用
踩坑记录:前后端状态同步最初我让前端在创建任务后,盲目地每2秒轮询一次所有任务,这在任务多时会给后端造成不必要的压力。优化方案是:a) 创建任务后,前端只轮询该单个任务的状态,直到完成或失败。b) 更进阶的做法是,在后端任务状态更新时,通过WebSocket或Server-Sent Events主动推送给前端。在3小时挑战中,轮询是性价比最高的方案,但必须在代码中处理好清理定时器,防止内存泄漏。
3.3 第三阶段:联调、测试与部署准备(约60分钟)
最后阶段,将所有部分连接起来,形成一个可运行的整体。
- 跨域问题(CORS):在FastAPI后端,使用
fastapi.middleware.cors的CORSMiddleware,正确配置前端Next.js开发服务器的地址(通常是http://localhost:3000),允许其进行跨域请求。 - 静态文件服务:为了让前端能访问到模拟引擎生成的“视频文件”,需要在FastAPI中配置静态文件目录,将
./storage/videos目录暴露出来。from fastapi.staticfiles import StaticFiles app.mount("/storage", StaticFiles(directory="storage"), name="storage") - 集成测试:手动进行端到端测试。从前端注册新用户开始,登录,创建任务,在仪表盘观察状态变化,直到任务完成并播放视频。检查整个流程是否畅通,错误是否被妥善处理(如网络错误、生成失败)。
- 部署配置:
- 后端:创建
Dockerfile,基于Python镜像,复制代码,安装依赖,暴露端口。编写docker-compose.prod.yml,定义后端服务、PostgreSQL、Redis等。 - 前端:运行
npm run build生成生产环境优化包。Next.js应用可以轻松部署到Vercel,只需关联Git仓库即可。 - 环境变量:将数据库连接字符串、JWT密钥等敏感信息从代码中抽离,通过环境变量配置。
- 后端:创建
4. GLM-5在“全栈长任务”中的表现分析
经过这场紧张的3小时实战,GLM-5的“全栈长任务”能力得到了具象化的验证。它的表现远超一个单纯的代码补全工具。
优势与亮点:
- 宏观架构规划能力:GLM-5并非机械地堆砌代码。它能理解“SaaS”、“视频生成”、“前后端分离”这些概念,并主动推荐了Next.js + FastAPI + PostgreSQL这套非常合理且现代的技术栈组合。它甚至能考虑到异步任务队列、对象存储这些生产环境必需的组件。
- 上下文记忆与状态维持:在整个长对话中,GLM-5能牢牢记住项目的核心目标、已选技术栈和已实现的模块。当我要求它“接着实现用户登录API”时,它知道要在已有的FastAPI项目中,在
app/api/auth.py路径下,使用之前定义好的Pydantic模型和数据库连接来编写代码,而不会凭空创造一个新的项目结构。 - 多工具协同与代码生成:它不仅能生成Python、TypeScript、SQL代码,还能生成Dockerfile、docker-compose.yml、环境变量示例(.env.example)、甚至简单的README说明。它像一个真正的工程师,知道一个完整的项目需要哪些类型的文件。
- 问题诊断与修复建议:当我在测试中故意引入一个错误(比如错误的导入语句)并向它描述现象时,GLM-5能根据错误信息给出非常具体的排查步骤和修复代码,而不是泛泛而谈。
局限与挑战:
- 逻辑深度与业务复杂性:对于极其复杂的业务逻辑(比如一个真实的、多阶段的AI视频生成Pipeline),GLM-5目前可能无法一次性生成完美无缺的代码。它更擅长搭建框架和实现标准模式(如CRUD、JWT认证)。复杂的算法和业务规则仍需人类工程师深度介入设计和调试。
- 对最新库版本的细微差异不敏感:在生成代码时,它可能使用某个库的通用写法,但该写法可能与项目中选择的特定小版本存在细微的不兼容。例如,Prisma Client的调用方式或FastAPI某个参数在不同版本间可能有变化。这需要开发者具备基本的调试和查阅最新官方文档的能力。
- 资源与时间估算过于理想化:GLM-5规划的3小时,是在一切顺利、开发者对技术栈熟悉、且无需深入调试复杂Bug的理想情况下。实际开发中,环境配置问题、依赖冲突、第三方服务API变动等“黑天鹅”事件会消耗大量时间。它更像一个“最优情况”下的导航,而非绝对的时间保证。
5. 常见问题与避坑指南
在实际操作中,尤其是限时高压环境下,以下几个问题是高频雷区:
1. 端口冲突与CORS配置错误
- 问题:前端(localhost:3000)访问后端(localhost:8000)时,浏览器报CORS错误。
- 排查:首先确保后端服务正在运行(
uvicorn app.main:app --reload --port 8000)。然后,检查FastAPI的CORS中间件配置,确保allow_origins列表中包含了http://localhost:3000。不要使用通配符"*"在生产环境。 - 技巧:在开发环境,可以在后端启动命令中添加
--reload参数,这样修改代码后会自动重启。在前端Next.js中,配置next.config.js的async rewrites()函数,将API请求代理到后端端口,可以彻底避免CORS问题。
2. 数据库连接失败或迁移问题
- 问题:应用启动时无法连接到PostgreSQL,或表结构未同步。
- 排查:
- 检查Docker容器是否运行:
docker ps | grep postgres。 - 检查连接字符串格式:
postgresql://user:password@localhost:5432/dbname。注意主机名:在Docker容器内连接时用服务名(如db),在宿主机连接时用localhost。 - 对于Prisma,每次修改
schema.prisma后,必须依次运行prisma generate和prisma db push(开发环境)或创建迁移文件prisma migrate dev。
- 检查Docker容器是否运行:
- 技巧:在
docker-compose.yml中为数据库服务添加healthcheck,并让后端服务依赖数据库的健康状态再启动,可以避免启动时序问题。
3. 模拟任务状态不更新
- 问题:前端看到任务一直处于“处理中”,但后端日志显示早已完成。
- 排查:
- 后端:确认Worker进程或异步任务函数在完成后,确实执行了更新数据库状态的代码。检查SQL更新语句是否成功,没有异常被静默吞掉。
- 前端:检查轮询逻辑。确保定时器在组件卸载时被正确清理(
useEffect的清理函数)。检查轮询API返回的数据结构是否与前端解析的格式一致。
- 技巧:在后端任务处理函数中,加入详细的日志记录(如
logging.info(f"Task {task_id} started...")),便于追踪执行流。在前端,可以使用React Query或SWR这类库来管理异步状态和轮询,它们内置了缓存、重试和定时更新功能,比手动写setInterval更健壮。
4. 静态文件访问404
- 问题:视频生成后,前端拿到的URL是
/storage/videos/123/output.mp4,但播放时提示404。 - 排查:
- 确认FastAPI的
StaticFiles中间件正确挂载,且目录路径正确。 - 确认文件确实存在于服务器的
./storage/videos/123/目录下。 - 检查服务器文件系统的权限,确保应用进程有该目录的读写权限。
- 确认FastAPI的
- 技巧:在生产环境中,绝对不要用这种方式提供用户上传的文件。必须使用对象存储服务(如AWS S3、Cloudflare R2、阿里云OSS)。这些服务提供高可用、高并发、低成本的文件存储和CDN分发。在开发环境模拟时,可以先将文件写入本地,但返回给前端的URL应是一个能通过对象存储SDK预签名的临时访问URL,这样前端代码就无需改变,未来切换存储服务时只需修改后端上传逻辑。
这次3小时挑战,与其说是在“测试AI”,不如说是在探索一种“人机协同”的新开发范式。GLM-5像一个不知疲倦、知识渊博的初级全栈伙伴,负责将高层想法转化为具体的代码框架和模块实现,极大地压缩了项目从0到1的启动时间。而开发者则扮演架构师和资深调试员的角色,负责把握方向、设计核心算法、处理边界情况以及解决那些棘手的、需要深度领域知识的Bug。这种组合,或许正是未来高效软件开发的常态。对于个人开发者或小团队来说,这意味着可以用极低的成本快速验证产品创意;对于经验丰富的工程师,这则是将你从重复性的样板代码中解放出来,更专注于创造真正价值的神兵利器。