简介:一份面向AI大模型应用学习者的完整笔记包,以HuggingLLM项目为主线,系统整理了大模型应用开发中的关键知识点,覆盖人工智能与自然语言处理实践场景。资源共30个文件,压缩包大小36.19MB,包含10个Python脚本用于代码示例与工具实现,8个Markdown笔记文档记录学习过程与要点,5个CSV数据文件供实验使用,另有XML配置及项目配置文件用于环境搭建。内容按Chapter_1至Chapter_3分章节组织,配合README与docs文档,便于从零开始逐步深入,理解大模型调用、数据处理与项目部署的整体流程。目前已有536人学习下载,适合希望快速上手大模型应用、需要参考项目结构与学习路径的开发者。作者结合自身实战积累,对大模型账号申请、环境配置及技术落地方案中的常见问题提供了经验性整理,能有效帮助读者减少踩坑,提升学习与开发效率。

1. 为什么“AI大模型”学习笔记最该先写应用

收藏夹里躺着几十篇“大模型学习路线”,笔记本上抄满 Transformer 结构图和注意力公式,合上电脑时却回答不出一个最简单的问题:给我一台普通办公电脑,今天之内能不能做出一个能对话的 AI 大模型应用?多数人的学习笔记停在“原理收集”,没有进入“应用闭环”。这篇笔记的写作顺序和一般资料反着来:先把模型跑起来,再研究怎么调用、怎么接入业务、怎么验收效果,回头再去补原理时一切定义都记得更牢。适合想转大模型应用开发的工程师、做内部工具的后端同学,以及准备大模型相关岗位面试的候选人。如果你已经在调 API 做业务,读完这条路线,零散经验能串成一张完整的图。

2. 用最小闭环组织大模型学习路线:从 Ollama 部署到第一次对话

2.1 学习笔记的信息架构:框架、接口、模型、场景

动手写代码前,先把笔记按四层结构归档,这是后面不迷路的关键。第一层是推理与部署框架,比如 Ollama、vLLM,解决“模型装在哪”的问题。第二层是接口协议,如今大部分推理框架都对外暴露 OpenAI 兼容的 HTTP 接口,这一层决定业务代码怎么写。第三层是模型本身,开源模型的规格、上下文长度、量化方式决定它能否装进你的显卡。第四层是应用场景,包括提示词模板、上下文组织和工具调用。

笔记分层 关注问题 常见对象
推理框架层 模型怎么跑起来、并发多少 Ollama、vLLM、SGLang
接口协议层 应用用什么方式访问模型 OpenAI 兼容 API、框架原生 SDK
模型选型层 效果、上下文、显存占用 Qwen、Llama 系列及各量化版本
场景应用层 提示词、RAG、Agent 模板、向量库、函数调用

一页笔记如果同时写了 vLLM 显存优化和某个提示词的措辞调整,说明你已经越过入门阶段。把笔记按这四层拆开,后面查参数时不用在一大篇流水账里到处翻。我一般建议在第一层和第四层之间留一条主线:每个技术点都回答“它让应用多做了哪件事”,记下来的东西才能被下次实验复用。

2.2 用 Ollama 在本地跑通大模型的最小命令

本地部署大模型最省事的方式是用 Ollama。它把模型下载、量化、进程管理打包成一条命令,对普通办公电脑和三年前的显卡都算友好。常见做法是先去官网安装对应系统版本,然后执行:

ollama pull qwen2.5:7b     # 拉取 7B 参数的 Qwen2.5 模型
ollama run qwen2.5:7b      # 前台启动并进入交互对话

如果显存只有 8GB 左右,把模型换成 qwen2.5:3b,对话速度明显更快。首次运行需要下载模型文件,磁盘预留 6GB 以上空间,下载完毕后 Ollama 会常驻本地服务,默认监听 11434 端口。需要调整并发时,可以这样启动服务:

OLLAMA_NUM_PARALLEL=4 ollama serve   # 以 4 并行度启动服务

参数说明:OLLAMA_NUM_PARALLEL 表示同时处理的请求数,调大后并发能力提升,同时显存占用上升,8GB 显卡建议保持默认值 1 或 2。需要修改默认上下文长度时,在运行时加参数:

ollama run --num-ctx 8192 qwen2.5:7b

--num-ctx 控制模型一次能看到的 token 数量,做长文档问答时把它开到 8192 效果更明显,代价是推理时间变长。建议在笔记里单独记一行“当前显卡可用的 num-ctx 上限”,换机器后直接参考,不用重新试错。

2.3 用 OpenAI 兼容接口把模型接进业务代码

