feat(docs): restructure API design guide with interactive demos and practical examples

refactor(components): replace static API design components with interactive demos
- Add ApiRequestDemo, RestfulUrlDemo, StatusCodeDemo, ErrorHandlingDemo, and ApiVersioningDemo
- Remove outdated ResourceAnalogy, RequestStructureDemo, and VersioningStrategyDemo

docs(api-design): completely rewrite API design chapter with restaurant analogy
- Add clear problem scenarios and solutions
- Include practical e-commerce API examples
- Add terminology glossary
- Improve error handling and versioning sections

style(ai-history): enhance FoundationDemo with better visual hierarchy
- Add section blocks for core theories and early breakthroughs
- Improve typography and highlighting

chore: remove unused components (CpuArchitectureDemo, EvolutionFlowDemo)
This commit is contained in:
sanbuphy
2026-02-22 23:20:27 +08:00
parent e5a5b9df5b
commit 5b622800b8
26 changed files with 3217 additions and 4784 deletions
@@ -0,0 +1,107 @@
<template>
<div class="demo-card">
<div class="era-container">
<div class="era-header">
🌟 AI 发展阶段与核心范式全景对比
</div>
<div class="era-grid">
<div class="era-item" v-for="era in eras" :key="era.name" :style="{ borderTopColor: era.color }">
<div class="e-icon" :style="{ background: era.color }">{{ era.icon }}</div>
<div class="e-name" :style="{ color: era.color }">{{ era.name }}</div>
<div class="e-time">{{ era.time }}</div>
<div class="e-section">
<div class="e-label">驱动方式</div>
<div class="e-value">{{ era.driver }}</div>
</div>
<div class="e-section">
<div class="e-label">核心机制</div>
<div class="e-value">
<span class="highlight">{{ era.mechanism }}</span>
</div>
</div>
<div class="e-section">
<div class="e-label">典型代表</div>
<div class="e-tags">
<span class="e-tag" v-for="tag in era.examples" :key="tag">{{ tag }}</span>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
const eras = [
{
name: '规则系统时代',
time: '1960s - 1980s',
icon: '📜',
color: '#059669', // emerald
driver: '人类硬编码知识',
mechanism: 'If-Then 逻辑推演',
examples: ['Dendral', '深蓝 (Deep Blue)']
},
{
name: '传统机器学习',
time: '1990s - 2000s',
icon: '📊',
color: '#d97706', // amber
driver: '人工特征工程 + 统计学',
mechanism: '寻找数学决策边界',
examples: ['支持向量机 (SVM)', '随机森林']
},
{
name: '深度学习革命',
time: '2010s',
icon: '🧠',
color: '#dc2626', // red
driver: '大数据 + 算力爬升',
mechanism: '神经网络自动提取特征',
examples: ['AlexNet (CNN)', 'AlphaGo (RL)']
},
{
name: '大语言模型 (LLM)',
time: '2018 - 至今',
icon: '💬',
color: '#7c3aed', // violet
driver: '海量无标注数据 + 暴力计算',
mechanism: '预测下一个词 + 涌现常识',
examples: ['GPT-4', 'Claude 3']
},
{
name: '智能体 (Agentic AI)',
time: '现在 - 未来',
icon: '🤖',
color: '#0284c7', // light blue
driver: '大模型大脑 + 环境感知',
mechanism: '自主规划 + 工具调用',
examples: ['AI 程序员', '具身智能']
}
]
</script>
<style scoped>
.demo-card { border: 1px solid var(--vp-c-divider); border-radius: 8px; background: var(--vp-c-bg-soft); padding: 1.25rem; margin: 1.5rem 0; overflow-x: auto; }
.era-container { min-width: 800px; display: flex; flex-direction: column; gap: 1rem; }
.era-header { text-align: center; font-weight: bold; font-size: 1.1rem; color: var(--vp-c-text-1); margin-bottom: 0.5rem; }
.era-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 0.8rem; }
.era-item { background: var(--vp-c-bg); border: 1px solid var(--vp-c-divider); border-top: 4px solid; border-radius: 8px; padding: 1rem; display: flex; flex-direction: column; align-items: center; text-align: center; gap: 0.8rem; }
.e-icon { width: 36px; height: 36px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 1.2rem; margin-bottom: 0.2rem; }
.e-name { font-weight: 800; font-size: 0.95rem; }
.e-time { font-size: 0.75rem; color: var(--vp-c-text-3); font-weight: bold; margin-top: -0.6rem; }
.e-section { width: 100%; display: flex; flex-direction: column; gap: 0.3rem; margin-top: 0.2rem; }
.e-label { font-size: 0.7rem; color: var(--vp-c-text-3); text-transform: uppercase; letter-spacing: 0.5px; }
.e-value { font-size: 0.8rem; color: var(--vp-c-text-2); line-height: 1.4; }
.highlight { display: inline-block; background: var(--vp-c-bg-soft); padding: 0.2rem 0.5rem; border-radius: 4px; font-weight: 600; color: var(--vp-c-text-1); border: 1px dashed var(--vp-c-divider); }
.e-tags { display: flex; flex-direction: column; gap: 0.4rem; align-items: center; justify-content: center; }
.e-tag { font-size: 0.75rem; background: var(--vp-c-bg-alt); border: 1px solid var(--vp-c-divider); color: var(--vp-c-text-1); padding: 0.25rem 0.6rem; border-radius: 12px; width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.html.dark .highlight { background: var(--vp-c-bg-alt); }
</style>
@@ -10,11 +10,26 @@
</div>
<div class="loss-visual">
<div class="loss-label">Loss误差随训练轮次下降</div>
<svg viewBox="0 0 300 60" class="loss-svg">
<polyline :points="lossPoints" fill="none" stroke="var(--vp-c-brand)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
<text x="5" y="10" class="ax"></text>
<text x="5" y="56" class="ax"></text>
<text x="220" y="56" class="ax">训练轮次 </text>
<svg viewBox="0 0 320 130" class="loss-svg">
<!-- Axes -->
<line x1="40" y1="110" x2="300" y2="110" stroke="var(--vp-c-text-3)" stroke-width="1.5" />
<line x1="40" y1="110" x2="40" y2="15" stroke="var(--vp-c-text-3)" stroke-width="1.5" />
<!-- X Arrow -->
<polygon points="300,107 305,110 300,113" fill="var(--vp-c-text-3)" />
<!-- Y Arrow -->
<polygon points="37,15 40,10 43,15" fill="var(--vp-c-text-3)" />
<!-- Y Label -->
<text x="30" y="25" text-anchor="end" class="ax-text"></text>
<text x="30" y="105" text-anchor="end" class="ax-text"></text>
<text x="20" y="65" text-anchor="middle" transform="rotate(-90 20 65)" class="ax-title">Loss</text>
<!-- X Label -->
<text x="300" y="125" text-anchor="end" class="ax-title">训练轮次 (Epochs)</text>
<!-- Loss 曲线 -->
<polyline :points="lossPoints" fill="none" stroke="var(--vp-c-brand)" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" />
</svg>
</div>
</div>
@@ -30,8 +45,15 @@ const steps = [
const lossPoints = (() => {
const pts = []
for (let i = 0; i <= 50; i++) {
const x = 20 + i * 5.2
const y = 52 - 44 * Math.exp(-i * 0.09) + Math.sin(i * 0.7) * 1
const x = 40 + i * 5; // 40 to 290
// Y从上(小值)到下(大值),Loss越来越低,意味着Y越来越大,靠近110
// 我们让一开始的高Loss出现在 y=20 附近,最终的低Loss停留 在 y=105 附近
let noise = (Math.random() - 0.5) * 3;
let y = 105 - 85 * Math.exp(-i * 0.12) + noise;
if (i === 0) y = 20; // 确保起点干净
if (y > 108) y = 108; // 不超过底轴
pts.push(`${x},${y}`)
}
return pts.join(' ')
@@ -49,6 +71,8 @@ const lossPoints = (() => {
.step-desc { font-size: 0.68rem; color: var(--vp-c-text-2); line-height: 1.3; }
.loss-visual { background: var(--vp-c-bg); border: 1px solid var(--vp-c-divider); border-radius: 6px; padding: 0.7rem; }
.loss-label { font-size: 0.75rem; color: var(--vp-c-text-2); margin-bottom: 0.3rem; }
.loss-svg { width: 100%; max-width: 380px; height: auto; display: block; margin: 0 auto; }
.ax { font-size: 6px; fill: var(--vp-c-text-3); }
.loss-svg { width: 100%; max-width: 460px; height: auto; display: block; margin: 0 auto; overflow: visible; font-family: sans-serif; }
.axis-line { color: var(--vp-c-text-3); }
.ax-text { font-size: 10px; fill: var(--vp-c-text-2); }
.ax-title { font-size: 11px; fill: var(--vp-c-text-1); font-weight: 500; }
</style>
@@ -0,0 +1,87 @@
<template>
<div class="demo-card">
<div class="expert-system-flow">
<div class="es-card success">
<div class="es-title">🌟 专家系统的辉煌</div>
<div class="es-list">
<div class="es-item">
<span class="es-box input">人类专家经验</span>
<span class="es-arrow"></span>
<span class="es-box rules">转为 IF-THEN 规则库</span>
</div>
<div class="es-item">
<span class="es-box input">特定领域问题</span>
<span class="es-arrow"></span>
<span class="es-box output">推理解答 (诊断/配置)</span>
</div>
</div>
<div class="es-tags">
<span class="es-tag">1965: Dendral (化学)</span>
<span class="es-tag">1977: MYCIN (医疗)</span>
<span class="es-tag">1980: XCON (配置)</span>
</div>
</div>
<div class="es-arrow-down"> 局限性爆发 </div>
<div class="es-card winter">
<div class="es-title"><span class="snow"></span> 第一次 AI 寒冬 (1974-1980)</div>
<div class="winter-reasons">
<div class="reason">
<span class="r-icon">📝</span>
<div class="r-text">
<strong>知识获取瓶颈</strong>
<span>波兰尼悖论人类无法说清所有规律大量"常识"无法被人工硬编码</span>
</div>
</div>
<div class="reason">
<span class="r-icon">💥</span>
<div class="r-text">
<strong>组合爆炸 & 脆性问题</strong>
<span>现实情况太多穷举极难且缺少常识稍微偏离规则库系统就直接崩溃</span>
</div>
</div>
<div class="reason">
<span class="r-icon">📉</span>
<div class="r-text">
<strong>算力不足 & 经费断层</strong>
<span>当时的硬件算力根本无法支撑爆发性的逻辑推演遭遇 DARPA 研发经费大削减</span>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
</script>
<style scoped>
.demo-card { border: 1px solid var(--vp-c-divider); border-radius: 8px; background: var(--vp-c-bg-soft); padding: 1.25rem; margin: 1rem 0; }
.expert-system-flow { display: flex; flex-direction: column; align-items: center; gap: 0.8rem; }
.es-card { width: 100%; max-width: 500px; border: 1px solid var(--vp-c-divider); border-radius: 6px; padding: 1rem; background: var(--vp-c-bg); }
.es-card.success { border-top: 3px solid #059669; }
.es-card.winter { border-top: 3px solid #3b82f6; background: rgba(59, 130, 246, 0.03); }
.es-title { font-weight: bold; font-size: 0.9rem; margin-bottom: 0.8rem; text-align: center; color: var(--vp-c-text-1); }
.es-list { display: flex; flex-direction: column; gap: 0.6rem; margin-bottom: 1rem; }
.es-item { display: flex; align-items: center; justify-content: center; gap: 0.4rem; font-size: 0.75rem; }
.es-box { padding: 0.4rem 0.6rem; border-radius: 4px; font-weight: 500; border: 1px solid var(--vp-c-divider); text-align: center; }
.es-box.input { background: var(--vp-c-bg-soft); color: var(--vp-c-text-2); }
.es-box.rules { background: #d1fae5; color: #065f46; border-color: #34d399; }
.es-box.output { background: #e0e7ff; color: #3730a3; border-color: #818cf8; }
.html.dark .es-box.rules { background: rgba(5, 150, 105, 0.2); color: #a7f3d0; border-color: #059669; }
.html.dark .es-box.output { background: rgba(79, 70, 229, 0.2); color: #c7d2fe; border-color: #4f46e5; }
.es-arrow { color: var(--vp-c-text-3); font-weight: bold; }
.es-tags { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.5rem; }
.es-tag { font-size: 0.65rem; background: var(--vp-c-bg-soft); padding: 0.15rem 0.5rem; border-radius: 12px; color: var(--vp-c-text-2); border: 1px solid var(--vp-c-divider); }
.es-arrow-down { font-size: 0.8rem; color: var(--vp-c-text-3); font-weight: bold; margin: 0.2rem 0; }
.snow { color: #3b82f6; margin-right: 0.2rem; }
.winter-reasons { display: flex; flex-direction: column; gap: 0.6rem; }
.reason { display: flex; align-items: flex-start; gap: 0.6rem; background: var(--vp-c-bg-alt); padding: 0.6rem; border-radius: 6px; border: 1px solid var(--vp-c-divider); }
.r-icon { font-size: 1.2rem; margin-top: 0.1rem; }
.r-text { display: flex; flex-direction: column; }
.r-text strong { font-size: 0.8rem; color: var(--vp-c-text-1); }
.r-text span { font-size: 0.7rem; color: var(--vp-c-text-2); line-height: 1.4; margin-top: 0.15rem; }
</style>
@@ -1,44 +1,87 @@
<template>
<div class="demo-card">
<div class="events">
<div class="event" v-for="e in events" :key="e.year">
<div class="year-col">
<span class="year-badge">{{ e.year }}</span>
</div>
<div class="dot-col">
<div class="dot" :style="{ background: e.color }"></div>
<div class="line" v-if="e !== events[events.length - 1]"></div>
</div>
<div class="content-col">
<div class="event-title">{{ e.title }}</div>
<div class="event-note">{{ e.note }}</div>
<div class="foundation-container">
<!-- Part 1: Core Theories -->
<div class="section-block">
<div class="section-title">核心人物与理论</div>
<div class="event-list">
<div class="event-item">
<span class="e-year">1943</span>
<span class="e-text"><strong>沃伦·麦卡洛克 & 沃尔特·皮茨</strong> 提出 <em>MP 神经元模型</em>首次用数学描述神经网络</span>
</div>
<div class="event-item">
<span class="e-year">1950</span>
<span class="e-text"><strong>艾伦·图灵</strong> 发表计算机器与智能提出 <em>图灵测试</em>定义机器智能标准</span>
</div>
<div class="event-item highlight-event">
<span class="e-year">1956</span>
<span class="e-text"><strong>达特茅斯会议</strong>约翰·麦卡锡首次提出"人工智能"概念标志 AI 学科正式诞生</span>
</div>
</div>
</div>
<!-- Part 2: Symbolism -->
<div class="symbolism-panel">
<div class="s-header">
<span class="s-icon">📜</span>
<span class="s-title">符号主义兴起 (Symbolism)</span>
</div>
<div class="s-body">
<div class="s-equation">智能 = 符号推理</div>
<div class="s-desc">
符号主义逻辑主义/计算机学派主张将知识编码为符号通过 <strong>逻辑规则与推导</strong> 解决问题这是一条极其依赖人类专家的 <em>自上而下</em> 的智能模拟路径
</div>
</div>
</div>
<!-- Part 3: Early Breakthroughs -->
<div class="section-block">
<div class="section-title">早期突破</div>
<div class="event-list">
<div class="event-item">
<span class="e-year">1956</span>
<span class="e-text">纽厄尔和西蒙开发 <strong>逻辑理论家 (Logic Theorist)</strong>首个能证明数学定理的 AI 程序</span>
</div>
<div class="event-item">
<span class="e-year">1958</span>
<span class="e-text">麦卡锡发明 <strong>LISP 语言</strong>成为 AI 研究的重要工具</span>
</div>
<div class="event-item">
<span class="e-year">1959</span>
<span class="e-text">乔治·德沃尔与约瑟夫·恩格尔伯格开发首台 <strong>工业机器人</strong>标志 AI 从理论走向应用</span>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
const events = [
{ year: '1943', title: 'MP 神经元模型', note: '麦卡洛克 & 皮茨:首次用数学公式模拟神经元,证明"神经元可被计算"。', color: '#3b82f6' },
{ year: '1950', title: '图灵测试', note: '图灵:如果机器的回答让人无法分辨是人还是机器,则认为它具备智能。', color: '#7c3aed' },
{ year: '1956', title: '达特茅斯会议 — AI 学科诞生', note: '麦卡锡等人首次提出"人工智能"概念,AI 正式成为一门学科。', color: '#059669' },
{ year: '1956', title: '逻辑理论家(Logic Theorist', note: '纽厄尔 & 西蒙:第一个用规则自动证明数学定理的 AI 程序。', color: '#059669' },
{ year: '1958', title: 'LISP 语言诞生', note: '麦卡锡发明,成为此后数十年 AI 研究的核心编程语言。', color: '#d97706' },
{ year: '1959', title: '首台工业机器人', note: '德沃尔 & 恩格尔伯格:AI 从实验室走向工厂,开始改变工业生产。', color: '#dc2626' },
]
</script>
<style scoped>
.demo-card { border: 1px solid var(--vp-c-divider); border-radius: 8px; background: var(--vp-c-bg-soft); padding: 1.25rem; margin: 1rem 0; }
.events { display: flex; flex-direction: column; }
.event { display: grid; grid-template-columns: 52px 24px 1fr; gap: 0 0.6rem; }
.year-col { display: flex; align-items: flex-start; padding-top: 0.15rem; justify-content: flex-end; }
.year-badge { font-size: 0.7rem; font-weight: bold; color: var(--vp-c-text-3); white-space: nowrap; }
.dot-col { display: flex; flex-direction: column; align-items: center; }
.dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; margin-top: 0.2rem; }
.line { width: 2px; flex: 1; background: var(--vp-c-divider); margin: 3px 0; min-height: 16px; }
.content-col { padding-bottom: 0.9rem; }
.event-title { font-weight: bold; font-size: 0.85rem; color: var(--vp-c-text-1); margin-bottom: 0.15rem; }
.event-note { font-size: 0.78rem; color: var(--vp-c-text-2); line-height: 1.5; }
.demo-card { border: 1px solid var(--vp-c-divider); border-radius: 8px; background: var(--vp-c-bg-soft); padding: 1.2rem; margin: 1rem 0; }
.foundation-container { display: flex; flex-direction: column; gap: 1.2rem; }
.section-block { display: flex; flex-direction: column; gap: 0.5rem; }
.section-title { font-weight: bold; font-size: 0.9rem; color: var(--vp-c-brand-1); border-bottom: 1px solid var(--vp-c-divider); padding-bottom: 0.3rem; margin-bottom: 0.3rem; }
.event-list { display: flex; flex-direction: column; gap: 0.5rem; }
.event-item { display: flex; align-items: flex-start; gap: 0.6rem; font-size: 0.8rem; line-height: 1.4; }
.e-year { font-weight: bold; background: var(--vp-c-bg-alt); padding: 0.1rem 0.4rem; border-radius: 4px; color: var(--vp-c-text-1); border: 1px solid var(--vp-c-divider); font-family: monospace; flex-shrink: 0; }
.e-text { color: var(--vp-c-text-2); padding-top: 0.1rem; }
.e-text strong { color: var(--vp-c-text-1); }
.e-text em { color: var(--vp-c-brand-1); font-style: normal; font-weight: 500; }
.highlight-event .e-year { background: #10b981; color: white; border-color: #059669; }
.symbolism-panel { background: rgba(16, 185, 129, 0.05); border: 1px dashed #10b981; border-radius: 8px; padding: 1rem; display: flex; flex-direction: column; gap: 0.6rem; text-align: center; }
.s-header { display: flex; align-items: center; justify-content: center; gap: 0.4rem; }
.s-icon { font-size: 1.2rem; }
.s-title { font-weight: bold; font-size: 0.95rem; color: #059669; }
.s-equation { font-family: monospace; font-size: 1rem; font-weight: bold; color: var(--vp-c-text-1); background: var(--vp-c-bg); padding: 0.4rem 1rem; border-radius: 6px; border: 1px solid var(--vp-c-divider); display: inline-block; margin: 0 auto; }
.s-desc { font-size: 0.78rem; color: var(--vp-c-text-2); line-height: 1.5; max-width: 90%; margin: 0 auto; }
.html.dark .symbolism-panel { background: rgba(5, 150, 105, 0.15); border-color: #059669; }
.html.dark .s-title { color: #34d399; }
</style>