首页
/ generative-ai-for-beginners 第 20 课:用 Mistral Large、Mistral Small 与 Mistral NeMo 构建生成式 AI 应用实战指南

generative-ai-for-beginners 第 20 课:用 Mistral Large、Mistral Small 与 Mistral NeMo 构建生成式 AI 应用实战指南

2026-09-06 19:21:07作者:卓艾滢Kingsley

本指南完整讲解开源课程 generative-ai-for-beginners(21 课时入门课程)第 20 课「用 Mistral 模型构建应用」的核心内容,聚焦 Mistral 家族三种风格迥异的模型——企业级旗舰大模型 Mistral Large 2、低成本低延迟小模型 Mistral Small,以及 Apache 2.0 开源模型 Mistral NeMo。读完本文,你将掌握三个模型的定位差异与适用场景,并能够直接运行文中给出的 RAG 检索增强生成、延迟对比、函数调用式 Token 化对比三组真实代码样例,把它们迁移到自己的原型项目中。

本文依据的源文档为仓库捷克语译本 translations/cs/20-mistral/README.md,内容与仓库主版本 20-mistral/README.md 保持一致;代码样例同时对应可交互执行的 Jupyter Notebook:20-mistral/python/githubmodels-assignment.ipynb

课程背景:本课要解决什么问题

本课覆盖三个学习目标,全部围绕「选对模型、跑通样例」展开:

  • 探索 Mistral 的不同模型(Mistral LargeMistral SmallMistral NeMo);
  • 理解每个模型的用例(use-case)与适用场景;
  • 通过展示每个模型独特能力的代码样例,直观感受它们之间的差异。

课程文档特别强调:这三种模型都可免费用于原型实验(prototyping)——译本文档中指称其为 GitHub 模型市场(GitHub Models)上的免费模型。需要说明的是,仓库主版本 20-mistral/README.mdAGENTS.md 均已标注:GitHub Models 于 2026 年 7 月底退役,当前主文档与 Notebook 推荐改用 Microsoft Foundry Models 提供的模型推理目录来运行本课代码。下文将给出两套环境变量写法,读者按手头可用的服务任选其一即可。

从整个课程结构看,这一课属于「供应商模型专题」,与第 19 课 19-slm/README.md(小语言模型)、第 21 课 21-meta/README.md(Meta 模型)互为姊妹篇,可对照学习。

运行前置:环境变量与依赖

本课全部代码通过 Azure AI Inference SDK(azure.ai.inference)调用模型推理接口,Python 侧依赖清单如下:

依赖包 用途
azure-ai-inference 统一封装 Chat Completions 与 Embeddings 客户端
azure-core 提供 AzureKeyCredential 凭据类型
faiss-cpu 本地向量检索库(RAG 样例的向量存储)
mistral-common Mistral 官方 Tokenizer(NeMo/Large 的 Token 对比样例)
requestsnumpy 拉取语料、数值计算与向量矩阵处理

两种环境变量写法

捷克语译本 translations/cs/20-mistral/README.md 中的代码使用 GitHub Models 时期的写法——端点固定为 https://models.inference.ai.azure.com,凭据取自 GITHUB_TOKEN

endpoint = "https://models.inference.ai.azure.com"
token = os.environ["GITHUB_TOKEN"]

而仓库当前主版本 20-mistral/README.mdgithubmodels-assignment.ipynb 已全部迁移为 Microsoft Foundry Models 写法

# Get these from your Microsoft Foundry project's "Overview" page
endpoint = os.environ["AZURE_INFERENCE_ENDPOINT"]
token = os.environ["AZURE_INFERENCE_CREDENTIAL"]

两种方式殊途同归:AZURE_INFERENCE_ENDPOINT 取代了硬编码端点,AZURE_INFERENCE_CREDENTIAL 取代了退役的 GITHUB_TOKEN。仓库中还提供了配套的密钥管理工具 shared/python/env_utils.pyget_required_env/validate_env_vars),可用于在脚本启动时校验这类环境变量是否已正确配置。环境变量的配置方式(.env 文件、python-dotenv 加载、Codespaces secrets 等)详见 00-course-setup/README.md00-course-setup/02-setup-local.md00-course-setup/03-providers.md