Ollama 对外暴露 OpenAI 兼容接口,这意味着业务代码不需要依赖专属 SDK,直接用常见的 OpenAI 工具库就能访问本地模型。用 Python 写一个最小客户端:

from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:11434/v1",  # 指向本地 Ollama 服务
    api_key="ollama",                       # 本地服务不校验,占位即可
)

resp = client.chat.completions.create(
    model="qwen2.5:7b",
    messages=[
        {"role": "system", "content": "你是负责解释技术概念的助手。"},
        {"role": "user", "content": "用一句话说明什么是 RAG"},
    ],
    temperature=0.3,     # 偏低,让答案更可预期
    max_tokens=256,      # 限制最大输出长度
)
print(resp.choices[0].message.content)

逻辑说明:这段代码先构造一个指向本地 11434 端口的客户端,再以消息列表形式把系统设定和用户问题发给模型。temperature 控制回答随机性,调低后多次运行的结果更接近;调高则更有发散性。max_tokens 限制生成长度,避免单次请求拖太久。接口返回结构是 choices[0].message.content,把这个字段提取出来就完成一次对话。在笔记里记下“OpenAI 兼容接口就是协议层面兼容”这一句,后面换任何推理框架都只在 base_url 上动刀。

2.4 给笔记补上提示词课:一套可复用的问答模板

模型跑通后,第一场真正的 AI 大模型应用实验是提示词设计。很多新手一上来就背各种“高级提示词”,其实真正的问题是角色、上下文、约束没写清楚。下面是一套可直接套用的通用模板:

角色:{role}
任务:回答用户问题。只能依据【参考上下文】作答。
要求:
1. 上下文没有答案时,明确回答“资料中没有相关信息”。
2. 回答不超过 {max_length} 个字。
3. 使用简体中文,分条输出。

【参考上下文】
{context}

【用户问题】
{question}

参数说明:role 让模型带上身份约束;context 是检索到的资料片段,RAG 场景会把这一段动态填进去;max_length 控制回答篇幅;用户问题放结尾,因为模型对输入末尾的内容更敏感。改提示词时一次只改一个变量,对比前后输出差异,才不会把效果好坏归错原因。这套模板同样适用于 AI 编程辅助场景,补全质量差的代码很多时候是上下文没给够,而不是模型能力不够。学习路线走到这里就完成了“部署、调用、调参”的闭环,此时再去看上海交大开源的《动手学大模型》,每一步都能找到对应的可运行示例。

3. 大模型应用开发核心模块:接口封装、上下文与 AI Agent

3.1 三种模型调用方式的取舍

模型部署完成后,应用层先要决定和模型怎么连接。开发中常见三种方式:托管 API 不需要关心显卡和进程,适合原型验证;本地推理服务(Ollama、vLLM)让数据不出内网,适合内部知识库和私有化交付;自行部署推理集群可以指定调度策略,适合高并发场景。LLM 应用开发团队经常在这三者之间纠结。

调用方式 优点 适用场景
托管 API 无需关心显卡和进程 原型验证、快速试错
本地推理服务 数据不离开内网 内部知识库、私有化交付
自建推理集群 可指定调度策略 高并发、多模型统一管理

我一般建议团队从本地 Ollama 起步,等到每秒请求数明显增加时再迁移到 vLLM,因为业务代码始终走 OpenAI 兼容接口,迁移时只需要改一处 base_url。接口抽象的价值就在这一步体现出来:模型是你随时可以替换的组件,应用代码不感知模型身份。对后端团队,推荐直接用 Spring AI 这类框架,它把对话、结构化输出、工具调用封装成一组跟业务更贴近的 API,对 Ollama 也有内置支持,不需要额外搭一层网关。

3.2 用 Spring AI 接入 Ollama 并完成结构化输出

先加配置到 application.yml:

spring:
  ai:
    ollama:
      base-url: http://localhost:11434
      chat:
        model: qwen2.5:7b
        options:
          temperature: 0.3

逻辑说明:这段配置把 Spring AI 的聊天模型指向本地 Ollama 服务,指定模型名和默认采样参数。随后在业务代码里注入 ChatClient:

ChatClient chatClient = ChatClient.builder(chatModel).build();

String answer = chatClient.prompt()
    .user("把下面这句话翻译成英文:大模型应用开发")
    .call()
    .content();

System.out.println(answer);

参数说明:ChatClient 是 Spring AI 对模型调用的统一入口,prompt() 用于拼装用户消息,call() 执行同步调用,content() 取出文本结果。对业务系统来说,真正有价值的是结构化输出:多数业务系统需要模型返回 JSON 而不是散文。在 Spring AI 里把返回结构定义成 Java 类,提示词里描述清楚输出规则,模型输出的内容由框架映射成强类型对象,应用层拿到的不是一串还要自己解析的文本。笔记里建议单列一节:模型输出不直接落库,先做格式校验再进入业务逻辑。

