feat(appendix): 添加多个交互式演示组件,完善 AI/Infra 等章节内容
- 新增 Vibe Coding 全栈相关演示组件 (DeveloperSkillShift, FrontendTriad, BackendCore 等) - 新增 RAG 相关组件 (RAGPipeline, ChunkingStrategy, Retrieval 等) - 新增 Embedding & Vector 相关组件 (EmbeddingConcept, VectorSimilarity 等) - 新增 AI Native App 设计组件 (AINativeArch, PromptDesign 等) - 新增 Infrastructure as Code 组件 (IaCConcept, TerraformWorkflow 等) - 新增 DNS & HTTPS 演示组件 (DnsResolution, HttpsHandshake 等) - 新增 Model Finetuning 组件 (FinetuningPipeline 等) - 更新多个章节的 markdown 内容,集成交互式演示
This commit is contained in:
@@ -1,3 +1,164 @@
|
||||
# AI 原生应用设计
|
||||
|
||||
> 待实现
|
||||
::: tip 前言
|
||||
**为什么有些 AI 产品让人惊艳,而有些只是"套壳 ChatGPT"?** 差别不在于用了多强的模型,而在于产品是否从底层就围绕 AI 的特性来设计。AI 原生应用不是在传统应用上"加个聊天框",而是重新思考用户交互、系统架构和产品逻辑的全新范式。
|
||||
:::
|
||||
|
||||
**这篇文章会带你学什么?**
|
||||
|
||||
学完这章后,你将获得:
|
||||
|
||||
- **范式认知**:理解 AI 原生应用与传统应用的本质区别
|
||||
- **设计原则**:掌握 AI 原生产品设计的核心原则
|
||||
- **Prompt 工程**:了解如何设计高质量的 Prompt 来驱动 AI 能力
|
||||
- **交互模式**:认识 AI 时代的新型用户交互范式
|
||||
- **架构思维**:理解 AI 应用的请求处理流程和系统架构
|
||||
|
||||
| 章节 | 内容 | 核心概念 |
|
||||
|-----|------|---------|
|
||||
| **第 1 章** | 架构对比 | 传统应用 vs AI 原生应用 |
|
||||
| **第 2 章** | 设计原则 | AI-First 思维、不确定性设计 |
|
||||
| **第 3 章** | Prompt 工程 | 系统提示词、模板设计 |
|
||||
| **第 4 章** | 交互模式 | 流式输出、多模态、Agent |
|
||||
| **第 5 章** | 请求流程 | AI 应用的完整生命周期 |
|
||||
|
||||
---
|
||||
|
||||
## 0. 全景图:从"加个 AI"到"AI 原生"
|
||||
|
||||
过去几年,很多产品的 AI 化路径是这样的:有一个现成的应用,然后在某个角落加一个"AI 助手"按钮。这种做法就像在马车上装一个引擎——能跑,但远不如从头设计一辆汽车。
|
||||
|
||||
**AI 原生应用**是一种全新的产品思维:从第一行代码开始,就把 AI 作为核心能力来设计,而不是事后附加的功能。
|
||||
|
||||
::: tip 传统应用 vs AI 原生应用
|
||||
- **传统应用**:用户操作 → 确定性逻辑 → 确定性结果。每次点击"提交订单",流程完全一样。
|
||||
- **AI 原生应用**:用户意图 → AI 理解 → 概率性结果。同样的问题,每次回答可能略有不同。
|
||||
- **核心转变**:从"编写规则"到"描述意图",从"确定性"到"概率性",从"操作界面"到"对话界面"。
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## 1. 架构对比:两种完全不同的世界
|
||||
|
||||
传统应用的架构是"请求-响应"模型:用户点击按钮,后端执行确定性逻辑,返回确定性结果。整个过程可预测、可测试、可复现。
|
||||
|
||||
AI 原生应用则引入了一个全新的角色——**大语言模型**。它像一个"智能中间层",接收自然语言输入,输出自然语言结果。这带来了架构上的根本性变化。
|
||||
|
||||
<AINativeArchDemo />
|
||||
|
||||
| 维度 | 传统应用 | AI 原生应用 |
|
||||
|------|---------|------------|
|
||||
| 输入方式 | 表单、按钮、下拉框 | 自然语言、图片、语音 |
|
||||
| 处理逻辑 | if-else、规则引擎 | LLM 推理、Prompt 驱动 |
|
||||
| 输出特性 | 确定性、可复现 | 概率性、每次可能不同 |
|
||||
| 延迟特征 | 毫秒级 | 秒级(需要流式输出) |
|
||||
| 错误处理 | 明确的错误码 | 幻觉、拒绝回答、答非所问 |
|
||||
| 成本模型 | 固定计算资源 | 按 token 计费,成本波动大 |
|
||||
|
||||
::: tip 架构演进的三个阶段
|
||||
1. **AI 增强型**:在现有应用中嵌入 AI 功能(如自动补全、智能推荐)
|
||||
2. **AI 协作型**:AI 作为核心交互方式,但仍有传统 UI 兜底(如 Notion AI、GitHub Copilot)
|
||||
3. **AI 原生型**:整个产品围绕 AI 构建,去掉 AI 产品就不成立(如 ChatGPT、Cursor、Midjourney)
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## 2. 设计原则:AI 原生产品的"宪法"
|
||||
|
||||
设计 AI 原生应用不能照搬传统软件的设计思路。AI 的概率性、延迟性和不可预测性,要求我们建立一套全新的设计原则。
|
||||
|
||||
<AIDesignPrincipleDemo />
|
||||
|
||||
::: tip 五大核心设计原则
|
||||
1. **拥抱不确定性**:AI 的输出不是 100% 可靠的,产品设计必须考虑"AI 可能出错"的情况。提供编辑、重试、反馈机制,让用户始终拥有控制权。
|
||||
2. **渐进式信任**:不要一开始就让 AI 做高风险决策。先从低风险场景建立用户信任,再逐步扩展 AI 的自主权。
|
||||
3. **透明可解释**:让用户知道 AI 在做什么、为什么这么做。展示推理过程、引用来源、标注置信度。
|
||||
4. **人机协作**:AI 不是替代人,而是增强人。最好的设计是让 AI 做初稿,人做终审。
|
||||
5. **优雅降级**:当 AI 服务不可用或结果不理想时,产品仍然可用。永远有 Plan B。
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## 3. Prompt 工程:AI 应用的"编程语言"
|
||||
|
||||
在传统应用中,你用代码告诉计算机做什么。在 AI 原生应用中,你用 Prompt 告诉模型做什么。**Prompt 就是 AI 时代的编程语言**——写得好,AI 表现惊艳;写得差,AI 胡说八道。
|
||||
|
||||
<PromptDesignDemo />
|
||||
|
||||
::: tip Prompt 设计的四层结构
|
||||
1. **系统提示词(System Prompt)**:定义 AI 的角色、能力边界和行为规范。这是"宪法"级别的指令,用户看不到但始终生效。
|
||||
2. **上下文注入(Context)**:通过 RAG 检索到的相关文档、用户历史记录等,为 AI 提供回答所需的背景信息。
|
||||
3. **用户输入(User Message)**:用户的实际问题或指令。
|
||||
4. **输出格式约束(Format)**:指定 AI 的输出格式(JSON、Markdown、特定模板),确保结果可被程序解析。
|
||||
:::
|
||||
|
||||
| Prompt 技巧 | 说明 | 效果 |
|
||||
|------------|------|------|
|
||||
| 角色设定 | "你是一个资深前端工程师" | 提升专业领域回答质量 |
|
||||
| Few-shot 示例 | 给出 2-3 个输入输出示例 | 让模型理解期望的格式和风格 |
|
||||
| 思维链(CoT) | "请一步步思考" | 提升复杂推理的准确性 |
|
||||
| 输出约束 | "用 JSON 格式回答" | 确保输出可被程序解析 |
|
||||
| 负面指令 | "不要编造不确定的信息" | 减少幻觉和错误信息 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 交互模式:AI 时代的用户体验
|
||||
|
||||
AI 原生应用催生了一批全新的交互模式。传统应用的交互是"点击-等待-查看",而 AI 应用的交互更像是"对话-观察-调整"。
|
||||
|
||||
<AIUXPatternDemo />
|
||||
|
||||
::: tip 四种核心交互模式
|
||||
1. **流式输出(Streaming)**:AI 生成内容时逐字显示,而不是等全部生成完再展示。这大幅降低了用户的感知等待时间,也让用户可以在生成过程中判断方向是否正确。
|
||||
2. **多轮对话(Multi-turn)**:通过上下文记忆实现连续对话,用户可以逐步细化需求。关键挑战是上下文窗口管理和对话历史压缩。
|
||||
3. **多模态交互(Multimodal)**:支持文本、图片、语音、文件等多种输入方式,AI 也能输出图片、代码、表格等多种格式。
|
||||
4. **Agent 模式(Agentic)**:AI 不只是回答问题,而是自主规划、执行多步骤任务。用户给出目标,AI 自行拆解步骤并逐一完成。
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## 5. 请求流程:一次 AI 调用的完整生命周期
|
||||
|
||||
当用户在 AI 应用中发送一条消息,背后发生了什么?理解这个完整流程,是构建可靠 AI 应用的基础。
|
||||
|
||||
<AIAppFlowDemo />
|
||||
|
||||
::: tip 请求处理的六个阶段
|
||||
1. **输入预处理**:校验用户输入、内容安全审核、敏感信息脱敏
|
||||
2. **上下文组装**:拼接系统提示词、检索相关文档(RAG)、加载对话历史
|
||||
3. **模型调用**:将组装好的 Prompt 发送给 LLM API,开启流式响应
|
||||
4. **输出后处理**:格式化输出、内容安全过滤、结构化数据提取
|
||||
5. **结果缓存**:对常见问题缓存结果,降低成本和延迟
|
||||
6. **监控记录**:记录 token 用量、响应时间、用户反馈,用于持续优化
|
||||
:::
|
||||
|
||||
| 阶段 | 关键考量 | 常见问题 |
|
||||
|------|---------|---------|
|
||||
| 输入预处理 | 注入攻击防护、长度限制 | Prompt 注入、越狱攻击 |
|
||||
| 上下文组装 | token 预算分配、信息优先级 | 上下文溢出、关键信息被截断 |
|
||||
| 模型调用 | 超时处理、重试策略、流式传输 | API 限流、网络超时 |
|
||||
| 输出后处理 | 格式校验、幻觉检测 | 输出格式不符预期 |
|
||||
| 缓存策略 | 语义缓存 vs 精确缓存 | 缓存命中率低 |
|
||||
| 监控告警 | 成本监控、质量评估 | token 成本失控 |
|
||||
|
||||
---
|
||||
|
||||
## 总结
|
||||
|
||||
AI 原生应用设计不是简单地在传统应用上叠加 AI 功能,而是从架构、交互、工程实践等维度进行全面重构。
|
||||
|
||||
回顾本章的关键要点:
|
||||
|
||||
1. **架构转变**:从确定性逻辑到概率性推理,AI 原生应用需要全新的架构思维
|
||||
2. **设计原则**:拥抱不确定性、渐进式信任、透明可解释、人机协作、优雅降级
|
||||
3. **Prompt 是核心**:Prompt 工程是 AI 应用的"编程语言",直接决定产品质量
|
||||
4. **交互革新**:流式输出、多轮对话、多模态、Agent 模式重新定义了用户体验
|
||||
5. **全链路思维**:从输入预处理到监控告警,每个环节都需要针对 AI 特性专门设计
|
||||
|
||||
## 延伸阅读
|
||||
|
||||
- [Google PAIR Guidelines](https://pair.withgoogle.com/) - Google 的人机交互 AI 设计指南
|
||||
- [OpenAI Prompt Engineering Guide](https://platform.openai.com/docs/guides/prompt-engineering) - 官方 Prompt 工程最佳实践
|
||||
- [Anthropic Prompt Engineering](https://docs.anthropic.com/en/docs/build-with-claude/prompt-engineering) - Claude 的 Prompt 设计指南
|
||||
- [Nielsen Norman Group: AI UX](https://www.nngroup.com/topic/artificial-intelligence/) - AI 用户体验研究
|
||||
- [Building LLM Applications](https://www.oreilly.com/library/view/building-llm-powered/9781835462317/) - 构建 LLM 应用的实战指南
|
||||
|
||||
@@ -1,3 +1,193 @@
|
||||
# Embedding 与向量检索
|
||||
|
||||
> 待实现
|
||||
::: tip 前言
|
||||
**计算机怎么理解"猫和狗很像,但和汽车不像"这件事?** 对人类来说这是常识,但对计算机来说,"猫"、"狗"、"汽车"不过是三个毫无关联的字符串。Embedding(嵌入)技术就是解决这个问题的关键——它把文字变成数字向量,让计算机也能理解语义上的"远近亲疏"。
|
||||
:::
|
||||
|
||||
**这篇文章会带你学什么?**
|
||||
|
||||
学完这章后,你将获得:
|
||||
|
||||
- **直觉理解**:明白 Embedding 是什么,为什么"猫"和"狗"的向量会靠近
|
||||
- **相似度计算**:掌握余弦相似度、欧氏距离等核心度量方法
|
||||
- **索引原理**:理解向量数据库如何在百万级数据中毫秒级检索
|
||||
- **技术选型**:了解主流向量数据库的特点和适用场景
|
||||
- **端到端流程**:掌握从文本到向量到检索的完整 Pipeline
|
||||
|
||||
| 章节 | 内容 | 核心概念 |
|
||||
|-----|------|---------|
|
||||
| **第 1 章** | Embedding 概念 | 语义空间、向量表示 |
|
||||
| **第 2 章** | 相似度计算 | 余弦相似度、欧氏距离 |
|
||||
| **第 3 章** | 向量索引 | 暴力搜索 vs ANN |
|
||||
| **第 4 章** | 向量数据库 | Pinecone、Milvus、Chroma |
|
||||
| **第 5 章** | 端到端 Pipeline | 文本→向量→存储→查询 |
|
||||
|
||||
---
|
||||
|
||||
## 0. 全景图:从文字到数字的桥梁
|
||||
|
||||
在自然语言处理的世界里,有一个根本性的挑战:**计算机只认识数字,不认识文字**。
|
||||
|
||||
早期的做法是给每个词分配一个编号(One-Hot 编码),比如"猫"=001,"狗"=010,"汽车"=100。但这样做有个致命问题:**所有词之间的距离都一样远**。"猫"到"狗"的距离和"猫"到"汽车"的距离完全相同——这显然不符合我们的直觉。
|
||||
|
||||
Embedding 的革命性在于:它把每个词映射到一个**稠密的低维向量空间**,让语义相近的词自然聚集在一起。在这个空间里,"猫"和"狗"靠得很近,而"汽车"则在远处——计算机终于能"理解"语义了。
|
||||
|
||||
::: tip 从 One-Hot 到 Embedding 的飞跃
|
||||
- **One-Hot**:维度 = 词表大小(可能几万维),每个向量只有一个 1,其余全是 0,稀疏且无语义
|
||||
- **Embedding**:维度通常 768~1536,每个数字都有意义,稠密且富含语义信息
|
||||
- **关键突破**:Word2Vec(2013)证明了"词的含义可以用它的上下文来定义",开启了 Embedding 时代
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## 1. Embedding 概念:把文字变成坐标
|
||||
|
||||
Embedding 的核心思想可以用一句话概括:**用一组数字(向量)来表示一个词或句子的含义**。
|
||||
|
||||
想象一个二维坐标系。我们把"猫"放在坐标 (0.2, 0.7),"狗"放在 (0.3, 0.6),"汽车"放在 (0.9, 0.1)。你会发现"猫"和"狗"的坐标很接近,而"汽车"离它们很远。这就是 Embedding 的直觉——**语义相似度变成了空间距离**。
|
||||
|
||||
<EmbeddingConceptDemo />
|
||||
|
||||
::: tip Embedding 的三个关键特性
|
||||
1. **语义聚类**:相似含义的词会自动聚集在一起(动物一簇、食物一簇、科技一簇)
|
||||
2. **类比关系**:向量运算可以表达语义关系,经典例子:king - man + woman ≈ queen
|
||||
3. **维度含义**:每个维度隐式编码了某种语义特征(如"是否是动物"、"大小"、"情感倾向"等)
|
||||
:::
|
||||
|
||||
| 编码方式 | 维度 | 语义信息 | 典型应用 |
|
||||
|---------|------|---------|---------|
|
||||
| One-Hot | 词表大小(~50000) | 无 | 传统 NLP |
|
||||
| Word2Vec | 100~300 | 词级语义 | 词相似度、类比推理 |
|
||||
| BERT Embedding | 768 | 上下文语义 | 句子理解、问答 |
|
||||
| OpenAI text-embedding-3 | 1536~3072 | 深层语义 | RAG、语义搜索 |
|
||||
|
||||
---
|
||||
|
||||
## 2. 相似度计算:向量之间有多"近"?
|
||||
|
||||
有了向量表示,下一个问题自然是:**怎么衡量两个向量有多相似?** 这就像在地图上衡量两个城市有多近——你可以量直线距离,也可以看方向是否一致。
|
||||
|
||||
<VectorSimilarityDemo />
|
||||
|
||||
::: tip 两种核心度量
|
||||
- **余弦相似度(Cosine Similarity)**:衡量两个向量的**方向**是否一致,值域 [-1, 1]。1 表示方向完全相同,0 表示正交(无关),-1 表示完全相反。文本语义比较的首选,因为它不受向量长度影响。
|
||||
- **欧氏距离(Euclidean Distance)**:衡量两个向量端点之间的**直线距离**,值域 [0, ∞)。0 表示完全重合,值越大越不相似。适合需要考虑"绝对大小"的场景。
|
||||
:::
|
||||
|
||||
| 度量方式 | 公式直觉 | 值域 | 适用场景 |
|
||||
|---------|---------|------|---------|
|
||||
| 余弦相似度 | 看方向,忽略长度 | [-1, 1] | 文本语义搜索、推荐系统 |
|
||||
| 欧氏距离 | 看端点直线距离 | [0, ∞) | 图像特征、聚类分析 |
|
||||
| 点积 | 方向 × 长度 | (-∞, +∞) | 归一化向量的快速计算 |
|
||||
| 曼哈顿距离 | 沿坐标轴走的距离 | [0, ∞) | 高维稀疏向量 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 向量索引:如何在百万向量中毫秒检索?
|
||||
|
||||
假设你有 100 万条文档,每条都转成了 1536 维的向量。用户提了一个问题,你需要找到最相似的 10 条。最直接的方法是逐一计算相似度——但这意味着要做 100 万次 1536 维的向量运算,太慢了。
|
||||
|
||||
这就是**向量索引**要解决的问题:**用空间换时间,通过预处理建立索引结构,让检索速度从 O(n) 降到近似 O(log n)**。
|
||||
|
||||
<VectorIndexDemo />
|
||||
|
||||
::: tip 暴力搜索 vs 近似最近邻(ANN)
|
||||
- **暴力搜索(Flat)**:逐一比较,100% 准确但速度慢。适合数据量小(< 10 万)的场景。
|
||||
- **IVF(倒排文件索引)**:先把向量空间划分成若干区域(聚类),查询时只搜索最近的几个区域。像是把图书馆按主题分区,找书时只去相关区域。
|
||||
- **HNSW(分层可导航小世界图)**:构建多层图结构,从粗粒度到细粒度逐层导航。像是先看世界地图定位到国家,再看省级地图,最后看街道地图。
|
||||
- **PQ(乘积量化)**:把高维向量压缩成短编码,牺牲少量精度换取大幅内存节省。适合超大规模数据集。
|
||||
:::
|
||||
|
||||
| 索引类型 | 构建速度 | 查询速度 | 召回率 | 内存占用 | 适用规模 |
|
||||
|---------|---------|---------|-------|---------|---------|
|
||||
| Flat(暴力) | 无需构建 | 慢 | 100% | 高 | < 10 万 |
|
||||
| IVF | 中等 | 快 | 95%+ | 中 | 10 万~1000 万 |
|
||||
| HNSW | 慢 | 很快 | 99%+ | 高 | 10 万~1000 万 |
|
||||
| PQ | 中等 | 快 | 90%+ | 很低 | > 1000 万 |
|
||||
| IVF-PQ | 中等 | 快 | 92%+ | 低 | > 1 亿 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 向量数据库:专为向量而生的存储引擎
|
||||
|
||||
有了向量和索引算法,你需要一个地方来存储和管理它们。传统数据库(MySQL、PostgreSQL)擅长处理结构化数据,但对高维向量的相似度搜索力不从心。**向量数据库**就是为这个场景专门设计的。
|
||||
|
||||
<VectorDatabaseDemo />
|
||||
|
||||
::: tip 向量数据库的核心能力
|
||||
1. **高效存储**:针对高维浮点向量优化的存储格式
|
||||
2. **ANN 检索**:内置多种近似最近邻索引算法(HNSW、IVF 等)
|
||||
3. **元数据过滤**:支持在向量搜索的同时按标签、时间等条件过滤
|
||||
4. **实时更新**:支持动态增删改向量,无需重建整个索引
|
||||
5. **水平扩展**:分布式架构支持亿级向量规模
|
||||
:::
|
||||
|
||||
| 数据库 | 类型 | 特点 | 适用场景 |
|
||||
|-------|------|------|---------|
|
||||
| Pinecone | 全托管云服务 | 零运维、开箱即用 | 快速原型、中小规模生产 |
|
||||
| Milvus | 开源分布式 | 高性能、可扩展 | 大规模生产环境 |
|
||||
| Chroma | 开源轻量 | 嵌入式、API 简洁 | 本地开发、小型项目 |
|
||||
| Weaviate | 开源云原生 | 内置向量化、GraphQL | 需要自动向量化的场景 |
|
||||
| Qdrant | 开源高性能 | Rust 实现、过滤强 | 需要复杂过滤的场景 |
|
||||
| pgvector | PG 扩展 | 复用现有 PG 基础设施 | 已有 PostgreSQL 的团队 |
|
||||
|
||||
---
|
||||
|
||||
## 5. 端到端 Pipeline:从文本到检索的完整流程
|
||||
|
||||
理解了各个组件后,让我们把它们串起来,看看一个完整的向量检索系统是怎么工作的。
|
||||
|
||||
整个流程分为两条线:**离线写入**(把文档变成向量存起来)和**在线查询**(把问题变成向量去搜索)。
|
||||
|
||||
<EmbeddingPipelineDemo />
|
||||
|
||||
::: tip 离线写入流程
|
||||
1. **文档加载**:从各种来源(PDF、网页、数据库)读取原始文本
|
||||
2. **文本预处理**:清洗、去噪、标准化(去掉 HTML 标签、特殊字符等)
|
||||
3. **文本分块**:按策略将长文本切分为合适大小的片段(200~500 tokens)
|
||||
4. **向量化**:调用嵌入模型(如 OpenAI text-embedding-3-small)将每个片段转为向量
|
||||
5. **存入向量数据库**:将向量和原始文本、元数据一起写入数据库
|
||||
:::
|
||||
|
||||
::: tip 在线查询流程
|
||||
1. **接收查询**:用户输入自然语言问题
|
||||
2. **查询向量化**:用同一个嵌入模型将问题转为向量
|
||||
3. **相似度检索**:在向量数据库中搜索 Top-K 最相似的文档片段
|
||||
4. **后处理**:重排序、去重、元数据过滤
|
||||
5. **返回结果**:将最相关的文档片段返回给调用方(或交给 LLM 生成回答)
|
||||
:::
|
||||
|
||||
| 环节 | 关键选择 | 推荐方案 |
|
||||
|------|---------|---------|
|
||||
| 嵌入模型 | 精度 vs 成本 vs 速度 | OpenAI text-embedding-3-small(性价比高) |
|
||||
| 分块策略 | 粒度 vs 语义完整性 | 递归分块,200~500 tokens |
|
||||
| 向量数据库 | 规模 vs 运维成本 | 小项目用 Chroma,生产用 Pinecone/Milvus |
|
||||
| 相似度度量 | 语义 vs 精确 | 余弦相似度(文本场景首选) |
|
||||
| Top-K 值 | 召回率 vs 噪音 | 先检索 20 条,重排序后取 Top 5 |
|
||||
|
||||
---
|
||||
|
||||
## 总结
|
||||
|
||||
Embedding 与向量检索是连接"人类语言"和"机器理解"的桥梁,也是 RAG、语义搜索、推荐系统等 AI 应用的基础设施。
|
||||
|
||||
回顾本章的关键要点:
|
||||
|
||||
1. **Embedding 的本质**:把文本映射到高维向量空间,让语义相似度变成空间距离
|
||||
2. **相似度度量**:余弦相似度关注方向(适合文本),欧氏距离关注绝对距离
|
||||
3. **索引是性能关键**:HNSW 和 IVF 让百万级向量的检索降到毫秒级
|
||||
4. **向量数据库选型**:小项目用 Chroma/pgvector,生产环境用 Pinecone/Milvus
|
||||
5. **端到端思维**:从文档加载到最终检索,每个环节的选择都会影响最终效果
|
||||
|
||||
## 延伸阅读
|
||||
|
||||
- [OpenAI Embeddings 文档](https://platform.openai.com/docs/guides/embeddings) - 官方嵌入模型使用指南
|
||||
- [Pinecone Learning Center](https://www.pinecone.io/learn/) - 向量数据库和检索的系统教程
|
||||
- [FAISS Wiki](https://github.com/facebookresearch/faiss/wiki) - Facebook 开源的向量检索库文档
|
||||
- [Word2Vec 原始论文](https://arxiv.org/abs/1301.3781) - Embedding 时代的开山之作
|
||||
- [MTEB 排行榜](https://huggingface.co/spaces/mteb/leaderboard) - 嵌入模型性能对比排行榜
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,173 @@
|
||||
# 模型微调与部署
|
||||
|
||||
> 待实现
|
||||
::: tip 前言
|
||||
**大模型很强,但它不懂你的业务。** GPT-4 能写诗、能编程,但它不知道你公司的产品术语、不了解你行业的专业规范。微调(Fine-tuning)就是让通用大模型"学会"你的专业知识的过程——就像给一个博学的通才做岗前培训,让它变成你的领域专家。
|
||||
:::
|
||||
|
||||
**这篇文章会带你学什么?**
|
||||
|
||||
学完这章后,你将获得:
|
||||
|
||||
- **流程认知**:掌握从数据准备到模型上线的完整微调流水线
|
||||
- **数据工程**:了解微调数据的格式要求和质量标准
|
||||
- **高效微调**:理解 LoRA 等参数高效微调技术的原理和优势
|
||||
- **模型压缩**:掌握量化技术如何让大模型在消费级硬件上运行
|
||||
- **部署实践**:了解模型服务的主流架构和选型策略
|
||||
|
||||
| 章节 | 内容 | 核心概念 |
|
||||
|-----|------|---------|
|
||||
| **第 1 章** | 微调流水线 | 数据→训练→评估→部署 |
|
||||
| **第 2 章** | 训练数据 | 数据格式、质量控制 |
|
||||
| **第 3 章** | LoRA 微调 | 低秩适配、参数高效 |
|
||||
| **第 4 章** | 模型量化 | FP16、INT8、INT4 |
|
||||
| **第 5 章** | 模型部署 | 推理服务、API 网关 |
|
||||
|
||||
---
|
||||
|
||||
## 0. 全景图:为什么需要微调?
|
||||
|
||||
大语言模型的训练分为两个阶段:**预训练**和**微调**。预训练是在海量通用数据上学习语言能力,微调是在特定任务数据上学习专业能力。
|
||||
|
||||
打个比方:预训练像是上大学——学习通识知识,什么都懂一点;微调像是入职培训——针对具体岗位学习专业技能。
|
||||
|
||||
::: tip 什么时候需要微调?
|
||||
- **特定输出格式**:需要模型始终以固定 JSON 格式输出
|
||||
- **专业领域知识**:医疗、法律、金融等领域的专业术语和规范
|
||||
- **语言风格迁移**:让模型用特定的语气、风格回答(如客服话术)
|
||||
- **小众语言支持**:提升模型在特定语言上的表现
|
||||
- **成本优化**:用小模型微调替代大模型调用,降低推理成本
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## 1. 微调流水线:从数据到上线的完整旅程
|
||||
|
||||
微调不是"把数据丢给模型就完事"。它是一个严谨的工程流程,每个环节都会影响最终效果。
|
||||
|
||||
<FinetuningPipelineDemo />
|
||||
|
||||
::: tip 微调的五个阶段
|
||||
1. **数据准备**:收集、清洗、标注训练数据,这是最耗时也最关键的环节
|
||||
2. **模型选择**:选择合适的基座模型(Base Model),如 Llama 3、Qwen、Mistral
|
||||
3. **训练配置**:设置学习率、batch size、epoch 数等超参数
|
||||
4. **训练执行**:在 GPU 上运行训练,监控 loss 曲线和评估指标
|
||||
5. **评估上线**:在测试集上评估效果,通过后部署为 API 服务
|
||||
:::
|
||||
|
||||
| 阶段 | 关键动作 | 常见陷阱 |
|
||||
|------|---------|---------|
|
||||
| 数据准备 | 清洗、去重、格式化 | 数据质量差导致模型"学坏" |
|
||||
| 模型选择 | 评估基座模型能力 | 模型太大训练不动,太小效果差 |
|
||||
| 训练配置 | 调整超参数 | 学习率过高导致灾难性遗忘 |
|
||||
| 训练执行 | 监控 loss 和指标 | 过拟合、训练不收敛 |
|
||||
| 评估上线 | A/B 测试、灰度发布 | 测试集泄漏导致评估虚高 |
|
||||
|
||||
---
|
||||
|
||||
## 2. 训练数据:微调效果的天花板
|
||||
|
||||
在微调中有一句老话:**"Garbage in, garbage out"**。训练数据的质量直接决定了微调效果的上限。100 条高质量数据的效果,往往好过 10000 条低质量数据。
|
||||
|
||||
<TrainingDataDemo />
|
||||
|
||||
::: tip 微调数据的三种常见格式
|
||||
1. **指令格式(Instruction)**:最常用的格式,包含 instruction(指令)、input(输入)、output(期望输出)三个字段。适合训练模型遵循指令。
|
||||
2. **对话格式(Chat)**:多轮对话形式,包含 system、user、assistant 角色的消息列表。适合训练聊天机器人。
|
||||
3. **补全格式(Completion)**:简单的 prompt-completion 对,适合文本生成、代码补全等场景。
|
||||
:::
|
||||
|
||||
| 数据质量维度 | 说明 | 检查方法 |
|
||||
|------------|------|---------|
|
||||
| 准确性 | 答案必须正确无误 | 人工审核、专家校验 |
|
||||
| 一致性 | 相似问题的回答风格一致 | 抽样对比检查 |
|
||||
| 多样性 | 覆盖足够多的场景和变体 | 统计问题类型分布 |
|
||||
| 去重 | 避免重复样本导致过拟合 | 文本去重、语义去重 |
|
||||
| 数据量 | 通常 500~5000 条高质量数据即可 | 从少量开始,逐步增加 |
|
||||
|
||||
---
|
||||
|
||||
## 3. LoRA:用 1% 的参数实现 90% 的效果
|
||||
|
||||
全量微调(Full Fine-tuning)需要更新模型的所有参数——对于一个 70B 参数的模型,这意味着需要数百 GB 的显存和大量的 GPU 算力。对大多数团队来说,这不现实。
|
||||
|
||||
LoRA(Low-Rank Adaptation)提供了一个优雅的解决方案:**冻结原始模型参数,只训练一小组新增的低秩矩阵**。这些矩阵的参数量通常只有原模型的 0.1%~1%,但能达到接近全量微调的效果。
|
||||
|
||||
<LoRADemo />
|
||||
|
||||
::: tip LoRA 的核心思想
|
||||
原始模型的权重矩阵 W 是一个巨大的矩阵(如 4096×4096)。LoRA 不直接修改 W,而是在旁边加一个"旁路":W' = W + BA,其中 B 和 A 是两个小矩阵(如 4096×8 和 8×4096)。训练时只更新 B 和 A,原始 W 保持不变。
|
||||
- **秩(Rank)**:r 值越大,表达能力越强,但参数量也越多。通常 r=8~64 就够用
|
||||
- **合并部署**:训练完成后,可以把 BA 合并回 W,推理时零额外开销
|
||||
:::
|
||||
|
||||
| 微调方式 | 可训练参数 | 显存需求 | 训练速度 | 效果 |
|
||||
|---------|-----------|---------|---------|------|
|
||||
| 全量微调 | 100% | 极高 | 慢 | 最好 |
|
||||
| LoRA | 0.1%~1% | 低 | 快 | 接近全量 |
|
||||
| QLoRA | 0.1%~1% | 更低 | 中等 | 略低于 LoRA |
|
||||
| Prompt Tuning | < 0.01% | 极低 | 很快 | 有限 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 模型量化:让大模型"瘦身"
|
||||
|
||||
一个 70B 参数的模型,如果用 FP32(32 位浮点数)存储,需要 280GB 显存——没有几块顶级 GPU 根本跑不起来。量化(Quantization)技术通过降低数值精度来压缩模型体积,让大模型能在消费级硬件上运行。
|
||||
|
||||
<ModelQuantizationDemo />
|
||||
|
||||
::: tip 量化的核心权衡
|
||||
量化本质上是**精度换空间**的权衡。FP32 → FP16 几乎无损,INT8 有轻微损失,INT4 会有明显但通常可接受的质量下降。关键是找到你场景下的最佳平衡点。
|
||||
- **FP16(半精度)**:体积减半,质量几乎无损,是训练和推理的默认选择
|
||||
- **INT8(8 位整数)**:体积再减半,质量损失很小,适合大多数推理场景
|
||||
- **INT4(4 位整数)**:体积仅为 FP32 的 1/8,质量有一定损失,适合资源受限场景
|
||||
:::
|
||||
|
||||
| 精度 | 每参数字节 | 70B 模型体积 | 质量损失 | 适用场景 |
|
||||
|------|-----------|-------------|---------|---------|
|
||||
| FP32 | 4 字节 | ~280 GB | 无 | 训练基准 |
|
||||
| FP16 | 2 字节 | ~140 GB | 几乎无 | 标准训练和推理 |
|
||||
| INT8 | 1 字节 | ~70 GB | 很小 | 生产推理 |
|
||||
| INT4 | 0.5 字节 | ~35 GB | 可接受 | 边缘设备、本地部署 |
|
||||
|
||||
---
|
||||
|
||||
## 5. 模型部署:从实验室到生产环境
|
||||
|
||||
模型训练好了,量化压缩了,最后一步是把它部署成可供调用的服务。模型部署不只是"把模型跑起来",还涉及并发处理、负载均衡、成本控制等工程问题。
|
||||
|
||||
<ModelServingDemo />
|
||||
|
||||
::: tip 三种主流部署方案
|
||||
1. **API 服务商**:直接使用 OpenAI、Anthropic 等厂商的 API。零运维,按 token 付费,适合快速验证和中小规模使用。
|
||||
2. **自托管推理服务**:用 vLLM、TGI 等框架在自己的 GPU 服务器上部署。成本可控,数据不出域,适合有隐私要求或大规模调用的场景。
|
||||
3. **Serverless 推理**:使用 AWS SageMaker、Replicate 等平台,按请求付费,自动扩缩容。适合流量波动大的场景。
|
||||
:::
|
||||
|
||||
| 部署方案 | 成本模型 | 延迟 | 运维复杂度 | 适用场景 |
|
||||
|---------|---------|------|-----------|---------|
|
||||
| API 服务商 | 按 token 计费 | 中等 | 零 | 快速原型、中小规模 |
|
||||
| vLLM 自部署 | GPU 租赁费用 | 低 | 高 | 大规模、隐私敏感 |
|
||||
| Serverless | 按请求计费 | 冷启动较高 | 低 | 流量波动大 |
|
||||
| 边缘部署 | 硬件一次性投入 | 极低 | 中 | 离线场景、IoT |
|
||||
|
||||
---
|
||||
|
||||
## 总结
|
||||
|
||||
模型微调与部署是让大模型从"通用工具"变成"专业助手"的关键环节。从数据准备到模型上线,每一步都需要工程化的思维和实践。
|
||||
|
||||
回顾本章的关键要点:
|
||||
|
||||
1. **微调是岗前培训**:让通用模型学会特定领域的知识和行为模式
|
||||
2. **数据质量决定上限**:100 条高质量数据胜过 10000 条低质量数据
|
||||
3. **LoRA 是效率之王**:用不到 1% 的参数实现接近全量微调的效果
|
||||
4. **量化是部署利器**:INT4 量化让 70B 模型在单卡上运行成为可能
|
||||
5. **部署方案因地制宜**:快速验证用 API,大规模用自部署,波动大用 Serverless
|
||||
|
||||
## 延伸阅读
|
||||
|
||||
- [Hugging Face PEFT 文档](https://huggingface.co/docs/peft) - 参数高效微调库官方文档
|
||||
- [vLLM 文档](https://docs.vllm.ai/) - 高性能 LLM 推理引擎
|
||||
- [Unsloth](https://github.com/unslothai/unsloth) - 2x 加速的 LoRA 微调框架
|
||||
- [GGUF 格式说明](https://github.com/ggerganov/ggml/blob/master/docs/gguf.md) - llama.cpp 使用的量化模型格式
|
||||
- [OpenAI Fine-tuning Guide](https://platform.openai.com/docs/guides/fine-tuning) - OpenAI 官方微调指南
|
||||
|
||||
@@ -1,3 +1,161 @@
|
||||
# RAG 架构
|
||||
# RAG:检索增强生成
|
||||
|
||||
> 待实现
|
||||
::: tip 前言
|
||||
**为什么 ChatGPT 有时候会"一本正经地胡说八道"?** 大语言模型的知识来自训练数据,但训练数据有截止日期,也不包含你公司的内部文档。RAG(Retrieval-Augmented Generation,检索增强生成)就是解决这个问题的核心技术——让 AI 在回答之前,先去"查资料"。
|
||||
:::
|
||||
|
||||
**这篇文章会带你学什么?**
|
||||
|
||||
学完这章后,你将获得:
|
||||
|
||||
- **核心概念理解**:明白 RAG 是什么、为什么需要它,以及它如何解决大模型的"幻觉"问题
|
||||
- **完整流程认知**:掌握从文档加载、分块、向量化到检索、生成的端到端流程
|
||||
- **技术选型能力**:了解不同分块策略、检索方法的优劣,能根据场景做出选择
|
||||
- **架构演进视角**:理解 RAG 从 Naive 到 Advanced 再到 Modular 的演进路线
|
||||
- **实践决策能力**:知道什么时候该用 RAG、什么时候该用微调
|
||||
|
||||
| 章节 | 内容 | 核心概念 |
|
||||
|-----|------|---------|
|
||||
| **第 1 章** | RAG 基础流程 | 索引、检索、生成三阶段 |
|
||||
| **第 2 章** | 文本分块策略 | 固定分块、语义分块、递归分块 |
|
||||
| **第 3 章** | 检索技术 | 向量检索、关键词检索、混合检索 |
|
||||
| **第 4 章** | 架构演进 | Naive RAG → Advanced RAG → Modular RAG |
|
||||
| **第 5 章** | RAG vs 微调 | 两种方案的适用场景对比 |
|
||||
|
||||
---
|
||||
|
||||
## 0. 全景图:为什么大模型需要"查资料"?
|
||||
|
||||
想象你是一个博学的教授,读过无数书籍。但如果有人问你"昨天公司的销售数据是多少",你肯定答不上来——因为这些信息不在你读过的书里。
|
||||
|
||||
大语言模型面临的就是同样的困境:
|
||||
|
||||
- **知识有截止日期**:GPT-4 的训练数据截止到某个时间点,之后发生的事它不知道
|
||||
- **缺乏私有知识**:你公司的内部文档、产品手册、客户数据,模型从未见过
|
||||
- **容易产生幻觉**:当模型不确定答案时,它倾向于"编造"一个看起来合理的回答
|
||||
|
||||
::: tip RAG 的核心思想
|
||||
RAG 的解决方案非常直觉:**在让模型回答之前,先帮它找到相关的参考资料**。就像开卷考试——你不需要记住所有知识,只需要知道去哪里找、怎么找。
|
||||
|
||||
RAG = 检索(Retrieval)+ 增强(Augmented)+ 生成(Generation)
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## 1. RAG 基础流程:索引、检索、生成
|
||||
|
||||
RAG 的工作流程可以分为两个阶段:**离线索引**和**在线查询**。
|
||||
|
||||
离线阶段就像图书馆的编目工作——把所有书籍分类、编号、上架,方便日后查找。在线阶段则是读者来图书馆查资料的过程——根据问题找到相关书籍,然后综合信息给出回答。
|
||||
|
||||
<RAGPipelineDemo />
|
||||
|
||||
::: tip 三个核心阶段
|
||||
1. **索引阶段(Indexing)**:将原始文档加载、清洗、分块,然后通过嵌入模型转化为向量,存入向量数据库。这是一次性的准备工作。
|
||||
2. **检索阶段(Retrieval)**:用户提问时,将问题也转化为向量,在向量数据库中搜索最相似的文档片段。
|
||||
3. **生成阶段(Generation)**:将检索到的文档片段和用户问题一起拼接为 Prompt,交给大模型生成最终回答。
|
||||
:::
|
||||
|
||||
| 阶段 | 输入 | 输出 | 关键技术 |
|
||||
|------|------|------|---------|
|
||||
| 索引 | 原始文档 | 向量数据库 | 文本分块、嵌入模型 |
|
||||
| 检索 | 用户问题 | Top-K 文档片段 | 向量相似度、重排序 |
|
||||
| 生成 | 问题 + 上下文 | 最终回答 | Prompt 工程、LLM |
|
||||
|
||||
---
|
||||
|
||||
## 2. 文本分块:把大象装进冰箱
|
||||
|
||||
文本分块是 RAG 中最容易被忽视、却对效果影响最大的环节。为什么需要分块?因为大模型的上下文窗口有限,我们不可能把整本书塞进去。更重要的是,**分块的质量直接决定了检索的质量**。
|
||||
|
||||
想象你在图书馆找一本书的某个知识点。如果整本书是一个"块",检索到了也没用——你还是得翻遍全书。但如果按章节甚至段落分块,就能精准定位到你需要的内容。
|
||||
|
||||
<ChunkingStrategyDemo />
|
||||
|
||||
::: tip 分块策略的选择
|
||||
- **固定大小分块**:按字符数或 token 数切分,简单粗暴但可能切断语义
|
||||
- **递归分块**:先按段落分,段落太长再按句子分,保持语义完整性
|
||||
- **语义分块**:用嵌入模型判断语义边界,相似度突变处切分
|
||||
- **文档结构分块**:利用 Markdown 标题、HTML 标签等结构信息分块
|
||||
|
||||
没有"最好"的分块策略,只有最适合你数据的策略。一般建议从递归分块开始,chunk 大小 200-500 tokens,overlap 10-20%。
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## 3. 检索技术:如何找到最相关的内容?
|
||||
|
||||
分块完成后,下一个关键问题是:**用户提了一个问题,怎么从成千上万个文档片段中找到最相关的那几个?**
|
||||
|
||||
这就像在一个巨大的图书馆里找书。你可以按书名关键词搜索(关键词检索),也可以描述你想要的内容让图书管理员帮你找(语义检索),最好的方式是两者结合(混合检索)。
|
||||
|
||||
<RetrievalDemo />
|
||||
|
||||
| 检索方式 | 原理 | 优势 | 劣势 |
|
||||
|---------|------|------|------|
|
||||
| 关键词检索(BM25) | 基于词频和逆文档频率 | 精确匹配、速度快 | 无法理解语义、同义词失效 |
|
||||
| 向量检索 | 基于嵌入向量的余弦相似度 | 理解语义、支持模糊匹配 | 对专有名词不敏感 |
|
||||
| 混合检索 | 融合关键词和向量检索结果 | 兼顾精确和语义 | 需要调权重、复杂度高 |
|
||||
|
||||
::: tip 重排序(Reranking)
|
||||
检索到候选文档后,通常还需要一步"重排序"。初始检索追求召回率(尽量不遗漏),重排序追求精确率(把最相关的排到最前面)。常用的重排序模型有 Cohere Rerank、BGE Reranker 等,它们使用交叉编码器对 query-document 对进行精细打分。
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## 4. 架构演进:从简单到智能
|
||||
|
||||
RAG 技术在短短两年内经历了三代演进,每一代都在解决上一代的痛点。
|
||||
|
||||
<RAGArchitectureDemo />
|
||||
|
||||
::: tip 三代 RAG 架构对比
|
||||
- **Naive RAG(2023)**:最基础的"索引→检索→生成"流程,实现简单但效果有限。问题包括:检索质量不稳定、无法处理复杂查询、容易引入噪音上下文。
|
||||
- **Advanced RAG(2024)**:在 Naive RAG 基础上增加了查询改写、混合检索、重排序、上下文压缩等优化环节,显著提升了检索精度和生成质量。
|
||||
- **Modular RAG(2025)**:将 RAG 拆解为可插拔的模块,支持路由判断、自适应检索、自我反思等高级能力。可根据查询类型动态选择最优处理流程。
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## 5. RAG vs 微调:该选哪个?
|
||||
|
||||
当你想让大模型掌握特定领域的知识时,通常有两条路:RAG 和微调(Fine-tuning)。它们不是互斥的,而是互补的。
|
||||
|
||||
打个比方:**微调像是让学生上培训班**,把知识内化到大脑里;**RAG 像是给学生发参考书**,考试时可以翻阅。两种方式各有优劣,关键看你的具体需求。
|
||||
|
||||
<RAGvsFineTuningDemo />
|
||||
|
||||
| 维度 | RAG | 微调 |
|
||||
|------|-----|------|
|
||||
| 知识更新 | 实时更新,改文档即可 | 需要重新训练 |
|
||||
| 成本 | 低(无需 GPU 训练) | 高(需要训练资源) |
|
||||
| 可解释性 | 高(可追溯来源) | 低(知识内化在权重中) |
|
||||
| 适用场景 | 知识库问答、文档检索 | 风格迁移、特定任务优化 |
|
||||
| 幻觉控制 | 较好(有参考依据) | 一般(仍可能幻觉) |
|
||||
|
||||
::: tip 实践建议
|
||||
大多数场景下,**先试 RAG**。RAG 的优势在于:不需要训练、知识可实时更新、回答可追溯来源。只有当你需要改变模型的"行为模式"(比如输出格式、语言风格、推理方式)时,才考虑微调。最强的方案往往是 **RAG + 微调** 的组合。
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## 总结
|
||||
|
||||
RAG 是当前让大模型"落地"最实用的技术之一。它的核心价值在于:让模型的回答有据可查、知识可实时更新、幻觉可有效控制。
|
||||
|
||||
回顾本章的关键要点:
|
||||
|
||||
1. **RAG 解决的核心问题**:大模型知识过时、缺乏私有数据、容易幻觉
|
||||
2. **三阶段流程**:索引(离线准备)→ 检索(在线查找)→ 生成(综合回答)
|
||||
3. **分块是基础**:分块质量直接决定检索质量,选择合适的分块策略至关重要
|
||||
4. **检索是关键**:混合检索 + 重排序是目前效果最好的组合
|
||||
5. **架构在演进**:从 Naive RAG 到 Modular RAG,系统越来越智能和灵活
|
||||
6. **RAG 和微调互补**:大多数场景先试 RAG,需要改变模型行为时再考虑微调
|
||||
|
||||
## 延伸阅读
|
||||
|
||||
- [LangChain RAG 教程](https://python.langchain.com/docs/tutorials/rag/) - 最流行的 RAG 框架实战指南
|
||||
- [LlamaIndex 文档](https://docs.llamaindex.ai/) - 专注于 RAG 的框架,提供丰富的数据连接器
|
||||
- [RAG Survey 论文](https://arxiv.org/abs/2312.10997) - 全面的 RAG 技术综述
|
||||
- [Chunking Strategies](https://www.pinecone.io/learn/chunking-strategies/) - Pinecone 的分块策略详解
|
||||
- [向量数据库对比](https://superlinked.com/vector-db-comparison) - 主流向量数据库的功能对比
|
||||
|
||||
Reference in New Issue
Block a user