diff --git a/README.md b/README.md index c9b55f9..49c3590 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ # Easy-Vibe : Learn vibe coding from 0 to 1

- 📌 开始在线阅读 (Start Reading Online) + 📌 在线阅读 (Read Online) · ✨ 交互式教程 (Interactive Tutorial)

@@ -49,6 +49,57 @@ + + + + + + + + + + + + + +
+ +
+ 新手专属学习地图 +
+ 零基础专属指引,清晰规划路径,告别“学了忘” +
+ +
+ 手把手图文教程 +
+ 保姆级图文详解,如同私教在旁,跟着做就能学会 +
+ +
+ 沉浸式模拟编程 +
+ 虚拟鼠标自动导览,带你快速上手 IDE 核心用法 +
+ +
+ 看得见的 AI 原理 +
+ 算法原理动画化,一眼看懂 AI 如何“画”出图片 +
+ +
+ 像玩游戏一样学 RAG +
+ 独家交互组件,点击即可看清 RAG 数据流向 +
+ +
+ 可视化终端原理 +
+ 命令行操作可视化,直观展示后台逻辑与原理 +
+ --- 在 AI 时代,把想法变成产品的人,往往技术不是最强,而是最先迈出行动。 diff --git a/assets/gif-diffusion.gif b/assets/gif-diffusion.gif new file mode 100644 index 0000000..7165579 Binary files /dev/null and b/assets/gif-diffusion.gif differ diff --git a/assets/gif-header.png b/assets/gif-header.png new file mode 100644 index 0000000..ad744c7 Binary files /dev/null and b/assets/gif-header.png differ diff --git a/assets/gif-ide.gif b/assets/gif-ide.gif new file mode 100644 index 0000000..49380b3 Binary files /dev/null and b/assets/gif-ide.gif differ diff --git a/assets/gif-rag.gif b/assets/gif-rag.gif new file mode 100644 index 0000000..e697b7e Binary files /dev/null and b/assets/gif-rag.gif differ diff --git a/assets/gif-tutorial.png b/assets/gif-tutorial.png new file mode 100644 index 0000000..376daf2 Binary files /dev/null and b/assets/gif-tutorial.png differ diff --git a/assets/gif-tutorial2.png b/assets/gif-tutorial2.png new file mode 100644 index 0000000..947eee9 Binary files /dev/null and b/assets/gif-tutorial2.png differ diff --git a/assets/git-terminal.gif b/assets/git-terminal.gif new file mode 100644 index 0000000..0adca3a Binary files /dev/null and b/assets/git-terminal.gif differ diff --git a/docs/.vitepress/config.mjs b/docs/.vitepress/config.mjs index ba19b3f..78afe69 100644 --- a/docs/.vitepress/config.mjs +++ b/docs/.vitepress/config.mjs @@ -538,10 +538,6 @@ export default defineConfig({ text: '提示词工程', link: '/zh-cn/appendix/prompt-engineering' }, - { - text: '上下文工程', - link: '/zh-cn/appendix/context-engineering' - }, { text: '人工智能进化史', link: '/zh-cn/appendix/ai-evolution' @@ -553,6 +549,10 @@ export default defineConfig({ link: '/zh-cn/appendix/image-gen-intro' }, { text: 'AI 音频模型', link: '/zh-cn/appendix/audio-intro' }, + { + text: '上下文工程', + link: '/zh-cn/appendix/context-engineering' + }, { text: 'Agent 智能体', link: '/zh-cn/appendix/agent-intro' }, { text: 'AI 能力词典', @@ -561,7 +561,7 @@ export default defineConfig({ ] }, { - text: 'Web 基础', + text: '前端开发', collapsed: false, items: [ { @@ -580,14 +580,6 @@ export default defineConfig({ text: 'Canvas 2D 入门', link: '/zh-cn/appendix/canvas-intro' }, - { - text: '后端进化史', - link: '/zh-cn/appendix/backend-evolution' - }, - { - text: '后端编程语言', - link: '/zh-cn/appendix/backend-languages' - }, { text: 'URL 到浏览器显示', link: '/zh-cn/appendix/url-to-browser' @@ -599,30 +591,38 @@ export default defineConfig({ ] }, { - text: '开发基础', + text: '后端开发', collapsed: false, items: [ - { text: 'IDE 原理', link: '/zh-cn/appendix/ide-intro' }, - { text: '终端入门', link: '/zh-cn/appendix/terminal-intro' }, - { text: 'Git 详细介绍', link: '/zh-cn/appendix/git-intro' }, - { text: '数据库原理', link: '/zh-cn/appendix/database-intro' }, { - text: '计算机网络', - link: '/zh-cn/appendix/computer-networks' + text: '后端进化史', + link: '/zh-cn/appendix/backend-evolution' }, - { text: '部署与上线', link: '/zh-cn/appendix/deployment' } - ] - }, - { - text: '后端进阶', - collapsed: false, - items: [ + { + text: '后端编程语言', + link: '/zh-cn/appendix/backend-languages' + }, + { text: '数据库原理', link: '/zh-cn/appendix/database-intro' }, { text: '系统缓存设计', link: '/zh-cn/appendix/cache-design' }, { text: '消息队列设计', link: '/zh-cn/appendix/queue-design' }, { text: '鉴权原理与实战', link: '/zh-cn/appendix/auth-design' }, { text: '埋点设计', link: '/zh-cn/appendix/tracking-design' }, { text: '线上运维', link: '/zh-cn/appendix/operations' } ] + }, + { + text: '通用技能', + collapsed: false, + items: [ + { text: 'IDE 原理', link: '/zh-cn/appendix/ide-intro' }, + { text: '终端入门', link: '/zh-cn/appendix/terminal-intro' }, + { text: 'Git 详细介绍', link: '/zh-cn/appendix/git-intro' }, + { + text: '计算机网络', + link: '/zh-cn/appendix/computer-networks' + }, + { text: '部署与上线', link: '/zh-cn/appendix/deployment' } + ] } ] } diff --git a/docs/.vitepress/theme/components/appendix/ai-history/AIEvolutionTimelineDemo.vue b/docs/.vitepress/theme/components/appendix/ai-history/AIEvolutionTimelineDemo.vue new file mode 100644 index 0000000..c4d0276 --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/ai-history/AIEvolutionTimelineDemo.vue @@ -0,0 +1,305 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/ai-history/AiEvolutionDemo.vue b/docs/.vitepress/theme/components/appendix/ai-history/AiEvolutionDemo.vue index e0af6db..537beac 100644 --- a/docs/.vitepress/theme/components/appendix/ai-history/AiEvolutionDemo.vue +++ b/docs/.vitepress/theme/components/appendix/ai-history/AiEvolutionDemo.vue @@ -197,21 +197,17 @@ const stages = [ diff --git a/docs/.vitepress/theme/components/appendix/ai-history/BackpropagationDemo.vue b/docs/.vitepress/theme/components/appendix/ai-history/BackpropagationDemo.vue new file mode 100644 index 0000000..bf53f3c --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/ai-history/BackpropagationDemo.vue @@ -0,0 +1,383 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/ai-history/CombinatorialExplosionDemo.vue b/docs/.vitepress/theme/components/appendix/ai-history/CombinatorialExplosionDemo.vue new file mode 100644 index 0000000..9a0ad09 --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/ai-history/CombinatorialExplosionDemo.vue @@ -0,0 +1,760 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/ai-history/DiscriminativeVsGenerativeDemo.vue b/docs/.vitepress/theme/components/appendix/ai-history/DiscriminativeVsGenerativeDemo.vue new file mode 100644 index 0000000..2740f04 --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/ai-history/DiscriminativeVsGenerativeDemo.vue @@ -0,0 +1,401 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/ai-history/GPTEvolutionDemo.vue b/docs/.vitepress/theme/components/appendix/ai-history/GPTEvolutionDemo.vue new file mode 100644 index 0000000..4a33b93 --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/ai-history/GPTEvolutionDemo.vue @@ -0,0 +1,468 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/ai-history/NeuralNetworkVisualizationDemo.vue b/docs/.vitepress/theme/components/appendix/ai-history/NeuralNetworkVisualizationDemo.vue new file mode 100644 index 0000000..82cc697 --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/ai-history/NeuralNetworkVisualizationDemo.vue @@ -0,0 +1,390 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/ai-history/PerceptronDemo.vue b/docs/.vitepress/theme/components/appendix/ai-history/PerceptronDemo.vue index 13d6b78..0699368 100644 --- a/docs/.vitepress/theme/components/appendix/ai-history/PerceptronDemo.vue +++ b/docs/.vitepress/theme/components/appendix/ai-history/PerceptronDemo.vue @@ -96,7 +96,7 @@ const output = computed(() => { .perceptron-demo { border: 1px solid var(--vp-c-divider); border-radius: 8px; - background: white; + background: var(--vp-c-bg-soft); padding: 1.5rem; margin: 1rem 0; overflow-x: auto; @@ -123,19 +123,20 @@ const output = computed(() => { width: 60px; height: 60px; border-radius: 50%; - border: 2px solid #94a3b8; + border: 2px solid var(--vp-c-divider); display: flex; flex-direction: column; align-items: center; justify-content: center; - background: #f1f5f9; + background: var(--vp-c-bg); position: relative; + color: var(--vp-c-text-1); } .output-node.active { - background: #4ade80; - border-color: #16a34a; - color: white; + background: var(--vp-c-brand); + border-color: var(--vp-c-brand); + color: var(--vp-c-bg); font-weight: bold; } @@ -145,7 +146,7 @@ const output = computed(() => { top: -15px; width: 80px; text-align: center; - color: #64748b; + color: var(--vp-c-text-2); } .val-input { @@ -169,7 +170,7 @@ const output = computed(() => { .weight-line { height: 2px; - background: #475569; + background: var(--vp-c-text-2); position: absolute; left: 0; right: 0; @@ -184,9 +185,9 @@ const output = computed(() => { display: flex; align-items: center; gap: 4px; - background: white; + background: var(--vp-c-bg); padding: 2px 4px; - border: 1px solid #e2e8f0; + border: 1px solid var(--vp-c-divider); border-radius: 4px; z-index: 2; } @@ -195,14 +196,14 @@ const output = computed(() => { width: 100px; height: 100px; border-radius: 50%; - background: #3b82f6; - color: white; + background: var(--vp-c-brand); + color: var(--vp-c-bg); display: flex; flex-direction: column; align-items: center; justify-content: center; position: relative; - box-shadow: 0 4px 10px rgba(59, 130, 246, 0.3); + border: 1px solid rgba(var(--vp-c-brand-rgb), 0.35); } .sum-part { @@ -218,11 +219,11 @@ const output = computed(() => { .bias-control { position: absolute; bottom: -30px; - background: white; - color: #333; + background: var(--vp-c-bg); + color: var(--vp-c-text-1); padding: 2px 8px; border-radius: 10px; - border: 1px solid #e2e8f0; + border: 1px solid var(--vp-c-divider); font-size: 0.7rem; display: flex; align-items: center; @@ -230,21 +231,21 @@ const output = computed(() => { } .bias-input { width: 30px; - border: 1px solid #cbd5e1; + border: 1px solid var(--vp-c-divider); border-radius: 2px; text-align: center; } .formula-bar { margin-top: 2rem; - background: #f8fafc; + background: var(--vp-c-bg); padding: 1rem; border-radius: 6px; - font-family: monospace; + font-family: var(--vp-font-family-mono); font-size: 0.8rem; - color: #334155; + color: var(--vp-c-text-1); text-align: center; - border: 1px dashed #cbd5e1; + border: 1px dashed var(--vp-c-divider); } input[type='range'] { diff --git a/docs/.vitepress/theme/components/appendix/ai-history/RuleBasedVsLearningDemo.vue b/docs/.vitepress/theme/components/appendix/ai-history/RuleBasedVsLearningDemo.vue index ee47c00..279125f 100644 --- a/docs/.vitepress/theme/components/appendix/ai-history/RuleBasedVsLearningDemo.vue +++ b/docs/.vitepress/theme/components/appendix/ai-history/RuleBasedVsLearningDemo.vue @@ -159,19 +159,20 @@ const mlResult = computed(() => { } .code-block { - background: #1e1e2e; - color: #a6accd; + background: var(--vp-c-bg-alt); + color: var(--vp-c-text-1); padding: 0.8rem; border-radius: 4px; - font-family: monospace; + font-family: var(--vp-font-family-mono); font-size: 0.8rem; + border: 1px solid var(--vp-c-divider); } .mini-input { width: 40px; - background: #334155; - border: 1px solid #475569; - color: white; + background: var(--vp-c-bg); + border: 1px solid var(--vp-c-divider); + color: var(--vp-c-text-1); border-radius: 2px; text-align: center; } @@ -194,18 +195,18 @@ const mlResult = computed(() => { font-size: 1.1rem; padding: 0.5rem; border-radius: 4px; - background: white; + background: var(--vp-c-bg); border: 1px solid var(--vp-c-divider); } .result-box.big { - color: #ef4444; - border-color: #fecaca; - background: #fef2f2; + color: var(--vp-c-red-1, #ef4444); + border-color: rgba(var(--vp-c-brand-rgb), 0.18); + background: var(--vp-c-bg); } .result-box.small { - color: #db2777; - border-color: #fce7f3; - background: #fdf2f8; + color: var(--vp-c-text-1); + border-color: rgba(var(--vp-c-brand-rgb), 0.18); + background: var(--vp-c-bg); } .note { @@ -224,24 +225,28 @@ const mlResult = computed(() => { } .data-point { - background: #e2e8f0; + background: var(--vp-c-bg-alt); + border: 1px solid var(--vp-c-divider); padding: 2px 6px; border-radius: 4px; font-size: 0.7rem; + color: var(--vp-c-text-2); } .train-btn { width: 100%; padding: 0.5rem; - background: #3b82f6; - color: white; - border: none; + background: var(--vp-c-brand); + color: var(--vp-c-bg); + border: 1px solid var(--vp-c-brand); border-radius: 4px; cursor: pointer; transition: all 0.2s; } .train-btn:disabled { - background: #10b981; - cursor: default; + background: var(--vp-c-bg); + border-color: var(--vp-c-divider); + color: var(--vp-c-text-2); + cursor: not-allowed; } diff --git a/docs/.vitepress/theme/components/appendix/api-intro/ApiConceptDemo.vue b/docs/.vitepress/theme/components/appendix/api-intro/ApiConceptDemo.vue new file mode 100644 index 0000000..39539f0 --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/api-intro/ApiConceptDemo.vue @@ -0,0 +1,395 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/api-intro/ApiDocumentDemo.vue b/docs/.vitepress/theme/components/appendix/api-intro/ApiDocumentDemo.vue new file mode 100644 index 0000000..cf41613 --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/api-intro/ApiDocumentDemo.vue @@ -0,0 +1,830 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/api-intro/ApiMethodDemo.vue b/docs/.vitepress/theme/components/appendix/api-intro/ApiMethodDemo.vue new file mode 100644 index 0000000..a5d9c4a --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/api-intro/ApiMethodDemo.vue @@ -0,0 +1,615 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/api-intro/ApiPlayground.vue b/docs/.vitepress/theme/components/appendix/api-intro/ApiPlayground.vue new file mode 100644 index 0000000..d1107b8 --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/api-intro/ApiPlayground.vue @@ -0,0 +1,856 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/api-intro/ApiQuickStartDemo.vue b/docs/.vitepress/theme/components/appendix/api-intro/ApiQuickStartDemo.vue new file mode 100644 index 0000000..8dcadf0 --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/api-intro/ApiQuickStartDemo.vue @@ -0,0 +1,725 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/api-intro/RequestResponseFlow.vue b/docs/.vitepress/theme/components/appendix/api-intro/RequestResponseFlow.vue new file mode 100644 index 0000000..d5748fa --- /dev/null +++ b/docs/.vitepress/theme/components/appendix/api-intro/RequestResponseFlow.vue @@ -0,0 +1,452 @@ + + + + + diff --git a/docs/.vitepress/theme/components/appendix/auth-design/AuthBasicsDemo.vue b/docs/.vitepress/theme/components/appendix/auth-design/AuthBasicsDemo.vue index 1698efe..7612d14 100644 --- a/docs/.vitepress/theme/components/appendix/auth-design/AuthBasicsDemo.vue +++ b/docs/.vitepress/theme/components/appendix/auth-design/AuthBasicsDemo.vue @@ -1,457 +1,266 @@ diff --git a/docs/.vitepress/theme/components/appendix/auth-design/AuthEvolutionDemo.vue b/docs/.vitepress/theme/components/appendix/auth-design/AuthEvolutionDemo.vue index 8370596..8675101 100644 --- a/docs/.vitepress/theme/components/appendix/auth-design/AuthEvolutionDemo.vue +++ b/docs/.vitepress/theme/components/appendix/auth-design/AuthEvolutionDemo.vue @@ -1,415 +1,256 @@ diff --git a/docs/.vitepress/theme/components/appendix/auth-design/AuthNvsAuthZDemo.vue b/docs/.vitepress/theme/components/appendix/auth-design/AuthNvsAuthZDemo.vue index 23454a7..0c58dce 100644 --- a/docs/.vitepress/theme/components/appendix/auth-design/AuthNvsAuthZDemo.vue +++ b/docs/.vitepress/theme/components/appendix/auth-design/AuthNvsAuthZDemo.vue @@ -1,654 +1,288 @@ diff --git a/docs/.vitepress/theme/components/appendix/auth-design/CSRFDefenseDemo.vue b/docs/.vitepress/theme/components/appendix/auth-design/CSRFDefenseDemo.vue index 34427ba..40fcf0c 100644 --- a/docs/.vitepress/theme/components/appendix/auth-design/CSRFDefenseDemo.vue +++ b/docs/.vitepress/theme/components/appendix/auth-design/CSRFDefenseDemo.vue @@ -1,772 +1,294 @@ diff --git a/docs/.vitepress/theme/components/appendix/auth-design/PasswordHashingDemo.vue b/docs/.vitepress/theme/components/appendix/auth-design/PasswordHashingDemo.vue index 4ddf6d9..0c8ff39 100644 --- a/docs/.vitepress/theme/components/appendix/auth-design/PasswordHashingDemo.vue +++ b/docs/.vitepress/theme/components/appendix/auth-design/PasswordHashingDemo.vue @@ -1,699 +1,405 @@ diff --git a/docs/.vitepress/theme/components/appendix/git-intro/GitThreeAreasDemo.vue b/docs/.vitepress/theme/components/appendix/git-intro/GitThreeAreasDemo.vue index 68acb01..f97b8fe 100644 --- a/docs/.vitepress/theme/components/appendix/git-intro/GitThreeAreasDemo.vue +++ b/docs/.vitepress/theme/components/appendix/git-intro/GitThreeAreasDemo.vue @@ -121,11 +121,22 @@ + +

+
+
当前等价命令
+
{{ historyText }}
+
+
+
git status(模拟)
+
{{ statusText }}
+
+
diff --git a/docs/.vitepress/theme/components/appendix/git-intro/GitWorkflowDemo.vue b/docs/.vitepress/theme/components/appendix/git-intro/GitWorkflowDemo.vue index 11d37f1..6785e5c 100644 --- a/docs/.vitepress/theme/components/appendix/git-intro/GitWorkflowDemo.vue +++ b/docs/.vitepress/theme/components/appendix/git-intro/GitWorkflowDemo.vue @@ -9,25 +9,36 @@
- - +
@@ -68,10 +79,10 @@ @@ -127,12 +138,12 @@ import { ref, computed } from 'vue' const inited = ref(false) const hasBranch = ref(false) -const merging = ref(false) +const mergePending = ref(false) const mainCommits = ref([]) const branchCommits = ref([]) const status = computed(() => { - if (merging) return '合并中...' + if (mergePending.value) return '准备合并:检查改动/解决冲突后再完成合并' if (hasBranch) return '分支已创建' if (inited) return '已初始化' return '未初始化' @@ -156,22 +167,23 @@ const createBranch = () => { } } -const mergeBranch = () => { - if (hasBranch.value) { - merging.value = true - setTimeout(() => { - mainCommits.value.push({ hash: Math.random().toString(16).substr(2, 6) }) - hasBranch.value = false - branchCommits.value = [] - merging.value = false - }, 1000) - } +const prepareMerge = () => { + if (!hasBranch.value) return + mergePending.value = true +} + +const finishMerge = () => { + if (!mergePending.value) return + mainCommits.value.push({ hash: Math.random().toString(16).substr(2, 6) }) + hasBranch.value = false + branchCommits.value = [] + mergePending.value = false } const reset = () => { inited.value = false hasBranch.value = false - merging.value = false + mergePending.value = false mainCommits.value = [] branchCommits.value = [] } diff --git a/docs/.vitepress/theme/components/appendix/queue-design/PeakShavingDemo.vue b/docs/.vitepress/theme/components/appendix/queue-design/PeakShavingDemo.vue index 4996893..4578549 100644 --- a/docs/.vitepress/theme/components/appendix/queue-design/PeakShavingDemo.vue +++ b/docs/.vitepress/theme/components/appendix/queue-design/PeakShavingDemo.vue @@ -6,131 +6,102 @@
削峰填谷:把高峰"摊平"
-
调整请求速率,观察队列如何缓冲流量
+
模拟流量突增场景,观察队列如何保护后端系统
-
-
- - -
-
- - -
-
- - -
-
- -
- - -
- -
-
-
📥 入站流量
-
{{ requestRate }}/s
-
-
+
+ +
+
+
+ 处理能力 (Consumer) + {{ processRate }} req/s +
+ +
后端系统的最大处理速度
-
-
+ +
+
+ 队列容量 (Queue Size) + {{ queueCapacity }} +
+ +
消息队列能暂存的最大请求数
+
+ +
+ +
-
-
📦 消息队列
-
-
{{ queueLength }} / {{ queueCapacity }}
-
{{ queuePercent }}%
+ +
+ +
+
+
当前入站流量
+
{{ currentRequestRate }} req/s
+
+
+
队列积压量
+
{{ queueLength }} msgs
+
+
+
+
+
+
实际处理速率
+
{{ currentProcessRate }} req/s
+
+
+
丢弃请求 (限流)
+
{{ rejectedCount }} req
+
-
-
-
-
{{ queueStatusText }}
-
-
-
📤 处理流量
-
{{ processRate }}/s
-
-
+ +
+ +
+ 入站流量 (用户请求) + 处理流量 (系统负载) + 队列积压 +
-
-
-
-
-
- -
-
-
队列积压
-
{{ queueLength }}
-
-
-
平均等待时间
-
{{ avgWaitTime }}s
-
-
-
已处理请求
-
{{ processedCount }}
-
-
-
拒绝请求
-
{{ rejectedCount }}
-
- 💡 典型场景:秒杀活动 1 秒内 10 万请求,数据库只能处理 - 1000/秒 +
💡
+
+ 核心原理: + 当入站流量(蓝色)超过处理能力(绿色直线)时,多余的请求会被存入消息队列(橙色区域)。 +
+ 一旦流量高峰过去,系统会继续全速处理队列中的积压,直到队列清空。这就是"削峰填谷"。
@@ -139,126 +110,220 @@ @@ -267,238 +332,227 @@ onUnmounted(() => { border: 1px solid var(--vp-c-divider); background: var(--vp-c-bg-soft); border-radius: 12px; - padding: 1.5rem; - margin: 1.5rem 0; + padding: 20px; + margin: 20px 0; font-family: var(--vp-font-family-base); } .header { - margin-bottom: 1rem; + margin-bottom: 24px; } - .title { - font-weight: 700; - font-size: 1.05rem; -} - -.subtitle { - color: var(--vp-c-text-2); - font-size: 0.9rem; - margin-top: 0.25rem; -} - -.controls { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); - gap: 1rem; - margin-bottom: 1rem; -} - -.control label { - display: block; - margin-bottom: 0.4rem; - font-size: 0.9rem; -} - -.control input[type='range'] { - width: 100%; -} - -.simulation { - display: flex; - gap: 0.75rem; - justify-content: center; - margin: 1rem 0; -} - -.sim-btn { - background: var(--vp-c-brand); - color: #fff; - border: none; - border-radius: 8px; - padding: 0.6rem 1.5rem; - cursor: pointer; + font-size: 18px; font-weight: 600; + color: var(--vp-c-text-1); +} +.subtitle { + font-size: 14px; + color: var(--vp-c-text-2); + margin-top: 4px; +} + +.main-layout { + display: grid; + grid-template-columns: 300px 1fr; + gap: 24px; +} + +@media (max-width: 768px) { + .main-layout { + grid-template-columns: 1fr; + } +} + +.controls-panel { + background: var(--vp-c-bg); + padding: 16px; + border-radius: 8px; + border: 1px solid var(--vp-c-divider); + display: flex; + flex-direction: column; + gap: 20px; +} + +.control-group { + display: flex; + flex-direction: column; + gap: 8px; +} + +.label-row { + display: flex; + justify-content: space-between; + align-items: center; +} + +.label { + font-size: 14px; + font-weight: 500; +} + +.value { + font-size: 13px; + font-family: monospace; + background: var(--vp-c-bg-alt); + padding: 2px 6px; + border-radius: 4px; +} + +.desc { + font-size: 12px; + color: var(--vp-c-text-3); +} + +.range-input { + width: 100%; + accent-color: var(--vp-c-brand); +} + +.actions { + margin-top: auto; + display: flex; + flex-direction: column; + gap: 12px; +} + +.action-btn { + padding: 10px; + border-radius: 6px; + border: none; + font-weight: 600; + cursor: pointer; transition: all 0.2s; } -.sim-btn:hover { - transform: translateY(-1px); - box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3); +.burst-btn { + background: var(--vp-c-brand); + color: white; +} +.burst-btn:hover:not(:disabled) { + background: var(--vp-c-brand-dark); +} +.burst-btn:disabled { + opacity: 0.5; + cursor: not-allowed; } -.sim-btn.reset { - background: var(--vp-c-text-2); +.reset-btn { + background: var(--vp-c-bg-alt); + color: var(--vp-c-text-1); + border: 1px solid var(--vp-c-divider); +} +.reset-btn:hover { + background: var(--vp-c-bg-mute); } -.flow-visualization { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); - gap: 1.5rem; - margin: 1.5rem 0; - padding: 1rem; - background: var(--vp-c-bg); - border-radius: 10px; -} - -.column { +.monitor-panel { display: flex; flex-direction: column; - align-items: center; - gap: 0.75rem; + gap: 16px; } -.col-header { - font-weight: 600; - font-size: 0.9rem; +.metrics-grid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 12px; } -.rate-display { - font-size: 1.1rem; - font-weight: 700; - color: var(--vp-c-brand); -} - -.bar-container { - width: 60px; - height: 120px; - background: var(--vp-c-bg-soft); +.metric-item { + background: var(--vp-c-bg); + padding: 12px; border-radius: 8px; - position: relative; - overflow: hidden; border: 1px solid var(--vp-c-divider); } -.bar-fill { - position: absolute; - bottom: 0; - left: 0; - right: 0; - background: linear-gradient(180deg, #3b82f6, #1d4ed8); - border-radius: 0 0 8px 8px; - transition: height 0.3s ease; +.m-label { + font-size: 12px; + color: var(--vp-c-text-2); + margin-bottom: 4px; } -.bar-fill.stable { - background: linear-gradient(180deg, #22c55e, #16a34a); -} - -.queue-info { - text-align: center; -} - -.queue-count { - font-size: 1.2rem; +.m-value { + font-size: 18px; font-weight: 700; + display: flex; + align-items: baseline; + gap: 4px; } -.queue-percent { - font-size: 0.85rem; +.unit { + font-size: 12px; + font-weight: 400; + opacity: 0.7; +} + +.m-value.blue { color: #3b82f6; } +.m-value.green { color: #22c55e; } +.m-value.orange { color: #f97316; } +.m-value.red { color: #ef4444; } + +.m-bar-bg { + height: 4px; + background: var(--vp-c-bg-soft); + border-radius: 2px; + margin-top: 8px; + overflow: hidden; +} + +.m-bar-fill { + height: 100%; + transition: width 0.2s; +} + +.chart-container { + flex: 1; + background: var(--vp-c-bg); + border: 1px solid var(--vp-c-divider); + border-radius: 8px; + padding: 12px; + display: flex; + flex-direction: column; + min-height: 250px; +} + +canvas { + width: 100%; + height: 100%; + flex: 1; +} + +.chart-legend { + display: flex; + gap: 16px; + justify-content: center; + margin-top: 8px; + font-size: 12px; color: var(--vp-c-text-2); } -.queue-bar-container { - width: 100%; - height: 24px; - background: var(--vp-c-bg-soft); - border-radius: 12px; - overflow: hidden; - border: 1px solid var(--vp-c-divider); - position: relative; +.legend-item { + display: flex; + align-items: center; + gap: 6px; } -.queue-bar { - height: 100%; - transition: - width 0.3s ease, - background 0.3s ease; -} - -.queue-bar.normal { - background: linear-gradient(90deg, #22c55e, #16a34a); -} - -.queue-bar.warning { - background: linear-gradient(90deg, #f59e0b, #d97706); -} - -.queue-bar.critical { - background: linear-gradient(90deg, #ef4444, #dc2626); -} - -.queue-status-text { - font-size: 0.85rem; - text-align: center; - margin-top: 0.25rem; -} - -.particles { - position: relative; - height: 60px; - width: 100%; -} - -.particle { - position: absolute; +.dot { width: 8px; height: 8px; - background: var(--vp-c-brand); border-radius: 50%; - animation: fall 0.5s linear infinite; -} - -.particle.processed { - background: #22c55e; -} - -@keyframes fall { - 0% { - transform: translateY(0); - opacity: 1; - } - 100% { - transform: translateY(60px); - opacity: 0; - } -} - -.metrics { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); - gap: 1rem; - margin-top: 1rem; -} - -.metric-card { - background: var(--vp-c-bg); - border-radius: 10px; - padding: 1rem; - text-align: center; - border: 1px solid var(--vp-c-divider); -} - -.metric-label { - font-size: 0.85rem; - color: var(--vp-c-text-2); - margin-bottom: 0.5rem; -} - -.metric-value { - font-size: 1.3rem; - font-weight: 700; - color: var(--vp-c-text-1); -} - -.metric-value.error { - color: #ef4444; } +.dot.blue { background: #3b82f6; } +.dot.green { background: #22c55e; } +.dot.orange { background: #f97316; } .scenario-tips { - margin-top: 1rem; - padding: 0.75rem 1rem; + margin-top: 16px; background: rgba(59, 130, 246, 0.1); + border: 1px solid rgba(59, 130, 246, 0.2); border-radius: 8px; - font-size: 0.9rem; + padding: 12px; + display: flex; + gap: 12px; + font-size: 14px; line-height: 1.5; + color: var(--vp-c-text-1); } diff --git a/docs/.vitepress/theme/index.js b/docs/.vitepress/theme/index.js index 9a3296d..f832d6e 100644 --- a/docs/.vitepress/theme/index.js +++ b/docs/.vitepress/theme/index.js @@ -77,6 +77,7 @@ import GitBranchMergeDemo from './components/appendix/git-intro/GitBranchMergeDe import GitConflictDemo from './components/appendix/git-intro/GitConflictDemo.vue' import GitStashDemo from './components/appendix/git-intro/GitStashDemo.vue' import GitRemoteDemo from './components/appendix/git-intro/GitRemoteDemo.vue' +import GitScenariosDemo from './components/appendix/git-intro/GitScenariosDemo.vue' // (保留网络相关,未修改) import NetworkLayers from './components/appendix/web-basics/NetworkLayers.vue' import TcpUdpComparison from './components/appendix/web-basics/TcpUdpComparison.vue' @@ -118,6 +119,13 @@ import BigFrontendScopeDemo from './components/appendix/web-basics/BigFrontendSc import AiEvolutionDemo from './components/appendix/ai-history/AiEvolutionDemo.vue' import RuleBasedVsLearningDemo from './components/appendix/ai-history/RuleBasedVsLearningDemo.vue' import PerceptronDemo from './components/appendix/ai-history/PerceptronDemo.vue' +import AIEvolutionTimelineDemo from './components/appendix/ai-history/AIEvolutionTimelineDemo.vue' +import CombinatorialExplosionDemo from './components/appendix/ai-history/CombinatorialExplosionDemo.vue' +import NeuralNetworkVisualizationDemo from './components/appendix/ai-history/NeuralNetworkVisualizationDemo.vue' +import BackpropagationDemo from './components/appendix/ai-history/BackpropagationDemo.vue' +import AttentionMechanismDemo from './components/appendix/ai-history/AttentionMechanismDemo.vue' +import DiscriminativeVsGenerativeDemo from './components/appendix/ai-history/DiscriminativeVsGenerativeDemo.vue' +import GPTEvolutionDemo from './components/appendix/ai-history/GPTEvolutionDemo.vue' import ImperativeVsDeclarativeDemo from './components/appendix/web-basics/ImperativeVsDeclarativeDemo.vue' import ComponentReusabilityDemo from './components/appendix/web-basics/ComponentReusabilityDemo.vue' @@ -160,6 +168,7 @@ import ProductCacheDemo from './components/appendix/cache-design/ProductCacheDem // Auth Design Components import AuthEvolutionDemo from './components/appendix/auth-design/AuthEvolutionDemo.vue' import AuthBasicsDemo from './components/appendix/auth-design/AuthBasicsDemo.vue' +import AuthInteractiveLoginDemo from './components/appendix/auth-design/AuthInteractiveLoginDemo.vue' import AuthNvsAuthZDemo from './components/appendix/auth-design/AuthNvsAuthZDemo.vue' import SessionCookieDemo from './components/appendix/auth-design/SessionCookieDemo.vue' import JWTWorkflowDemo from './components/appendix/auth-design/JWTWorkflowDemo.vue' @@ -187,6 +196,7 @@ import FewShotDemo from './components/appendix/prompt-engineering/FewShotDemo.vu import ChainOfThoughtDemo from './components/appendix/prompt-engineering/ChainOfThoughtDemo.vue' // Context Engineering Components +import AgentContextFlow from './components/appendix/context-engineering/AgentContextFlow.vue' import ContextWindowVisualizer from './components/appendix/context-engineering/ContextWindowVisualizer.vue' import SlidingWindowDemo from './components/appendix/context-engineering/SlidingWindowDemo.vue' import SelectiveContextDemo from './components/appendix/context-engineering/SelectiveContextDemo.vue' @@ -318,6 +328,7 @@ export default { app.component('GitConflictDemo', GitConflictDemo) app.component('GitStashDemo', GitStashDemo) app.component('GitRemoteDemo', GitRemoteDemo) + app.component('GitScenariosDemo', GitScenariosDemo) app.component('NetworkLayers', NetworkLayers) app.component('TcpUdpComparison', TcpUdpComparison) app.component('SubnetCalculator', SubnetCalculator) @@ -357,6 +368,19 @@ export default { app.component('AiEvolutionDemo', AiEvolutionDemo) app.component('RuleBasedVsLearningDemo', RuleBasedVsLearningDemo) app.component('PerceptronDemo', PerceptronDemo) + app.component('AIEvolutionTimelineDemo', AIEvolutionTimelineDemo) + app.component('CombinatorialExplosionDemo', CombinatorialExplosionDemo) + app.component( + 'NeuralNetworkVisualizationDemo', + NeuralNetworkVisualizationDemo + ) + app.component('BackpropagationDemo', BackpropagationDemo) + app.component('AttentionMechanismDemo', AttentionMechanismDemo) + app.component( + 'DiscriminativeVsGenerativeDemo', + DiscriminativeVsGenerativeDemo + ) + app.component('GPTEvolutionDemo', GPTEvolutionDemo) app.component('ImperativeVsDeclarativeDemo', ImperativeVsDeclarativeDemo) app.component('ComponentReusabilityDemo', ComponentReusabilityDemo) @@ -399,6 +423,7 @@ export default { // Auth Design Components Registration app.component('AuthEvolutionDemo', AuthEvolutionDemo) app.component('AuthBasicsDemo', AuthBasicsDemo) + app.component('AuthInteractiveLoginDemo', AuthInteractiveLoginDemo) app.component('AuthNvsAuthZDemo', AuthNvsAuthZDemo) app.component('SessionCookieDemo', SessionCookieDemo) app.component('JWTWorkflowDemo', JWTWorkflowDemo) @@ -426,6 +451,7 @@ export default { app.component('ChainOfThoughtDemo', ChainOfThoughtDemo) // Context Engineering Components Registration + app.component('AgentContextFlow', AgentContextFlow) app.component('ContextWindowVisualizer', ContextWindowVisualizer) app.component('SlidingWindowDemo', SlidingWindowDemo) app.component('SelectiveContextDemo', SelectiveContextDemo) diff --git a/docs/zh-cn/appendix/ai-evolution.md b/docs/zh-cn/appendix/ai-evolution.md index 665b46a..cb5ec44 100644 --- a/docs/zh-cn/appendix/ai-evolution.md +++ b/docs/zh-cn/appendix/ai-evolution.md @@ -1,24 +1,34 @@ -# 人工智能进化史:从 "逻辑" 到 "直觉" (Interactive Intro) +# 人工智能进化史:从"逻辑"到"直觉"(交互式教程) -> 💡 **学习指南**:本章节通过交互式演示,带你梳理人工智能 70 年的发展脉络。从最早的下棋程序,到今天能写诗作画的 ChatGPT。 +> 💡 **学习指南**:本章节无需编程基础,通过交互式演示带你梳理人工智能 70 年的发展脉络。从最早的下棋程序,到今天能写诗作画的 ChatGPT。我们将深入理解 AI 从"人工规则"到"机器学习"的进化历程。 ## 0. 引言:机器能思考吗? -图灵在 1950 年提出了这个问题。 -为了回答它,人类进行了长达半个多世纪的探索。 +1950 年,艾伦·图灵在论文《计算机器与智能》中提出了这个问题: +**"机器能思考吗?"** -我们走过弯路(试图穷举规则),也经历过寒冬(算力不足),最终在模仿人脑(神经网络)的道路上取得了突破。 +为了回答它,人类进行了长达半个多世纪的探索。我们走过弯路(试图穷举规则),也经历过寒冬(算力不足),最终在模仿人脑(神经网络)的道路上取得了突破。 + +AI 的进化史,就是人类探索"如何让机器拥有智能"的历史。这条探索之路经历了三个主要阶段: + +1. **符号主义**:教机器"守规矩"——人工写规则 +2. **连接主义**:教机器"像人脑一样思考"——神经网络学习 +3. **生成式人工智能**:机器有了"创造力"——大语言模型 + +本教程将带你从零开始,一步步理解这些范式的演变。 + + --- -## 1. 符号主义:教机器"守规矩" (1950s - 1980s) +## 1. 符号主义:教机器"守规矩"(20世纪50年代 - 80年代) 早期的 AI 科学家认为:智慧就是**逻辑推理**。 只要我们把世界上的所有知识都写成 `If...Then...` 的规则,机器就能像人一样聪明。 -这被称为**专家系统 (Expert Systems)**。 +这被称为**专家系统**或**符号主义人工智能**。 ### 1.1 什么是"基于规则"? @@ -27,7 +37,60 @@ - 如果看到红灯,就停下。 - 如果下雨,就带伞。 -### 1.2 交互演示:规则 vs 学习 +在代码中,这表现为: + +```javascript +// 基于规则的 AI 示例 +function decideTrafficLight(color) { + if (color === 'red') { + return 'stop' + } else if (color === 'yellow') { + return 'caution' + } else if (color === 'green') { + return 'go' + } +} +``` + +### 1.2 专家系统的巅峰:MYCIN + +1970 年代,斯坦福大学开发的 MYCIN 系统能诊断血液感染,准确率达到专家水平。 + +它的工作原理是: + +```lisp +;; MYCIN 系统的规则示例 (伪代码) +(IF + (organism IS gram-positive) + (morphology IS coccus) + (growth-chains IS chains) +THEN + (identity IS 0.7 streptococcus)) +``` + +_数据示例 (知识库格式)_: +```json +// 专家系统知识库示例 +{ + "rules": [ + { + "id": "RULE-001", + "conditions": ["traffic_light == red", "speed > 0"], + "action": "brake", + "priority": 1 + }, + { + "id": "RULE-002", + "conditions": ["weather == rainy", "visibility < 100m"], + "action": "turn_on_lights", + "priority": 2 + } + ] + // 系统按优先级依次匹配规则,遇到匹配就执行 +} +``` + +### 1.3 交互演示:规则 vs 学习 下方的演示展示了两种方式的区别。 @@ -36,55 +99,230 @@ -**局限性**:你能写出"识别猫"的规则吗? -"有胡须"?老鼠也有。"有尖耳朵"?狗也有。 -现实世界太复杂,规则写不完。这就是符号主义 AI 衰落的原因。 +### 1.4 符号主义的局限性 + +规则看起来很完美,但现实世界太复杂了。 + + + +**问题 1:组合爆炸** +- 试图写下"识别猫"的所有规则?不可能! +- "有胡须"?老鼠也有。 +- "有尖耳朵"?狗也有。 +- "毛茸茸的"?兔子也是。 +- 现实世界有无限边界情况,规则永远写不完。 + +**问题 2:无法处理不确定性** +- 如果规则冲突怎么办? +- 如果遇到没见过的情况怎么办? +- 规则系统很"脆弱",缺少人类常识。 + +> ⚠️ **教训**:试图用有限规则描述无限现实,注定失败。这导致了 1980 年代的**AI 寒冬**。 --- -## 2. 连接主义:教机器"像人脑一样思考" (2010s+) +## 2. 连接主义:教机器"像人脑一样思考"(21世纪10年代至今) -既然规则写不完,不如让机器自己学? +既然规则写不完,不如换个思路:**让机器自己学**? 科学家开始模仿人脑的结构——**神经元**。 -### 2.1 感知机 (Perceptron) +这就是**连接主义**的核心思想。 -这是最简单的神经元模型。它接收多个输入,根据**权重 (Weight)** 加权求和,如果超过某个**阈值 (Bias)**,就激活。 +### 2.1 人脑的启示 + +人脑有约 860 亿个神经元,每个神经元通过突触连接成千上万个其他神经元。 + +**关键发现**: +- 单个神经元很"笨"(只是兴奋或不兴奋) +- 但几百亿个神经元连在一起,就产生了智能 + +### 2.2 感知机 + +1957 年,康奈尔大学的 Frank Rosenblatt 发明了感知机——这是最简单的人工神经元。 + +它的工作原理: + +1. **接收输入**:从多个"突触"接收信号($x_1, x_2, ...$) +2. **加权求和**:每个输入有对应的**权重**,代表重要性 +3. **激活判断**:如果总和超过某个**阈值(偏置)**,就激活(输出 1) $$ Output = \begin{cases} 1 & \text{if } \sum (w_i \cdot x_i) + b > 0 \\ 0 & \text{otherwise} \end{cases} $$ -听起来很复杂?动手试一下! +### 2.3 交互演示:玩转神经元 -### 2.2 交互演示:玩转神经元 +调整下方的**权重**和**偏置**,看看能否控制神经元的输出。 -调整下方的 **Weights (权重)** 和 **Bias (偏置)**,看看能否控制神经元的输出。 - -- **Weights ($w$)**:代表输入的"重要性"。$w$ 越大,这个输入对结果影响越大。 -- **Bias ($b$)**:代表神经元的"门槛"。$b$ 越小,神经元越容易兴奋(输出 1)。 +- **权重($w$)**:代表输入的"重要性"。$w$ 越大,这个输入对结果影响越大。 +- **偏置($b$)**:代表神经元的"门槛"。$b$ 越小,神经元越容易兴奋(输出 1)。 -当几十亿个这样的神经元连接在一起,奇迹就发生了——这就是**深度学习 (Deep Learning)**。 +### 2.4 从单神经元到深度学习 + +单个神经元能做什么?只能做简单分类(比如判断"苹果还是樱桃")。 + +但如果把神经元分层连接: + +``` +输入层 (图片像素) + ↓ +隐藏层 1 (识别边缘) + ↓ +隐藏层 2 (识别形状) + ↓ +隐藏层 3 (识别物体部件) + ↓ +输出层 (识别物体) +``` + +这就是**神经网络**。当网络有很多层时,我们称之为**深度学习**。 + + + +### 2.5 神经网络是如何学习的? + +不像专家系统需要人写规则,神经网络通过**看数据**自己学。 + +**学习过程(反向传播)**: +1. **前向传播**:输入数据,得到预测结果 +2. **计算误差**:对比预测和真实答案 +3. **反向传播**:根据误差调整每个神经元的权重 +4. **重复**:重复几百万次,直到误差足够小 + + + +_数据示例 (训练数据格式)_: +```json +// 图像分类训练数据示例 +{ + "dataset": "cats_vs_dogs", + "samples": [ + { + "image": "cat_001.jpg", + "label": 1, // 1 = 猫 + "features": [0.2, 0.8, 0.5, ...] // 提取的特征向量 + }, + { + "image": "dog_001.jpg", + "label": 0, // 0 = 狗 + "features": [0.7, 0.3, 0.9, ...] + } + ] + // 神经网络会自动学习:什么样的 feature 组合更可能是猫 +} +``` + +### 2.6 连接主义的突破:2012 年 AlexNet + +2012 年,AlexNet 在 ImageNet 竞赛中以压倒性优势夺冠,标志着深度学习时代的到来。 + +**关键因素**: +- **大数据**:ImageNet 提供了 1400 万张标注图片 +- **大算力**:GPU 的并行计算能力让训练深度网络成为可能 +- **新算法**:ReLU 激活函数、Dropout 正则化等技术突破 + +### 2.7 连接主义的局限 + +深度学习很强大,但也不是完美的: + +- **黑盒问题**:虽然能识别猫,但我们说不清"它是怎么识别的" +- **数据饥渴**:需要海量标注数据,获取成本高 +- **缺乏常识**:能认猫,但不知道"猫会怕狗" --- -## 3. 生成式 AI:机器有了"创造力" (2020s+) +## 3. 生成式人工智能:机器有了"创造力"(21世纪20年代至今) 以前的 AI 主要是**判别式**(这是猫还是狗?)。 现在的 AI 是**生成式**(画一只猫!)。 这一切的背后,是 **Transformer** 架构的诞生。它让 AI 学会了理解上下文,学会了"举一反三"。 -> 关于大语言模型 (LLM) 的详细原理,请移步下一章:[大语言模型入门](./llm-intro.md) +### 3.1 从"识别"到"创造" + +传统深度学习(判别式模型): +- 输入:一张图 +- 输出:这是猫(概率 98%) + +生成式 AI: +- 输入:一句话"一只戴着墨镜的猫" +- 输出:生成一张对应的图片 + + + +### 3.2 Transformer:AI 的"瑞士军刀" + +2017 年,Google 发表论文《Attention Is All You Need》(注意力机制就是你所需的全部),提出 Transformer 架构。 + +它的核心创新:**注意力机制** + +**原理**:让模型在处理一个词时,能"关注"到句子中其他相关的词。 + +例如:"小明把苹果给了**他**的母亲" + +当模型处理"他"时,注意力机制会让它关注到"小明",从而理解"他"指代的是小明。 + + + +### 3.3 GPT:从文本生成到通用智能 + +2018 年,OpenAI 发布 GPT-1(生成式预训练变换器)。 + +**核心思想**: +1. **预训练**:在海量文本上学习"预测下一个词" +2. **微调**:在特定任务上调整(比如问答、翻译) + +从 GPT-1 (2018) → GPT-2 (2019) → GPT-3 (2020) → GPT-4 (2023) +- 参数量从 1.17 亿 → 1750 亿 → 1.8 万亿(估计) +- 能力从文本生成 → 多模态(图片、音频、视频) + + + +### 3.4 生成式人工智能的局限 + +虽然强大,但也存在问题: + +- **幻觉**:一本正经地胡说八道 +- **偏见放大**:从训练数据中学到人类偏见 +- **不可解释**:仍然是个黑盒,不知道内部怎么运作 --- -## 4. 总结 +## 4. AI 范式对比总结 -| 时代 | 核心理念 | 代表产物 | 局限 | -| :------------ | :-------------- | :------------------------ | :--------------------------- | -| **符号主义** | 智慧 = 规则 | 深蓝 (下棋), 医疗诊断系统 | 无法处理模糊、复杂的现实世界 | -| **连接主义** | 智慧 = 神经网络 | AlphaGo, 人脸识别 | 需要海量数据,是个"黑盒" | -| **生成式 AI** | 智慧 = 通用理解 | ChatGPT, Midjourney | 幻觉 (一本正经胡说八道) | +| 时代 | 核心理念 | 代表产物 | 优势 | 局限 | +| :------------------ | :-------------- | :------------------------ | :------------------------ | :--------------------------- | +| **符号主义** | 智慧 = 规则 | 深蓝(下棋)、MYCIN(诊断) | 可解释性强,逻辑清晰 | 无法处理模糊、复杂的现实世界 | +| **连接主义** | 智慧 = 神经网络 | AlphaGo、人脸识别 | 能处理复杂模式,性能强大 | 需要海量数据,是个"黑盒" | +| **生成式人工智能** | 智慧 = 通用理解 | ChatGPT、Midjourney | 能创造新内容,理解上下文 | 幻觉、偏见、不可解释 | -AI 的进化,就是从"人工设定规则"到"机器自动学习数据"的过程。 +**AI 的进化趋势**: + +1. **从人工到自动**:从人写规则 → 机器自动学习 +2. **从单一到通用**:从下棋专用 → 通用人工智能 +3. **从判别到生成**:从分类识别 → 创造新内容 + +> 关于大语言模型的详细原理,请移步下一章:[大语言模型入门](./llm-intro.md) + +--- + +## 5. 名词速查表 + +| 名词 | 英文原文 | 解释 | +| :----------------- | :------------------------- | :----------------------------------------------------------------------------------------- | +| **符号主义** | Symbolic AI | 基于规则的人工智能。认为智能可以用逻辑规则表示。代表:专家系统、深蓝。 | +| **专家系统** | Expert Systems | 符号主义的代表产物。通过人工编写大量规则来模拟专家决策。代表:MYCIN(医疗诊断)。 | +| **连接主义** | Connectionism | 基于神经网络的人工智能。模仿人脑神经元连接结构,通过数据自动学习。 | +| **感知机** | Perceptron | 最简单的神经网络单元。接收多个输入,加权求和后通过激活函数输出。 | +| **神经网络** | Neural Network | 由多个感知机分层连接组成的模型。通过调整权重来学习数据中的模式。 | +| **深度学习** | Deep Learning | 使用**多层**神经网络的学习方法。能自动提取层次化特征(边缘 → 形状 → 物体)。 | +| **反向传播** | Backpropagation | 神经网络的学习算法。通过计算预测误差,反向调整每层的权重,逐步优化模型。 | +| **生成式人工智能** | Generative AI | 能**创造新内容**的人工智能(文本、图片、音频等),而非仅仅是分类或识别。代表:ChatGPT、Midjourney。 | +| **判别式人工智能** | Discriminative AI | 用于**分类**的人工智能(如:这是猫还是狗?)。传统深度学习大多是判别式的。 | +| **Transformer** | Transformer | 2017 年由 Google 提出的架构,基于注意力机制。是现代大语言模型(GPT、BERT)的基础。 | +| **注意力机制** | Attention Mechanism | 让模型在处理一个元素时,能动态"关注"其他相关元素的技术。是 Transformer 的核心。 | +| **GPT** | Generative Pre-trained Transformer | OpenAI 的系列模型。通过"预训练 + 微调"范式,在大量文本上学习生成能力。 | +| **预训练** | Pre-training | 在大规模无标注数据上进行初步训练,学习通用知识(如语言规律)。 | +| **微调** | Fine-tuning | 在预训练模型基础上,使用特定任务的小规模数据进行调整,使模型适应具体应用。 | +| **幻觉** | Hallucination | 生成式人工智能模型"自信地编造错误内容"的现象。如 ChatGPT 编造不存在的论文或事实。 | +| **通用人工智能** | Artificial General Intelligence | 像人类一样具备多领域智能、能自主学习推理的人工智能(尚未实现)。 | diff --git a/docs/zh-cn/appendix/api-intro.md b/docs/zh-cn/appendix/api-intro.md new file mode 100644 index 0000000..7d35849 --- /dev/null +++ b/docs/zh-cn/appendix/api-intro.md @@ -0,0 +1,314 @@ +# API 入门:软件世界的"服务员" + +> 💡 **学习指南**:本章节无需编程基础,通过交互式演示带你深入了解 API(应用程序接口)。我们将从最基础的"什么是 API"讲起,到如何阅读 API 文档,再到实际调用 API。 + + + +## 0. 引言:无处不在的"桥梁" + +你用微信登录第三方 APP 时,是谁在幕后传递信息? +你在淘宝查询物流时,是谁帮你连接快递公司的数据? +你用 AI 写代码时,是谁把你的需求传给大模型? + +这背后都有一个功臣:**API (Application Programming Interface)**。 + +如果软件是"餐厅",那 API 就是"服务员"。 +你需要什么(数据、功能),告诉服务员(调用 API),服务员会去厨房(服务器)取来,端到你面前(返回结果)。 + +### 0.1 为什么需要 API? + +想象一下,如果没有服务员(API): + +- ❌ 每个顾客都要自己冲进厨房找菜 +- ❌ 厨房会被搞乱,效率极低 +- ❌ 顾客需要知道厨房怎么运作 + +有了服务员(API): + +- ✅ 顾客只需看菜单(API 文档)点餐 +- ✅ 服务员传递订单,厨房专注做菜 +- ✅ 顾客不需要知道厨房怎么运作 + +**关键点**:API 让不同软件之间能够"对话",而不需要了解对方的内部实现。 + +--- + +## 1. 第一步:理解 API 的本质 + +### 1.1 什么是 API? + +**API (Application Programming Interface)** = 应用程序编程接口。 + +翻译成人话:**软件之间的"约定"和"服务员"**。 + +- **Application(应用)**:两个不同的软件系统(如你的 APP 和微信服务器) +- **Programming(编程)**:通过代码来交互 +- **Interface(接口)**:双方约定的"沟通方式" + + + +**关键点**:API 定义了: +- 你可以请求什么(有哪些功能) +- 怎么请求(格式、参数) +- 会返回什么(数据结构) + +### 1.2 API 的类型 + +API 有很多种形式,最常见的有: + +| 类型 | 例子 | 说明 | +| :--- | :--- | :--- | +| **Web API** | REST API、GraphQL | 通过 HTTP 协议调用,最常见 | +| **库 API** | React、Vue | 代码库提供的函数接口 | +| **系统 API** | 文件系统 API | 操作系统提供的功能接口 | + +本教程重点讲解 **Web API**,因为它最常用,也最容易理解。 + +--- + +## 2. API 是怎么工作的? + +### 2.1 请求-响应模型 + +API 的工作原理就像"点餐-上菜": + +1. **发起请求**:你告诉服务员要什么(调用 API) +2. **处理请求**:服务员去厨房传达(服务器处理) +3. **返回结果**:服务员把菜端上来(返回数据) + + + +### 2.2 HTTP 方法:四种基本操作 + +在 Web API 中,我们使用 HTTP 方法来表达不同的操作: + +| 方法 | 作用 | 类比 | +| :--- | :--- | :--- | +| **GET** | 获取数据 | "给我看看菜单" | +| **POST** | 创建数据 | "我要点这道菜" | +| **PUT** | 更新数据 | "把这道菜换成辣的" | +| **DELETE** | 删除数据 | "取消这道菜" | + + + +**关键点**:REST API 遵循"统一接口"原则,用这四种方法就能完成所有操作。 + +--- + +## 3. 认识 API 文档 + +### 3.1 什么是 API 文档? + +API 文档就像**餐厅的菜单**,它告诉你: + +- 📋 **有哪些菜可以点**(API 提供哪些功能) +- 💰 **每个菜的名字和价格**(接口地址、参数) +- 📝 **菜的详细说明**(返回数据格式) +- ⚠️ **注意事项**(限制条件、错误码) + + + +### 3.2 API 文档的组成 + +一个完整的 API 文档通常包含: + +#### 1️⃣ 基本信息 +``` +接口地址:https://api.example.com/users +请求方法:GET +功能说明:获取用户列表 +``` + +#### 2️⃣ 请求参数 +``` +参数名 类型 必填 说明 +page number 否 页码,默认 1 +limit number 否 每页数量,默认 20 +``` + +#### 3️⃣ 返回示例 +```json +{ + "code": 200, + "message": "success", + "data": [ + { + "id": 1, + "name": "张三", + "email": "zhangsan@example.com" + } + ] +} +``` + +#### 4️⃣ 错误码说明 +``` +400 - 参数错误 +401 - 未授权 +404 - 资源不存在 +500 - 服务器错误 +``` + +--- + +## 4. 实战:如何使用 API? + +### 4.1 阅读文档的步骤 + +拿到一个新的 API,按以下步骤操作: + +**第 1 步:找到文档入口** +- 通常在官网的 "Developers" 或 "API" 板块 +- 常见的文档平台:Swagger、Apiary、Readme.io + +**第 2 步:理解接口功能** +- 看接口名称和说明,判断是否是你需要的功能 +- 注意请求方法(GET/POST/PUT/DELETE) + +**第 3 步:查看请求参数** +- 必填参数:一定要提供 +- 可选参数:根据需要提供 +- 参数类型:字符串、数字、布尔值 + +**第 4 步:看返回示例** +- 了解成功时的返回格式 +- 查看错误时的返回格式 + +**第 5 步:尝试调用** +- 可以用在线工具(如 Postman、curl) +- 或者在代码中调用 + + + +### 4.2 真实案例:调用天气 API + +让我们调用一个真实的天气 API 来查询北京的天气。 + + + +**代码示例**: + +```javascript +// 使用 JavaScript 调用 API +fetch('https://api.weatherapi.com/v1/current.json?key=YOUR_KEY&q=Beijing') + .then(response => response.json()) + .then(data => { + console.log('北京天气:', data.current.temp_c, '°C'); + console.log('天气状况:', data.current.condition.text); + }) + .catch(error => { + console.error('出错了:', error); + }); +``` + +```python +# 使用 Python 调用 API +import requests + +response = requests.get('https://api.weatherapi.com/v1/current.json', params={ + 'key': 'YOUR_KEY', + 'q': 'Beijing' +}) + +data = response.json() +print(f"北京天气:{data['current']['temp_c']}°C") +print(f"天气状况:{data['current']['condition']['text']}") +``` + +--- + +## 5. 常见问题与最佳实践 + +### 5.1 为什么我的 API 调用失败了? + +常见错误: + +| 错误码 | 原因 | 解决方案 | +| :--- | :--- | :--- | +| **400** | 参数错误 | 检查参数名、类型、格式 | +| **401** | 未授权 | 检查 API Key 是否正确 | +| **404** | 接口不存在 | 确认 URL 是否正确 | +| **429** | 请求过于频繁 | 降低请求频率或联系提供方 | +| **500** | 服务器错误 | 稍后重试或联系技术支持 | + +### 5.2 最佳实践 + +✅ **使用 API 时要注意**: + +1. **阅读文档**:不要猜测,仔细看文档 +2. **处理错误**:不要假设调用总是成功 +3. **控制频率**:避免被限流(Rate Limit) +4. **保护密钥**:不要把 API Key 写在公开代码里 +5. **缓存数据**:相同数据不要重复请求 + +❌ **常见错误**: + +- 不看文档就盲目调用 +- 不处理错误响应 +- 密钥泄露到 GitHub +- 无限重试导致被封禁 + +--- + +## 6. 总结与进阶 + +恭喜你!现在你已经掌握了 API 的基础知识。 + +### 6.1 核心知识点回顾 + +- ✅ API 是软件之间的"服务员"和"桥梁" +- ✅ API 工作原理:请求 → 处理 → 响应 +- ✅ HTTP 方法:GET(查)、POST(增)、PUT(改)、DELETE(删) +- ✅ API 文档包含:接口地址、参数、返回格式、错误码 +- ✅ 调用 API 的五步法:找文档 → 理解功能 → 查参数 → 看示例 → 尝试调用 + +### 6.2 学习路线 + +1. **入门**(今天) + - 理解 API 的概念 + - 会阅读简单的 API 文档 + - 能用工具(Postman)调用 API + +2. **进阶**(1 周) + - 在代码中调用 API + - 处理认证(API Key、OAuth) + - 处理分页、过滤等高级功能 + +3. **深入**(持续) + - 学习 GraphQL(REST 的替代方案) + - 设计自己的 API + - API 性能优化和安全 + +### 6.3 推荐资源 + +- **练习平台**: + - [JSONPlaceholder](https://jsonplaceholder.typicode.com/) - 假数据 API,用于练习 + - [Public APIs](https://publicapis.dev/) - 收录了大量免费 API + +- **文档工具**: + - [Postman](https://www.postman.com/) - API 调试工具 + - [Swagger Editor](https://editor.swagger.io/) - API 文档编辑器 + +- **学习资料**: + - [REST API Tutorial](https://restfulapi.net/) + - [MDN Web API 文档](https://developer.mozilla.org/zh-CN/docs/Web/API) + +--- + +## 7. 名词速查表 + +| 名词 | 英文 | 解释 | +| :--- | :--- | :--- | +| **API** | Application Programming Interface | 应用程序编程接口,软件之间的"服务员" | +| **HTTP** | HyperText Transfer Protocol | 超文本传输协议,Web API 的基础 | +| **REST** | Representational State Transfer | 一种 API 设计风格,最常见 | +| **GET** | - | HTTP 方法,用于获取数据 | +| **POST** | - | HTTP 方法,用于创建数据 | +| **PUT** | - | HTTP 方法,用于更新数据 | +| **DELETE** | - | HTTP 方法,用于删除数据 | +| **Endpoint** | - | 接口地址,如 /users | +| **Request** | - | 请求,客户端发给服务器 | +| **Response** | - | 响应,服务器返回给客户端 | +| **JSON** | JavaScript Object Notation | 一种数据格式,API 常用 | +| **Authentication** | - | 认证,验证你是谁 | +| **Rate Limit** | - | 限流,控制请求频率 | diff --git a/docs/zh-cn/appendix/auth-design.md b/docs/zh-cn/appendix/auth-design.md index 1960ae4..8b5341b 100644 --- a/docs/zh-cn/appendix/auth-design.md +++ b/docs/zh-cn/appendix/auth-design.md @@ -27,6 +27,12 @@ +### 0.2 交互式演示:登录流程 + +让我们通过一个真实的登录演示,来理解认证和授权是如何工作的。 + + + **关键点**:鉴权是第一道防线,所有敏感操作都必须先验证身份。 --- diff --git a/docs/zh-cn/appendix/cache-design.md b/docs/zh-cn/appendix/cache-design.md index 1e8d2ec..3f56bb4 100644 --- a/docs/zh-cn/appendix/cache-design.md +++ b/docs/zh-cn/appendix/cache-design.md @@ -6,26 +6,181 @@ ## 0. 引言:看不见的"加速器" -你刷朋友圈时,为什么几秒钟就能加载出几百张图片? -你查询订单时,为什么瞬间就能看到几个月前的数据? +你有没有想过这些问题: + +- 刷朋友圈时,为什么几秒钟就能加载出几百张图片? +- 查询订单时,为什么瞬间就能看到几个月前的数据? +- 刷新短视频时,为什么视频几乎瞬间就能播放? 这背后都有一个功臣:**缓存 (Cache)**。 -如果数据库是"仓库",那缓存就是"柜台"。 -常用的商品(热数据)放在柜台上,随拿随用;不常用的商品才需要去仓库里找。 +### 0.1 什么是缓存?用生活化的例子理解 -### 0.1 为什么要缓存? +想象一下你在家里的场景: + +**场景 1:没有缓存的日子** + +每次想喝水,你都要: +1. 走到厨房(相当于访问数据库) +2. 打开柜子 +3. 拿出水壶 +4. 倒水 +5. 回到客厅 + +即使你一小时内要喝 10 次水,每次都要重复这个过程。很累对吧? + +**场景 2:有了缓存** + +你在客厅的茶几上放了一个水杯(这就是缓存!): +- 第一次喝水:你还是要去厨房倒水,但把水杯留在茶几上 +- 之后每次喝水:直接拿起茶几上的水杯喝就行 + +**这就是缓存的核心思想**:把常用的东西放在触手可及的地方,避免每次都"跑远路"。 + +回到计算机世界: + +| 生活中的例子 | 计算机中的对应 | +| :--- | :--- | +| **茶几上的水杯** | **内存缓存**(速度快,但容量小) | +| **厨房的水壶** | **数据库**(速度慢,但容量大) | +| **"我刚才用过这个水杯"** | **时间局部性**(刚用过的数据,很可能还会用) | +| **"把这些常用的都放在茶几上"** | **空间局部性**(用过的数据附近的数据,也可能用到) | + +### 0.2 为什么要缓存? 只有一个理由:**快**。 -| 存储介质 | 访问延迟 | 吞吐量 | 典型用途 | -| :--------------- | :------- | :----- | :------------- | -| **L1 CPU 缓存** | ~1 ns | 极高 | 寄存器、变量 | -| **内存 (Redis)** | ~100 ns | 高 | 热点数据、会话 | -| **SSD 数据库** | ~1 ms | 中 | 持久化存储 | -| **HDD 数据库** | ~10 ms | 低 | 归档存储 | +但有多快呢?我们用个形象的比喻: -**关键点**:缓存的本质是**用空间换时间**,通过在更快的存储介质中保留数据副本,减少访问慢速存储的次数。 +| 存储介质 | 访问时间 | 生活类比 | 能做什么 | +| :--- | :--- | :--- | :--- | +| **L1 CPU 缓存** | ~1 纳秒 | 眨一下眼睛(1/10秒)的 **十亿分之一** | CPU 执行一条指令 | +| **内存 (Redis)** | ~100 纳秒 | 眨一下眼睛的 **千万分之一** | 存储热点数据 | +| **SSD 数据库** | ~1 毫秒 | 眨一下眼睛 | 读写文件 | +| **HDD 数据库** | ~10 毫秒 | 眨 10 下眼睛 | 传统硬盘操作 | + +**换个角度理解**: +- 从内存读数据 = 从茶几拿水杯 +- 从 SSD 读数据 = 从厨房拿水壶 +- 从 HDD 读数据 = 从楼下便利店买水 + +**关键点**:缓存的本质是**用空间换时间**——多准备几份"副本"放在快速的地方,节省每次都去"慢速地方"取数据的时间。 + +### 0.3 缓存的真实案例 + +**案例 1:淘宝商品详情页** + +当你打开一个商品页面时: +- **商品基本信息**(价格、标题):从 Redis 缓存读取(~5 毫秒) +- **商品大图**:从 CDN 缓存读取(~20 毫秒) +- **用户浏览历史**:从本地缓存读取(~1 毫秒) + +如果这些都不用缓存,全部查数据库: +- 查询时间可能从 **5 毫秒** 变成 **200 毫秒** +- 数据库要同时处理几百万人的请求,直接"累垮" + +**案例 2:微信朋友圈** + +你刷朋友圈时: +- **图片**:之前看过的图片,都在手机本地缓存里 +- **好友列表**:第一次加载后缓存在内存里 +- **点赞数据**:热点数据在 Redis 缓存中 + +没有缓存的话:每次刷新都要重新下载所有内容,流量和速度都受不了。 + +--- + +## 🗺️ 全局观:缓存知识地图 + +在深入细节之前,让我们先看看缓存设计的"全貌"。就像旅游前先看地图一样,这样你不会迷路。 + +### 核心目标(一句话概括) + +**让数据访问更快、系统更强,同时保证数据不出错。** + +### 知识体系地图 + +``` +缓存设计 +│ +├─ 📦 基础概念(为什么需要缓存?) +│ ├─ 局部性原理(时间局部性、空间局部性) +│ ├─ 缓存生命周期(写入 → 命中 → 过期 → 淘汰) +│ └─ 性能对比(内存 vs 数据库:快 100 倍) +│ +├─ 🏗️ 架构选型(用什么缓存?) +│ ├─ 本地缓存(单机快,但容量小) +│ ├─ 分布式缓存(容量大,但稍慢) +│ └─ 多级缓存(组合使用,最佳方案) +│ ├─ 浏览器缓存(用户本地) +│ ├─ CDN 缓存(离用户近) +│ ├─ 应用本地缓存(极速) +│ ├─ Redis 缓存(高容量) +│ └─ 数据库(兜底) +│ +├─ 🎯 设计模式(怎么用缓存?) +│ ├─ Cache-Aside(最常用,手动控制) +│ ├─ Read-Through(缓存自己加载) +│ ├─ Write-Through(同步写缓存和数据库) +│ └─ Write-Behind(异步写,最快但可能丢数据) +│ +├─ ⚠️ 常见问题(缓存会出什么错?) +│ ├─ 缓存穿透(查不存在数据,数据库压力大) +│ ├─ 缓存击穿(热点数据过期,瞬间高并发) +│ └─ 缓存雪崩(大量数据同时过期) +│ +├─ 🔒 一致性保证(缓存和数据库不一致怎么办?) +│ ├─ 更新策略(先更数据库,再删缓存) +│ ├─ 延迟双删(极致一致性) +│ └─ Binlog 订阅(异步解耦) +│ +└─ 🛠️ 实战技巧(工程中怎么做?) + ├─ 布隆过滤器(快速判断数据是否存在) + ├─ 分布式锁(防止缓存击穿) + ├─ 随机 TTL(防止雪崩) + ├─ 缓存预热(启动时加载热点数据) + └─ 监控调优(命中率要 > 90%) +``` + +### 学习路径建议(0基础小白版) + +**第一步:理解核心概念**(1-2 天) +- 理解"为什么需要缓存"(茶几 vs 厨房的例子) +- 记住性能数据:内存比数据库快 100 倍 +- 了解缓存的生命周期(写入 → 命中 → 过期 → 淘汰) + +**第二步:掌握最常用的模式**(2-3 天) +- 重点学习 **Cache-Aside 模式**(90% 的场景都用这个) +- 动手写代码:用 Redis 做简单的键值缓存 +- 理解"为什么删缓存而不是更新缓存" + +**第三步:学习多级缓存**(3-5 天) +- 理解为什么需要"多层防御"(浏览器 → CDN → 本地 → Redis → 数据库) +- 掌握每一层的用途和特点 +- 动手实践:给自己的项目加一层缓存 + +**第四步:解决常见问题**(1 周) +- 理解缓存三大问题(穿透、击穿、雪崩) +- 学习解决方案(布隆过滤器、分布式锁、随机 TTL) +- 实战演练:模拟高并发场景,看缓存如何保护数据库 + +**第五步:深入一致性**(1-2 周) +- 理解缓存和数据库可能不一致的场景 +- 掌握"先更数据库,再删缓存"的最佳实践 +- 进阶:学习 Binlog 订阅方案 + +**第六步:实战项目**(2-4 周) +- 设计一个完整的缓存系统(如商品详情页缓存) +- 搭建监控系统,实时查看缓存命中率 +- 压测验证:看看性能提升了多少倍 + +### 关键指标(学完后你要能回答) + +- 缓存的**命中率**是多少?(优秀:> 90%) +- 缓存能**提升多少性能**?(10-100 倍) +- 如何解决缓存**三大问题**?(穿透、击穿、雪崩) +- 缓存和数据库**不一致**怎么办?(先更库,再删缓存) +- **多级缓存**的顺序是什么?(浏览器 → CDN → 本地 → Redis → 数据库) --- diff --git a/docs/zh-cn/appendix/canvas-intro.md b/docs/zh-cn/appendix/canvas-intro.md index 46b2937..fa8ca82 100644 --- a/docs/zh-cn/appendix/canvas-intro.md +++ b/docs/zh-cn/appendix/canvas-intro.md @@ -1,4 +1,4 @@ -# Canvas 2D 入门:从像素到动画 (Interactive Guide to Canvas) +# Canvas 2D 入门:从像素到动画(交互式教程) > **学习指南**:本章节无需深厚的前端基础,通过交互式演示带你掌握 Canvas 2D 的核心原理和实践技巧。我们将从最基础的绘制开始,一直到构建复杂的交互式图形应用。 diff --git a/docs/zh-cn/appendix/context-engineering.md b/docs/zh-cn/appendix/context-engineering.md index 02f7940..82aabb3 100644 --- a/docs/zh-cn/appendix/context-engineering.md +++ b/docs/zh-cn/appendix/context-engineering.md @@ -2,6 +2,13 @@ > 💡 **学习指南**:如果说 Prompt Engineering 是教 AI "怎么说话",那么 Context Engineering 就是教 AI "怎么记事"。本章节将通过一系列交互式实验,带你深入理解 AI 的记忆机制,从基础的滑动窗口到高级的 RAG 系统,掌握让 AI "过目不忘"的核心技术。 +在开始之前,建议你先了解两个概念: + +- **Token 是什么**:可以先阅读 [大语言模型入门](./llm-intro.md) 的「分词 & Token」部分。 +- **Prompt 是什么**:如果你还不熟悉 System / User / Assistant 的基本结构,可以先看 [提示词工程](./prompt-engineering.md)。 + + + ## 0. 引言:金鱼与大象 想象一下,你正在和两个人聊天: @@ -11,6 +18,13 @@ **上下文工程 (Context Engineering)** 的目标,就是通过技术手段,让 AI 从 "金鱼" 进化成 "大象"。 +更具体地说:你每次调用模型时,都会把一份「输入包」发给它,这份输入包通常由这些部分拼起来: + +- **系统设定**(System Prompt):角色、规则、边界。 +- **对话历史**(Messages):你们之前聊过什么。 +- **工具结果**(Tool / Observation):Agent 调用外部工具拿到的新信息。 +- **检索片段**(RAG Context):从知识库临时取回的相关内容。 + 但这里有一个核心挑战:**AI 的"脑容量"(上下文窗口)是有限的**。我们不能把全世界的信息都塞进去。 我们需要解决五个核心问题: @@ -31,7 +45,8 @@ ### 1.2 实验:Token 与容量 -在 AI 的世界里,计量的单位不是"字",而是 **Token**。一个 Token 大约相当于 0.75 个英文单词,或者 0.5-1 个汉字。 +在 AI 的世界里,计量的单位不是"字",而是 **Token**。(Token 的更完整解释可以回看 [大语言模型入门](./llm-intro.md)。) +粗略地说,一个 Token 大约相当于 0.75 个英文单词,或 0.5-1 个汉字(会因内容而变化)。 试着在下面的模拟器中输入文字,看看它是如何填满上下文窗口的: @@ -39,9 +54,14 @@ **关键点**: -- **溢出即丢失**:一旦超过红色警戒线,模型不仅会报错,或者会直接截断后面的内容。 +- **溢出即丢失**:一旦超过红色警戒线,模型可能会报错,或者直接截断后面的内容。 - **昂贵的记忆**:上下文越长,推理速度越慢,费用也越高。 +### 1.3 额外收益:前缀稳定与缓存命中 + +在 Agent 场景里,上下文通常是「系统设定 + 工具定义 + 历史消息 + 本轮新信息」的拼接。 +如果你能让这份输入包的**前半段尽量稳定**(比如系统提示、工具列表不要频繁变动),很多模型/服务会更容易复用缓存,从而降低延迟与成本。 + --- ## 2. 第二步:即时记忆 (Sliding Window) diff --git a/docs/zh-cn/appendix/git-intro.md b/docs/zh-cn/appendix/git-intro.md index 994aafb..fa9fe63 100644 --- a/docs/zh-cn/appendix/git-intro.md +++ b/docs/zh-cn/appendix/git-intro.md @@ -2,6 +2,14 @@ > 💡 **一句话解释**:Git 就是代码世界的**游戏存档管理器**。它能让你随时“读档”重来,也能让你和队友在各自的“平行宇宙”里互不干扰地开发。 +> ✅ **安全说明**:本页所有交互组件都是“模拟器”,不会对你电脑上的真实 Git 仓库执行任何操作;但真实项目里建议严格按步骤来,不要依赖“自动下一步”。 + +## 0. 最常用的 5 个场景(直接照抄) + +如果你只想“立刻能用”,先把这块过一遍:每个场景都是现实工作中最常见的 Git 流程。 + + + ## 1. 为什么我们需要它? 你是否经历过这种绝望? diff --git a/docs/zh-cn/appendix/llm-intro.md b/docs/zh-cn/appendix/llm-intro.md index 5c6e129..87296a4 100644 --- a/docs/zh-cn/appendix/llm-intro.md +++ b/docs/zh-cn/appendix/llm-intro.md @@ -107,24 +107,95 @@ --- +## 3.5 插播:到底什么是“模型”? + +在讲具体的架构之前,我们先通俗地理解一下“模型”这个词。 + +在 AI 领域,**模型(Model)** 其实就是一个超级复杂的**函数**或者**黑盒子**。 + +- **输入**:一堆数字(比如上面的 Token ID)。 +- **处理**:黑盒子里有亿万个参数(可以理解为亿万个调节旋钮),它们会对输入数据进行疯狂的加减乘除运算。 +- **输出**:另一堆数字(代表预测结果,比如下一个词的概率)。 + +**打个比方:** + +你可以把模型想象成一位**经验丰富的老厨师**: +1. **输入(食材)**:你给他牛肉、土豆、番茄。 +2. **模型(厨师的脑子)**:他根据自己学过的成千上万道菜谱(训练数据),在脑子里快速计算:牛肉切块、土豆去皮、火候控制... +3. **输出(菜肴)**:最后端出一盘土豆炖牛腩。 + +所谓的**训练(Training)**,就是让这位厨师从学徒做起,让他试错亿万次。做咸了就调一下“盐旋钮”,做淡了就调一下“火候旋钮”,直到他能稳定做出美味的菜肴。 + +现在的 LLM,就是一位“读过全人类书本”的超级厨师,只不过他炒的不是菜,而是文字。 + ## 4. 进化之路:从 RNN 到 Transformer -现在我们有了**高效的数据表达**(矩阵),接下来需要一个**高效的机器**(模型)来处理它。 +有了数据(Token),有了厨师(模型),接下来要看这位厨师是怎么思考的。 -### 4.1 为什么要淘汰 RNN? +在 AI 进化史上,主要有两种“思考方式”(架构):**RNN** 和 **Transformer**。 -以前的模型(RNN)像人读书一样,**从左到右**一个字一个字读。 +### 4.1 以前的笨办法:RNN(传话游戏) -- **缺点1:慢**。必须读完第1个字才能读第2个,没法并行(浪费了矩阵并行的优势)。 -- **缺点2:忘**。读到文章最后,可能已经忘了开头讲什么了(长距离遗忘)。 +早期的模型(RNN,循环神经网络)处理一句话时,就像我们在玩**传话游戏**。 -### 4.2 Transformer 强在哪? +**工作方式:** +1. 读第 1 个词“我”,记在脑子里,传给第 2 步。 +2. 读第 2 个词“喜欢”,结合刚才的记忆,更新一下脑子里的信息,再传给第 3 步。 +3. 读第 3 个词“吃”,再更新记忆... +4. ...直到读完最后一个词。 -现在的 LLM 都基于 Transformer 架构,它完美契合了矩阵并行的特性: +**这就带来了两个致命缺点:** -1. **并行阅读**:它可以**一眼看完**整句话,不用一个字一个字读。 -2. **注意力机制 (Attention)**:它可以让句子里的每一个词,都**直接关注**到其他所有词。 - - 比如读到“它”这个字时,模型能瞬间注意到前面的“小猫”,从而知道“它”指代的是猫。 +1. **慢(无法并行)**:必须等上一个人传完话,下一个人才能开始。没法让 100 个人同时干活。 +2. **忘(长距离遗忘)**:传话传到第 100 个人时,他可能早就忘了第 1 个人说的是“我”还是“你”。这就导致模型写长文章时,容易前言不搭后语。 + +### 4.2 现在的天才设计:Transformer(圆桌会议) + +2017 年,Google 提出了一种全新的架构——**Transformer**。它彻底改变了规则,把“传话游戏”变成了**圆桌会议**。 + +**工作方式:** +Transformer 不再一个接一个地传话,而是让**所有词一次性全部坐上桌**。 + +1. **上帝视角(并行计算)**:所有词同时进场,不用排队。大家把自己的信息写在纸上,摊在桌子中间。 +2. **注意力机制(Attention)**:这是它的杀手锏。每个词都可以**直接**去看桌上其他任何一个词的信息。 + - 比如读到“它”这个字时,模型不需要回忆前面的传话,而是直接一眼看到前面的“小猫”,瞬间明白“它 = 小猫”。 + +**这就完美解决了 RNN 的痛点:** + +* **快**:大家同时看资料,GPU 可以火力全开,效率极高。 +* **不忘**:不管句子多长,第 1 个词和第 10000 个词的距离都是“一步之遥”,想看谁就看谁。 + +> **总结一下**: +> * **RNN**:像走迷宫,一步一步摸索,容易迷路。 +> * **Transformer**:像开上帝视角看地图,终点起点尽收眼底。 + +#### 为什么还需要“位置”信息? + +因为 Transformer 是“一锅端”,如果不做特殊处理,它分不清“我爱你”和“你爱我”的区别(词都一样,只是顺序不同)。 +所以我们会给每个词贴个**号码牌(位置编码)**,告诉模型谁在第 1 位,谁在第 2 位。 + +> 小提醒:很多 LLM 是自回归(预测下一个词)的,所以在生成时仍然是一 token 一 token 往外吐;但在**每一步生成**的内部计算里,Transformer 依旧更能利用矩阵并行与缓存优化。 + +### 4.3 效率黑科技:KV 缓存 (KV Cache) + +你可能听说过,生成长文本时,越到后面越慢,或者显存占用越大。这通常是因为模型需要“记住”之前生成的所有内容。 + +**Transformer 怎么“记笔记”?** + +在 Transformer 的注意力机制中,每个词都会生成 `Key (K)` 和 `Value (V)` 两个向量,用来供后面的词“查询”。 + +- 当模型生成第 100 个词时,它需要回头看前 99 个词的 K 和 V。 +- 如果每次都重新计算前 99 个词的 K 和 V,那就太浪费了! + +**KV Cache 的作用:** + +KV Cache 就像是一个**“增量笔记本”**。 + +1. **不重算**:算完第 1 个词的 K 和 V,存起来。 +2. **只算新**:生成第 2 个词时,只计算第 2 个词的 K 和 V,然后和第 1 个词的 K、V 拼在一起。 +3. **越存越多**:随着对话进行,这个“笔记本”(显存占用)会越来越厚。 + +这就是为什么长文本对话(Long Context)会消耗大量显存的原因——**不是模型变大了,而是笔记(KV Cache)太厚了。** diff --git a/docs/zh-cn/appendix/queue-design.md b/docs/zh-cn/appendix/queue-design.md index fb27d7b..f6849f0 100644 --- a/docs/zh-cn/appendix/queue-design.md +++ b/docs/zh-cn/appendix/queue-design.md @@ -6,26 +6,245 @@ ## 0. 引言:系统的"缓冲器" -你在淘宝买完东西,为什么点击"支付"后,不会立刻收到短信通知? -你在抖音发了一条评论,为什么点赞数不是瞬间就增加? +### 0.1 从生活中的例子说起 -这背后都有一个功臣:**消息队列 (Message Queue)**。 +想象一下这个场景: -如果同步调用是"打电话",那消息队列就是"发微信"。 -打电话要求对方**立即响应**(同步),发微信可以等对方**稍后处理**(异步)。 +**🏪 餐厅点餐的智慧** -### 0.1 为什么要用消息队列? +你走进一家繁忙的餐厅,前台服务员(A)迅速给你点单、收钱,然后告诉你"请稍等,餐好了会叫号"。你不需要站在厨房门口等着厨师(B)直接把菜端给你,而是可以安心坐下刷手机。 -只有一个理由:**解耦和削峰**。 +**为什么这么做?** +- 如果每个顾客都站在厨房门口等(同步调用),厨房会乱成一团 +- 用"叫号系统"(消息队列),服务员快速完成点餐,厨房按自己的节奏做菜 +- 即使厨师临时休息了,点餐也不会受影响,订单会排队等他回来 -- **解耦**:A 不需要直接调用 B,把消息扔给队列就完事了。 - - _例子_:用户下单后,订单服务不需要直接调用库存、积分、通知服务,而是发一条"下单成功"消息。 -- **削峰**:把瞬间的高峰流量"摊平",避免系统被打爆。 - - _例子_:秒杀活动,1 秒内有 10 万个请求,但数据库只能处理 1000 个。队列把这 10 万个请求暂存起来,慢慢处理。 +**🛒 淘宝支付的秘密** + +你在淘宝买完东西,点击"支付"后,系统显示"支付成功",但你可能要等几秒甚至几分钟才收到短信通知。 + +**为什么不是立即收到?** +因为支付系统要做的事情太多了: +- ✅ 扣款(必须立即完成) +- ⏳ 发送短信通知(可以稍后) +- ⏳ 更新积分(可以稍后) +- ⏳ 给推荐系统发送数据(可以稍后) + +如果把所有事情都卡在"支付"这个按钮上,你可能要等 5 秒才能看到"支付成功"。聪明的系统会: +1. 先完成扣款 +2. 把其他任务扔进一个"待办事项池"(消息队列) +3. 立即告诉你"支付成功" +4. 后台慢慢处理那些待办事项 + +**这就是消息队列的核心价值:把"必须现在做"和"可以稍后做"的事情分开。** + +### 0.2 什么是消息队列? + +**消息队列**就像一个智能的"中转站"或"缓冲区": + +``` +如果同步调用是"打电话"(要求对方立即响应) +那消息队列就是"发微信"(可以等对方稍后处理) +``` + +**用一个比喻理解**: + +> **没有消息队列**:你直接把文件交给同事,他正在开会,你只能干等。 +> +> **有消息队列**:你把文件放到他的办公桌(队列),继续做自己的事。他开完会自己来拿。 + +### 0.3 为什么要用消息队列? + +核心原因就两个:**解耦**和**削峰**。 + +#### 📌 解耦:让系统更灵活 + +**问题**:A 直接调用 B,一旦 B 出问题,A 也跟着完蛋。 + +```python +# 紧耦合的例子(不好) +def create_order(user_id, product_id): + order = db.save_order(user_id, product_id) + + # 如果通知服务挂了,整个订单创建就失败 + notification.send_sms(user_id, "订单创建成功") + notification.send_email(user_id, "订单创建成功") + + return order +``` + +**解决**:用消息队列做"中介",A 只管发消息,不关心 B 是否在线。 + +```python +# 松耦合的例子(好) +def create_order(user_id, product_id): + order = db.save_order(user_id, product_id) + + # 扔到队列里就完事了,不管通知服务是否在线 + queue.publish("order.created", { + "user_id": user_id, + "order_id": order.id + }) + + return order +``` + +**好处**: +- ✅ 订单系统不依赖通知系统 +- ✅ 可以随时增加新的消费者(比如加一个"积分系统") +- ✅ 通知系统升级不影响订单系统 + +#### 📌 削峰:把洪峰变成平缓的水流 + +**问题**:瞬间流量太高,系统扛不住。 + +**场景**:双11秒杀 +- 1 秒内有 10 万个请求涌进来 +- 数据库每秒只能处理 1000 个 +- 如果直接打到数据库,数据库会直接"爆掉" + +**解决**:用消息队列当"蓄水池" + +``` +洪水来了(10 万请求/秒) + ↓ +[大坝] 消息队列暂存 + ↓ +平缓流出(1000 请求/秒) + ↓ +[农田] 数据库慢慢处理 +``` -**关键点**:消息队列的本质是**异步通信**,通过把"立即执行"变成"稍后处理",提升系统的吞吐量和可用性。 +### 0.4 消息队列的本质 + +**一句话总结**:消息队列的本质是**异步通信**,通过把"立即执行"变成"稍后处理",提升系统的吞吐量和可用性。 + +**关键特点**: +- ✅ **异步**:不需要等任务完成,立即返回 +- ✅ **解耦**:服务之间不直接依赖 +- ✅ **缓冲**:暂存消息,平滑流量 +- ✅ **可靠**:消息持久化,不怕丢失 + +--- + +## 🗺️ 全局观:消息队列知识地图 + +### 消息队列的核心价值 + +> **用"空间换时间,用异步换性能"** —— 让系统可以"快速响应请求,慢慢处理任务" + +### 知识体系地图 + +``` +消息队列知识体系 +│ +├── 📦 基础概念(必学) +│ ├── 生产者(Producer):发送消息的一方 +│ ├── 消费者(Consumer):接收并处理消息的一方 +│ ├── 消息代理(Broker):存储和转发消息的中介 +│ └── 消息模式 +│ ├── 点对点(P2P):一条消息被一个消费者消费 +│ └── 发布订阅(Pub/Sub):一条消息被多个消费者消费 +│ +├── 🎯 核心应用场景(必学) +│ ├── 异步处理:把同步改成异步,提升响应速度 +│ ├── 削峰填谷:缓冲高峰流量,保护系统 +│ ├── 系统解耦:消除服务之间的直接依赖 +│ └── 数据分发:一条消息分发给多个消费者 +│ +├── 🔒 可靠性保证(重要) +│ ├── 消息不丢失:持久化 + ACK 机制 + 多副本 +│ ├── 消息不重复:幂等性设计 +│ └── 消息顺序:单分区或内存排序 +│ +├── 🚀 高级特性(进阶) +│ ├── 死信队列(DLQ):处理无法消费的消息 +│ ├── 延迟消息:指定时间后才消费 +│ └── 事务消息:保证本地事务和消息发送的一致性 +│ +├── 🛠️ 主流消息队列(了解) +│ ├── RabbitMQ:传统消息队列,功能丰富 +│ ├── Kafka:分布式日志系统,吞吐量极大 +│ ├── RocketMQ:电商级消息队列,功能全面 +│ └── Redis Stream:轻量级队列,适合小规模应用 +│ +└── 📊 实战设计(综合应用) + └── 秒杀系统、订单系统、异步任务处理 +``` + +### 学习路径建议(0 基础小白) + +#### 🎒 第一阶段:建立直觉(1-2 小时) +**目标**:理解消息队列是什么,为什么需要它 + +1. **阅读本章节的 0. 引言部分** + - 理解"餐厅点餐"和"淘宝支付"的例子 + - 掌握"解耦"和"削峰"两个核心价值 + +2. **动手体验**(可选) + - 找一个生活中的"队列"例子(如餐厅叫号、客服排队) + - 画出它的流程图 + +#### 📚 第二阶段:掌握基础(1-2 天) +**目标**:理解核心概念和基本用法 + +1. **学习基础概念** + - 生产者、消费者、Broker + - 点对点 vs 发布订阅 + - 阅读本章节第 1 部分 + +2. **选择一个消息队列上手** + - 推荐从 **Redis Stream** 或 **RabbitMQ** 开始(学习曲线低) + - 跟着官方文档写一个"生产者-消费者"的 Hello World + +3. **实现第一个异步任务** + - 场景:用户注册后,异步发送欢迎邮件 + - 用代码实现:注册接口 → 发消息到队列 → 消费者发送邮件 + +#### 🔥 第三阶段:深入核心(1 周) +**目标**:掌握消息队列的核心用法 + +1. **学习核心设计模式** + - 异步处理:提升响应速度 + - 削峰填谷:保护系统 + - 系统解耦:降低依赖 + - 阅读本章节第 3 部分 + +2. **保证可靠性** + - 消息不丢失:持久化 + ACK + - 消息不重复:幂等性设计 + - 阅读本章节第 4 部分 + +3. **实战练习** + - 设计一个"秒杀系统":用消息队列削峰 + - 设计一个"订单系统":用消息队列解耦 + +#### 🚀 第四阶段:精通高级特性(2-4 周) +**目标**:处理复杂场景 + +1. **高级特性** + - 死信队列:处理异常消息 + - 延迟消息:定时任务 + - 事务消息:保证一致性 + - 阅读本章节第 5 部分 + +2. **完整系统设计** + - 设计一个带监控的异步处理系统 + - 处理各种异常场景(消息丢失、重复、顺序错乱) + +3. **深入学习特定 MQ** + - Kafka:学习高可用架构(多副本、分区) + - RocketMQ:学习事务消息 + +### 学习建议 + +- ✅ **先理解,再动手**:不要一开始就陷入代码细节,先理解为什么需要消息队列 +- ✅ **从简单开始**:不要一上来就学 Kafka,从 Redis Stream 或 RabbitMQ 开始 +- ✅ **边学边练**:每学一个概念,就写代码实践一下 +- ✅ **关注应用场景**:不仅要知其然,还要知其所以然 +- ✅ **阅读真实案例**:看看淘宝、抖音等大厂如何使用消息队列 ---