3.3 上下文管理:固定窗口、滑动窗口与 RAG

对话一长,模型会忘记前面说过什么,这是上下文长度限制导致的。处理方式有三种。固定窗口截断最简单:只保留最近若干轮消息,代码里对 messages 做切片,超出长度就把最早的部分丢弃,代价是模型会丢失早期信息,适合客服机器人这类短期会话。滑动窗口做得更细一点:每条消息记录 token 数,累计超过阈值时从前往后删,保证单次请求不会超出模型上下文上限。RAG 则更进一步:把知识库按语义切块、向量化,每次提问只检索最相关的几个片段拼进提示词,模型看到的始终是与当前问题相关的资料。第三种方案实现量最大,但对长文档问答的效果提升也最明显。

做上下文管理时最容易犯的错是把所有历史记录原样发给模型。实际请求量会迅速涨满上下文窗口,费用和延迟同时上升。笔记里可以记一条经验:先回答“这个问题是否需要历史信息”,再决定用哪种方案,而不是一律把全文塞给模型。

3.4 让模型拥有工具能力:AI Agent 的函数调用机制

AI Agent 的核心不是聊天,而是让模型学会调用外部函数。模型本身不执行代码,它负责输出一个结构化的调用意图,由应用代码去执行并回传结果。

{
  "type": "function",
  "function": {
    "name": "search_kb",
    "description": "在知识库中搜索相关文档",
    "parameters": {
      "type": "object",
      "properties": {
        "query": {"type": "string", "description": "搜索关键词"}
      },
      "required": ["query"]
    }
  }
}

这段 JSON 描述一个名为 search_kb 的工具,模型看到后会在需要时返回 tool_calls 字段,里面包含函数名和参数。应用代码接到这个字段后执行真实搜索,再把搜索结果作为新消息回传给模型,模型据此生成最终回答。整个循环是“接收用户问题 → 模型决定调哪个函数 → 执行函数 → 回传结果 → 模型总结回答”,这就是 ReAct 思路在工程上的落地形式。

对这个过程做一轮实操记录,比读十篇 Agent 概念文章都管用。笔记里建议固定记录三件事:工具描述写多详细、模型答非所问时返回什么错误、多轮工具调用最多允许多少次。这三条直接决定 Agent 应用能不能交付。

4. 把笔记写厚:大模型微调与评估的进阶路线

4.1 什么时候值得微调

准备大模型相关岗位面试的开发者都熟悉一个问题:提示词解决不了的问题,是该上 RAG 还是微调?真实答案常是“先都不要”。大部分业务问题先用提示词模板加示例解决,再靠 RAG 补充私有知识,只有少数场景才需要微调。

典型场景 处理优先级
回答需要引用未公开资料 RAG 优先
模型始终不按指定格式输出 提示词加约束,不行再微调
需要模型学会特定说话风格或术语体系 微调
模型数学或逻辑能力不达标 换更大模型优先
需要降低单次调用成本 先量化再考虑蒸馏

微调适合让模型学会一种行为模式,不适合往模型里塞事实知识。把知识库文档拿去微调是最常见的误用,效果差还难以更新。笔记里直接写结论:知识用 RAG 管理,行为用微调校正。

4.2 QLoRA 微调的最小步骤与关键参数

在有限显卡上做微调,最常用的是 QLoRA:量化基座模型 + 低秩适配器,只需要更新一小部分参数。用 7B 模型做指令微调,单卡 24GB 显存基本够用。核心代码:

from transformers import AutoModelForCausalLM, AutoTokenizer, TrainingArguments
from peft import LoraConfig, get_peft_model
from trl import SFTTrainer

model_name = "./qwen2.5-7b-instruct"  # 本地已下载的模型目录
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
    model_name,
    torch_dtype="auto",
    device_map="auto",
)

lora_config = LoraConfig(
    r=16,                  # 低秩矩阵的秩,越大可学习参数越多
    lora_alpha=32,         # 缩放系数,一般取 r 的两倍
    lora_dropout=0.05,     # 防止过拟合的随机丢弃比例
    target_modules=["q_proj", "k_proj", "v_proj", "o_proj"],
)
model = get_peft_model(model, lora_config)

training_args = TrainingArguments(
    output_dir="./qwen-lora",
    per_device_train_batch_size=1,
    gradient_accumulation_steps=8,   # 等效 batch size = 1×8
    learning_rate=2e-4,
    num_train_epochs=3,
    logging_steps=10,
    save_strategy="epoch",
    bf16=True,                        # Ampere 及以上架构显卡可开
)

