@langchain/mistralai 集成实战:在 LangChain.js 中接入 Mistral 聊天模型、嵌入与代码补全
【免费下载链接】langchainjsThe agent engineering platform项目地址: https://gitcode.com/GitHub_Trending/la/langchainjs
本指南以@langchain/mistralai官方 README 为核心,系统讲解如何在 LangChain.js 项目中安装并接入 Mistral 系列模型:通过ChatMistralAI完成对话与流式输出、借助MistralAIEmbeddings生成文本向量、并利用MistralAI实现以 Codestral 为代表的代码补全(FIM)能力。读完本文,你将掌握完整的环境配置、构造参数含义、工具调用与结构化输出等进阶用法,并了解该包在开源仓库langchainjs中的源码实现细节。
一、包定位与安装
@langchain/mistralai是 LangChain.js 针对 Mistral 官方 SDK(@mistralai/mistralai)的集成包。在仓库中它位于 libs/providers/langchain-mistralai,包内导出三个核心类(见 src/index.ts):
ChatMistralAI:推荐使用的聊天模型集成(封装 Mistral 系列对话模型);MistralAIEmbeddings:Mistral 嵌入模型集成;MistralAI:面向代码补全场景的 LLM 集成(默认对接 Codestral 模型)。
1.1 安装命令
在任意 Node.js(>=20)项目中执行:
npm install @langchain/mistralai @langchain/core该包在 package.json 中声明@mistralai/mistralai: 2.2.1为直接依赖,@langchain/core: ^1.0.0为 peerDependency(peer 依赖版本以仓库当前声明为准,README 中的^0.3.0示例为早期模板写法)。
1.2 统一 @langchain/core 实例
LangChain 生态由多个包组成,如果@langchain/mistralai与项目中的其他 LangChain 包各自解析到不同版本的@langchain/core,可能出现类型不兼容或运行时行为异常。官方推荐在项目package.json中显式锁定版本,README 给出的完整模板如下:
{ "name": "your-project", "version": "0.0.0", "dependencies": { "@langchain/core": "^0.3.0", "@langchain/mistralai": "^0.0.0" }, "resolutions": { "@langchain/core": "^0.3.0" }, "overrides": { "@langchain/core": "^0.3.0" }, "pnpm": { "overrides": { "@langchain/core": "^0.3.0" } } }其中resolutions(yarn)、overrides(npm)、pnpm.overrides(pnpm)分别对应不同包管理器,建议同时声明以最大化兼容性。实际使用时应将版本号替换为你安装的@langchain/core版本,并与 langchainjs 仓库的 package.json 中 pnpm workspace 锁定的版本保持一致。
1.3 配置 API Key
聊天、嵌入、LLM 三个类均支持两种方式提供密钥:构造参数apiKey,或环境变量MISTRAL_API_KEY。若两者均缺失,构造函数会直接抛出异常(源码见 chat_models.ts、embeddings.ts):
export MISTRAL_API_KEY=your-api-key二、ChatMistralAI:聊天模型接入
ChatMistralAI是官方推荐的 Mistral 模型交互入口,继承BaseChatModel,默认模型为mistral-small-latest。
2.1 最小可运行示例
import { ChatMistralAI } from "@langchain/mistralai"; import { HumanMessage } from "@langchain/core/messages"; const model = new ChatMistralAI({ apiKey: process.env.MISTRAL_API_KEY, modelName: "mistral-small", }); const response = await model.invoke(new HumanMessage("Hello world!"));invoke返回标准AIMessage对象,包含content、response_metadata、tool_calls、usage_metadata等字段。
2.2 构造参数详解
源码中ChatMistralAIInput接口(chat_models.ts)定义了以下核心参数:
| 参数 | 类型/默认值 | 说明 |
|---|---|---|
apiKey | 默认读MISTRAL_API_KEY | Mistral API 密钥 |
model | "mistral-small-latest" | 模型名称,推荐写法 |
modelName | 同model | 旧版别名,已标记@deprecated |
temperature | 0.7(范围 0.0~2.0) | 采样温度,越高输出越随机 |
topP | 1(范围 0~1) | 核采样,仅考虑概率质量占比 topP 的 token |
maxTokens | 无默认 | 最大生成 token 数,prompt+maxTokens 不能超过模型上下文长度 |
streaming | false | 是否流式返回 |
safePrompt | false | 是否在对话前注入安全提示词(safeMode为旧别名) |
seed/randomSeed | 无默认 | 随机采样种子,设置后多次调用可复现 |
presencePenalty | 无默认 | 存在惩罚,值越高词汇越多样 |
frequencyPenalty | 无默认 | 频率惩罚,抑制已高频出现词汇的重复 |
numCompletions | 无默认 | 每次请求返回的补全数量,输入 token 只计费一次 |
streamUsage | true | 流式响应中是否携带 token 用量 |
serverURL | 无默认 | 覆盖 Mistral SDK 默认服务地址(endpoint为旧别名) |
beforeRequestHooks/requestErrorHooks/responseHooks | 无默认 | 请求生命周期钩子 |
httpClient | 无默认 | 自定义 HTTP 客户端,可定制 fetch 实现 |
所有字段默认值均可在 chat_models.ts 的类属性声明与构造函数赋值逻辑(L973-L1015)中得到验证。
2.3 流式输出
ChatMistralAI重写了基类的流式链路:内部通过client.chat.stream({ ...input, stream: true })调用 Mistral SDK(chat_models.ts),并将每个增量块转换为AIMessageChunk:
import { ChatMistralAI } from "@langchain/mistralai"; const model = new ChatMistralAI({ apiKey: process.env.MISTRAL_API_KEY, modelName: "mistral-small", }); const stream = await model.stream(new HumanMessage("Hello world!")); for await (const chunk of stream) { console.log(chunk); }每个 chunk 只包含增量片段;若需聚合为完整消息,可用concat工具函数累积合并。流式场景下默认输出 token 用量(streamUsage为 true),最终块的usage_metadata会携带input_tokens/output_tokens/total_tokens。
2.4 工具调用(bindTools)
ChatMistralAI通过bindTools将 LangChain 工具转换为 Mistral 格式(chat_models.ts)。LangChain 工具(如 zod schema 描述的structuredTool)会被转换为{ type: "function", function: { name, description, parameters } },zod schema 自动序列化为 JSON Schema(toJsonSchema,见 _convertToolToMistralTool):
import { z } from "zod"; const GetWeather = { name: "GetWeather", description: "Get the current weather in a given location", schema: z.object({ location: z.string().describe("The city and state, e.g. San Francisco, CA"), }), }; const modelWithTools = model.bindTools([GetWeather], { tool_choice: "auto" }); const aiMsg = await modelWithTools.invoke( "Which city is hotter today: LA or NY?" ); console.log(aiMsg.tool_calls); // [{ name, args, type, id }, ...]调用选项(如tool_choice、response_format)也可通过.invoke第二参数或.withConfig传入。
2.5 结构化输出
配合withStructuredOutput可直接获得符合 zod schema 的 JSON 对象:
import { z } from "zod"; const Joke = z.object({ setup: z.string().describe("The setup of the joke"), punchline: z.string().describe("The punchline to the joke"), rating: z.number().optional().describe("How funny the joke is, from 1 to 10"), }).describe("Joke to tell user."); const structuredLlm = model.withStructuredOutput(Joke, { name: "Joke" }); const jokeResult = await structuredLlm.invoke("Tell me a joke about cats"); // { setup: "...", punchline: "...", rating: 7 }2.6 Token 用量统计
非流式与流式调用均可在结果上读取用量元数据:
const aiMsg = await model.invoke("Hello world!"); console.log(aiMsg.usage_metadata); // { input_tokens: 13, output_tokens: 89, total_tokens: 102 }三、底层消息转换机制
ChatMistralAI与 Mistral API 之间的消息桥接由 convertMessagesToMistralMessages 完成,角色映射规则为:human → user、ai → assistant、system → system、tool → tool、function → assistant。
值得注意的细节:
- 多模态内容:复杂消息内容仅支持
text与image_url两种 chunk 类型,且image_url仅允许出现在user/assistant角色中,其余类型会抛出明确错误(chat_models.ts); - 工具调用一致性:构建请求前会收集所有 tool 响应 ID,过滤掉没有对应响应的助手工具调用,确保 assistant toolCalls 与 tool 响应一一对应(chat_models.ts);
- 流式增量转换:工具调用增量会补上
index字段并映射为tool_call_chunks,流式 token 用量的处理逻辑见 _convertDeltaToMessageChunk。
四、MistralAIEmbeddings:嵌入模型
包内通过MistralAIEmbeddings支持 Mistral 嵌入模型,默认模型为mistral-embed。
4.1 基本用法
import { MistralAIEmbeddings } from "@langchain/mistralai"; const embeddings = new MistralAIEmbeddings({ apiKey: process.env.MISTRAL_API_KEY, }); // 单条文本 const queryEmbedding = await embeddings.embedQuery("Hello world"); // 批量文本 const docEmbeddings = await embeddings.embedDocuments([ "Hello world", "Bye bye", ]);4.2 参数与实现要点
MistralAIEmbeddingsParams(embeddings.ts)中的关键参数:
| 参数 | 默认值 | 说明 |
|---|---|---|
model/modelName | "mistral-embed" | 嵌入模型名 |
encodingFormat | "float" | 输出向量格式 |
batchSize | 512 | 单次请求最多处理的文档数 |
stripNewLines | true | 是否将文本中的换行替换为空格(官方推荐,可能不适合部分场景) |
serverURL | 无默认 | 覆盖 SDK 默认服务地址 |
实现层面(embeddings.ts):
embedDocuments先按batchSize对输入分块(chunkArray),并发发出多个批次请求,再按原始顺序拼接结果;embedQuery单条调用,二者都返回number[];- 请求通过
AsyncCaller包装,自动具备重试能力。
五、MistralAI:面向代码补全的 LLM(FIM)
除了聊天与嵌入,包内还提供继承LLM的MistralAI类(llms.ts),默认模型为codestral-latest,主要面向代码补全场景。
5.1 Fill-In-Middle 支持
MistralAI通过useFim参数控制调用方式:
useFim: true:走 Mistral SDK 的client.fim.complete()/client.fim.stream()接口,支持 "prompt + suffix" 的代码中段补全;useFim: false:退回client.chat.complete()/client.chat.stream(),将 prompt 包装为 user 消息。
默认值由模型名自动推断:名称包含codestral时默认true,否则为false(见 isCodestralModel 与构造函数 L201-L202)。
5.2 参数与调用选项
MistralAIInput除复用temperature(默认 0)、topP、maxTokens、randomSeed、streaming等参数外,还新增:
suffix(调用选项):可选后缀文本,配合 prompt 让模型填充二者之间的内容;不提供时模型执行普通前缀补全;batchSize:默认20,批量生成时按此大小分批;useFim:是否启用 FIM 接口。
import { MistralAI } from "@langchain/mistralai"; const llm = new MistralAI({ apiKey: process.env.MISTRAL_API_KEY, model: "codestral-latest", }); // 前缀补全 const completion = await llm.invoke("def fibonacci(n):"); // FIM 中段补全:model 会根据前后文填充中间代码 const fimResult = await llm.invoke("def foo():", { suffix: "return result", });MistralAI的_generate实现会按batchSize分批并发,并在streaming: true时逐 token 触发handleLLMNewToken回调(llms.ts)。
六、请求钩子与自定义 HTTP 客户端
三个类均支持通过beforeRequestHooks、requestErrorHooks、responseHooks干预请求生命周期,钩子函数签名分别为:
beforeRequest: (req: Request) => Awaitable<Request | void>:可在请求发出前改写请求(如注入鉴权头);requestError: (err: unknown, req: Request) => Awaitable<void>:请求出错时回调;response: (res: Response, req: Request) => Awaitable<void>:收到响应时回调。
内部实现(embeddings.ts 可作参考)会在未提供httpClient但声明了钩子时自动创建HTTPClient,并在实例构造时统一注册钩子。httpClient参数则允许完全接管请求层,例如替换 fetch 实现或接入自有代理。
七、包的开发与测试
README 的 Development 章节面向希望二次开发本包的贡献者,以下命令在仓库根目录执行:
7.1 安装依赖与构建
pnpm install构建当前包:
pnpm build --filter @langchain/mistralai或进入 libs/providers/langchain-mistralai 目录后直接pnpm build。构建工具为 tsdown,产物按 package.json 的exports字段同时输出 ESM(dist/index.js)与 CJS(dist/index.cjs)入口及对应类型声明。
7.2 测试规范
测试文件位于src/tests/下,命名约定:
- 单元测试:以
.test.ts结尾,例如 chat_models.test.ts; - 集成测试:以
.int.test.ts结尾(需要真实 API Key),例如 chat_models.int.test.ts、embeddings.int.test.ts; - 另有基于
@langchain/standard-tests的标准行为测试与流事件测试(chat_models_stream_events.test.ts)。
运行方式:
pnpm test # 单元测试(vitest run) pnpm test:int # 集成测试(vitest run --mode int)7.3 代码质量与新增入口
pnpm lint && pnpm format若在src/下新增需要对外暴露的模块,有两种方式:将其导入并从 src/index.ts 再导出;或在 package.json 的exports字段登记新入口,随后执行pnpm build生成对应产物。
八、小结
@langchain/mistralai为 LangChain.js 提供了对 Mistral 模型家族的一站式接入:ChatMistralAI覆盖对话、流式、工具调用与结构化输出,MistralAIEmbeddings提供批量向量化能力,MistralAI则针对 Codestral 模型实现 Fill-In-Middle 代码补全。本文涉及的源码均可直接在该仓库 libs/providers/langchain-mistralai 目录下查阅,结合 单元测试 与 流事件转换工具 可以进一步深入理解其内部行为。
【免费下载链接】langchainjsThe agent engineering platform项目地址: https://gitcode.com/GitHub_Trending/la/langchainjs
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考