AI 专题学习手册
AI 专题学习手册
面向 Java 后端开发的 AI 应用开发学习指南——从基础概念到工程落地,结合 MindForge 考试指导 AI 平台项目代码,构建完整的 AI 工程能力体系。
前言:为什么学 AI 应用开发
2024-2026 年,AI 领域发生了根本性变化:大模型能力从"能用"到"好用",开发门槛从"需要 PhD + GPU 集群"降到"会调 API 就能搭应用"。对后端开发来说,这不是可选项——AI 应用开发正在成为和数据库、缓存、消息队列一样的基础技能。
AI 应用开发的能力分层:
| 层次 | 描述 | 能力定位 |
|---|---|---|
| 用过 AI 工具 | “我用 ChatGPT/Claude 写代码” | 基础操作 |
| 系统化使用 AI | “AI 辅助全流程:需求→设计→编码→审查” | 有方法论 |
| 基于大模型开发应用 | “我用 Agent + RAG 搭建了 AI 应用” | 核心目标层 |
| 微调/训练模型 | “用 LoRA 微调了领域模型” | 算法工程师方向 |
本文档的目标是从第二层跨越到第三层——不是泛泛了解概念,而是能讲清楚代码实现、设计决策和工程权衡。
阅读建议:
- 如果你刚接触 AI 开发:从第一章顺序读到第七章,每章约 20-30 分钟
- 如果你已有基础:跳读第四章(RAG)和第五章(Agent),重点看代码走读部分
第一章:AI 背景与基础概念
1.1 AI 是什么:从人工智能到大语言模型
人工智能(AI, Artificial Intelligence) 是一个宽泛的学科领域,目标是让机器表现出类似人类的智能行为——理解语言、识别图像、做出决策、解决问题。它不是单一技术,而是一组技术的统称。
理解 AI 的最佳方式是看它的层级包含关系:
人工智能(AI) ← 最大的范畴:一切让机器"看起来智能"的技术
└── 机器学习(ML) ← AI 的子集:不靠人写规则,靠从数据中学习规律
└── 神经网络 ← ML 的子集:模拟人脑神经元连接的计算模型
└── 深度学习 ← 神经网络的子集:层数多、参数多、数据多
├── CNN ← 图像领域:卷积神经网络
├── RNN/LSTM ← 序列领域:循环神经网络
├── Transformer ← 2017年诞生,当前主流架构
│ └── GPT/Claude/DeepSeek/GLM... ← 大语言模型
└── Diffusion ← 图像生成:Stable Diffusion/Midjourney
每一层的核心区别:
| 层级 | 代表技术 | 输入 → 输出 | 人需要做什么 | 典型应用 |
|---|---|---|---|---|
| AI(规则系统) | 专家系统 | 事实 → 推理结论 | 人写全部规则 | 早期医疗诊断 |
| 机器学习 | SVM/XGBoost | 特征向量 → 分类/回归 | 人设计特征 | 垃圾邮件过滤、信用评分 |
| 深度学习 | CNN/Transformer | 原始数据 → 结果 | 人设计网络结构 | 人脸识别、机器翻译 |
| 大语言模型 | GPT/Claude | 自然语言 → 自然语言 | 人描述需求 | 代码生成、智能问答、Agent |
关键跃迁:从 AI 到大语言模型,每一步都在减少"人的参与"——人写规则 → 人设计特征 → 人设计网络 → 人描述需求。大语言模型是当前 AI 领域中与应用开发关系最密切的子集,也是本书的核心关注对象。
1.2 大模型的构成:组件与协作原理
理解了"大模型在 AI 家族中的位置"之后,下一步是搞清楚它由哪些部件组成、各部件如何协作。可以把一个大语言模型比作一个"工厂":
┌────────────────────────────────────────────────────┐
│ 大语言模型"工厂" │
│ │
│ ①训练数据 ②Tokenizer ③Transformer │
│ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │
│ │ 互联网文本 │ ──→ │ 文本→ID │ ──→ │ 多层神经网络 │ │
│ │ 书籍/论文 │ │ (BPE分词) │ │ (注意力机制) │ │
│ │ 代码仓库 │ └──────────┘ │ 逐层提取特征 │ │
│ │ ... │ ↓ │ 预测下一个词 │ │
│ └──────────┘ ④词表映射 └──────┬───────┘ │
│ (ID↔向量) │ │
│ ↓ │
│ ⑥推理引擎 ◄──────────────────── ⑤模型参数 │
│ ┌──────────┐ ┌──────────┐ │
│ │ 加载参数 │ │ 权重矩阵 │ │
│ │ 运行计算 │ │ ~几百亿个 │ │
│ │ 输出Token │ │ 浮点数 │ │
│ └──────────┘ └──────────┘ │
└────────────────────────────────────────────────────┘
下面逐一拆解六个组件:
① 训练数据 —— 模型的"教科书"
大语言模型不是"学会推理"的,而是从海量文本中"统计出规律"的。训练数据的规模和多样性直接决定了模型的能力上限。
- GPT-4 的训练数据约 13 万亿 token(相当于数千万本书)
- DeepSeek-V3 约 14.8 万亿 token
- 来源:互联网公开文本、书籍、论文、代码仓库、维基百科等
类比:训练数据就像工厂的"原材料"。原材料不够或质量差,工厂设备再先进也产不出好产品。
② Tokenizer(分词器)—— 把文本切成"最小处理单元"
模型不是逐字读文本的,而是先把文本切成 Token。Token 是模型处理的最小粒度。
输入文本:"大语言模型如何工作?"
→ Tokenizer 切分 → ["大", "语言", "模型", "如何", "工作", "?"]
→ 映射为 ID → [12847, 9315, 5632, 2910, 1783, 62]
- 1 个中文约 1-2 个 Token,1 个英文单词约 1-2 个 Token
- Tokenizer 使用 BPE(Byte Pair Encoding)算法,自动发现高频词根
- 同一个 Tokenizer 必须用于训练和推理——换 Tokenizer 等于换"语言"
类比:Tokenizer 是工厂的"分拣机"——把原材料切分成统一规格的零件,后续流水线才能处理。
③ Transformer —— 模型的核心"计算流水线"
Transformer 是 2017 年 Google 提出的神经网络架构,当前所有主流大语言模型都基于它或其变体。它的核心创新是自注意力机制(Self-Attention):
传统 RNN 处理序列:
词1 → 词2 → 词3 → ... ← 必须按顺序,不能并行,长文本会"遗忘"开头
Transformer 自注意力:
输入所有词 → 每个词同时看所有其他词 → 计算关系权重 → 输出
词1 ←→ 词2
↕ ↕ ← 所有词两两计算关联度,完全并行
词3 ←→ 词4
自注意力的直觉理解:
- 输入:“她把苹果放进冰箱,然后坐下来吃了一个___”
- 要预测横线上的词,模型需要关注前面的"吃"和"苹果"(不是"冰箱")
- 自注意力机制自动为每对词计算"关联分数"——"苹果"和"吃"的分数高,"冰箱"和"吃"的分数低
Transformer 由多层(通常几十到上百层)堆叠而成,每层逐步提取更抽象的特征——底层识别词汇和语法,中层理解语义和逻辑,高层进行推理和生成。
类比:Transformer 是工厂的"核心流水线"——原材料经过几十道工序逐级加工,最终产出成品。
④ 词表(Vocabulary)—— 把数字还原为意义
词表是一个巨大的映射表,将 Token ID 映射为向量(一串浮点数):
- Tokenizer 将文本转为 ID
- 词表将 ID 转为向量(Embedding),例如 ID=12847 →
[0.023, -0.154, 0.891, ...](几千维) - 这个向量承载了语义信息——语义相近的词,向量也接近
词表大小通常在 5 万到 20 万之间(即模型认识的"词"的数量)。Embedding 向量维度通常在 1024 到 8192 之间(每个词用多少维数字来表示其语义)。
类比:词表是工厂的"原材料编码手册"——每个零件编号对应一个规格参数表。
⑤ 模型参数 —— 模型学到的"知识"
参数是模型在训练过程中学习到的数以亿计的浮点数(权重)。它们存在于 Transformer 的每一层、每一个注意力头和每一个前馈网络中。
- DeepSeek-V3:6710 亿总参数,每次推理激活约 370 亿(MoE 架构)
- Qwen2.5-7B:70 亿参数,全激活
- 参数量大致决定了模型的"知识容量",但不是线性关系——架构、数据质量同样重要
参数文件在磁盘上通常以数十到数百 GB 的形式存储(如 .safetensors 或 .gguf),推理时加载到显存或内存中。
类比:参数是工厂的"工艺配方"——同样的流水线(架构),不同的配方(训练出来的参数),产出的产品完全不同。
⑥ 推理引擎 —— 运行模型的"发动机"
推理引擎是加载模型参数并实际执行计算的软件。常见的推理引擎:
| 引擎 | 特点 | 适合场景 |
|---|---|---|
| Ollama | 一键下载量化模型,CPU 友好 | 本地开发、测试 |
| vLLM | PagedAttention 显存优化,吞吐提升 10-20 倍 | 生产部署 |
| llama.cpp | C++ 实现,纯 CPU 可运行 | 嵌入式、边缘设备 |
| 云 API | 厂商托管,无需自建 | 快速上线、个人项目 |
类比:推理引擎就像汽车的发动机——参数是图纸,推理引擎是引擎本体;同一个引擎可以搭配不同的参数(模型),同一个参数也可以在不同的引擎上运行。
六个组件如何协作:一次完整的问答流程
你输入:"什么是 AQS?"
↓
① Tokenizer 将文本切分为 Token → [688, 312, 9766, 5342, 62]
↓
② 词表将每个 Token ID 映射为向量 → 5 个向量,每个 1024 维
↓
③ Transformer(堆叠数十层)逐层计算:
第 1-10 层:理解词义和语法结构
第 11-30 层:捕捉语义关系和逻辑推理
第 31-N 层:规划输出内容和顺序
↓
④ 输出层产生下一个 Token 的概率分布
例如:Token "AQS" 后面最可能是 "是"(概率 0.73)、"全称"(概率 0.19)...
↓
⑤ 选择概率最高的 Token → 输出 "是" → 将 "是" 添加到输入末尾 → 重复步骤 ③-⑤
逐 Token 生成,直到输出结束标记(EOS)
↓
⑥ 最终输出:"AQS 是 AbstractQueuedSynchronizer 的缩写,是 Java 并发包中..."
关键认知:模型不是一次性输出整段回答,而是逐 Token 预测下一个最可能是什么——这个过程重复成千上万次,直到输出终止标记。
1.3 从规则到大模型:AI 的四次范式转移
理解 AI 的发展脉络,有助于把握当前技术所处的位置和演进方向。
第一代:符号 AI(1950s-1980s)
代表:专家系统
思路:人写规则 → 机器执行
问题:规则爆炸,无法覆盖开放场景
例子:IF 发烧 AND 咳嗽 THEN 诊断=感冒
第二代:统计机器学习(1990s-2010s)
代表:SVM、随机森林、XGBoost
思路:人设计特征 → 机器学权重
问题:特征工程依赖专家,泛化能力有限
例子:垃圾邮件分类器(手工设计"免费""中奖"等特征)
第三代:深度学习(2012-2018)
代表:CNN、RNN、Transformer
思路:人设计网络结构 → 机器学特征+权重
突破:不再需要手工特征,端到端学习
例子:ResNet 图像识别、BERT 文本理解
第四代:大语言模型 / 基础模型(2018-至今)
代表:GPT-4、Claude、DeepSeek、GLM
思路:海量数据预训练 → 自然语言交互 → 涌现推理能力
突破:单一模型处理数百种任务,不需要为每个任务训练专用模型
关键转变:从"编程解决问题"到"对话解决问题"
AI 的发展本质上就是不断减少"人工"、增加"智能"的过程——从人写规则到人设计特征,再到人设计网络结构,现在是人描述需求。
1.4 大语言模型的训练与推理
上一节拆解了大模型的六个静态组件。本节从生命周期角度理解模型如何诞生和使用——一个模型的完整生命周期分为三个阶段:
第一阶段:预训练(Pre-training)——“学会语言”
在海量文本上做"完形填空":给前半句预测后半句。训练过程遍历数万亿 token 的文本,用数千张 GPU 运行数周到数月。这个阶段模型学到了语言模式、世界知识、推理能力。
第二阶段:对齐(Alignment)——“学会好好说话”
预训练后的模型"什么都懂但不会好好说话"——它可能拒绝回答、输出有害内容、格式混乱。对齐阶段用人类偏好数据教模型:什么是有用的回答、什么是安全的回答、什么该拒绝。主流对齐方法 DPO(Direct Preference Optimization)直接用好/坏回答对优化,替代了传统复杂的 RLHF(人类反馈强化学习)。
第三阶段:推理(Inference)——“回答问题”
即每一次调用模型的过程。关键认知:每次推理是独立的——模型不记忆和你的对话,对话记忆是应用层管理的(把历史消息重新发回去)。这也是 Token 消耗的核心——对话越长,每次推理越贵。
预训练决定了模型的 “知识天花板”,对齐决定了模型的 “表达方式”,推理则是应用开发者和模型交互的唯一接口。大部分 AI 应用开发工作集中在推理阶段——如何构造 Prompt、如何管理上下文、如何解析输出。
1.5 核心概念速查
以下为 AI 应用开发必须掌握的核心概念,按从基础到进阶排列:
| 概念 | 一句话 | 工程意义 |
|---|---|---|
| LLM | 在海量文本上预训练的大规模神经网络,通过预测下一个 token 来理解和生成文本 | AI 应用的核心引擎。本质是概率模型,不可 100% 信赖,所有工程实践围绕"如何用好它、控制它、兜底它"展开 |
| Token | AI 处理文本的最小粒度,1 中文≈1-2 token,按 token 计费 | 决定了 API 调用的成本和上下文管理策略。DeepSeek 约 1 元/百万 token,GPT-5 约 70 元/百万 token |
| 上下文窗口 | 模型一次能"看到"的最大文本量 | 决定了信息加载策略——不能无脑塞全量文档,需要分层管理:常驻上下文 + 按需加载 + 摘要压缩 |
| Embedding | 把文本映射成一串数字(向量),语义相近的文本向量距离近 | RAG 的根基。不同 Embedding 模型产生的向量在不同语义空间中,跨模型不可混用——这是 MindForge 平台统一 Embedding 的根本原因 |
| 幻觉 | AI 自信地编造不存在的事实、API、引用 | AI 应用的第一大风险。应对策略:RAG 绑定来源、Context7 实时验证文档、结构化输出约束格式、关键逻辑人工审核 |
| 思维链(CoT) | 让 AI 一步步推理而非直接给答案,复杂任务准确率大幅提升 | 复杂推理任务的标配。DeepSeek-R1、GPT-o1 内置推理,普通模型可在 Prompt 中添加"请逐步分析"手动触发 |
| Agent | AI 不只是回答,而是自主规划→调工具→观察结果→调整→完成任务 | 从"聊天机器人"到"能干活的系统"的关键跃升。核心三要素:规划能力 + 工具调用 + 反馈循环 |
| RAG | 先检索相关文档,再基于文档生成回答 | 解决 LLM 知识截止日期和幻觉问题的首选方案。核心链路:文档解析→切分→向量化→检索→增强 Prompt→生成 |
| MCP | Model Context Protocol,AI 与外部工具的统一连接协议 | 让 AI 工具从"N×M 次一对一集成"变成"N+M 次统一对接"。初期可用 Function Calling 快速落地,规模上来再改造 |
| Function Calling | Agent 调用工具的底层机制——模型输出结构化 JSON 指定调哪个函数+传什么参数 | Agent 的"手"——没有它 AI 只能聊天。各厂商格式不同(OpenAI/Anthropic),MCP 是解决这一碎片化的开放标准 |
进阶概念(了解即可,拓展知识面):
| 概念 | 全称/含义 | 一句话 | 属于 |
|---|---|---|---|
| MoE | Mixture of Experts | 总参数大但每次只激活一小部分,DeepSeek 的标志性架构 | 模型架构 |
| LoRA | Low-Rank Adaptation | 不改原模型参数,在旁路训练极小参数包。全量微调=重写整本书,LoRA=贴便签纸 | 模型微调 |
| QLoRA | Quantized LoRA | LoRA 的省钱版——先把模型压到 4-bit 再贴便签纸,7B 模型只需 4GB 显存 | 模型微调 |
| DPO | Direct Preference Optimization | 直接用好/坏回答对优化模型,替代复杂的 RLHF。Llama3/Qwen2.5 的对齐方法 | 模型对齐 |
| vLLM | — | 开源推理引擎,PagedAttention 显存优化 + Continuous Batching 吞吐提升 10-20 倍 | 模型部署 |
| 量化 | Quantization | FP16→INT4,体积缩 4 倍、速度提 2-4 倍。Ollama 默认 Q4_K_M | 模型部署 |
| 语义缓存 | Semantic Cache | 不是缓存 key-value,是缓存"语义相似的问题"——相似度>0.95 直接返回,不走 LLM | 成本优化 |
| 结构化输出 | JSON Schema 约束 | LLM 按预定义 Schema 返回 JSON,确保下游代码可解析 | 输出控制 |
| BYOK | Bring Your Own Key | 平台不提供模型额度,用户自带 API Key | 架构模式 |
1.6 为什么 2024-2026 是 AI 应用开发的分水岭
三个趋势叠加:
- 模型能力突破临界点:GPT-4(2023.3)→ Claude Opus 4(2025)→ DeepSeek-V3/R1(2025),模型推理能力和代码能力达到了"可以作为工程组件信赖"的水平
- 成本断崖式下降:DeepSeek-V3 把 API 价格打到 GPT-4 的 1/70,个人开发者每月几十块就能搭建 AI 应用
- 工程生态成熟:LangChain/Spring AI/LlamaIndex 等框架把 LLM 调用从"手写 HTTP 请求"抽象为"声明式编排",Agent 和 RAG 的开发效率提升 10 倍
这意味着:AI 应用开发不再是大厂的专利,个人开发者也能做出有价值的产品。
第二章:AI 模型与工具生态
2.1 主流模型对比与选型
国外模型
| 模型 | 核心优势 | 短板 | 适合场景 |
|---|---|---|---|
| Claude Opus/Sonnet | Agent 能力最强,多文件理解+安全设计 | 国内访问不便 | 大型重构、项目级 Agent |
| GPT-5 / o1 | 推理深度最强 | 贵(70 元/百万 token)、国内访问不便 | 高难度算法、架构评审 |
| Gemini 2.5 | 多模态最强(图+视频+代码) | 中文弱 | 多模态场景、Google 生态 |
| Llama 4(开源) | 可本地部署,数据不出域 | 编码能力约闭源 70% | 数据合规、二次训练、金融场景 |
国内模型
| 模型 | 核心优势 | 适合场景 |
|---|---|---|
| DeepSeek V4-Pro / R1 | 性价比之王(约 GPT 1/70 价格),中文编程最优 | 日常编码首选 |
| GLM-5.1(智谱) | 国产合规首选,政务/金融信创认证 | 信创合规项目 |
| Qwen3 / CodeQwen | 阿里云生态集成好 | 阿里云技术栈 |
| Kimi K2 | 200 万字上下文,长文档分析最强 | 需求评审、代码库理解 |
选型决策框架
日常编码 / SQL 优化 → DeepSeek V4-Pro(性价比+中文编程)
大型重构 / 多文件修改 → Claude Opus/Sonnet(Agent 能力最强)
复杂算法推理 → GPT o1 / DeepSeek R1(思维链深度)
长文档分析 → Kimi K2(200 万字上下文)
信创合规 → GLM-5.1 + 本地部署(国产化认证)
推荐组合:DeepSeek(日常)+ Claude(复杂)+ Kimi(长文档)
常见误区:
- 最强模型 ≠ 最适合(GPT-5 贵且延迟高,CRUD 用它浪费)
- 开源模型 ≠ 免费(GPU 月租 5000+)
- 没有一个模型在所有维度最好——组合策略是最优解
2.2 AI 编程助手
| 工具 | 定位 | 一句话评价 |
|---|---|---|
| Claude Code | Agent 级 CLI | 项目级理解+多文件编辑+MCP 扩展,Agent 能力最强 |
| GitHub Copilot | IDE 行级补全 | "猜下一行"最准,行级补全王者,任务规划弱 |
| Cursor | AI-native IDE | IDE 深度集成 Agent,体验流畅 |
| Cline | VS Code 插件 | 开源 Agent,多模型支持,Token 消耗大 |
| Aider | CLI 开源 | 自动 git 提交,不如 Claude Code 灵活 |
选择原则:日常编码 Claude Code,快速补全 Copilot,前端调试 Cursor。没有银弹——根据任务切换工具。
大模型的"脚手架":MCP、Skills、Hooks
如果把大模型比作一台发动机,那么它要真正"驱动一辆车",还需要三样东西:
- MCP:连接外部世界的"管道"——让 AI 能访问数据库、调用 API、操作文件
- Skills:标准化的"操作手册"——把常见任务封装成可复用的工作流
- Hooks:自动化的"安全护栏"——在关键节点自动检查和拦截
三者共同构成大模型的工程化脚手架。它们不是模型的一部分,但没有它们,
模型只能停留在"聊天界面"里,无法融入真实的软件工程流程。
2.3 MCP — 连接 AI 与工具的通用协议
概念:MCP 是什么
MCP(Model Context Protocol)是 Anthropic 于 2024 年 11 月发布的开放标准协议,
目标是成为"AI 应用的 USB 协议"——正如 USB 让任何外设都能接入任何电脑,
MCP 让任何工具都能被任何 AI 应用调用。
没有 MCP 时:每接入一个新工具(数据库、文件系统、搜索引擎、API),
开发者都要为每个 AI 应用单独写适配代码。N 个 AI 应用 × M 个工具 = N×M 次集成。
而且每个 AI 厂商的 Function Calling 格式不同(OpenAI 用 JSON Schema,
Anthropic 用 XML 嵌套),换模型等于重写工具层。
有 MCP 后:工具只需实现一次 MCP Server,所有支持 MCP 的 AI 应用自动可用。
N 个 AI 应用 + M 个工具 = N+M 次对接。新增工具不需要改 AI 应用代码,
启动新的 MCP Server 即可。
架构与原理
MCP 采用经典的 Client-Server 架构,基于 JSON-RPC 2.0 协议通信:
┌─────────────┐ ┌──────────────────┐
│ MCP Host │ ── JSON-RPC ──► │ MCP Server │
│ (Claude/ │ ◄── 双向通信 ── │ │
│ Cursor/ │ │ 实现三个原语: │
│ 自研 App) │ tools/list │ • Tools(工具) │
│ │ tools/call │ • Resources(资源)│
│ │ resources/read │ • Prompts(模板) │
│ │ prompts/get │ │
└─────────────┘ └──────────────────┘
三个核心原语(MCP 暴露给 AI 的三类能力):
| 原语 | 用途 | 类比 | 例子 |
|---|---|---|---|
| Tools | 让 AI 执行操作 | 函数调用 | 查数据库、发邮件、创建 Issue |
| Resources | 让 AI 读取数据 | GET 请求 | 读文件内容、查配置、获取日志 |
| Prompts | 预定义的提示词模板 | 快捷指令 | “代码审查清单”、“提交信息生成” |
传输层——MCP 支持两种通信方式:
| 方式 | 通信机制 | 适合场景 | 例子 |
|---|---|---|---|
| stdio | 标准输入/输出,进程间通信 | 本地工具、CLI 场景 | 文件系统 Server、Git Server |
| HTTP + SSE | HTTP 请求 + Server-Sent Events 流式推送 | 远程服务、多客户端共享 | 数据库 Server、企业内部 API Server |
MCP 的完整生命周期:
1. 初始化(Handshake)
Client → Server: initialize { clientInfo, capabilities }
Server → Client: initializeResult { serverInfo, capabilities }
双方交换版本号和能力列表,协商兼容的功能集
2. 能力发现(Discovery)
Client → Server: tools/list → Server 返回: [{name, description, inputSchema}, ...]
Client → Server: resources/list → Server 返回: [{uri, name, mimeType}, ...]
AI 模型通过这些描述自主决定"何时"调用"哪个"工具
3. 操作执行(Operation)
Client → Server: tools/call { name: "query_db", arguments: { sql: "..." } }
Server → Client: { content: [{ type: "text", text: "查询结果..." }] }
支持流式返回——Server 可以逐步推送结果,不必等全部完成
4. 资源读取(Resource Access)
Client → Server: resources/read { uri: "config://app/settings" }
Server → Client: { contents: [{ uri: "...", mimeType: "application/json", text: "..." }] }
5. 断开(Shutdown)
Client → Server: notifications/cancelled (取消进行中的请求)
Client → Server: disconnect (优雅断开连接)
用法:如何配置和使用 MCP
以 Claude Code 为例,在 settings.json 中配置 MCP Server:
{
"mcpServers": {
"context7": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@upstash/context7-mcp@latest"],
"env": {}
},
"postgres": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@anthropic/mcp-server-postgres", "postgresql://localhost/mydb"]
},
"github": {
"type": "http",
"url": "https://mcp-server.example.com/github",
"headers": { "Authorization": "Bearer ${GITHUB_TOKEN}" }
}
}
}
配置后,Claude Code 启动时自动连接这些 Server,AI 就能在对话中直接操作数据库、
查询文档、管理 GitHub——不需要在每次对话中重新解释上下文。
常用 MCP Server 分类
| 类别 | 推荐 Server | 一句话功能 |
|---|---|---|
| 文档 | Context7 | 实时查最新版本文档,消除幻觉 API |
| 数据库 | PostgreSQL / SQLite / Redis | AI 直连数据库执行查询和 Schema 分析 |
| 浏览器 | Puppeteer / Chrome DevTools | 截图、填表、E2E 自动化测试 |
| 开发工具 | GitHub / GitLab | PR 审查、Issue 管理、代码搜索 |
| 容器 | Docker / Kubernetes | 容器管理、Pod 日志查询 |
| 搜索 | Brave Search / Tavily / Exa | 实时网络搜索 |
| 文件 | Filesystem | 读写文件、目录遍历 |
价值:MCP 改变了什么
-
标准化:工具开发者只需实现一次 MCP Server,所有 AI 应用(Claude、Cursor、
Continue、自研 App)都能复用。对比 Function Calling——每个厂商有自己的格式,
换模型就要改工具描述方式。 -
热插拔:新增工具不需要改 AI 应用代码、不需要重新部署。启动新的 MCP Server
进程,AI 应用下次连接时自动发现。这对微服务架构尤其重要。 -
生态效应:社区已有 10000+ MCP Server,覆盖数据库、云服务、开发工具、
办公软件等几乎所有品类。这意味着大部分外部系统大概率已有现成的 MCP Server,
不需要从零写适配。 -
安全边界:MCP Server 运行在独立进程中,权限隔离。你可以给不同的 Server
分配不同的系统权限(数据库 Server 给只读账号、文件 Server 限制目录范围),
AI 的"手"伸不到你没授权的地方。
注意:MCP 的价值在于规模——如果你的应用只有 2-3 个固定工具且短期内不会扩展,
Function Calling 足够。当工具数量增长、需要跨应用复用时,MCP 的优势开始显现。
MindForge V1 用 FC 是合理的工程决策,V2 切 MCP 是规模驱动的自然演进。
2.4 Skills — 封装可复用的 AI 工作流
概念:Skill 是什么
每个人和 AI 协作时都会积累一些"固定套路"——比如"生成单元测试报告"这件事,
每次都一样:读取截图索引 → 解析模块列表 → 填充模板 → 生成报告文件。
如果你每次都要从头向 AI 解释这个流程,效率极低。
Skill 就是把这种"固定套路"封装成一个可复用的能力包——相当于给 AI 写了一份
“标准操作程序(SOP)”。激活 Skill 后,AI 自动获得完成该任务所需的全部上下文、
规则和步骤,不需要你每次重复解释。
类比:Skill 之于 AI,如同"制造工艺卡"之于工厂——不是机器本身的能力,
但规定了机器该按什么顺序、用什么参数、检验什么标准来完成特定产品。
原理:Skill 如何工作
加载机制:
用户输入 /skill-name 或 AI 自动匹配
→ 系统读取 SKILL.md(Skill 的核心文件)
→ 内容注入到 System Prompt(优先级高于默认系统提示词)
→ AI 获得该 Skill 的专用知识、规则、工作流
→ 执行过程中严格遵循 Skill 中定义的步骤
→ Skill 执行完毕,专用上下文释放
Skill 的文件结构:
.claude/skills/my-skill/
├── SKILL.md ← 核心:Skill 的定义文件(必须)
│ ├── frontmatter ← 元数据:名称、描述、触发条件
│ └── body ← 具体指令:步骤、规则、示例
└── resources/ ← 可选:模板文件、参考数据
SKILL.md 的 frontmatter 示例:
---
name: gen-unit-test-report
description: 从截图索引生成单元测试报告(.doc 格式)
trigger: 用户要求生成单元测试报告时
---
Skill 的三种来源:
| 类型 | 位置 | 谁维护 | 范围 |
|---|---|---|---|
| 项目级 | 项目的 .claude/skills/ |
项目团队 | 当前项目 |
| 个人级 | 用户的 ~/.claude/skills/ |
个人 | 所有项目 |
| 插件级 | 通过插件管理器安装 | 社区/第三方 | 全局 |
用法:创建和使用 Skill
创建 Skill 的核心原则:
- 一个 Skill 只做一件事——职责单一,组合使用而不是大而全
- 站在 AI 的视角写指令——不要写"你应该理解",而是"遇到 X 情况执行 Y 步骤"
- 包含具体示例——AI 从示例中比从规则中学习得更准确
- 写清楚失败处理——“如果文件不存在,提示用户检查路径,不要自行创建”
调用方式:
/skill-name—— 显式调用- AI 自动匹配 —— 当检测到任务和 Skill 描述一致时自动激活
- 编程调用 —— 在 Workflow 脚本中引用其他 Skill
价值:Skill 改变了什么
-
知识捕获:把"老员工脑子里的经验"变成"新人运行
/skill-name就能执行的流程"。
从"口口相传"变成"可执行的代码"。 -
效率跃升:我的
gen-unit-test-reportSkill——130+ 份单元测试报告,
从人工 65+ 小时降到 AI 自动几分钟完成。 -
质量一致:每次执行同一 Skill,产出物的格式、检查点、质量门禁完全一致。
不会出现"这次写得好、下次忘了检查某个项"的情况。 -
团队杠杆:一人写好 Skill,全团队受益。新人不需要培训就能输出和老员工
同等质量的工作成果——Skill 就是"写在纸上"的经验。
Skill 的核心价值不在于"让 AI 做某件事"(裸 Prompt 也能做到),而在于
让 AI 每次都按同一套标准做这件事——可重复、可审计、可改进。
2.5 Hooks — 事件驱动的自动化守卫
概念:Hook 是什么
AI 工作时有一些关键节点需要"自动检查"——比如每次改文件之前确认改的不是生产配置、
每次改完之后自动格式化、每次结束会话前检查测试是否通过。
如果这些全靠人来记住和执行,迟早会出疏漏。Hooks 就是这些关键节点上的
“自动哨兵”——到达触发点时自动执行预设的检查脚本,不通过则拦截操作。
类比:Hooks 之于 AI 操作,如同 CI/CD Pipeline 的各个 Gate 之于代码提交——
lint 不过不能合入、测试不过不能部署、安全扫描不过不能上线。只不过 Hooks
管控的不是 CI 流程,而是 AI 的每一次工具调用和会话生命周期。
原理:Hook 的触发和执行
四种 Hook 类型:
| Hook 类型 | 触发时机 | 典型用途 |
|---|---|---|
| PreToolUse | 工具执行前 | “即将执行 rm -rf,确认目标路径不在保护列表中” |
| PostToolUse | 工具执行后 | “写完文件了,自动运行 prettier 格式化” |
| Stop | 会话结束前 | “退出前检查:还有未提交的 TODO 吗?测试过了吗?” |
| SessionStart | 会话启动时 | “加载项目上下文,注入自定义规则” |
Hook 的执行流:
用户请求 AI 执行某个操作
→
┌─ 匹配到 PreToolUse Hook? ──是──→ 执行 Hook 脚本 ──→ 返回结果
│ ├── allow:继续执行
│ ├── deny:拦截操作 + 返回原因
│ └── modify:修改参数后继续
└─ 未匹配 → 正常执行
→
AI 操作执行完成
→
┌─ 匹配到 PostToolUse Hook? ──是──→ 执行 Hook 脚本(格式化/记录/通知)
└─ 未匹配 → 流程结束
关键特性:Hook 是同步阻塞的——PreToolUse 返回 deny 时,操作不会发生;
Hook 执行超时(默认 60 秒)视为 deny。这是安全的底线设计。
Hook 的返回值协议(PreToolUse 示例):
{
"decision": "allow",
"reason": "拒绝或修改的原因说明",
"modifiedInput": {}
}
用法:配置和使用 Hooks
在 Claude Code 的 settings.json 中配置:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"command": "python",
"args": [".claude/hooks/check_protected_files.py"],
"timeout": 10000
},
{
"matcher": "Bash",
"command": "python",
"args": [".claude/hooks/deny_dangerous_commands.py"]
}
],
"PostToolUse": [
{
"matcher": "Edit|Write",
"command": "bash",
"args": [".claude/hooks/auto_format_and_log.sh"]
}
],
"Stop": [
{
"command": "bash",
"args": [".claude/hooks/check_todos_and_tests.sh"]
}
]
}
}
matcher 字段支持正则,精确控制哪些工具操作触发 Hook:
"Edit|Write":只拦截文件写入操作"Bash":拦截所有 shell 命令"*":拦截所有工具操作(慎用)
实战模式
模式 1:改文件前自动检查(PreToolUse)
触发条件:Edit / Write 工具
Hook 逻辑:
1. 检查目标文件是否在 "受保护文件列表" 中(如 production.yml, .env)
2. 若是 → 返回 deny:"此文件为生产配置,请先在测试环境验证"
3. 若否 → 返回 allow
模式 2:改完后自动格式化 + 记录(PostToolUse)
触发条件:Edit / Write 工具执行成功
Hook 逻辑:
1. 获取修改的文件路径
2. 运行 prettier / clang-format 自动格式化
3. 将变更记录追加到 .claude/CHANGELOG.md
模式 3:会话结束前质量检查(Stop)
触发条件:会话即将退出
Hook 逻辑:
1. git diff --stat 检查是否有未提交变更
2. grep "TODO\|FIXME" 检查是否有遗留的待办标记
3. 运行单元测试确认全部通过
4. 有未通过项 → 返回 deny + 清单,阻止退出
价值:Hooks 改变了什么
-
安全兜底:PreToolUse 是第一道防线——在你看到确认弹窗前,
自动脚本已经拦截了明显危险的操作(删除系统文件、修改生产配置)。
它不依赖"人注意到危险",而是靠预设规则自动判断。 -
质量自动化:格式化、Lint、测试检查变成默认行为而不是"记得就做"。
PostToolUse + Stop 组合覆盖了代码修改的完整生命周期。 -
流程强制:团队规范从"README 里的一句话"变成"Hook 里的硬约束"。
不通过 Hook 就走不下去——比 Code Review Checklist 的约束力强得多。 -
可组合:Hooks 和 Skills 联动——Skill 定义怎么做事,
Hooks 保证做事过程中不出错。两者配合形成完整的 AI 工程化闭环。
Skill vs Hook 的区别:Skill 是 AI 的"操作手册"(告诉它能做什么、怎么做),
Hook 是 AI 的"交通规则"(告诉它什么不能做、做完要检查什么)。Skill 是增强能力,
Hook 是约束行为——两者缺一不可。
第三章:Prompt Engineering — 从写提示词到管资产
3.1 Prompt 六要素
个人使用 Prompt 和工程化 Prompt 的区别,就像个人写脚本和团队开发系统——前者能跑就行,后者需要可维护、可测试、可追溯。
六要素模板:
① 角色:"你是 5 年 Spring Boot 开发,熟悉金融系统规范"
② 任务:一个 Prompt 只聚焦一个任务
③ 上下文:@引用相关代码 + 业务规则说明
④ 约束:"保持现有方法签名不变"、"不要引入新第三方依赖"
⑤ 输出格式:指定结构(正常3个 + 边界2个 + 异常2个)
⑥ 示例:@ExistingTest.java "新测试风格保持一致"
对比:
- ❌ “帮我优化这段代码”
- ✅ “这段代码在 Oracle→OceanBase 迁移中性能下降 50%。分析执行计划,找出瓶颈,给 2-3 种改写方案,保持语义等价。@SlowQuery.sql”
实用技巧:
- “一步一步思考” → 触发思维链
- “先给方案,确认后再写代码” → 避免方向错误
- “不对,XXX 应该是 YYY” → AI 根据反馈即时调整
3.2 思维链(CoT)与推理模型
思维链(Chain of Thought)的本质是让模型把隐式的推理过程显式化。研究表明,对于数学推理、逻辑分析等复杂任务,CoT 能将准确率从 30% 提升到 80% 以上。
两种触发方式:
- 手动触发:Prompt 中加"请一步一步思考"或"先分析再给出结论"
- 模型内置:DeepSeek-R1、GPT-o1 在训练时就学习了推理模式,调用时自动进行
何时需要 CoT:
- 多步骤推理(逻辑题、数学题、复杂 SQL 分析)
- 多条件权衡(架构选型、方案对比)
- 不需要 CoT 时不要硬加——会增加 Token 消耗和延迟
3.3 结构化输出 + 流式响应
这是 AI 应用输出的两个维度,不是二选一,而是标配:
结构化输出(JSON Schema)——控制"输出什么格式":
- 出题:
{"type":"选择","stem":"...","options":[...],"answer":"A"} - 评分:
{"score":85,"correctness":4,"weakness":["CAS"]} - 意图分类:
{"intent":"解题","subject":"AQS","difficulty":"中等"} - 没有结构化输出 → 用正则从自由文本里抠数据 → 脆弱不可靠
流式响应(SSE)——控制"输出怎么呈现":
- LLM 逐 token 返回,用户看到文字一个个出现
- 没有流式 → 用户等 10 秒看空白页 → 体验不可接受
两者配合:LLM 流式输出 JSON 字符串 → 前端一边接收 chunks 一边展示 → 收到完整 JSON 后做最终解析和校验。这是当前主流做法。
3.4 Prompt 工程化管理
当你的 AI 应用有 5+ 种场景,每种场景又对应不同备考方向时,Prompt 就不是"写一段话存备忘录"了——它是一套需要版本管理的代码资产。
MindForge 的 Prompt 管理实践完整展示了这套体系:
模板分类:出题 / 评估 / 追问 / 简历 / 意图 —— 5 种场景各有独立模板
方向绑定:会计出题提示词 ≠ Java 出题提示词,每个方向可配置专属模板变量占位符:{{备考方向名称}} {{检索关键词}} {{题型列表}} {{难度}}
版本管理:tb_prompt_template + tb_prompt_version 两张表,每次修改留历史,支持 Git-revert 式回滚
升级门禁:模板升级前跑离线评估集,Faithfulness 低于阈值不发布
删除保护:被备考方向引用的模板不可直接删除
默认回退:未配置专属模板的方向,使用系统默认模板
工程化带来的好处:
- 改 prompt 不用发版——管理员后台编辑即可
- prompt 质量可追溯——版本对比知道"改了哪句话导致质量变化"
- 知识可复用——"Java 出题提示词 v1.3"可被多个 Java 相关方向共享
第四章:RAG — 检索增强生成
RAG 是 AI 应用开发中最重要的技术范式之一。本章从原理讲到评估,从基础实现讲到高级优化,最后以 MindForge 代码为例走读完整链路。
4.1 RAG 解决了什么问题
LLM 有两大先天缺陷:① 知识截止日期(训练数据有终点)② 幻觉(对训练数据外的问题可能编造答案)。RAG 通过"检索+生成"的方式,让 LLM 能使用训练数据之外的知识。
有 RAG 和没有 RAG 的区别:
没有 RAG(纯 LLM):
用户:"OceanBase 迁移后性能为什么断崖下跌?"
LLM:编造一段听起来合理但可能完全错误的分析
有 RAG:
用户:"OceanBase 迁移后性能为什么断崖下跌?"
→ 向量检索找到相关技术文档中的"PL/SQL 函数逐行求值"段落
→ 作为上下文传给 LLM
→ LLM:"根据文档记录,根因是 OceanBase 对 WHERE 条件中的 PL/SQL 函数逐行求值...
解决方案有 4 种:参数绑定、标量子查询包装..."
→ 回答正确,且有据可查
RAG 数据流:
文档上传 → 解析(PDF/Word/Markdown)→ 文本切分 → 向量化 → 入库(向量数据库)
↓
用户提问 → 问题向量化 → 相似度检索 Top-K → 拼接 Prompt → LLM 生成 → 带引用来源的回答
4.2 文档切分策略
这是 RAG 最容易出问题的环节。切分不对,后面全白费。
三种策略:
| 策略 | 方式 | 适合 | 不适合 |
|---|---|---|---|
| 固定大小 | 每 N 个 token 一刀切,相邻块重叠 10-20% | FAQ、规章制度(条目独立性强) | 连贯性强的技术文档 |
| 语义切分 | 按段落/章节边界切,保持语义完整 | 技术文档、业务手册 | 无结构文本 |
| 递归切分 | 先按一级标题→二级标题→段落逐级切 | 合同协议、法规(层级清晰) | 扁平结构文档 |
关键参数:
- Chunk Size:256-512 token(中文约 200-400 字)。太小丢失上下文,太大检索精度下降
- Overlap:10-20%。防止关键信息恰好落在分块边界上
- 核心原则:每个 Chunk 自包含——单独拿出来看,不需要翻前一段也知道在说什么
Chunk Enrichment(块增强)——一个成本极低但效果显著的优化:
原文:"根据第3条,订单取消需提前通知..."
增强后:"[《代客交易系统接口规范》/ 第三章 订单接口 / 2025-06 更新]
根据第3条,订单取消需提前通知..."
检索时 AI 就知道这段内容的来源和时效性,输出的引用也更准确。
4.3 Embedding 与向量数据库
Embedding 模型选择:
| 模型 | 维度 | 语言 | 费用 | 适合 |
|---|---|---|---|---|
| BGE-large-zh-v1.5 | 1024 | 中文最优 | 免费(本地) | 中文知识库首选 |
| text-embedding-3-small | 1536 | 多语言 | OpenAI 计费 | 多语言、快速验证 |
| Jina embeddings-v3 | 1024 | 多语言 | 有免费额度 | 长文本(支持 8192 token 输入) |
MindForge 的 Embedding 设计决策:平台统一使用 BGE 模型,而不是用用户自己的 API Key 调 Embedding API。为什么?公共知识库需要跨用户检索一致性——如果用户 A 用 GLM 的 Embedding 模型写向量,用户 B 用通义千问的模型去检索,两个向量在不同的语义空间中,检索结果完全不可用。平台统一 Embedding 保证了跨用户的向量空间兼容。
向量数据库选型:
| 方案 | 规模 | 部署 | 延迟 | MindForge 状态 |
|---|---|---|---|---|
| Chroma | < 10 万条 | pip install 零部署 | < 10ms | 本地开发/原型 |
| 内存暴力搜索 | < 1 万条 | 无依赖 | O(n) 遍历 | ✅ MindForge V1 使用 |
| Milvus | 百万~十亿 | Docker/K8s 部署 | < 5ms(HNSW) | V2 升级方向 |
MindForge V1 选择了最轻量的内存暴力搜索方案(见 VectorIndexService.java)——启动时全量加载向量到 ConcurrentHashMap,查询时遍历计算余弦相似度,用小顶堆维护 Top-K。设计注释写得很诚实:
“当单方向文档量 >5000 或搜索 P99 >200ms 时,可替换为 Lucene HNSW 实现。”
这就是工程上"先跑通再优化"的典型决策——V1 阶段文档量少,暴力搜索完全够用,不引入 Milvus 的运维复杂度。
余弦相似度计算(VectorIndexService.java:196-206):
// MindForge 实际代码
private double cosineSimilarity(float[] a, float[] b) {
if (a.length != b.length) return 0.0;
double dot = 0.0, normA = 0.0, normB = 0.0;
for (int i = 0; i < a.length; i++) {
dot += (double) a[i] * b[i];
normA += (double) a[i] * a[i];
normB += (double) b[i] * b[i];
}
if (normA == 0.0 || normB == 0.0) return 0.0;
return dot / (Math.sqrt(normA) * Math.sqrt(normB));
}
4.4 混合检索
纯向量检索的盲区:擅长语义匹配(“数据库"↔"DB”),但可能漏掉精确的关键词(“PGET_SYSCURRDATE”)。混合检索 = 向量语义相似度 + BM25 关键词精确匹配,加权融合后重排序。
混合检索流程:
用户问题
├── 向量检索(语义匹配) → Top-K₁ 结果 ──┐
└── BM25 检索(关键词匹配) → Top-K₂ 结果 ──┼── RRF 融合(k=60)→ 最终排序 → 传给 LLM
MindForge 设计文档中采用了 RRF(Reciprocal Rank Fusion, k=60)进行融合。BM25 权重 0.3 + 向量权重 0.7——向量为主、关键词为辅,适合中文技术文档场景。
4.5 RAG 评估:你怎么知道你的 RAG 好不好用
三层评估体系:
第一层:检索评估 → 检索回来的文档是否相关?排序是否正确?
指标:Hit Rate(Top-K 命中率)、MRR(首个相关文档的排名倒数)、NDCG(排序加权)
第二层:生成评估 → 答案是否忠实于检索文档?有没有编造?
框架:RAGAS(业界最常用)
指标:Faithfulness(忠实度)、Answer Relevancy(答案相关性)、
Context Precision(上下文精度)、Context Recall(上下文召回)
第三层:端到端评估 → 用户满意度
指标:点赞率、点踩率、回答可用率、考试通过率
LLM-as-Judge(当前性价比最高的自动评估方式):
用强模型评估弱模型输出——输入问题+检索文档+待评估答案,输出 1-5 分的 faithfulness/correctness/completeness + 解释。每 100 条对话抽样 5 条自动打分。
MindForge 的评估策略:
- 离线:建 50 条标准问答对,每次改 prompt 或检索策略跑一遍,对比 MRR 和 Faithfulness
- 在线:用户点赞/点踩 + LLM-as-Judge 自动抽样
- 监控:检索命中率、平均相似度、AI 搜索触发频率(反映知识库覆盖不足)
- 门禁:prompt 模板升级前先跑离线评估集,低于阈值不发布
4.6 高级 RAG 技术
基础 RAG 有三个常见问题,各有对应方案:
| 问题 | 现象 | 方案 | 原理 |
|---|---|---|---|
| 检索不相关 | 问"AQS 原理"返回"美国质量标准 AQS" | Self-RAG / CRAG | LLM 生成前先自评检索文档相关性,低分丢弃+触发 Web 搜索 |
| 跨文档多跳推理 | “synchronized 锁升级后对 GC 有什么影响” | GraphRAG | 用知识图谱替代向量检索,沿图谱路径做多跳遍历 |
| 短问题精度低 | "怎么优化慢查询"口语化太短 | HyDE | 先让 LLM 生成"假设性答案",用答案的向量去检索——答案和文档在向量空间更接近 |
MindForge 的 RAG 升级路线:
| 阶段 | 技术 | 解决的问题 |
|---|---|---|
| V1(已实现) | 基础 RAG + 内存向量索引 | 基本问答、来源标注 |
| V1.5 | + Self-RAG(检索结果自评) | 减少不相关文档干扰 |
| V2 | + Milvus HNSW + HyDE | 检索性能 + 短问题精度 |
| V3(按需) | + GraphRAG | 跨文档多跳推理 |
MindForge 三级出题源降级(本质是简化版 CRAG):
出题时获取知识:
Layer 1:知识库 RAG 检索 → 有结果 → 使用
→ 无结果/相关性低 ↓
Layer 2:LLM 训练数据 → 模型自身知识兜底
→ 知识不可靠 ↓
Layer 3:AI 搜索(可选) → DuckDuckGo 等外部搜索补充
4.7 RAG vs 微调:选型决策框架
RAG vs 微调的本质区别:
| 维度 | RAG | 微调(Fine-tuning) |
|---|---|---|
| 改什么 | 不改模型参数,只优化检索+prompt | 改模型权重参数 |
| 知识更新 | 实时(更新向量库即可) | 需重新训练 |
| 成本 | 低(Embedding + 检索开销) | 高(GPU 训练 + 数据标注) |
| 幻觉控制 | 有来源可追溯 | 来源不可追溯 |
| 适合 | 知识密集型、频繁变动 | 风格/格式固定、领域术语注入 |
决策框架:
知识是否频繁变动?
├── 是 → RAG(考纲每年更新、法规变化)
└── 否 → 需要特定输出格式/风格?
├── 是 → 微调(客服话术、代码风格)
└── 否 → RAG 或 Prompt 工程即可
资源有多少?
├── 有 GPU + 标注数据 → 可考虑微调
└── 只有 API Key → RAG
MindForge 为什么选 RAG:
- 考纲每年可能变化,微调跟不上,RAG 更新文档即可
- Java/会计/架构师三套完全不同的知识域,微调一个模型全覆盖极难
- 考试答案必须标注来源,RAG 天然支持,微调做不到
- 个人项目无 GPU,API 调用是唯一可行方案
- 公共知识库跨用户共享,RAG 天然支持,微调无法做到
进阶——不是二选一:RAFT(训练时注入检索文档,让模型学会忽略不相关文档)、GraphRAG(知识图谱替代向量检索)、RAG + LoRA 微调混合。业界趋势是组合使用。
4.8 实战:MindForge RAG 全链路代码走读
MindForge 的 RAG 全链路涉及三个核心组件:
链路全景:
用户上传文档(PDF/Word/Markdown)
→ DocumentParser(解析为纯文本)
→ TextSplitter(语义切分,512 token/chunk,64 token overlap)
→ EmbeddingService.embedBatchAndStore()(BGE 向量化 + 磁盘持久化)
→ DocumentChunkRepository(MySQL 存元数据:chunkId/documentId/content/vectorId)
→ VectorIndexService.loadAll()(启动时 ConcurretHashMap 全量加载)
→ RagSearchTool(Agent 工具——LLM 自主决定何时调用)
→ VectorIndexService.search()(余弦相似度 + 小顶堆 Top-K)
→ 结果拼入 System Prompt → LLM 生成 → SSE 流式返回
EmbeddingService(mindforge-rag/.../EmbeddingService.java):
- 支持 GLM(embedding-2)和通义千问(text-embedding-v3)两种 Embedding API
- 向量以 JSON 数组格式存到
data/vectors/{uuid}.json - 30 秒超时,调用失败抛 RuntimeException(由 Agent Tool 层 catch)
VectorIndexService(mindforge-rag/.../VectorIndexService.java):
@PostConstruct loadAll()启动时全量加载到 ConcurrentHashMapdirectionIndex(Map<Long, List>)实现按备考方向隔离检索- 查询用 PriorityQueue 小顶堆维护 Top-K,时间复杂度 O(n log k)
- 设计注释标注了升级路径:“>5000 条或 P99>200ms 时换 Lucene HNSW”
RagSearchTool(mindforge-agent/.../tools/RagSearchTool.java):
- 实现 AgentTool 接口,注册到 AgentToolRegistry
- 参数 query + topK(上限 10),由 LLM 自主决定何时调用
- 返回 JSON 格式的检索结果列表(含 chunkId/documentId/content/score)
- 通过
_provider、_apiKey、_directionId等系统注入参数获取运行时上下文
第五章:Agent — 让 AI 从"聊天"到"干活"
5.1 Agent 的本质
三种 AI 能力的递进:
| 纯 LLM | RAG | Agent | |
|---|---|---|---|
| 能力 | 仅靠训练数据回答 | LLM + 检索外部知识 | LLM + 调用工具 + 多步推理 |
| 能做什么 | 回答问题 | 基于文档回答 | 执行任务(查数据库、调 API、操作文件) |
| 例子 | “什么是 MVCC” | “根据面试笔记回答锁升级过程” | “查表找出交易量最大的客户,生成 Excel 报表” |
Agent 的三个核心能力:
- 规划:把复杂任务拆成可执行的步骤
- 工具调用:自主决定何时调用什么工具
- 反馈循环:观察工具结果 → 调整下一步计划 → 继续执行
5.2 ReAct 模式深入
ReAct(Reasoning + Acting)是当前最主流的 Agent 推理范式:
循环结构(Thought → Action → Observation → 回到 Thought):
用户:"出 5 道 Java 多线程的单选题,难度中等"
→ Thought: 需要先从知识库检索多线程相关内容
→ Action: call rag_search(query="Java 多线程 知识点")
→ Observation: 返回 12 个文本片段(synchronized/ReentrantLock/线程池/volatile/AQS...)
→ Thought: 有足够的知识点,可以出题了。结合 LLM 知识出 5 道中等难度单选题。
→ Action: call exam_generation(
topics=["synchronized","ReentrantLock","线程池","volatile","AQS"],
questionType="单选", count=5, difficulty="中等"
)
→ Observation: 生成了 5 道题目
→ Thought: 题目生成完成,检查一下是否覆盖了要求的 5 个主题
→ Final Answer: (输出 5 道题目,标注每题来源)
和传统编程的本质区别:
- 传统:人思考 → 人写代码 → 人检查
- Agent:AI 思考 → AI 调工具 → AI 看结果 → AI 调整 → AI 输出
ReAct 的进化版:
- Plan-and-Execute:先一次性规划出完整步骤(Plan),再逐步执行(Execute),执行中发现问题就调整 Plan。适合复杂多步骤任务
- Reflexion:执行失败后不只重试,而是先反思"为什么失败"→ 把反思记入上下文,下次自动避免同类错误
5.3 Function Calling vs MCP
两者的关系不是对立,而是演进:
| 维度 | Function Calling | MCP |
|---|---|---|
| 定义者 | 各厂商各自定义(OpenAI/Anthropic 格式不同) | Anthropic 提出的开放标准,社区共建 |
| 工具描述 | 写在每次 API 请求的 tools 参数里 | Server 启动时通过 tools/list 动态提供 |
| 工具发现 | 应用代码硬编码工具列表 | 连接到 Server 时自动发现可用工具 |
| 新增工具 | 改代码 + 重新部署 | 启动新 MCP Server 即可(热插拔) |
| 生态 | 厂商锁定 | 社区共建,已有 10000+ Server |
MindForge 为什么 V1 用 Function Calling:
- 工具集固定(RAG 检索/AI 搜索/题库查询/代码沙箱),不会频繁变动
- Spring AI 的 ToolCallback 机制开发效率高,
AgentTool接口注册到AgentToolRegistry后自动适配 - 个人项目单机部署,MCP 每个 Server 独立进程增加运维负担
V2 改造方向:
当前(FC):Agent → @Tool 注解的 Java 方法 → 直接调用
V2(MCP):Agent → MCP Client → MCP Server(RAG检索) → 向量库
→ MCP Server(题库) → MySQL
→ MCP Server(沙箱) → Docker
改造后的价值:
- 工具热插拔:新增"简历评估服务"作为独立 MCP Server,不停机上线
- 工具复用:RAG 检索 MCP Server 可被其他应用直接复用
- 协议演进意义:“V1 用 FC 快速落地,V2 改造 MCP 开放生态”
Function Calling vs MCP = 各厂商的私有充电口 vs USB-C。前者够用但换手机得换线,后者一次适配到处能用。关键是知道什么时候用什么——初期 FC 快速验证,规模上来切 MCP。
5.4 多 Agent 协作模式
单 Agent 能解决大部分问题,但当任务规模超过单一上下文的承载能力时,需要多 Agent 协作。
四种经典模式:
| 模式 | 结构 | 适合场景 | 例子 |
|---|---|---|---|
| 顺序流水线 | A→B→C 串行 | 步骤有明确依赖关系 | 需求→设计→编码→测试→审查 |
| 辩论模式 | 多 Agent 独立分析→互相质疑→收敛 | 高风险决策 | 技术方案评审、安全审查 |
| 投票/集成 | 多 Agent 独立输出→汇总比较 | 有多个可行解的开放问题 | Bug 根因分析、SQL 优化方案 |
| 分层委派 | 主 Agent 拆任务→N 个子 Agent→汇总 | 大型跨模块任务 | 项目框架升级 |
关键原则:人永远是总指挥——任务的拆解边界、验收标准、最终决策权在人手上。AI 是执行者,不是决策者。
5.5 语义缓存与降级策略
两个容易被忽视但实际价值极大的工程手段。
语义缓存:
- 不是缓存 key-value 字符串,是缓存"语义相似的问题"
- “synchronized 原理” = “Java 内置锁的工作机制” → 语义相同 → 缓存命中
- 相似度阈值 ≥ 0.95 直接返回,不走 LLM
- BYOK 模式下,每省一次 LLM 调用 = 帮用户省钱
降级策略(MindForge 的三级降级):
RAG 检索
├── 返回结果充足 → 基于知识库生成,标注来源
├── 返回结果不足 → 降级到 LLM 训练数据 + 提示"以下答案基于通用知识,非您的资料"
└── RAG 不可用(异常)
├── LLM 训练数据 → 降级兜底
├── 两者均不可用 → 提示用户"服务暂不可用,请稍后重试"
└── 绝不让用户看到 500 / 空白页
5.6 实战:MindForge Agent + ReAct 代码走读
MindForge 的 Agent 实现是全文最核心的代码,完整展示了如何用 Spring AI 构建 ReAct 循环。
架构设计:
mindforge-agent 模块(独立 Maven 模块,不依赖 mindforge-service)
AgentTool (接口)
├── getName() → "rag_search"
├── getDescription() → "从用户知识库中检索..."(LLM 决策依据)
├── getParametersSchema() → JSON Schema(LLM 理解参数格式)
└── execute(Map params) → ToolResult(实际执行逻辑)
AgentToolRegistry (注册中心)
├── Spring 自动注入所有 AgentTool Bean
├── buildToolsDescription() → 生成工具列表文本,注入 System Prompt
└── get(String name) → 按名查找工具
ReActLoop (循环调度器)
├── buildInitialMessages() → System Prompt + 对话历史 + 用户查询
├── buildToolCallbacks() → AgentTool → Spring AI ToolCallback 适配
└── execute() → ChatClient.prompt().tools(...).call().chatResponse()
关键设计:AgentTool → ToolCallback 适配(ReActLoop.java:142-193):
// 将 AgentTool 适配为 Spring AI 2.0 ToolCallback
// 核心是三个动作:
// 1. 提供 ToolDefinition(名/描述/参数Schema)—— LLM 用来决定是否调用
// 2. 实现 call(String input) —— Spring AI 自动解析 LLM 的工具调用请求
// 3. 合并系统注入参数(_provider, _apiKey, _directionId)—— 这些是 LLM 不知道的
ToolCallback callback = new ToolCallback() {
@Override
public ToolDefinition getToolDefinition() {
return DefaultToolDefinition.builder()
.name(tool.getName())
.description(tool.getDescription())
.inputSchema(tool.getParametersSchema())
.build();
}
@Override
public String call(String input) {
Map<String, Object> params = new HashMap<>(JSON.parseObject(input, Map.class));
// 合并系统注入的额外参数
if (context.getExtraToolParams() != null) {
params.putAll(context.getExtraToolParams());
}
// 发送 SSE thinking 事件 → 前端展示"正在检索知识库..."
emitThinking(context, 0, tool.getName(), "started", null);
ToolResult result = tool.execute(params);
emitThinking(context, 0, tool.getName(),
result.isSuccess() ? "completed" : "failed", buildSummary(result));
return result.isSuccess() ? result.getData() : "ERROR: " + result.getErrorMessage();
}
};
ReActContext(ReActContext.java):
// 封装一次 Agent 调用所需的全部参数
ChatModel chatModel; // 由调用方通过 LlmChatRouter 获取
String systemPrompt; // 含工具列表 + 角色定义 + 行为规则
String userQuery; // 用户输入的原始问题
List<Message> history; // 对话历史(多轮对话)
Map<String, Object> extraToolParams; // 系统注入参数(_provider, _apiKey 等)
Consumer<ThinkingEvent> thinkingCallback; // SSE 事件回调
int maxIterations = 10; // 兜底:单次最多 10 步
int toolTimeoutSeconds = 30; // 单次工具调用 30 秒超时
工具列表(已实现的 3 个 + 设计中的 3 个):
| 工具 | 类 | 功能 |
|---|---|---|
rag_search |
RagSearchTool | 知识库语义检索 |
ai_search |
AiSearchTool | 外部网络搜索(DuckDuckGo 免费兜底,按 Provider 路由) |
question_bank_query |
QuestionBankQueryTool | 历史题库查询 |
exam_generation |
(设计中) | 根据检索结果生成考题 |
answer_evaluation |
(设计中) | 评估用户答案,输出评分+建议 |
follow_up_decision |
(设计中) | 从四维度判断是否继续追问 |
上下文窗口管理(ContextWindowManager.java):
- 会话超过 20 轮时,自动摘要前 10 轮
- 摘要注入为 SystemMessage,后续轮次基于摘要继续
- 摘要 LLM 调用失败时降级为简单截断(保留最近 10 轮)
第六章:AI 工程化实践
6.1 内容安全纵深防御
AI 应用的内容安全不只是 Prompt Injection 防护,而是输入→模型→输出的三层纵深防御。
第一层:输入安全(用户给 LLM 的内容)
- 敏感词过滤:本地部署敏感词库,用户输入命中则拦截(< 5ms 延迟)
- 文件内容扫描:上传的 PDF/Word 先过文本审核再入知识库
- 频率限制:单用户每分钟最多 N 次请求,防滥用
第二层:Prompt 约束(模型的行为边界)
- 系统提示词中写入内容边界:“你只能回答考试相关内容,拒绝政治/违法/色情/暴力问题”
- 注意:Prompt 约束定义的是正当行为底线,不是防注入的手段(注入会覆盖系统指令)
第三层:输出安全(LLM 给用户的内容)
- 规则校验:正则 + 关键词黑名单检测输出
- 可疑标记:触发规则 → 标记"仅个人可见" + 后台记录待审查
- 人工审核:AI 自动生成的题库题目需管理员审核后方可进入公共题库
MindForge 安全架构:
用户输入 → 敏感词过滤 → 合规 → Agent 处理
→ 不合规 → "输入包含不当内容,请修改后重试"
LLM 输出 → 规则校验 → 合规 → 返回用户
→ 可疑 → 标记+仅个人可见+后台待审查
Prompt Injection 四道防线(金融系统特别重要):
- 输入校验:用户输入只作为"数据"处理,用参数化方式拼接,绝不让用户输入成为"指令"
- 角色隔离:System Prompt(不可变)和 User Message(标签化)物理隔离
- 输出过滤:AI 回复在返回前二次检查——正则匹配敏感词、长度异常检测
- 最小权限:AI 数据库连接用只读账号、代码沙箱 --network none --read-only
6.2 成本控制策略
MindForge 采用 BYOK(用户自带 Key)模式,平台不承担模型成本。但用户体验的核心是"帮我省钱"。
成本控制层次:
第一层:模型选型(最大省钱点)
DeepSeek(¥1/百万 token) vs GPT-5(¥70/百万 token)= 70 倍差距
日常 CRUD → DeepSeek,复杂推理 → Claude
第二层:语义缓存
高频问题相似度 > 0.95 → 直接返回缓存 → 不走 LLM
考试场景下,"synchronized 原理"类问题重复率很高
第三层:上下文控制
对话超过 20 轮自动摘要压缩 → 减少每次请求的 token 数
不是把所有历史消息重新发一次
第四层:限制兜底
ReAct 最多 10 步、追问最多 5 层、上下文最多 8000 Token
防止 Agent 无限循环消耗 Token
6.3 AI 应用可观测性
AI 应用的可观测性和传统后端不同——不是 CPU/内存/QPS,而是 AI 特有的指标:
| 指标类别 | 具体指标 | 为什么重要 |
|---|---|---|
| 成本 | Token 消耗(输入/输出/总计),按用户+方向汇总 | 用户自带的 Key,要知道钱花在哪了 |
| 延迟 | 首 Token 延迟(用户感知最强)、工具调用耗时 | 等 2 秒 vs 等 10 秒出第一个字的体验天差地别 |
| 质量 | 检索命中率、平均相似度、AI 搜索触发频率 | 命中率持续下降 = 知识库需要更新 |
| 可用性 | LLM API 错误率、Embedding 失败率、沙箱执行失败率 | 降级策略触发频率过高 → 需要扩容或优化 |
| 用户反馈 | 点赞率、点踩率、追问接受率 | 点踩率突增 → prompt 或检索策略可能出问题了 |
MindForge 的 Token 追踪设计:90 天明细保留(tb_token_usage_log),按日汇总归档(tb_token_daily_summary)。这样可以做趋势分析——“这周的 Token 消耗为什么比上周多了 30%?”
6.4 模型部署与量化
本地 vs 生产,技术栈完全不同:
本地开发(Ollama):
ollama pull deepseek-r1:7b → 一行命令搞定
自动下载 Q4_K_M 量化版本,CPU 友好
适合:验证、测试、数据不出域的场景
生产部署(vLLM / TensorRT-LLM):
vLLM:PagedAttention 显存优化 + Continuous Batching 吞吐提升 10-20 倍
一条命令启动 OpenAI 兼容 API:vllm serve Qwen/Qwen2.5-7B-Instruct
适合:上线服务、高并发
量化——把模型从 CD 压成 MP3:
- FP16 → INT4,体积缩 4 倍,速度提 2-4 倍,效果几乎无损
- 三种格式:GGUF(CPU 推理/Ollama)、GPTQ(GPU/需校准数据)、AWQ(GPU/精度优于 GPTQ)
- Q4_K_M:4-bit,质量与速度的最佳平衡点(Ollama 默认)
6.5 微调入门
虽然大部分场景 RAG 就够了,但了解微调有助于理解模型能力边界和 AI 应用的全技术栈。
三种方式,成本从高到低:
| 方式 | 成本 | 原理 | 适用 |
|---|---|---|---|
| 全量微调 | 最高(7B 需 56GB+) | 更新全部参数 | 大公司专属模型 |
| LoRA | 中(7B 需 8GB) | 在旁路训练小参数包 | 当前主流 |
| QLoRA | 低(7B 需 4GB) | 先量化再 LoRA | 消费级显卡可跑 |
DPO(直接偏好优化)——当前开源模型的标准对齐方法:
- 传统 RLHF 需要三步:训奖励模型→评分→PPO 强化学习(复杂+不稳定)
- DPO 直接用好/坏回答对优化,数学上等价 RLHF 但简单得多
- Llama 3、Qwen 2.5 等主流开源模型都用 DPO 做对齐
微调数据准备——最容易被忽视的环节:
- 数据格式:
{"instruction":"任务","input":"用户输入","output":"期望输出"} - LoRA 几百到几千条高质量样本就有效果
- 数据质量 >> 数据数量:100 条精心标注 > 1000 条自动生成
- 多样性:覆盖正常/边界/异常场景
选型判断:RAG 优先验证价值 → 确实需要固化输出风格/格式 → LoRA/QLoRA 微调。大部分场景 RAG + Prompt 工程已经够用,微调是最后的优化手段。
第七章:实战全景 — MindForge 考试指导 AI 平台
本章将前面六章的知识点串联到一个完整的项目中,展示它们在实际代码中是如何组合在一起的。
7.1 项目架构全景
业务定位:AI 驱动的多方向考试/面试辅导平台。用户自带 API Key(DeepSeek/GLM/通义千问),选择备考方向(Java 求职/会计中级/架构师),平台通过 Agent + RAG 提供智能问答、模拟考试和简历评估。
技术栈:
| 层 | 技术 | 备注 |
|---|---|---|
| 后端框架 | Spring Boot 4.1.0 + Spring MVC | Java 17 |
| AI 框架 | Spring AI 2.0(ChatClient + ToolCallback) | 而非 LangChain4j(需求文档写的是后者,实际选了前者) |
| 数据库 | MySQL 8.0(业务) + 内存 ConcurrentHashMap(向量) | V1 无外部向量数据库 |
| 前端 | Vue 3 + TypeScript + Element Plus + Vite 6 | Composition API |
| 安全 | JWT + AES-256-CBC(API Key 加密) | 每次加密随机 16 字节 IV |
| 实时通信 | SSE(LLM 流式) + WebSocket(代码沙箱输出) |
Maven 模块结构:
mindforge (parent POM)
├── mindforge-common/ 共享 DTO/枚举/常量/异常
├── mindforge-repository/ JPA Entity + Repository(MySQL)
├── mindforge-security/ JWT + AES 加密 + Spring Security 配置
├── mindforge-rag/ Embedding 向量化 + 内存向量索引
├── mindforge-agent/ AgentTool 接口 + ReActLoop + 工具实现
├── mindforge-service/ 业务逻辑编排(调用 Agent + RAG)
├── mindforge-web/ REST Controller + Spring Boot 入口
└── mindforge-frontend/ Vue 3 前端(Vite)
依赖方向:web → service → {repository, agent, security} → common
7.2 关键设计决策复盘
以下是 MindForge 开发过程中的关键设计决策,体现了 AI 应用开发中的典型工程权衡:
决策 1:Spring AI 2.0 而非 LangChain4j
需求文档最初写的是 LangChain4j,实际选的是 Spring AI。原因:
- Spring AI 2.0 的 ChatClient API 与 Spring Boot 生态深度集成(依赖注入、自动配置、属性绑定)
- ToolCallback 机制比 LangChain4j 的 @Tool 注解更直接地映射 Agent 工具
- MindForge 作为 Spring Boot 项目,减少跨生态依赖降低维护成本
决策 2:内存向量索引而非 Milvus
V1 选择了最简单的方案——ConcurrentHashMap + 启动时全量加载。这是刻意的工程决策:
- V1 阶段文档量少(每个备考方向几百条 chunk),暴力搜索 O(n) 完全够用
- 避免引入外部依赖(Milvus 需要 Docker 部署,增加运维复杂度)
- 代码中明确标注了升级条件(>5000 条或 P99 > 200ms)和升级路径(Lucene HNSW)
- 体现工程判断力——知道什么时候该简单、什么时候该复杂
决策 3:平台统一 Embedding 而非用户自带
这是实际开发中发现的关键问题:
- 公共知识库需要跨用户检索,如果各用各的 Embedding 模型 → 向量在不同语义空间 → 检索完全不可用
- 解决:平台统一使用 BGE 中文模型,不绑定用户的 API Key 提供商
- 技术价值:展示对"跨用户数据一致性"这一分布式系统经典问题的延伸思考
决策 4:Agent 模块独立,不反向依赖 Service
注意 mindforge-agent 模块的依赖方向——它不依赖 mindforge-service:
ReActContext通过extraToolParams从外部接收运行时参数(_provider、_apiKey、_directionId)- ChatModel 由调用方通过 LlmChatRouter 获取后传入,Agent 层不管路由逻辑
- 这是一个经典的依赖倒置——Agent 层定义接口,Service 层注入实现
决策 5:BYOK 模式的前提和代价
- 前提:用户有自己的 API Key(国内 LLM 注册即可获取)
- 好处:平台零模型成本、用户可选择便宜的模型
- 代价:Key 安全存储(AES-256-CBC 加密+UI 脱敏)、过期验证、多 Key 管理、Embedding 策略必须独立于用户 Key
7.3 代码核心链路走读
链路 1:智能问答完整流程
用户在前端输入问题 → Vue 发起 SSE 连接(fetch + ReadableStream)
Controller 层(ExamController / ChatController):
→ 验证 JWT Token → 获取 userId
→ 获取当前备考方向 directionId
→ 获取用户 API Key → AesEncryptionService.decrypt()
→ 构造 ReActContext → 调用 ReActLoop.execute()
Agent 层(ReActLoop):
→ buildInitialMessages(): System Prompt(含工具列表)+ 历史 + 用户问题
→ buildToolCallbacks(): 6 个 AgentTool → 6 个 ToolCallback
→ ChatClient.prompt().messages().tools().call().chatResponse()
→ Spring AI 自动处理 LLM 的工具调用决策(多轮)
→ LLM 返回最终答案
SSE 推送:
→ ThinkingEvent 通过 thinkingCallback → SseEmitter.send()
→ 前端展示 "正在检索知识库..." / "正在搜索外部资料..."
→ 最终答案逐 token 流式返回
链路 2:API Key 加密存储
// AesEncryptionService.java — AES-256-CBC,每次加密随机 16 字节 IV
public String encrypt(String plaintext) {
byte[] iv = new byte[16];
new SecureRandom().nextBytes(iv); // 每次随机 IV
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(iv));
byte[] ciphertext = cipher.doFinal(plaintext.getBytes(UTF_8));
// 存储格式: Base64(IV + ciphertext)
byte[] combined = new byte[16 + ciphertext.length];
System.arraycopy(iv, 0, combined, 0, 16);
System.arraycopy(ciphertext, 0, combined, 16, ciphertext.length);
return Base64.getEncoder().encodeToString(combined);
}
链路 3:AI 搜索的 Provider 路由
// AiSearchTool.java — 按 _provider 选择搜索适配器
// 当前默认 DuckDuckGo(免费,无需 Key)
// 后续扩展:provider=GLM → GLM 内置搜索, provider=QWEN → 千问内置搜索
private SearchAdapter selectAdapter(String provider) {
if (provider != null) {
// 后续扩展:按 LLM 提供商选择对应的搜索能力
}
return adapters.getOrDefault("duckduckgo",
adapters.values().stream().findFirst().orElse(null));
}
7.4 从需求到代码:一个 AI 应用的完整工程链路
MindForge 不只是"一个 CRUD 项目加了 LLM 调用"——它涉及了 AI 应用开发的完整工程链路:
需求分析(6 个功能模块 + 5 个非功能需求)
→ 数据库设计(16 张表 + 50 个索引 + ER 图)
→ 接口设计(74 个 REST API + 14 种 SSE 事件类型 + WebSocket)
→ 前端设计(Vue 3 + 状态机驱动的考试流程 + 5 个 Pinia Store)
→ 部署设计(Nginx + systemd + Docker 沙箱 + .env 密钥管理)
→ 编码实现(7 个 Maven 模块 + Spring AI + Vue 3 + Element Plus)
→ AI 特有的工程关注:Prompt 模板管理、语义缓存、降级策略、Token 追踪、内容安全
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)