Mistral Large 2 (2407):企业级旗舰大模型

Mistral Large 2 是 Mistral 当前的旗舰模型(flagship model),定位面向企业级(enterprise)使用。它是第一代 Mistral Large 的升级版,三个关键改进构成了它的核心卖点:

能力维度 Mistral Large 2 原版 Mistral Large
上下文窗口 128k 32k
数学与编程任务平均准确率 76.9% 60.4%
多语言表现 英语、法语、德语、西班牙语、意大利语、葡萄牙语、荷兰语、俄语、中文、日语、韩语、阿拉伯语、印地语等 较弱

说明:76.9% 与 60.4% 这两个数字来自课程文档 20-mistral/README.md 的官方描述,属 Mistral 官方对外宣传口径,引用时请以模型官方评测为准。

得益于更大的上下文窗口与原生工具调用能力,Mistral Large 2 在以下三类任务上尤为突出:

  • 检索增强生成(RAG):128k 的超长上下文可以塞进更多检索到的相关片段,供模型综合回答;
  • 函数调用(Function Calling):原生支持函数调用协议,可与外部工具和 API 集成,调用方式既支持并行执行,也支持逐个顺序执行;
  • 代码生成:在 Python、Java、TypeScript、C++ 生成任务上表现优异。

实战:用 Mistral Large 2 跑通一个跨语言 RAG 流程

课程提供了一个非常典型且完整的 RAG 示例,其技术栈是:长文本切块 → Cohere 多语种 Embedding 模型向量化 → FAISS 本地向量检索 → 将检索片段与问题组装成 Prompt → Mistral Large 2 生成自然语言回答

这个例子的精妙之处在于提问是韩语저자가 대학에 오기 전에 주로 했던 두 가지 일은 무엇이었나요?,询问作者上大学前主要做的两件事),充分展示了「多语种 Embedding 检索 + 跨语言问答」的组合能力。文档数据来自 Paul Graham 的随笔。

第一步,安装 FAISS CPU 版:

pip install faiss-cpu

第二步,运行完整 RAG 流程。代码逐段加注了关键逻辑:

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

# 连接模型推理服务(译本使用 GitHub Models 时代的端点与 GITHUB_TOKEN)
endpoint = "https://models.inference.ai.azure.com"
model_name = "Mistral-large"
token = os.environ["GITHUB_TOKEN"]

client = ChatCompletionsClient(
    endpoint=endpoint,
    credential=AzureKeyCredential(token),
)

# 1) 拉取语料: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

# 2) 按 2048 字符切块(chunking)
chunk_size = 2048
chunks = [text[i:i + chunk_size] for i in range(0, len(text), chunk_size)]
len(chunks)

# 3) 用 Cohere 多语种 Embedding 模型为每个文本块生成向量
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
)

# 4) 将向量组装成 numpy 数组,写入 FAISS 索引
text_embeddings = []
for item in embed_response.data:
    length = len(item.embedding)
    text_embeddings.append(item.embedding)
text_embeddings = np.array(text_embeddings)

# 5) 建立 L2 欧氏距离索引(IndexFlatL2 为暴力精确检索)
d = text_embeddings.shape[1]
index = faiss.IndexFlatL2(d)
index.add(text_embeddings)

# 6) 韩语问题同样向量化
question = "저자가 대학에 오기 전에 주로 했던 두 가지 일은 무엇이었나요?"

question_embedding = embed_client.embed(
    input=[question],
    model=embed_model_name
)

question_embeddings = np.array(question_embedding.data[0].embedding)

# 7) 检索最相似的 top-k(k=2)文本块,返回 (距离, 索引)
D, I = index.search(question_embeddings.reshape(1, -1), k=2) # distance, index
retrieved_chunks = [chunks[i] for i in I.tolist()[0]]

# 8) 构造 RAG Prompt:上下文 + 问题,并要求"仅依据给定上下文回答"
prompt = f"""
Context information is below.
---------------------
{retrieved_chunks}
---------------------
Given the context information and not prior knowledge, answer the query.
Query: {question}
Answer:
"""

