<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI产品经理特训营:程序员的视角</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
line-height: 1.7;
max-width: 900px;
margin: 0 auto;
padding: 20px;
background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);
color: #e2e8f0;
position: relative;
overflow-x: hidden;
}
body::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background:
radial-gradient(circle at 10% 20%, rgba(56, 189, 248, 0.05) 0%, transparent 20%),
radial-gradient(circle at 90% 80%, rgba(124, 58, 237, 0.05) 0%, transparent 20%),
repeating-linear-gradient(45deg, rgba(30, 41, 59, 0.8) 0px, rgba(30, 41, 59, 0.8) 1px, transparent 1px, transparent 11px),
repeating-linear-gradient(-45deg, rgba(30, 41, 59, 0.8) 0px, rgba(30, 41, 59, 0.8) 1px, transparent 1px, transparent 11px);
z-index: -1;
}
.article-container {
background: rgba(15, 23, 42, 0.85);
backdrop-filter: blur(10px);
padding: 40px;
border-radius: 16px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(56, 189, 248, 0.1);
border: 1px solid rgba(56, 189, 248, 0.15);
position: relative;
overflow: hidden;
}
.article-container::after {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
height: 4px;
background: linear-gradient(90deg, #0ea5e9, #8b5cf6, #ec4899);
z-index: 1;
}
h1 {
color: #7dd3fc;
font-size: 2.8em;
margin-bottom: 30px;
padding-bottom: 20px;
border-bottom: 1px solid rgba(56, 189, 248, 0.3);
font-weight: 700;
position: relative;
z-index: 2;
}
h2 {
color: #38bdf8;
margin-top: 40px;
margin-bottom: 20px;
font-size: 1.9em;
font-weight: 600;
position: relative;
padding-left: 20px;
}
h2::before {
content: "";
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
height: 70%;
width: 4px;
background: linear-gradient(to bottom, #0ea5e9, #8b5cf6);
border-radius: 2px;
}
h3 {
color: #22d3ee;
margin-top: 25px;
margin-bottom: 15px;
font-size: 1.4em;
font-weight: 500;
}
p {
margin-bottom: 20px;
font-size: 1.15em;
color: #cbd5e1;
}
.code-block {
background: rgba(15, 23, 42, 0.7);
border: 1px solid rgba(56, 189, 248, 0.2);
border-radius: 10px;
padding: 20px;
margin: 25px 0;
overflow-x: auto;
position: relative;
box-shadow: inset 0 0 20px rgba(0, 0, 0, 0.2);
}
.code-block::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
height: 30px;
background: rgba(15, 23, 42, 0.9);
border-radius: 10px 10px 0 0;
border-bottom: 1px solid rgba(56, 189, 248, 0.2);
}
.code-header {
position: absolute;
top: 5px;
left: 15px;
font-size: 0.9em;
color: #94a3b8;
z-index: 10;
font-weight: 500;
}
.code-lang {
display: inline-block;
background: rgba(30, 41, 59, 0.7);
padding: 2px 10px;
border-radius: 4px;
font-size: 0.85em;
margin-right: 10px;
border: 1px solid rgba(56, 189, 248, 0.2);
}
.copy-btn {
position: absolute;
top: 5px;
right: 15px;
background: rgba(30, 41, 59, 0.7);
color: #38bdf8;
border: 1px solid rgba(56, 189, 248, 0.2);
padding: 4px 12px;
border-radius: 4px;
cursor: pointer;
font-size: 0.85em;
transition: all 0.3s ease;
z-index: 10;
font-weight: 500;
}
.copy-btn:hover {
background: rgba(56, 189, 248, 0.2);
color: #7dd3fc;
transform: translateY(-1px);
}
.copy-btn.copied {
background: rgba(34, 197, 94, 0.2);
color: #86efac;
border-color: rgba(34, 197, 94, 0.3);
}
pre {
margin: 40px 0 20px;
font-size: 15px;
line-height: 1.6;
font-family: 'Fira Code', 'Consolas', 'Monaco', 'Courier New', monospace;
color: #e2e8f0;
}
.highlight {
background: rgba(56, 189, 248, 0.15);
padding: 2px 8px;
border-radius: 4px;
color: #7dd3fc;
font-weight: 500;
}
.tech-stack {
display: flex;
flex-wrap: wrap;
gap: 12px;
margin: 20px 0;
}
.tech-tag {
background: linear-gradient(135deg, rgba(56, 189, 248, 0.15), rgba(139, 92, 236, 0.15));
color: #38bdf8;
padding: 6px 16px;
border-radius: 20px;
font-size: 0.95em;
border: 1px solid rgba(56, 189, 248, 0.2);
transition: all 0.3s ease;
font-weight: 500;
}
.tech-tag:hover {
transform: translateY(-2px);
background: linear-gradient(135deg, rgba(56, 189, 248, 0.25), rgba(139, 92, 236, 0.25));
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
}
.warning {
background: linear-gradient(135deg, rgba(245, 158, 11, 0.1), rgba(217, 119, 6, 0.1));
border-left: 4px solid #f59e0b;
padding: 20px;
margin: 25px 0;
border-radius: 0 8px 8px 0;
position: relative;
border: 1px solid rgba(245, 158, 11, 0.2);
}
.warning::before {
content: "⚠️";
position: absolute;
top: 15px;
left: -15px;
background: #f59e0b;
width: 30px;
height: 30px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: #0f172a;
font-size: 1.2em;
font-weight: bold;
}
.warning p {
color: #fde68a;
margin: 0;
padding-left: 15px;
}
.feature-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 25px;
margin: 30px 0;
}
.feature-card {
background: rgba(15, 23, 42, 0.6);
padding: 25px;
border-radius: 12px;
border: 1px solid rgba(56, 189, 248, 0.15);
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.feature-card:hover {
transform: translateY(-5px);
border-color: rgba(56, 189, 248, 0.3);
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
}
.feature-card::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
height: 4px;
background: linear-gradient(90deg, #0ea5e9, #8b5cf6);
}
.feature-card h4 {
color: #22d3ee;
margin-top: 0;
font-size: 1.3em;
margin-bottom: 15px;
}
.feature-card p {
color: #cbd5e1;
margin-bottom: 0;
}
.interactive-demo {
background: rgba(15, 23, 42, 0.7);
border: 1px solid rgba(56, 189, 248, 0.2);
border-radius: 12px;
padding: 25px;
margin: 25px 0;
position: relative;
}
.demo-controls {
display: flex;
gap: 15px;
margin-bottom: 25px;
flex-wrap: wrap;
}
.demo-btn {
background: linear-gradient(135deg, rgba(56, 189, 248, 0.2), rgba(139, 92, 236, 0.2));
color: #38bdf8;
border: 1px solid rgba(56, 189, 248, 0.3);
padding: 10px 20px;
border-radius: 8px;
cursor: pointer;
transition: all 0.3s ease;
font-weight: 500;
font-size: 1em;
}
.demo-btn:hover {
background: linear-gradient(135deg, rgba(56, 189, 248, 0.3), rgba(139, 92, 236, 0.3));
transform: translateY(-2px);
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
}
.demo-btn.active {
background: linear-gradient(135deg, #0ea5e9, #8b5cf6);
color: white;
box-shadow: 0 4px 15px rgba(56, 189, 248, 0.3);
}
.demo-output {
background: rgba(15, 23, 42, 0.9);
border: 1px solid rgba(56, 189, 248, 0.2);
border-radius: 8px;
padding: 20px;
font-family: 'Fira Code', 'Consolas', 'Monaco', 'Courier New', monospace;
font-size: 14px;
line-height: 1.6;
min-height: 100px;
white-space: pre-wrap;
color: #e2e8f0;
position: relative;
}
.demo-output::before {
content: "输出结果:";
position: absolute;
top: -10px;
left: 15px;
background: #0f172a;
padding: 0 10px;
font-size: 12px;
color: #94a3b8;
font-weight: 500;
}
.progress-bar {
width: 100%;
height: 8px;
background: rgba(30, 41, 59, 0.7);
border-radius: 4px;
overflow: hidden;
margin: 15px 0;
border: 1px solid rgba(56, 189, 248, 0.1);
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, #0ea5e9, #8b5cf6);
width: 0%;
transition: width 0.3s ease;
position: relative;
}
.progress-fill::after {
content: "";
position: absolute;
top: 0;
right: 0;
bottom: 0;
width: 20px;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3));
}
.tab-container {
margin: 25px 0;
}
.tab-nav {
display: flex;
border-bottom: 1px solid rgba(56, 189, 248, 0.2);
margin-bottom: 25px;
flex-wrap: wrap;
}
.tab-btn {
background: none;
border: none;
color: #94a3b8;
padding: 12px 25px;
cursor: pointer;
font-size: 1.05em;
transition: all 0.3s ease;
position: relative;
font-weight: 500;
border-radius: 6px 6px 0 0;
}
.tab-btn:hover {
color: #38bdf8;
background: rgba(30, 41, 59, 0.5);
}
.tab-btn.active {
color: #38bdf8;
background: rgba(15, 23, 42, 0.7);
}
.tab-btn.active::after {
content: "";
position: absolute;
bottom: -1px;
left: 0;
right: 0;
height: 3px;
background: linear-gradient(90deg, #0ea5e9, #8b5cf6);
border-radius: 3px 3px 0 0;
}
.tab-content {
display: none;
}
.tab-content.active {
display: block;
}
.api-endpoint {
background: rgba(15, 23, 42, 0.7);
border: 1px solid rgba(56, 189, 248, 0.2);
border-radius: 8px;
padding: 15px;
margin: 15px 0;
font-family: 'Fira Code', 'Consolas', 'Monaco', 'Courier New', monospace;
position: relative;
}
.api-method {
display: inline-block;
padding: 4px 10px;
border-radius: 4px;
font-size: 0.85em;
font-weight: bold;
margin-right: 10px;
min-width: 60px;
text-align: center;
}
.method-get { background: rgba(34, 197, 94, 0.15); color: #86efac; border: 1px solid rgba(34, 197, 94, 0.3); }
.method-post { background: rgba(245, 158, 11, 0.15); color: #fde68a; border: 1px solid rgba(245, 158, 11, 0.3); }
.method-put { background: rgba(59, 130, 246, 0.15); color: #93c5fd; border: 1px solid rgba(59, 130, 246, 0.3); }
.method-delete { background: rgba(239, 68, 68, 0.15); color: #fca5a5; border: 1px solid rgba(239, 68, 68, 0.3); }
.json-key { color: #38bdf8; }
.json-string { color: #86efac; }
.json-number { color: #fbbf24; }
.json-boolean { color: #ec4899; }
.json-null { color: #94a3b8; }
@media (max-width: 768px) {
.article-container {
padding: 25px;
}
h1 {
font-size: 2.2em;
}
h2 {
font-size: 1.6em;
}
.demo-controls {
flex-direction: column;
}
.tab-nav {
flex-direction: column;
border-bottom: none;
}
.tab-btn {
border-radius: 6px;
margin-bottom: 5px;
text-align: left;
}
.tab-btn.active::after {
display: none;
}
.tab-btn.active {
background: linear-gradient(90deg, rgba(56, 189, 248, 0.2), rgba(139, 92, 236, 0.2));
border-left: 4px solid #0ea5e9;
}
}
.loading {
display: inline-block;
width: 20px;
height: 20px;
border: 3px solid rgba(30, 41, 59, 0.7);
border-top: 3px solid #0ea5e9;
border-radius: 50%;
animation: spin 1s linear infinite;
margin-left: 10px;
vertical-align: middle;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.fade-in {
animation: fadeIn 0.5s ease-in;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.pulse {
animation: pulse 2s infinite;
}
@keyframes pulse {
0% { box-shadow: 0 0 0 0 rgba(56, 189, 248, 0.4); }
70% { box-shadow: 0 0 0 10px rgba(56, 189, 248, 0); }
100% { box-shadow: 0 0 0 0 rgba(56, 189, 248, 0); }
}
</style>
</head>
<body>
<div class="article-container">
<h1>🚀 AI产品经理特训营:程序员的视角</h1>
<p>作为一个在代码世界里摸爬滚打多年的程序员,当我第一次看到<span class="highlight">《AI产品经理特训营》</span>这个课程时,内心是拒绝的。"产品经理?那不是画原型图的吗?"但当我深入研究了课程大纲,特别是看到<span class="highlight">AIGC产品设计</span>和<span class="highlight">企业级项目实战</span>这几个关键词时,我的程序员DNA动了。</p>
<h2>💡 为什么程序员应该关注这个课程?</h2>
<p>让我们先来看一段代码,了解一下现代AI应用的技术栈:</p>
<div class="code-block">
<div class="code-header">
<span class="code-lang">Python</span>
<button class="copy-btn" onclick="copyCode(this)">复制代码</button>
</div>
<pre><code># 现代AI应用技术栈示例
tech_stack = {
"frontend": ["React", "Vue", "TypeScript", "Tailwind CSS"],
"backend": ["Python", "FastAPI", "Node.js", "Go"],
"ai_models": ["GPT-4", "Claude", "Stable Diffusion", "Whisper"],
"infrastructure": ["Docker", "Kubernetes", "AWS/GCP", "Redis"],
"data": ["PostgreSQL", "MongoDB", "Pinecone", "Weaviate"],
"mlops": ["MLflow", "Weights & Biases", "Jenkins", "GitLab CI"]
}
# 程序员视角的产品理解
class AIProductUnderstanding:
def __init__(self):
self.technical_depth = "deep"
self.product_sense = "developing"
self.user Empathy = "loading..."
def bridge_tech_and_product(self):
"""连接技术与产品的桥梁"""
return {
"translate_user_needs": self.convert_requirements_to_specs(),
"evaluate_feasibility": self.assess_technical_constraints(),
"optimize_resources": self.balance_time_quality_cost()
}</code></pre>
</div>
<div class="tech-stack">
<span class="tech-tag">机器学习</span>
<span class="tech-tag">自然语言处理</span>
<span class="tech-tag">计算机视觉</span>
<span class="tech-tag">MLOps</span>
<span class="tech-tag">云原生</span>
<span class="tech-tag">微服务</span>
</div>
<h2>🎯 AIGC产品设计的程序员思维</h2>
<p>课程中的<span class="highlight">AIGC产品设计</span>部分深深吸引了我。作为程序员,我们习惯于用代码解决问题,但如何设计一个让用户爱不释手的AI产品呢?</p>
<h3>1. 从算法到产品的思维转换</h3>
<p>让我们看一个实际的AIGC产品设计案例:</p>
<div class="code-block">
<div class="code-header">
<span class="code-lang">JavaScript</span>
<button class="copy-btn" onclick="copyCode(this)">复制代码</button>
</div>
<pre><code>// AIGC文生图产品设计示例
class AIGCImageGenerator {
constructor() {
this.models = {
stable_diffusion: "v2.1",
dalle: "dall-e-3",
midjourney: "v6.0"
};
this.userPrompts = [];
this.generatedImages = [];
}
// 产品设计思维:不仅是技术实现
designProduct() {
return {
// 1. 用户体验设计
userExperience: {
onboarding: this.createInteractiveTutorial(),
promptAssistance: this.buildPromptHelper(),
realTimePreview: this.enableLivePreview(),
stylePresets: this.provideStyleTemplates()
},
// 2. 技术架构设计
technicalArchitecture: {
apiDesign: this.designRESTfulAPI(),
queueManagement: this.implementJobQueue(),
cachingStrategy: this.setupRedisCaching(),
rateLimiting: this.configureRateLimits()
},
// 3. 商业模式集成
businessModel: {
freemium: this.setupTieredPricing(),
credits: this.implementCreditSystem(),
subscriptions: this.createSubscriptionTiers()
}
};
}
// 企业级特性
enterpriseFeatures() {
return {
sso: "SAML/OAuth2",
auditLogs: "Comprehensive logging",
teamManagement: "Role-based access",
apiQuota: "Custom limits",
whiteLabel: "Branding options"
};
}
}</code></pre>
</div>
<h3>2. 用户调研的技术实现</h3>
<p>课程中的<span class="highlight">用户调研</span>部分让我眼前一亮。原来用户行为可以通过代码来追踪和分析:</p>
<div class="code-block">
<div class="code-header">
<span class="code-lang">Python</span>
<button class="copy-btn" onclick="copyCode(this)">复制代码</button>
</div>
<pre><code># 用户行为分析系统
import pandas as pd
from datetime import datetime, timedelta
import seaborn as sns
import matplotlib.pyplot as plt
class UserResearchAnalytics:
def __init__(self):
self.events = []
self.user_segments = {}
def track_user_event(self, user_id, event_type, metadata=None):
"""追踪用户行为事件"""
event = {
'user_id': user_id,
'event_type': event_type,
'timestamp': datetime.now(),
'metadata': metadata or {}
}
self.events.append(event)
# 实时分析
self.analyze_in_realtime(event)
def analyze_user_journey(self):
"""分析用户旅程"""
df = pd.DataFrame(self.events)
# 用户漏斗分析
funnel = self.create_conversion_funnel(df)
# 热力图分析
heatmap = self.generate_feature_heatmap(df)
# 留存分析
retention = self.calculate_retention_cohort(df)
return {
'funnel': funnel,
'heatmap': heatmap,
'retention': retention,
'insights': self.generate_insights(df)
}
def generate_insights(self, df):
"""生成产品洞察"""
insights = []
# 检测用户流失点
dropoff_points = self.identify_dropoff_points(df)
if dropoff_points:
insights.append({
'type': 'dropoff',
'severity': 'high',
'recommendation': f"优化 {dropoff_points[0]} 步骤的用户体验"
})
# 发现高价值功能
high_value_features = self.find_high_value_features(df)
insights.append({
'type': 'opportunity',
'severity': 'medium',
'recommendation': f"推广 {high_value_features[0]} 功能给更多用户"
})
return insights
# 使用示例
analytics = UserResearchAnalytics()
# 模拟用户行为
analytics.track_user_event("user_123", "app_open")
analytics.track_user_event("user_123", "feature_used", {"feature": "ai_image_gen"})
analytics.track_user_event("user_123", "subscription_upgraded")
# 生成分析报告
report = analytics.analyze_user_journey()
print(f"用户洞察: {report['insights']}")</code></pre>
</div>
<h2>🏗️ 企业级项目实战:从0到1构建AI产品</h2>
<p>课程最让我兴奋的是<span class="highlight">企业级项目实战案例</span>。让我们通过一个完整的案例来展示:</p>
<h3>项目:智能客服系统</h3>
<div class="interactive-demo">
<h4>🎮 交互式演示:智能客服架构</h4>
<div class="demo-controls">
<button class="demo-btn active" onclick="showArchitecture('overall')">整体架构</button>
<button class="demo-btn" onclick="showArchitecture('frontend')">前端设计</button>
<button class="demo-btn" onclick="showArchitecture('backend')">后端实现</button>
<button class="demo-btn" onclick="showArchitecture('ai')">AI集成</button>
<button class="demo-btn" onclick="showArchitecture('monitoring')">监控运维</button>
</div>
<div id="demo-output" class="demo-output">
// 智能客服系统 - 整体架构
系统架构:
├── 前端层 (Next.js + TypeScript)
│ ├── 聊天界面组件
│ ├── 文件上传组件
│ └── 管理后台
├── API网关 (Kong)
│ ├── 认证授权
│ ├── 限流熔断
│ └── 日志监控
├── 业务服务 (Python FastAPI)
│ ├── 会话管理
│ ├── 知识库检索
│ └── 智能路由
├── AI服务
│ ├── LLM服务 (GPT-4)
│ ├── 意图识别 (BERT)
│ └── 情感分析
└── 数据层
├── PostgreSQL (业务数据)
├── Redis (缓存)
├── Elasticsearch (搜索)
└── MinIO (文件存储)
</div>
</div>
<div class="tab-container">
<div class="tab-nav">
<button class="tab-btn active" onclick="showTab('product-design')">产品设计</button>
<button class="tab-btn" onclick="showTab('technical-implementation')">技术实现</button>
<button class="tab-btn" onclick="showTab('performance-optimization')">性能优化</button>
<button class="tab-btn" onclick="showTab('business-value')">商业价值</button>
</div>
<div id="product-design" class="tab-content active">
<h4>🎨 产品设计思维</h4>
<div class="code-block">
<div class="code-header">
<span class="code-lang">产品设计</span>
<button class="copy-btn" onclick="copyCode(this)">复制代码</button>
</div>
<pre><code># 智能客服产品设计框架
class IntelligentCustomerService:
def __init__(self):
self.target_users = ["企业客服", "中小商家", "在线教育"]
self.core_scenarios = [
"售前咨询", "售后支持", "订单查询",
"技术支持", "投诉处理"
]
def product_features(self):
return {
"基础功能": {
"智能问答": "7×24小时自动回复",
"多轮对话": "上下文理解,连续对话",
"知识库": "结构化知识管理",
"转人工": "智能判断转接时机"
},
"高级功能": {
"情感分析": "识别客户情绪",
"意图识别": "理解客户真实需求",
"个性化": "基于用户画像定制回复",
"多语言": "支持中英文等多语言"
},
"企业功能": {
"数据分析": "对话质量分析",
"A/B测试": "回复效果对比",
"权限管理": "多级权限控制",
"API集成": "对接CRM等系统"
}
}
def user_experience_design(self):
"""用户体验设计"""
return {
"响应速度": "<500ms",
"准确率": ">90%",
"满意度": ">85%",
"解决率": ">80%"
}</code></pre>
</div>
</div>
<div id="technical-implementation" class="tab-content">
<h4>⚙️ 技术实现细节</h4>
<div class="code-block">
<div class="code-header">
<span class="code-lang">后端实现</span>
<button class="copy-btn" onclick="copyCode(this)">复制代码</button>
</div>
<pre><code># 智能客服后端架构 (FastAPI)
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import asyncio
import aioredis
from typing import List, Optional
import openai
from sentence_transformers import SentenceTransformer
app = FastAPI(title="智能客服API")
# 模型初始化
embedding_model = SentenceTransformer('paraphrase-multilingual-MiniLM-L12-v2')
class ChatRequest(BaseModel):
message: str
session_id: str
user_id: Optional[str] = None
class ChatResponse(BaseModel):
reply: str
confidence: float
suggested_actions: List[str]
emotion: str
@app.post("/api/chat", response_model=ChatResponse)
async def handle_chat(request: ChatRequest):
"""处理用户消息"""
try:
# 1. 意图识别
intent = await classify_intent(request.message)
# 2. 情感分析
emotion = await analyze_emotion(request.message)
# 3. 知识库检索
relevant_docs = await search_knowledge_base(request.message)
# 4. 生成回复
reply = await generate_reply(
message=request.message,
intent=intent,
context=relevant_docs,
emotion=emotion
)
# 5. 建议操作
actions = await suggest_actions(intent, emotion)
return ChatResponse(
reply=reply,
confidence=0.92,
suggested_actions=actions,
emotion=emotion
)
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
async def classify_intent(message: str) -> str:
"""意图分类"""
intents = ["咨询", "投诉", "下单", "退款", "技术支持"]
# 使用微调后的BERT模型进行意图分类
return "咨询" # 简化示例
async def search_knowledge_base(query: str) -> List[str]:
"""向量检索知识库"""
# 生成查询向量
query_vector = embedding_model.encode(query)
# 在向量数据库中搜索
# 这里使用简化的相似度搜索
return ["相关文档1", "相关文档2"]
async def generate_reply(message: str, intent: str, context: List[str], emotion: str) -> str:
"""使用LLM生成回复"""
prompt = f"""
你是一个专业的客服助手。
用户情绪: {emotion}
用户意图: {intent}
相关知识: {context}
用户消息: {message}
请提供有帮助的回复:
"""
response = openai.ChatCompletion.create(
model="gpt-4",
messages=[{"role": "user", "content": prompt}],
temperature=0.7,
max_tokens=500
)
return response.choices[0].message.content</code></pre>
</div>
</div>
<div id="performance-optimization" class="tab-content">
<h4>🚀 性能优化策略</h4>
<div class="code-block">
<div class="code-header">
<span class="code-lang">性能优化</span>
<button class="copy-btn" onclick="copyCode(this)">复制代码</button>
</div>
<pre><code># 性能优化实现
class PerformanceOptimizer:
def __init__(self):
self.redis_client = aioredis.Redis()
self.cache_ttl = 3600 # 1小时
async def optimize_response_time(self):
"""优化响应时间"""
return {
"缓存策略": {
"LLM响应缓存": "对相似问题缓存AI回复",
"向量检索缓存": "缓存知识库搜索结果",
"用户会话缓存": "缓存最近对话历史"
},
"并发处理": {
"异步处理": "使用async/await",
"连接池": "复用数据库连接",
"批处理": "合并多个API调用"
},
"模型优化": {
"模型蒸馏": "使用小模型加速",
"量化压缩": "减少模型大小",
"边缘部署": "就近部署服务"
}
}
async def caching_strategy(self):
"""缓存策略实现"""
@cached(cache=RedisCache, ttl=self.cache_ttl)
async def get_cached_response(query_hash: str):
return await self.generate_ai_response(query_hash)
# 语义相似度缓存
async def get_semantic_cache(query: str):
query_embedding = self.embedding_model.encode(query)
# 在向量缓存中搜索相似查询
similar_queries = await self.search_similar_queries(query_embedding)
if similar_queries and similar_queries[0]['similarity'] > 0.95:
# 返回缓存的回复
return similar_queries[0]['response']
# 生成新回复并缓存
response = await self.generate_ai_response(query)
await self.cache_query_response(query, query_embedding, response)
return response
async def monitoring_metrics(self):
"""监控指标"""
return {
"响应时间": {
"P50": "<200ms",
"P95": "<500ms",
"P99": "<1000ms"
},
"准确率": ">90%",
"可用性": ">99.9%",
"并发量": "10000 QPS"
}</code></pre>
</div>
</div>
<div id="business-value" class="tab-content">
<h4>💰 商业价值实现</h4>
<div class="code-block">
<div class="code-header">
<span class="code-lang">商业价值</span>
<button class="copy-btn" onclick="copyCode(this)">复制代码</button>
</div>
<pre><code># 商业价值分析
class BusinessValueAnalyzer:
def calculate_roi(self):
"""计算投资回报率"""
return {
"成本节省": {
"人力成本": "减少80%客服坐席",
"培训成本": "降低90%培训时间",
"运营成本": "24/7无间断服务"
},
"效率提升": {
"响应速度": "比人工快10倍",
"处理能力": "同时处理1000+对话",
"一致性": "100%标准回复"
},
"业务增长": {
"转化率": "提升25%",
"客户满意度": "提升30%",
"复购率": "提升20%"
}
}
def pricing_strategy(self):
"""定价策略"""
return {
"免费版": {
"月调用次数": 1000,
"基础功能": True,
"社区支持": True,
"价格": 0
},
"专业版": {
"月调用次数": 10000,
"高级功能": True,
"邮件支持": True,
"价格": "¥999/月"
},
"企业版": {
"无限制调用": True,
"全部功能": True,
"7×24支持": True,
"私有化部署": True,
"价格": "¥9999/月"
}
}
def success_metrics(self):
"""成功指标"""
return {
"技术指标": [
"响应时间 < 500ms",
"准确率 > 90%",
"可用性 > 99.9%"
],
"业务指标": [
"客户满意度 > 85%",
"问题解决率 > 80%",
"人工成本节省 > 70%"
],
"财务指标": [
"ROI > 300%",
"回收期 < 6个月",
"年节省成本 > 100万"
]
}</code></pre>
</div>
</div>
</div>
<h2>🔍 程序员学习产品思维的价值</h2>
<div class="feature-grid">
<div class="feature-card">
<h4>🎯 技术决策更精准</h4>
<p>理解用户需求后,能够做出更合理的技术选型,避免过度工程化。</p>
</div>
<div class="feature-card">
<h4>🚀 创新机会更多</h4>
<p>结合技术能力和用户洞察,发现新的产品创新机会。</p>
</div>
<div class="feature-card">
<h4>💼 职业发展更广</h4>
<p>从纯技术岗位向技术管理、产品架构等方向发展。</p>
</div>
<div class="feature-card">
<h4>🤝 团队协作更高效</h4>
<p>能够更好地与产品经理、设计师、运营等非技术角色沟通。</p>
</div>
</div>
<h2>🎓 实战项目:AI简历优化工具</h2>
<p>让我们通过一个完整的实战项目,展示如何将课程中学到的知识应用到实际产品开发中:</p>
<div class="code-block">
<div class="code-header">
<span class="code-lang">全栈项目</span>
<button class="copy-btn" onclick="copyCode(this)">复制代码</button>
</div>
<pre><code># AI简历优化工具 - 完整项目架构
"""
项目背景:为求职者提供AI驱动的简历优化服务
技术栈:Next.js + Python FastAPI + GPT-4 + ChromaDB
"""
# 1. 产品需求分析
class ProductRequirements:
def __init__(self):
self.user_personas = [
{
"name": "应届生小王",
"pain_points": ["缺乏经验", "不会写简历", "不知道HR关注点"],
"needs": ["模板推荐", "内容优化", "关键词建议"]
},
{
"name": "职场老手老李",
"pain_points": ["简历过时", "技能不匹配", "缺乏亮点"],
"needs": ["行业洞察", "技能匹配", "成就量化"]
}
]
self.core_features = {
"智能分析": "上传简历,AI自动分析优缺点",
"内容优化": "针对职位描述优化简历内容",
"模板推荐": "根据行业和职位推荐合适模板",
"ATS优化": "确保简历能通过自动筛选系统",
"模拟面试": "基于简历生成可能的面试问题"
}
# 2. 技术架构设计
class TechnicalArchitecture:
def __init__(self):
self.frontend = {
"framework": "Next.js 14",
"styling": "Tailwind CSS + shadcn/ui",
"state_management": "Zustand",
"form_handling": "React Hook Form + Zod"
}
self.backend = {
"framework": "FastAPI",
"database": "PostgreSQL + Redis",
"vector_db": "ChromaDB",
"file_storage": "AWS S3",
"message_queue": "Celery + Redis"
}
self.ai_services = {
"llm": "GPT-4 for content generation",
"embedding": "text-embedding-ada-002",
"parsing": "pdfplumber for PDF parsing",
"ats_check": "custom ATS scoring algorithm"
}
# 3. 核心功能实现
class AIResumeOptimizer:
def __init__(self):
self.openai_client = OpenAI()
self.chroma_client = chromadb.Client()
self.collection = self.chroma_client.create_collection("job_descriptions")
async def analyze_resume(self, resume_text: str, job_description: str):
"""分析简历与职位的匹配度"""
# 1. 提取关键信息
resume_keywords = await self.extract_keywords(resume_text)
job_keywords = await self.extract_keywords(job_description)
# 2. 计算匹配度
match_score = self.calculate_match_score(resume_keywords, job_keywords)
# 3. 生成优化建议
suggestions = await self.generate_optimization_suggestions(
resume_text, job_description, match_score
)
# 4. ATS兼容性检查
ats_score = self.check_ats_compatibility(resume_text)
return {
"match_score": match_score,
"ats_score": ats_score,
"suggestions": suggestions,
"missing_keywords": self.find_missing_keywords(resume_keywords, job_keywords),
"improved_content": await self.rewrite_resume_section(resume_text, job_description)
}
async def extract_keywords(self, text: str) -> List[str]:
"""提取关键词"""
prompt = f"""
从以下文本中提取关键技能、经验和要求:
{text}
请返回一个JSON数组,包含提取的关键词。
"""
response = self.openai_client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": prompt}],
response_format={"type": "json_object"}
)
return json.loads(response.choices[0].message.content)["keywords"]
async def generate_optimization_suggestions(self, resume: str, job_desc: str, score: float):
"""生成个性化优化建议"""
prompt = f"""
作为一名专业的职业顾问,请分析以下简历和职位描述,
提供具体的优化建议:
简历内容:{resume}
职位描述:{job_desc}
当前匹配度:{score}%
请提供:
1. 内容优化建议
2. 技能提升建议
3. 量化成就建议
4. 格式排版建议
"""
response = self.openai_client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": prompt}]
)
return response.choices[0].message.content
# 4. 前端界面实现
"""
// React组件示例
import { useState, useCallback } from 'react'
import { useDropzone } from 'react-dropzone'
import { Button } from '@/components/ui/button'
import { Card } from '@/components/ui/card'
import { Progress } from '@/components/ui/progress'
export default function ResumeOptimizer() {
const [resume, setResume] = useState(null)
const [jobDescription, setJobDescription] = useState('')
const [analysis, setAnalysis] = useState(null)
const [loading, setLoading] = useState(false)
const onDrop = useCallback((acceptedFiles) => {
const file = acceptedFiles[0]
const reader = new FileReader()
reader.onload = () => setResume(reader.result)
reader.readAsText(file)
}, [])
const { getRootProps, getInputProps } = useDropzone({ onDrop })
const analyzeResume = async () => {
setLoading(true)
try {
const response = await fetch('/api/analyze', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ resume, jobDescription })
})
const data = await response.json()
setAnalysis(data)
} catch (error) {
console.error('Analysis failed:', error)
} finally {
setLoading(false)
}
}
return (
<div className="container mx-auto p-6">
<h1 className="text-3xl font-bold mb-6">AI简历优化工具</h1>
<div className="grid md:grid-cols-2 gap-6">
<Card className="p-6">
<h2 className="text-xl font-semibold mb-4">1. 上传简历</h2>
<div {...getRootProps()} className="border-2 border-dashed p-6 text-center">
<input {...getInputProps()} />
<p>拖拽PDF文件到这里,或点击选择</p>
</div>
</Card>
<Card className="p-6">
<h2 className="text-xl font-semibold mb-4">2. 粘贴职位描述</h2>
<textarea
className="w-full h-32 p-3 border rounded"
placeholder="粘贴目标职位的描述..."
value={jobDescription}
onChange={(e) => setJobDescription(e.target.value)}
/>
</Card>
</div>
<div className="mt-6 text-center">
<Button onClick={analyzeResume} disabled={loading}>
{loading ? '分析中...' : '开始分析'}
</Button>
</div>
{analysis && (
<Card className="mt-6 p-6">
<h2 className="text-xl font-semibold mb-4">分析结果</h2>
<div className="space-y-4">
<div>
<p className="font-medium">匹配度</p>
<Progress value={analysis.match_score} />
</div>
<div>
<p className="font-medium">ATS评分</p>
<Progress value={analysis.ats_score} />
</div>
<div>
<h3 className="font-medium">优化建议</h3>
<p className="whitespace-pre-wrap">{analysis.suggestions}</p>
</div>
</div>
</Card>
)}
</div>
)
}
"""
# 5. 部署和运维
class DeploymentConfig:
def __init__(self):
self.docker_config = """
# Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
"""
self.kubernetes_config = """
# k8s-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: resume-optimizer
spec:
replicas: 3
selector:
matchLabels:
app: resume-optimizer
template:
metadata:
labels:
app: resume-optimizer
spec:
containers:
- name: api
image: resume-optimizer:latest
ports:
- containerPort: 8000
env:
- name: OPENAI_API_KEY
valueFrom:
secretKeyRef:
name: openai-secret
key: api-key
"""
self.monitoring_config = {
"metrics": "Prometheus + Grafana",
"logging": "ELK Stack",
"tracing": "Jaeger",
"alerts": "AlertManager"
}
# 6. 商业模式和盈利
class BusinessModel:
def __init__(self):
self.revenue_streams = {
"订阅制": {
"免费版": "每月3次分析",
"专业版": "¥99/月,无限分析",
"企业版": "¥999/月,API接入"
},
"一次性付费": {
"单次分析": "¥19.9",
"简历模板": "¥9.9",
"面试问题生成": "¥29.9"
},
"增值服务": {
"人工润色": "¥199/次",
"职业规划": "¥499/次",
"猎头服务": "成交金额的10%"
}
}
self.customer_acquisition = {
"seo_optimization": "简历优化、求职技巧关键词",
"content_marketing": "简历写作教程、面试技巧",
"partnerships": "与招聘网站、HR平台合作",
"social_media": "LinkedIn、小红书、知乎"
}
# 使用示例
async def main():
optimizer = AIResumeOptimizer()
# 模拟用户上传
resume = "张三,3年Python开发经验,熟悉Django、Flask..."
job_desc = "招聘Python后端工程师,要求3年以上经验,熟悉微服务架构..."
# 分析简历
result = await optimizer.analyze_resume(resume, job_desc)
print(f"匹配度: {result['match_score']}%")
print(f"优化建议: {result['suggestions']}")
if __name__ == "__main__":
asyncio.run(main())</code></pre>
</div>
<div class="warning">
<p><strong>项目亮点:</strong>这个项目展示了如何从用户需求出发,结合AI技术,设计并实现一个完整的商业产品。涵盖了产品设计、技术实现、商业模式等全流程。</p>
</div>
<h2>🎯 总结:程序员的产品之路</h2>
<p>通过《AI产品经理特训营》的学习,我深刻认识到:</p>
<ol>
<li><strong>技术不是目的,而是手段</strong>:再先进的技术,如果不能解决用户的真实问题,就失去了价值。</li>
<li><strong>产品思维是技术人员的加分项</strong>:懂产品的程序员,能够做出更好的技术决策。</li>
<li><strong>AI时代需要复合型人才</strong>:既懂技术又懂产品的工程师,将在AI时代拥有更大的竞争优势。</li>
</ol>
<p>这门课程不仅教会了我如何设计AI产品,更重要的是让我学会了如何站在用户的角度思考问题。作为一名程序员,我不再是被动地实现需求,而是能够主动地发现机会,创造价值。</p>
<div class="interactive-demo">
<h4>🎮 课程收获互动测试</h4>
<p>通过一个小测试,看看你对AI产品设计的理解程度:</p>
<div class="demo-controls">
<button class="demo-btn" onclick="startQuiz()">开始测试</button>
<button class="demo-btn" onclick="showRoadmap()">学习路线图</button>
<button class="demo-btn" onclick="showResources()">推荐资源</button>
</div>
<div id="quiz-output" class="demo-output">
点击上方按钮开始互动学习之旅...
</div>
</div>
<p>如果你是一名程序员,想要在AI时代拓展自己的产品能力,我强烈推荐这门课程。它不仅能让你了解AI产品设计的全流程,更能帮助你建立产品思维,成为更全面的技术人才。</p>
<p><strong>最后,用一句话总结:</strong>在AI时代,最好的程序员不是只会写代码的人,而是能够用技术解决真实问题、创造用户价值的人。</p>
<div style="text-align: center; margin-top: 40px; padding: 20px; background: linear-gradient(135deg, rgba(56, 189, 248, 0.1), rgba(139, 92, 236, 0.1)); border-radius: 10px; border: 1px solid rgba(56, 189, 248, 0.2);">
<p style="font-style: italic; color: #7dd3fc; font-size: 1.2em;">"最好的技术不是最复杂的技术,而是最能解决用户问题的技术。"</p>
<p style="margin-top: 10px; color: #94a3b8;">— 一个正在学习产品思维的程序员</p>
</div>
</div>
<link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@300;400;500;600&display=swap" rel="stylesheet">
<script>
function copyCode(button) {
const codeBlock = button.parentElement.nextElementSibling;
const code = codeBlock.textContent;
navigator.clipboard.writeText(code).then(() => {
const originalText = button.textContent;
button.textContent = '已复制!';
button.classList.add('copied');
setTimeout(() => {
button.textContent = originalText;
button.classList.remove('copied');
}, 2000);
}).catch(err => {
console.error('复制失败:', err);
button.textContent = '复制失败';
setTimeout(() => {
button.textContent = '复制代码';
}, 2000);
});
}
function showArchitecture(type) {
const output = document.getElementById('demo-output');
const buttons = document.querySelectorAll('.demo-controls .demo-btn');
buttons.forEach(btn => btn.classList.remove('active'));
event.target.classList.add('active');
const architectures = {
overall: `// 智能客服系统 - 整体架构
系统架构:
├── 前端层 (Next.js + TypeScript)
│ ├── 聊天界面组件
│ ├── 文件上传组件
│ └── 管理后台
├── API网关 (Kong)
│ ├── 认证授权
│ ├── 限流熔断
│ └── 日志监控
├── 业务服务 (Python FastAPI)
│ ├── 会话管理
│ ├── 知识库检索
│ └── 智能路由
├── AI服务
│ ├── LLM服务 (GPT-4)
│ ├── 意图识别 (BERT)
│ └── 情感分析
└── 数据层
├── PostgreSQL (业务数据)
├── Redis (缓存)
├── Elasticsearch (搜索)
└── MinIO (文件存储)`,
frontend: `// 前端架构设计
技术栈:
├── Next.js 14 (App Router)
├── TypeScript (类型安全)
├── Tailwind CSS (样式)
├── shadcn/ui (组件库)
├── Zustand (状态管理)
├── React Hook Form (表单)
├── React Query (数据获取)
└── Socket.io (实时通信)
关键组件:
├── ChatInterface
│ ├── MessageList
│ ├── InputArea
│ └── TypingIndicator
├── FileUploader
├── VoiceRecorder
├── KnowledgeBase
└── AnalyticsDashboard
性能优化:
├── 虚拟滚动 (长列表)
├── 懒加载 (组件)
├── 缓存策略 (React Query)
└── 代码分割 (动态导入)`,
backend: `// 后端架构实现
核心服务:
├── API Gateway (Kong)
│ ├── 认证: JWT + OAuth2
│ ├── 限流: 令牌桶算法
│ ├── 熔断: Hystrix模式
│ └── 日志: 集中化日志
├── Chat Service (FastAPI)
│ ├── WebSocket管理
│ ├── 会话状态维护
│ └── 消息持久化
├── AI Service
│ ├── 意图分类 (BERT)
│ ├── 实体识别 (spaCy)
│ ├── 情感分析
│ └── 回复生成 (GPT-4)
├── Knowledge Service
│ ├── 向量检索 (ChromaDB)
│ ├── 全文搜索 (Elasticsearch)
│ └── 知识图谱
└── Analytics Service
├── 实时指标
├── 用户行为分析
└── 质量评估
数据流:
请求 → API网关 → 业务服务 → AI服务 → 响应
↓
消息队列 (Celery + Redis)
↓
异步处理 (日志、分析、通知)`,
ai: `// AI服务集成架构
模型服务:
├── LLM服务
│ ├── GPT-4 (主要)
│ ├── Claude (备用)
│ └── 文心一言 (本地化)
├── embedding服务
│ ├── text-embedding-ada-002
│ ├── bge-large-zh
│ └── 自定义微调模型
├── 分类服务
│ ├── 意图分类 (微调BERT)
│ ├── 情感分类
│ └── 紧急程度分类
└── 生成服务
├── 回复生成
├── 摘要生成
└── 翻译服务
部署策略:
├── 模型热更新
├── A/B测试
├── 灰度发布
├── 自动扩缩容
└── 多区域部署
优化技术:
├── 模型量化 (INT8)
├── 知识蒸馏
├── 缓存策略
├── 批处理优化
└── 流式响应`,
monitoring: `// 监控运维体系
监控指标:
├── 技术指标
│ ├── 响应时间 (P50, P95, P99)
│ ├── 吞吐量 (QPS)
│ ├── 错误率
│ └── 资源使用率
├── 业务指标
│ ├── 会话量
│ ├── 解决率
│ ├── 满意度
│ └── 转人工率
└── AI指标
├── 意图识别准确率
├── 回复质量评分
├── 模型响应时间
└── 模型置信度
监控栈:
├── Prometheus (指标收集)
├── Grafana (可视化)
├── ELK Stack (日志分析)
├── Jaeger (链路追踪)
├── AlertManager (告警)
└── PagerDuty (事件响应)
运维自动化:
├── 自动扩缩容 (HPA)
├── 健康检查
├── 故障自愈
├── 数据备份
└── 安全扫描`
};
output.textContent = architectures[type];
output.classList.add('fade-in');
setTimeout(() => output.classList.remove('fade-in'), 500);
}
function showTab(tabName) {
const contents = document.querySelectorAll('.tab-content');
contents.forEach(content => content.classList.remove('active'));
const buttons = document.querySelectorAll('.tab-btn');
buttons.forEach(btn => btn.classList.remove('active'));
document.getElementById(tabName).classList.add('active');
event.target.classList.add('active');
}
function startQuiz() {
const output = document.getElementById('quiz-output');
output.innerHTML = `
🧠 AI产品设计思维测试
┌─────────────────────────────────────┐
│ 问题1: 以下哪个是AI产品的核心要素? │
│ │
│ A. 先进的算法 │
│ B. 大量的数据 │
│ C. 用户价值 │
│ D. 复杂的架构 │
│ │
│ 💡 提示:从产品经理的角度思考 │
└─────────────────────────────────────┘
点击选项查看答案和解析...
`;
setTimeout(() => {
output.innerHTML += `
✅ 正确答案:C. 用户价值
📚 解析:
作为AI产品经理,最重要的是关注用户价值。
技术只是实现手段,真正的价值在于解决用户的实际问题。
课程中学到的产品思维:
• 用户第一原则
• 用技术解决真实问题
• 平衡技术可行性与商业价值
`;
}, 3000);
}
function showRoadmap() {
const output = document.getElementById('quiz-output');
output.innerHTML = `
🗺️ AI产品经理学习路线图
┌─────────────────────────────────────┐
│ 📍 第一阶段:基础认知 (1-2个月) │
│ ├── AI技术基础理解 │
│ ├── 产品开发流程 │
│ └── 用户研究方法 │
│ │
│ 📍 第二阶段:实战技能 (2-3个月) │
│ ├── AIGC产品设计 │
│ ├── 数据分析能力 │
│ └── 项目管理技能 │
│ │
│ 📍 第三阶段:进阶提升 (3-6个月) │
│ ├── 商业思维培养 │
│ ├── 团队协作能力 │
│ └── 行业洞察积累 │
│ │
│ 🎯 终极目标: │
│ 成为既懂技术又懂产品的复合型人才! │
└─────────────────────────────────────┘
`;
}
function showResources() {
const output = document.getElementById('quiz-output');
output.innerHTML = `
📚 推荐学习资源
┌─────────────────────────────────────┐
│ 🎓 在线课程 │
│ ├── 《AI产品经理特训营》✨ │
│ ├── Google AI产品经理认证 │
│ └── Coursera AI产品管理专项课程 │
│ │
│ 📖 经典书籍 │
│ ├── 《人工智能产品经理》 │
│ ├── 《机器学习实战》 │
│ └── 《用户故事地图》 │
│ │
│ 🛠️ 实用工具 │
│ ├── Figma (原型设计) │
│ ├── Postman (API测试) │
│ ├── Mixpanel (数据分析) │
│ └── Notion (知识管理) │
│ │
│ 🌐 优质社区 │
│ ├── Product Hunt │
│ ├── Medium (AI产品话题) │
│ └── 知乎AI产品话题 │
└─────────────────────────────────────┘
`;
}
document.addEventListener('DOMContentLoaded', function() {
const codeBlocks = document.querySelectorAll('.code-block');
codeBlocks.forEach((block, index) => {
block.style.opacity = '0';
block.style.transform = 'translateY(20px)';
setTimeout(() => {
block.style.transition = 'opacity 0.5s ease, transform 0.5s ease';
block.style.opacity = '1';
block.style.transform = 'translateY(0)';
}, index * 100);
});
});
function animateProgress() {
const progressBars = document.querySelectorAll('.progress-fill');
progressBars.forEach(bar => {
const width = bar.style.width;
bar.style.width = '0%';
setTimeout(() => {
bar.style.width = width;
}, 500);
});
}
window.addEventListener('load', animateProgress);
</script>
</body>
</html>