跳到主要内容

AI 全栈应用开发

问题

如何构建一个完整的 AI 全栈应用?从数据库到部署的完整架构是怎样的?

答案

一、典型技术栈

二、数据库设计

-- 用户表
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email VARCHAR(255) UNIQUE NOT NULL,
name VARCHAR(100),
created_at TIMESTAMP DEFAULT NOW()
);

-- 会话表
CREATE TABLE conversations (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id),
title VARCHAR(200),
model VARCHAR(50) DEFAULT 'gpt-4o',
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);

-- 消息表
CREATE TABLE messages (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
conversation_id UUID REFERENCES conversations(id) ON DELETE CASCADE,
role VARCHAR(20) NOT NULL, -- 'user' | 'assistant' | 'system'
content TEXT NOT NULL,
tokens_used INTEGER,
created_at TIMESTAMP DEFAULT NOW()
);

-- 向量索引(pgvector)
CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE documents (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
content TEXT NOT NULL,
embedding vector(1536),
metadata JSONB,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX ON documents USING hnsw (embedding vector_cosine_ops);

三、核心 API 实现

app/api/chat/route.ts
import { openai } from "@ai-sdk/openai";
import { streamText } from "ai";
import { auth } from "@/lib/auth";
import { db } from "@/lib/db";

export async function POST(req: Request) {
// 1. 认证
const session = await auth();
if (!session?.user) {
return new Response("Unauthorized", { status: 401 });
}

const { messages, conversationId } = await req.json();

// 2. 保存用户消息
const userMessage = messages[messages.length - 1];
await db.message.create({
data: {
conversationId,
role: "user",
content: userMessage.content,
},
});

// 3. 流式调用 LLM
const result = streamText({
model: openai("gpt-4o"),
messages,
onFinish: async ({ text, usage }) => {
// 4. 保存 AI 回复
await db.message.create({
data: {
conversationId,
role: "assistant",
content: text,
tokensUsed: usage.totalTokens,
},
});
},
});

return result.toDataStreamResponse();
}

四、认证方案

lib/auth.ts
import NextAuth from "next-auth";
import GitHub from "next-auth/providers/github";

export const { auth, handlers, signIn, signOut } = NextAuth({
providers: [GitHub],
callbacks: {
async session({ session, token }) {
session.user.id = token.sub!;
return session;
},
},
});

五、部署方案

平台优势适用
VercelNext.js 最佳体验,Edge Runtime标准 AI 应用
Railway全栈部署,Docker 支持后端复杂的应用
Fly.io全球边缘部署低延迟要求
自建 Docker完全控制企业私有部署
docker-compose.yml
services:
app:
build: .
ports: ["3000:3000"]
environment:
OPENAI_API_KEY: ${OPENAI_API_KEY}
DATABASE_URL: postgres://user:pass@db:5432/app
depends_on: [db, redis]

db:
image: pgvector/pgvector:pg16
volumes: [postgres_data:/var/lib/postgresql/data]

redis:
image: redis:7-alpine

volumes:
postgres_data:

常见面试问题

Q1: AI 应用的数据库选型?

答案

  • PostgreSQL + pgvector:关系数据 + 向量搜索一站式解决,推荐大多数场景
  • Supabase:托管 PostgreSQL + Auth + Storage + Realtime,快速搭建
  • Neon:Serverless PostgreSQL,按用量计费,适合 Serverless 架构
  • 如果向量数据量超过千万级,考虑专用向量数据库(Milvus/Qdrant)

Q2: 如何控制 AI 应用的成本?

答案

  1. Token 限制:设置每次对话的最大 token 数
  2. 用户配额:每日/每月 API 调用次数限制
  3. 缓存:相同问题缓存 LLM 响应
  4. 模型分级:简单问题用便宜模型,复杂问题用强模型
  5. Prompt 优化:精简 system prompt,减少上下文 token

相关链接