# 9) 调用 Mistral Large 生成回答
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)

这段代码浓缩了 RAG 的全部核心环节,值得拆解记忆:

步骤 组件/方法 作用
1-2 requests.get + 切片 拉取文档并按 chunk_size=2048 切块
3-4 EmbeddingsClient.embed 将全部文本块编码为向量(多语种模型可处理中/英/韩等多语言)
5 faiss.IndexFlatL2 + index.add 构建本地向量索引,IndexFlatL2 是精确的 L2 距离检索
6-7 index.search(..., k=2) 问题向量检索出最相似的两个文本块
8 Prompt 模板 把检索片段作为上下文注入提示词,并约束模型"不要使用先验知识"
9 ChatCompletionsClient.complete 让 Mistral Large 基于上下文给出自然语言答案

其中 complete() 的生成参数含义如下:temperature=1.0(采样随机性取默认上限附近)、top_p=1.0(不做核采样截断)、max_tokens=1000(回答最长 1000 个 token)、model="Mistral-large"(指定模型,推理目录会自动路由到 Mistral Large 最新版)。

在仓库 githubmodels-assignment.ipynb 的已保存输出中,Mistral Large 给出的答案大致是:作者上大学前主要做两件事——写作(写短篇小说)与编程(九年级时在 IBM 1401 上用早期 Fortran 与穿孔卡片写程序)。你可以把这个真实输出当作跑通全流程的参照基准。

Mistral Small:低成本低延迟的小语言模型(SLM)

Mistral Small 同样属于 premier/enterprise(旗舰/企业)产品线的成员,但从名称即可看出它是一个小语言模型(SLM)。它之所以重要,是因为与大而全的旗舰模型形成互补:

  • 成本节约:相比 Mistral Large、NeMo 这类大模型,价格下降约 80%(课程文档给出的官方口径);
  • 低延迟:响应速度明显快于 Mistral 的大模型;
  • 部署灵活:对资源要求更低,可部署到更多不同环境。

因此 Mistral Small 非常适合:

  • 纯文本类任务:摘要(summarization)、情感分析(sentiment analysis)、翻译;
  • 请求非常高频的应用(成本效益决定),例如大规模批量处理;
  • 低延迟要求的编码任务,如代码评审(code review)与代码补全建议。

关于 SLM 的完整技术背景(为何小模型能跑出大收益、与 LLM 的取舍关系),可以进一步学习第 19 课 19-slm/README.md

实战对比:Mistral Small 与 Mistral Large 的延迟差异

课程设计了一个直观的对照实验:对同一个 Prompt 分别调用 Mistral Small 与 Mistral Large 写一个 Python FizzBuzz 函数。由于系统提示词(system prompt)略有辅助说明,两者都会以"编程助手"身份作答,但你应该能观察到:

  • 响应时间存在 3–5 秒的差距(Small 更快);
  • 回答的长度与风格也明显不同(Large 通常给出更详尽、更结构化的解释)。

Mistral Small 版(模型名 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 版(仅模型名改为 Mistral-large,其余完全一致):

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)

把两个单元格依次执行、对比耗时与输出,就是一次教科书级的「延迟 vs 质量」权衡实验——这也是选型时最重要的判断依据之一。如果你的应用高频调用且对延迟敏感,Small 是首选;如果追求最强推理质量(RAG、复杂代码生成),则应该选择 Large。

Mistral NeMo:Apache 2.0 开源模型

与前两者不同,Mistral NeMo 是本节课讨论的三个模型中唯一采用 Apache 2.0 许可证的免费模型,被视为此前 Mistral 开源大模型 Mistral 7B 的升级换代版本。它的三个特性使它成为开源社区开发者关注的重点:

  • 更高效的 Token 化(Efficient Tokenization):NeMo 使用 Tekken tokenizer,而非更常见的 tiktoken。Tekken 针对更多语言与代码做了优化,因此跨语言、跨代码场景下的 token 效率更高;
  • 可微调(Finetuning):基础模型开放微调,为需要领域适配的用例提供了更大灵活性(微调完整方法论见第 18 课 18-fine-tuning/README.md);
  • 原生函数调用(Native Function Calling):与 Mistral Large 一样经过了函数调用训练,是最早具备该能力的开源模型之一(函数调用的工程实现可结合第 11 课 11-integrating-with-function-calling/README.md 学习)。

