generative-ai-for-beginners 第 20 课实战指南:用 Mistral Large / Small / NeMo 构建生成式 AI 应用
【免费下载链接】generative-ai-for-beginners21 Lessons, Get Started Building with Generative AI项目地址: https://gitcode.com/GitHub_Trending/ge/generative-ai-for-beginners
本文基于 generative-ai-for-beginners 课程第 20 课《Building with Mistral Models》(保加利亚语译本见 translations/bg/20-mistral/README.md)展开,带你系统走查 Mistral 家族的三款模型——Mistral Large、Mistral Small和Mistral NeMo:先理解各自的定位与适用场景,再用可复制的 Python 代码完成三组实战——基于 Mistral Large 2 的 RAG(检索增强生成)问答、Small 与 Large 的延迟/风格对比实验,以及 NeMo 与 Large 的 tokenizer 效率实测。学完本篇,你能独立完成"选模型 → 配环境 → 跑通代码 → 读懂输出"的完整流程,并在仓库配套的 Notebook 中复现全部结果。
本课学习目标
按课程文档(20-mistral/README.md)的定义,本课覆盖三个目标:
- 探索 Mistral 的不同模型(Exploring the different Mistral Models);
- 理解每个模型的用例与适用场景;
- 通过示例代码展示每个模型的独特能力。
仓库根目录 README.md 中第 20 课的条目也概括了这一点:"Learn: The features and differences of the Mistral Family Models"(学习 Mistral 家族模型的特性与差异)。
三款 Mistral 模型总览
本课聚焦三款模型,它们均可在模型市场免费调用,本课代码会直接调用这些模型运行:
| 模型 | 定位 | 关键特点 | 典型场景 |
|---|---|---|---|
| Mistral Large 2 (2407) | 旗舰模型,面向企业 | 128k 上下文窗口、原生 Function Calling、多语言(13 种) | RAG、代码生成、工具调用 |
| Mistral Small | 小型语言模型(SLM) | 价格低约 80%、低延迟、部署灵活 | 摘要/情感分析/翻译、高频请求、代码评审建议 |
| Mistral NeMo | 开源模型(Apache 2.0) | Tekken tokenizer、支持微调、原生函数调用 | 需要微调或自托管的场景 |
平台说明:本课(保加利亚语译本)中模型被标注为可在 GitHub Model marketplace 免费使用,代码使用
GITHUB_TOKEN环境变量鉴权。需要注意,仓库英文版课程文档(20-mistral/README.md)及其配套 Notebook 中已注明:GitHub Models 将于 2026 年 7 月底退役,建议改用 Microsoft Foundry Models 进行 AI 模型原型开发,且 Notebook 中已改用AZURE_INFERENCE_ENDPOINT/AZURE_INFERENCE_CREDENTIAL环境变量。若你按本文档旧版代码运行后遇到鉴权或端点问题,优先参照仓库 Notebook 中的最新环境变量写法。
Mistral Large 2 (2407):旗舰模型的能力规格
Mistral Large 2 目前是 Mistral 的旗舰模型,面向企业级使用。相较初代 Mistral Large,文档列出了三点升级:
- 更大的上下文窗口:128k tokens,对比初代的 32k(4 倍);
- 更强的数学与编程能力:平均准确率 76.9%,对比初代的 60.4%(该数据来自课程文档转述的模型评测口径);
- 增强的多语言能力:覆盖英语、法语、德语、西班牙语、意大利语、葡萄牙语、荷兰语、俄语、中文、日语、韩语、阿拉伯语和印地语共 13 种语言。
凭借这些特性,Mistral Large 在以下三类任务上表现突出:
- RAG(检索增强生成):得益于更大的上下文窗口,可以塞入更多检索到的文档片段;
- Function Calling:原生支持函数调用,可与外部工具和 API 集成,调用既支持并行也支持顺序执行;
- 代码生成:在 Python、Java、TypeScript 和 C++ 代码生成上表现优秀。
实战一:用 Mistral Large 2 构建 RAG 问答
下面这个示例使用 Mistral Large 2 对一篇纯文本文档做 RAG 问答。问题是韩语写的,询问作者上大学之前主要从事的两项活动——这恰好同时验证了多语言能力和检索质量。
技术栈要点:
- 使用Cohere Embeddings模型(
cohere-embed-v3-multilingual)对文档切片和问题分别生成向量; - 使用faissPython 包作为向量存储,
IndexFlatL2(欧氏距离精确索引)做近邻检索; - 发给 Mistral 模型的 prompt 同时包含问题与检索到的相似文本片段,模型基于上下文输出自然语言答案。
先安装依赖:
pip install faiss-cpu完整代码如下(继承自课程文档,可直接运行):
import requests import numpy as np import faiss import os from azure.ai.inference import ChatCompletionsClient from azure.ai.inference.models import SystemMessage, UserMessage from azure.core.credentials import AzureKeyCredential from azure.ai.inference import EmbeddingsClient endpoint = "https://models.inference.ai.azure.com" model_name = "Mistral-large" token = os.environ["GITHUB_TOKEN"] client = ChatCompletionsClient( endpoint=endpoint, credential=AzureKeyCredential(token), ) # 拉取 Paul Graham 的随笔原文作为检索语料 response = requests.get('https://raw.githubusercontent.com/run-llama/llama_index/main/docs/docs/examples/data/paul_graham/paul_graham_essay.txt') text = response.text # 按固定长度 2048 字符切片 chunk_size = 2048 chunks = [text[i:i + chunk_size] for i in range(0, len(text), chunk_size)] len(chunks) embed_model_name = "cohere-embed-v3-multilingual" embed_client = EmbeddingsClient( endpoint=endpoint, credential=AzureKeyCredential(token) ) # 对全部文本切片批量生成向量 embed_response = embed_client.embed( input=chunks, model=embed_model_name ) text_embeddings = [] for item in embed_response.data: length = len(item.embedding) text_embeddings.append(item.embedding) text_embeddings = np.array(text_embeddings) # d 为向量维度,IndexFlatL2 表示基于欧氏距离的精确索引 d = text_embeddings.shape[1] index = faiss.IndexFlatL2(d) index.add(text_embeddings) # 韩语问题:作者上大学前主要从事的两件事是什么? question = "저자가 대학에 오기 전에 주로 했던 두 가지 일은 무엇이었나요?" question_embedding = embed_client.embed( input=[question], model=embed_model_name ) question_embeddings = np.array(question_embedding.data[0].embedding) # k=2 表示检索最相似的 2 个片段;D 为距离,I 为命中索引 D, I = index.search(question_embeddings.reshape(1, -1), k=2) # 距离、索引 retrieved_chunks = [chunks[i] for i in I.tolist()[0]] prompt = f""" Context information is below. --------------------- {retrieved_chunks} --------------------- Given the context information and not prior knowledge, answer the query. Query: {question} Answer: """ chat_response = client.complete( messages=[ SystemMessage(content="You are a helpful assistant."), UserMessage(content=prompt), ], temperature=1.0, top_p=1.0, max_tokens=1000, model=model_name ) print(chat_response.choices[0].message.content)几个值得注意的实现细节:
- 切片策略:
chunk_size = 2048是"按字符定长切片"的最简方案。课程文档没有做句子边界切分或重叠(overlap),这在长文档生产场景中是常见的后续优化点; - 检索参数:
index.search(..., k=2)只取最相似的 2 个片段送入 prompt——上下文窗口足够大(128k)时,增加 k 值以纳入更多证据通常是安全的,这也是大上下文模型做 RAG 的天然优势; - 采样参数:
temperature=1.0、top_p=1.0、max_tokens=1000沿用文档默认配置,RAG 场景下回答风格偏"照资料回答",温度取值对事实性影响有限; - prompt 约束:"Given the context information and not prior knowledge" 明确要求模型只依据检索上下文作答,这是抑制幻觉的常用提示词约束。
仓库中已运行的 Notebook 给出了该示例的真实输出,Mistral Large 用英文回答:作者大学前主要从事写作(写短篇故事)和编程(13、14 岁时在 IBM 1401 上用早期 Fortran 通过打孔卡写程序)。韩语提问、英文语料、英文作答,与模型"多语言"特性描述一致。
Mistral Small:低成本、低延迟的 SLM
Mistral Small 同样属于 Mistral 家族中的 premier/enterprise 类别,但顾名思义它是一个小型语言模型(Small Language Model, SLM)。课程文档总结了使用它的三点优势:
- 成本节省:相比 Mistral Large、NeMo 等 LLM,价格下降约 80%(文档口径);
- 低延迟:响应速度比 Mistral 的大模型更快;
- 灵活:可在资源受限的不同环境中部署,约束更少。
对应的适用场景:
- 文本类任务:摘要、情感分析、翻译;
- 高频请求类应用(成本效益高);
- 低延迟代码任务:代码评审与代码建议。
实战二:Small 与 Large 的延迟与风格对比
课程设计了一个对照实验:用完全相同的 prompt("Can you write a Python function to the fizz buzz test?")分别请求两个模型,观察响应时间差(文档预期约 3–5 秒)以及回答的长度与风格差异。
Mistral Small 版本:
import os endpoint = "https://models.inference.ai.azure.com" model_name = "Mistral-small" token = os.environ["GITHUB_TOKEN"] client = ChatCompletionsClient( endpoint=endpoint, credential=AzureKeyCredential(token), ) response = client.complete( messages=[ SystemMessage(content="You are a helpful coding assistant."), UserMessage(content="Can you write a Python function to the fizz buzz test?"), ], temperature=1.0, top_p=1.0, max_tokens=1000, model=model_name ) print(response.choices[0].message.content)Mistral Large 版本(仅model_name不同,其余完全一致):
import os from azure.ai.inference import ChatCompletionsClient from azure.ai.inference.models import SystemMessage, UserMessage from azure.core.credentials import AzureKeyCredential endpoint = "https://models.inference.ai.azure.com" model_name = "Mistral-large" token = os.environ["GITHUB_TOKEN"] client = ChatCompletionsClient( endpoint=endpoint, credential=AzureKeyCredential(token), ) response = client.complete( messages=[ SystemMessage(content="You are a helpful coding assistant."), UserMessage(content="Can you write a Python function to the fizz buzz test?"), ], temperature=1.0, top_p=1.0, max_tokens=1000, model=model_name ) print(response.choices[0].message.content)运行两个单元格的要点:
- 分别记录两次请求的返回耗时,验证 Small 的响应时间优势(文档给出的参考区间是 3–5 秒差距,实际数值会随网络与平台负载浮动);
- 对比两段回答的长度与风格:同一提示下,两个模型的输出详略、注释习惯和结构组织可能不同——这是选模型时"质量/延迟/成本三角"最直观的体感来源。
提示:仓库 Notebook 中这两个单元格的
endpoint已改用os.environ["AZURE_INFERENCE_ENDPOINT"],token改用os.environ["AZURE_INFERENCE_CREDENTIAL"],见 20-mistral/python/githubmodels-assignment.ipynb。
Mistral NeMo:唯一的 Apache 2.0 免费开源模型
与本课另外两款模型相比,Mistral NeMo 是唯一采用 Apache 2.0 许可的免费模型,被视为 Mistral 早期开源 LLM(Mistral 7B)的升级。文档还列出了 NeMo 的三个特性:
- 更高效的 tokenization:使用 Tekken tokenizer,替代更常见的 tiktoken,在更多语言和代码场景下表现更好;
- 支持微调(Finetuning):基础模型开放用于微调,为需要定制的用例提供了灵活性;
- 原生函数调用:与 Mistral Large 一样在函数调用上经过训练,是首批具备该能力的开源模型之一。
实战三:Tokenizer 效率实测(NeMo vs Large)
tokenization 效率直接影响成本(多数 API 按 token 计费)与上下文利用率。课程用一个巧妙的设计来量化这一点:把"函数调用工具定义 + 用户消息"打包成一个完整的ChatCompletionRequest,分别用 NeMo 与 Large 的 tokenizer 编码同一个请求,再比较 token 数。
先安装:
pip install mistral-commonMistral NeMo 的 tokenizer 测试:
# Import needed packages: from mistral_common.protocol.instruct.messages import ( UserMessage, ) from mistral_common.protocol.instruct.request import ChatCompletionRequest from mistral_common.protocol.instruct.tool_calls import ( Function, Tool, ) from mistral_common.tokens.tokenizers.mistral import MistralTokenizer # Load Mistral tokenizer model_name = "open-mistral-nemo" tokenizer = MistralTokenizer.from_model(model_name) # Tokenize a list of messages tokenized = tokenizer.encode_chat_completion( ChatCompletionRequest( tools=[ Tool( function=Function( name="get_current_weather", description="Get the current weather", parameters={ "type": "object", "properties": { "location": { "type": "string", "description": "The city and state, e.g. San Francisco, CA", }, "format": { "type": "string", "enum": ["celsius", "fahrenheit"], "description": "The temperature unit to use. Infer this from the user's location.", }, }, "required": ["location", "format"], }, ) ) ], messages=[ UserMessage(content="What's the weather like today in Paris"), ], model=model_name, ) ) tokens, text = tokenized.tokens, tokenized.text # Count the number of tokens print(len(tokens))Mistral Large 的对照测试(同样请求结构,仅model_name换成mistral-large-latest):
# Import needed packages: from mistral_common.protocol.instruct.messages import ( UserMessage, ) from mistral_common.protocol.instruct.request import ChatCompletionRequest from mistral_common.protocol.instruct.tool_calls import ( Function, Tool, ) from mistral_common.tokens.tokenizers.mistral import MistralTokenizer # Load Mistral tokenizer model_name = "mistral-large-latest" tokenizer = MistralTokenizer.from_model(model_name) # Tokenize a list of messages tokenized = tokenizer.encode_chat_completion( ChatCompletionRequest( tools=[ Tool( function=Function( name="get_current_weather", description="Get the current weather", parameters={ "type": "object", "properties": { "location": { "type": "string", "description": "The city and state, e.g. San Francisco, CA", }, "format": { "type": "string", "enum": ["celsius", "fahrenheit"], "description": "The temperature unit to use. Infer this from the user's location.", }, }, "required": ["location", "format"], }, ) ) ], messages=[ UserMessage(content="What's the weather like today in Paris"), ], model=model_name, ) ) tokens, text = tokenized.tokens, tokenized.text # Count the number of tokens print(len(tokens))设计上有两处值得说明:
- 为什么把
tools也放进编码请求:工具定义(JSON Schema)通常占据大量 token。把"函数调用工具 + 一句话提问"整体编码,模拟的正是 Function Calling 应用的真实请求形态——这正是 NeMo"原生函数调用 + 高效 tokenization"两大特性的交汇处; MistralTokenizer.from_model(...):mistral-common会按模型名自动加载对应 tokenizer 配置,因此同一份代码只需改model_name即可横向比较不同模型的编码效率。
仓库中已运行完成的 Notebook 给出了真实执行结果:
open-mistral-nemo(NeMo tokenizer):128 tokens;mistral-large-latest(Large tokenizer):135 tokens。
即同样一个"天气查询函数 + 提问"的请求,NeMo 的 tokenizer 产出的 token 更少,验证了课程文档"NeMo returns fewer tokens than Mistral Large"的结论。token 越少,在按量计费与上下文占用上越占优,这也是"tokenizer 效率"这一特性可被直接量化的原因。
运行环境:依赖与验证记录
汇总本课全部代码块所需的环境(以仓库 Notebook 的实际运行记录为准,Python 3.12):
| 依赖 | 用途 | Notebook 中的实际版本 |
|---|---|---|
azure-ai-inference | ChatCompletionsClient/EmbeddingsClient(pip install azure-ai-inference) | 随代码环境预装 |
faiss-cpu | 向量索引(IndexFlatL2) | 1.8.0.post1 |
numpy | 向量数组运算 | 1.26.4(faiss-cpu 要求<2.0) |
requests | 拉取文本语料 | 随环境预装 |
mistral-common | MistralTokenizer本地编码 | 1.4.4(自动带上tiktoken 0.7.0、sentencepiece 0.2.0) |
鉴权方面,本课文档(保加利亚语译本)使用GITHUB_TOKEN环境变量;仓库当前 Notebook 已切换到AZURE_INFERENCE_ENDPOINT+AZURE_INFERENCE_CREDENTIAL(见上文"平台说明")。运行前请确保所用平台对应的环境变量已设置,否则os.environ[...]会直接抛出KeyError。
小结与延伸
本课以 Mistral 三款模型为主线完成了一次"模型选型 + 能力验证"的完整闭环:
- Mistral Large 2:大上下文(128k)、原生函数调用、13 种语言,适合 RAG 与复杂代码生成——实战一中你用
cohere-embed-v3-multilingual+ faiss 搭起了最小可用的 RAG 链路; - Mistral Small:约 80% 的价格降幅与更低延迟,适合高频、低延迟场景——实战二的 Fizz Buzz 对照实验让你对"延迟/风格差异"有直接体感;
- Mistral NeMo:Apache 2.0、可微调、原生函数调用,Tekken tokenizer 使其在同一请求下产出更少 token(128 vs 135,仓库 Notebook 实测)——实战三展示了如何量化 tokenizer 效率。
如果希望继续深入,可在同一仓库中延伸阅读:第 16 课 开源模型与 Hugging Face(开源模型选型背景)、第 15 课 RAG 与向量数据库(RAG 的更完整框架实现),本课的 RAG 示例正是其中"嵌入 + 近邻检索 + 受约束 prompt"三要素的最小化落地。
【免费下载链接】generative-ai-for-beginners21 Lessons, Get Started Building with Generative AI项目地址: https://gitcode.com/GitHub_Trending/ge/generative-ai-for-beginners
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考