trainer = SFTTrainer(
    model=model,
    args=training_args,
    train_dataset=dataset,
    tokenizer=tokenizer,
)
trainer.train()

逻辑说明:先把模型权重以量化方式加载进来,对注意力层的四个线性投影挂上 LoRA 适配器,完成“只训练一小部分参数”的准备。训练数据通过 SFTTrainer 的 train_dataset 参数传入,常见格式是 JSON 数组,每条包含 instruction、input、output 三个字段。

参数调整经验:r 从 8 到 32 之间尝试,多数任务 16 够用,过大容易过拟合;lora_alpha 保持 r 的两倍左右;学习率 1e-4 到 3e-4 是常见区间;gradient_accumulation_steps 的作用是攒够梯度再更新一次参数,显存不够时把 batch size 降到 1,再用它补回有效批大小。训练日志里重点看 loss,连续两三个 epoch 不再下降就早停,不必机械跑满轮数。笔记里写清“训练出的是行为,不是知识”,微调后的模型仍需配合 RAG 使用,两个手段是叠加关系,不是替代关系。

4.3 用对抗样例和格式用例做模型评估

大模型投毒测试在日常开发里更多指这一行为:在验证阶段人为构造输入,检查模型是否会被带偏、是否编造答案、是否守不住输出格式。它不需要把测试数据注入训练集,而是在模型上线前用一批刻意设计的样例做回归,常见做法是把这组样例固化成测试集。

import json
import pytest

def ask(question, context=""):
    # 调用本地或线上的模型,返回文本
    ...

def test_json_format():
    reply = ask("把“苹果”翻译成英文,只输出 JSON 对象,字段为 en")
    payload = json.loads(reply)      # 解析失败会直接抛异常
    assert payload["en"] == "apple"

def test_hallucination_when_context_missing():
    context = "材料中只包含产品安装说明。"
    reply = ask("这款产品的保修期是多久?", context)
    assert ("没有" in reply) or ("未提及" in reply)

逻辑说明:第一个用例约束输出必须是合法 JSON,防止模型在关键链路上返回不可解析的文本。第二个用例检查模型是否诚实,上下文没有答案时应当承认不知道,而不是编造保修期。这类用例跑在 CI 里,每次换模型、改提示词、调参数都重跑一遍,靠它兜底才能放心升级。构造测试样例时优先覆盖三类:格式类、事实类、边界类。格式类测输出是否可解析;事实类对比资料判断回答是否忠实;边界类测空上下文、超长输入和完全无关的问题。把失败样例的原始输出记进笔记,慢慢积累出最贴近业务场景的评估集。

5. 把大模型学习笔记变成实验台:回归测试与实验卡片

5.1 用 pytest 给提示词和工具调用做回归

AI 应用开发里最隐蔽的问题不是代码报错,而是模型悄悄变了行为。前两周好用的提示词,这周忽然频繁返回空结果;换一个模型版本后,原本约定的 JSON 格式失效。应对办法是把关键场景固化成 pytest 用例,这也是一种把 AI 测试前置的做法,断言的是行为而不是实现。

def test_tool_description_trigger():
    reply = ask("查一下退货政策", context="<知识库片段>")
    assert "search_kb" in json.dumps(reply)  # 模型应当触发工具调用

逻辑说明:这个用例锁定“工具描述是否被模型识别”这条关键行为。AI 测试用例不需要覆盖全部输出文本,只锁定不可协商的行为点:格式、字段、触发条件。

5.2 一张实验卡片模板,让笔记可复现

模型调用结果受众多变量影响,笔记里只写“效果好”没有任何价值。每次实验至少记录一张卡片:

字段 示例值
模型名与版本 qwen2.5:7b
推理参数 temperature=0.3, num_ctx=8192
提示词版本 retail-qa/v3
输入样例 用户问题 + 参考上下文
期望行为 输出 JSON 且包含 refund_days 字段
实测结果 通过/失败,失败时贴原始输出
改动原因 上一版未覆盖 7 天退货场景

这张卡片解决的是“复现难”问题:相同输入、相同参数、相同提示词版本之下,结果不同才是模型问题,否则先检查环境。

5.3 实验结束后先跑一条命令

实验收尾时,用一条命令快速核对环境:

ollama ps   # 查看当前加载的模型与显存占用

ollama ps 会打印当前加载进显存的模型、上下文长度和已用显存,换模型或调并发后先跑一遍,再用 pytest 跑实验,能省掉不少排障时间。把示例命令、测试文件和实验卡片模板都放进笔记仓库,下一次实验直接复制起点,编号顺延,这条学习路线就变成了可积累的资产。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

更多推荐