实战对比:NeMo 与 Large 的 Tokenizer 效率

判断 Tekken tokenizer 是否真的更省 token,最直接的办法是把同一个请求分别喂给两个模型的 tokenizer,比较输出 token 数。本实验借助 Mistral 官方 mistral-common 包,请求中附带一个天气查询函数(get_current_weather)以模拟真实函数调用场景。

先安装依赖:

pip install mistral-common

Mistral NeMoopen-mistral-nemo)进行 Token 化:

# Importujte potřebné balíčky:(导入所需包)
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

# Načtěte tokenizér Mistral(加载 Mistral tokenizer)
model_name = "open-mistral-nemo"

tokenizer = MistralTokenizer.from_model(model_name)

# Tokenizujte seznam zpráv(对一组消息做 Token 化)
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

# Spočítejte počet tokenů(统计 token 数量)
print(len(tokens))

再用 Mistral Largemistral-large-latest)做完全相同的事,仅替换 model_name

# 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))

代码要点解析:

  • MistralTokenizer.from_model(model_name) 按模型名自动加载对应的 tokenizer 权重;
  • ChatCompletionRequest 携带 toolsmessagesmodel 三段信息,其中 tools 通过 Tool(Function(...)) 声明了一个带 JSON Schema 参数的 get_current_weather 函数(参数 location 为字符串、format 取值限定 celsius/fahrenheit,两者均为 required);
  • encode_chat_completion() 返回的 tokens 是完整消息序列的 token 数组,len(tokens) 即为该请求消耗的 token 数。

两个单元格采用同一 Prompt 与同一函数 Schema,预期结论是 NeMo 返回的 token 数少于 Mistral Large。仓库 Notebook 中保存的真实执行记录恰好印证了这一点:同一请求下,NeMo(open-mistral-nemo)输出 128 个 token(见 githubmodels-assignment.ipynb),Mistral Large(mistral-large-latest)输出 135 个 token(见 githubmodels-assignment.ipynb)。

少 7 个 token 看似微小,但放到高频调用场景下,意味着更低的输入成本、更快的首 token 延迟与更大的有效上下文余量——这正是 Tekken tokenizer 在多语言与代码混合输入上的实际收益。

三个模型如何选择:决策速查

对比维度 Mistral Large 2 Mistral Small Mistral NeMo
定位 企业级旗舰大模型 旗舰线内的小语言模型(SLM) Apache 2.0 开源模型(Mistral 7B 的继任者)
上下文窗口 128k(超长上下文) 较低资源占用即可部署 面向开源/本地/微调场景
核心成本 最高 较 Mistral 大模型省约 80% 开源免费
独特能力 RAG、原生函数调用(并行/串行)、Python/Java/TS/C++ 代码生成 低延迟、高频文本任务、代码评审建议 Tekken tokenizer、可微调、原生函数调用
最佳场景 复杂推理、长文档检索问答 摘要/情感分析/翻译、高频请求、对延迟敏感 需要自托管、微调或完全开源合规的项目

选型建议一句话:追求上限能力选 Large,追求速度与性价比选 Small,追求开放可控选 NeMo。三者同属 Mistral 家族,调用接口(azure.ai.inferenceChatCompletionsClient.complete)完全一致,切换成本仅仅是更换 model_name——这正适合在 Microsoft Foundry 模型目录 中快速做横向对比。

延伸学习:与课程其他主题的衔接

本课是一个自然的"连接点",学完后可与下列课程联动,构建完整的生成式 AI 知识体系:

实践路径建议:先在 githubmodels-assignment.ipynb 中逐格运行三组实验(RAG 跨语言问答、Small vs Large 延迟对比、NeMo vs Large tokenizer 对比),再参照本文速查表为自己的场景选定模型;若需在脚本中管理密钥与端点,可复用 shared/python/env_utils.pyshared/python/api_utils.py 提供的工具函数,避免把凭据硬编码进代码。

登录后查看全文
热门项目推荐
相关项目推荐