## 项目简介
SBTI (Soul-Based Type Indicator) 是一个基于 AI 的人格测试系统,使用 Next.js 15 + NestJS +
Gemini 1.5 构建。
与传统的 MBTI 不同,SBTI
通过分析用户的潜意识反应、答题犹豫时长和情绪逻辑,生成更真实的人格报告。
## 技术架构
### 前端技术栈
- **Next.js 15** - React 框架,使用 App Router
- **TypeScript** - 类型安全
- **Tailwind CSS** - 原子化 CSS
- **shadcn/ui** - 组件库
- **next-intl** - 国际化
- **Framer Motion** - 动画
### 后端技术栈
- **NestJS** - Node.js 框架
- **Prisma** - ORM
- **SQLite** - 数据库
- **Google Gemini 1.5** - AI 模型
### 部署
- **Vercel** - 前端部署
- **Railway** - 后端部署
## 核心功能实现
### 1. 答题时长追踪
```typescript
// 前端实现
const [startTime, setStartTime] = useState<number>(Date.now());
const handleAnswer = (answer: string) => {
const hesitationTime = Date.now() - startTime;
// 记录犹豫时长
recordHesitation(currentQuestion.id, hesitationTime);
// 重置计时器
setStartTime(Date.now());
};
2. Gemini 1.5 集成
// 后端实现
import { GoogleGenerativeAI } from '@google/generative-ai';
const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
async function analyzePersonality(data: TestData) {
const model = genAI.getGenerativeModel({
model: 'gemini-1.5-pro'
});
const prompt = buildAnalysisPrompt(data);
const result = await model.generateContent(prompt);
const response = await result.response;
return response.text();
}
3. 数据库设计
// schema.prisma
model User {
id String @id @default(cuid())
email String? @unique
name String?
createdAt DateTime @default(now())
testResults TestResult[]
}
model TestResult {
id String @id @default(cuid())
userId String?
personalityType String
answers Json
hesitationData Json
aiAnalysis String @db.Text
createdAt DateTime @default(now())
user User? @relation(fields: [userId], references: [id])
}
model PersonalityType {
id String @id @default(cuid())
code String @unique // ATM-er, BOSS, etc.
name String
description String @db.Text
traits Json
}
4. API 设计
// NestJS Controller
@Controller('test')
export class TestController {
constructor(private readonly testService: TestService) {}
@Post('submit')
async submitTest(@Body() data: TestSubmitDto) {
// 1. 验证数据
const validated = await this.validateTestData(data);
// 2. 调用 Gemini 分析
const analysis = await this.testService.analyzeWithAI(validated);
// 3. 保存结果
const result = await this.testService.saveResult(analysis);
// 4. 返回报告
return this.testService.generateReport(result);
}
}
AI 分析逻辑
分析维度
1. 答案内容分析
- 选项倾向性
- 价值观判断
- 行为模式
2. 犹豫时长分析
- 快速回答 (< 2s) - 本能反应
- 正常思考 (2-5s) - 理性判断
- 长时间犹豫 (> 5s) - 内心冲突
3. 情绪逻辑推理
- 前后答案一致性
- 矛盾选项分析
- 潜意识动机
Prompt 工程
function buildAnalysisPrompt(data: TestData): string {
return `
你是一位专业的心理分析师。请基于以下数据分析用户的人格特征:
## 测试数据
- 答案: ${JSON.stringify(data.answers)}
- 犹豫时长: ${JSON.stringify(data.hesitationTimes)}
- 答题模式: ${data.patterns}
## 分析要求
1. 从潜意识层、情绪逻辑层、价值观层三个维度分析
2. 识别用户的核心动机和恐惧
3. 判断最匹配的人格原型(27种之一)
4. 生成 1000 字左右的详细报告
## 27种人格原型
${PERSONALITY_TYPES.map(t => \`- ${t.code}: ${t.name}\`).join('\n')}
请以 JSON 格式返回分析结果。
`;
}
27 种人格原型
系统定义了 27 种独特的人格原型,每种都有详细的特征描述:
┌────────┬────────┬──────────────────────┐
│ 代码 │ 名称 │ 核心特征 │
├────────┼────────┼──────────────────────┤
│ ATM-er │ 送钱者 │ 为他人付出的慷慨灵魂 │
├────────┼────────┼──────────────────────┤
│ BOSS │ 领导者 │ 天生的掌控者 │
├────────┼────────┼──────────────────────┤
│ CTRL │ 拿捏者 │ 精准把握人心 │
├────────┼────────┼──────────────────────┤
│ DRUNK │ 酒鬼 │ 用酒精逃避现实 │
├────────┼────────┼──────────────────────┤
│ IMFW │ 废物 │ 接纳自己的不完美 │
├────────┼────────┼──────────────────────┤
│ JOKE-R │ 小丑 │ 用幽默化解尴尬 │
├────────┼────────┼──────────────────────┤
│ MALO │ 吗喽 │ 甘愿做配角的人 │
├────────┼────────┼──────────────────────┤
│ SOLO │ 孤儿 │ 享受孤独的灵魂 │
├────────┼────────┼──────────────────────┤
│ ... │ ... │ ... │
└────────┴────────┴──────────────────────┘
性能优化
1. 服务端渲染
// app/[locale]/page.tsx
export default async function HomePage({
params: { locale }
}: {
params: { locale: string }
}) {
// 服务端获取数据
const data = await fetchData();
return <HomeContent data={data} />;
}
2. 静态生成
// 生成所有人格类型页面
export async function generateStaticParams() {
const types = await prisma.personalityType.findMany();
return types.map(type => ({
slug: type.code.toLowerCase(),
}));
}
3. 图片优化
import Image from 'next/image';
<Image
src="/personality-types.png"
alt="27 Personality Types"
width={1200}
height={630}
priority
/>
4. API 缓存
// 缓存 Gemini 响应
const cache = new Map<string, string>();
async function getCachedAnalysis(key: string, fn: () => Promise<string>) {
if (cache.has(key)) {
return cache.get(key);
}
const result = await fn();
cache.set(key, result);
return result;
}
SEO 优化
1. 元数据
export const metadata: Metadata = {
title: 'SBTI 人格测试 - 比 MBTI 更真实的灵魂分析',
description: '通过 AI 驱动的深度分析,发现你的真实人格',
openGraph: {
title: 'SBTI 人格测试',
description: '27 种人格原型,找到真实的自己',
images: ['/og-image.png'],
},
};
2. 结构化数据
const jsonLd = {
'@context': 'https://schema.org',
'@type': 'WebApplication',
name: 'SBTI 人格测试',
description: 'AI 驱动的人格分析系统',
url: 'https://sbtisoul.com',
};
3. Sitemap
// app/sitemap.ts
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const types = await prisma.personalityType.findMany();
return [
{ url: 'https://sbtisoul.com', changeFrequency: 'daily' },
{ url: 'https://sbtisoul.com/test', changeFrequency: 'weekly' },
...types.map(type => ({
url: \`https://sbtisoul.com/personality/${type.code}\`,
changeFrequency: 'monthly',
})),
];
}
博客系统
已发布 32 篇文章:
- 5 篇深度技术/产品文章
- 27 篇人格类型解读
技术实现:
- Markdown 渲染
- 代码高亮
- 目录生成
- SEO 优化
部署流程
前端部署(Vercel)
# 1. 安装 Vercel CLI
npm i -g vercel
# 2. 部署
vercel --prod
后端部署(Railway)
# 1. 安装 Railway CLI
npm i -g @railway/cli
# 2. 登录
railway login
# 3. 部署
railway up
未来计划
- 开源代码
- 添加更多人格类型
- 支持多语言(日语、韩语)
- 移动端 App
- 社交分享功能
- 人格匹配系统
---
技术交流:如果对实现细节感兴趣,欢迎留言讨论。
话题标签:#人格测试 #AI #Gemini #Next.js #NestJS #全栈开发
---