
使用 langchain/deepseek 在 LangChain.js 中集成 DeepSeek 聊天模型安装、调用与推理内容解析指南【免费下载链接】langchainjsThe agent engineering platform项目地址: https://gitcode.com/GitHub_Trending/la/langchainjslangchain/deepseek是 LangChain.js 官方维护的 DeepSeek 集成包它让开发者可以像使用任意 LangChain 聊天模型一样通过统一的 Runnable 接口调用 DeepSeek 的deepseek-chat、deepseek-reasoner等模型并直接获得流式输出、Tool Calling工具调用与结构化输出能力。读完本文你将掌握该包的安装配置、ChatDeepSeek类的完整参数体系、推理过程内容reasoning_content的流式解析原理以及如何在本仓库环境下进行开发、测试与构建。包概述与适用场景langchain/deepseek位于本仓库的 libs/providers/langchain-deepseek 目录其核心定位见 README.md为 LangChain.js 提供 DeepSeek 聊天模型推理chat model inference的完整集成。它依赖langchain/openai见 package.json 中的dependencies字段因为 DeepSeek API 与 OpenAI API 兼容包内部复用了 OpenAI 兼容的请求管线。从源码结构看该包只有两个对外导出的模块src/index.ts 中的export * from ./chat_models.js核心是一个ChatDeepSeek类。它的适用场景包括在 LangChain 生态中Runnable 链、Agent、工具调用无缝接入 DeepSeek 模型需要使用推理模型deepseek-reasoner并希望把思考过程与最终回答分离的场景需要流式输出、批量调用、结构化输出Structured Output等 LangChain 标准能力的场景。安装与 API Key 配置安装依赖根据 README.md 的安装说明使用 npm或 pnpm/yarn安装包本体与核心运行时npm install langchain/deepseek langchain/corelangchain/core以 peerDependency 形式存在要求^1.0.0提供消息、Runnable、回调等基础抽象。在 monorepo 环境下本仓库使用 pnpm workspace直接pnpm install即可安装所有依赖。设置 API Key包通过环境变量DEEPSEEK_API_KEY读取密钥两种注入方式任选其一。方式一环境变量推荐也是默认读取路径export DEEPSEEK_API_KEY你的密钥方式二构造函数直接传入apiKey字段。源码 src/chat_models.ts 的构造逻辑为fields.apiKey优先否则回退到getEnvironmentVariable(DEEPSEEK_API_KEY)两者都没有时直接抛出异常提示设置环境变量或传入apiKey字段。同时lc_secrets声明了apiKey: DEEPSEEK_API_KEY的映射序列化/反序列化场景下也能正确还原密钥。构造函数内部还会自动把请求baseURL指向https://api.deepseek.com可通过configuration字段覆盖并把langchain/deepseek的版本号写入调用信息this._addVersion便于服务端排查兼容性问题。ChatDeepSeek 参数体系ChatDeepSeek的输入接口ChatDeepSeekInput定义在 src/chat_models.ts支持两种构造方式源码第 430-439 行new ChatDeepSeek(model: string, fields?)字符串形式的模型名简写new ChatDeepSeek(fields: PartialChatDeepSeekInput)完整对象形式。常用参数如下参数类型默认值说明apiKeystringprocess.env.DEEPSEEK_API_KEYDeepSeek API 密钥缺省时从环境变量读取modelstring必填按需求指定模型名称如deepseek-chat、deepseek-reasonerstop/stopSequencesArraystring无最多 4 个停止序列生成到该序列即停止返回文本不包含停止序列两者互为别名streamingbooleanfalse是否以流式方式请求temperaturenumber由服务端默认采样温度控制输出的随机性maxTokensnumber无单次响应可生成的最大 token 数用于控制计算开销与资源使用configurationobject{ baseURL: https://api.deepseek.com }底层 OpenAI 兼容客户端配置如自定义fetch、超时等这些参数最终合并进ChatOpenAICompletions的字段中因此继承自 OpenAI 集成的大量能力如frequencyPenalty、presencePenalty、topP等同样可用只是未在ChatDeepSeekInput中显式声明。需要确认某个参数是否生效时可以结合 src/chat_models.ts 与 langchain/openai 包的实现对照查看。基本调用invoke 与消息格式最小可用示例import { ChatDeepSeek } from langchain/deepseek; import { HumanMessage } from langchain/core/messages; const model new ChatDeepSeek({ apiKey: process.env.DEEPSEEK_API_KEY, // 默认值可省略 model: model_name, // 例如 deepseek-chat }); const res await model.invoke([ { role: user, content: message, }, ]);除了上面的裸消息对象数组模型也接受字符串输入、HumanMessage等 BaseMessage 消息列表或格式化后的 Prompt见 src/chat_models.ts 的类文档示例。例如const input Translate I love programming into French.; const result await llm.invoke(input);invoke返回标准的AIMessage对象包含content最终回答、additional_kwargs、response_metadata内含tokenUsage与finish_reason、tool_calls等字段。Runtime 参数调用期选项调用期选项ChatDeepSeekCallOptions继承自ChatOpenAICallOptions并允许自定义headers。它们可以作为.invoke/.stream/.batch等 Runnable 方法的第二个参数传入通过.withConfig传入作为第一个参数通过.bindTools的第二个参数传入见 src/chat_models.ts 的类文档示例。// 通过 .withConfig 绑定调用选项 const llmWithArgsBound llm.withConfig({ stop: [\n], tools: [...], }); // 通过 .bindTools 的第二个参数绑定 const llmWithTools llm.bindTools([...], { tool_choice: auto, });流式输出与推理内容reasoning_content解析标准流式调用for await (const chunk of await llm.stream(input)) { console.log(chunk); }流式返回的是AIMessageChunk每个 chunk 携带部分内容response_metadata.finishReason在过程中为null流结束的最后一个 chunk 为stop。若需要聚合完整消息使用concat工具import { AIMessageChunk } from langchain/core/messages; import { concat } from langchain/core/utils/stream; const stream await llm.stream(input); let full: AIMessageChunk | undefined; for await (const chunk of stream) { full !full ? chunk : concat(full, chunk); }DeepSeek 推理内容的特殊处理源码级原理deepseek-reasoner等推理模型在流式返回时会把思考过程放在additional_kwargs.reasoning_content中。源码 src/chat_models.ts 重写了_streamResponseChunks实现了一套独立的think标签解析状态机核心逻辑如下优先透传原生推理字段如果模型本身已返回reasoning_contentchunk 直接原样 yield第 503-506 行标签缓冲与状态机维护tokensBuffer与isThinking两个状态。每当内容中出现think进入思考中状态出现/think时退出。由于 SSE 流会把标签切成多个片段如think实现采用最长前缀贪心匹配第 600-606、656-661 行在安全位置截断缓冲并即时 yield避免因等待完整标签而引入延迟内容分流思考区间的文本进入reasoning_content以空contentadditional_kwargs.reasoning_content的 chunk 形式输出思考区间外的文本正常进入content边界容错流结束时若仍处于思考状态未闭合标签会把剩余缓冲 flush 为推理内容第 705-725 行孤立的/think、未闭合的think、嵌套标签等异常情况均按内容处理不会破坏输出。这些边界行为在 src/tests/chat_models_reasoning.test.ts 中有完整的单元测试覆盖包括标签跨 chunk 拆分think、多个 think 块、空 think 块、嵌套 think、未闭合标签、畸形标签等用例。集成测试 src/tests/chat_models.int.test.ts 则验证了真实调用下invoke/stream返回的内容块中同时包含reasoning类型与text类型的contentBlocks。同时两个消息转换方法_convertCompletionsDeltaToBaseMessageChunk与_convertCompletionsMessageToBaseMessage第 462-485、728-742 行都会在response_metadata中写入model_provider: deepseek便于下游区分 provider 并做相应的内容块翻译。工具调用Tool Calling与结构化输出绑定工具ChatDeepSeek支持标准 OpenAI 风格的工具调用。使用bindTools传入带 Zod schema 的工具定义即可import { z } from zod; const llmForToolCalling new ChatDeepSeek({ model: deepseek-chat, temperature: 0, }); 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 GetPopulation { name: GetPopulation, description: Get the current population in a given location, schema: z.object({ location: z.string().describe(The city and state, e.g. San Francisco, CA) }), }; const llmWithTools llmForToolCalling.bindTools([GetWeather, GetPopulation]); const aiMsg await llmWithTools.invoke( Which city is hotter today and which is bigger: LA or NY? ); console.log(aiMsg.tool_calls);返回的aiMsg.tool_calls是结构化的工具调用数组每项包含name、argsJSON 对象、id等字段可直接路由到真实工具执行。结构化输出withStructuredOutput可以把 Zod schema 直接约束模型的输出格式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 llmForToolCalling.withStructuredOutput(Joke, { name: Joke }); const jokeResult await structuredLlm.invoke(Tell me a joke about cats); console.log(jokeResult);需要特别说明的一个实现细节源码 src/chat_models.ts 的withStructuredOutput重写中有一行注释// Deepseek does not support json schema yet——由于 DeepSeek 当前不支持 JSON Schema 方法当未显式指定method时实现会强制把方法设为functionCalling即通过函数调用的方式间接实现结构化输出。这意味着结构化输出的可用性取决于所用模型对函数调用的支持见下文的模型画像表。模型画像profile 与能力约束ChatDeepSeek实现了profilegettersrc/chat_models.ts返回基于 src/profiles.ts 的模型能力画像。该文件由 profiles.toml 通过pnpm typegen:profiles自动生成目前收录了 4 个模型模型最大输入 token最大输出 token推理输出工具调用结构化输出图像/音频/PDF/视频输入deepseek-chat1000000384000否是否均不支持deepseek-reasoner1000000384000是是否均不支持deepseek-v4-pro1000000384000是是是均不支持deepseek-v4-flash1000000384000是是是均不支持用法示例const model new ChatDeepSeek({ model: deepseek-chat }); const profile model.profile; console.log(profile.maxInputTokens); // 1000000 console.log(profile.imageInputs); // false这段画像数据可以直接用于构建模型路由、容量规划或能力探测逻辑例如在给deepseek-chat绑定时知道其structuredOutput: false加上前文强制 functionCalling 的机制从而提前规避不支持的用法。注意画像为仓库当前快照具体数值与模型清单以 DeepSeek 官方发布为准。在仓库中进行开发、测试与构建如果你想基于本仓库开发或二次贡献langchain/deepseekREADME 的 Development 章节给出了完整流程。安装依赖与构建pnpm install pnpm build或者在仓库根目录只构建本包pnpm build --filter langchain/deepseek构建由 tsdown 完成package.json中build:compile: tsdown产物输出到dist/同时提供 ESMdist/index.js与 CJSdist/index.cjs双格式Node 版本要求20。运行测试测试文件位于src/tests/目录命名约定单元测试以.test.ts结尾集成测试以.int.test.ts结尾。pnpm test # 运行单元测试vitest pnpm test:int # 运行集成测试vitest --mode int需要真实 DEEPSEEK_API_KEY包内还提供了标准测试入口pnpm test:standard会依次运行test:standard:unit与test:standard:int它们基于 langchain/standard-tests 的ChatModelUnitTests基类对ChatDeepSeek的 API Key 初始化、工具调用、结构化输出等能力做统一规格验证参见 src/tests/chat_models.standard.test.ts。代码规范与新增入口pnpm lint pnpm format如果新增了需要导出的文件有两种方式在src/index.ts中 import 并 re-export或者把新入口加入package.json的exports字段后执行pnpm build重新生成产物。目前包对外只暴露一个入口../package.json另算见 package.json 的exports字段。常见问题与注意事项API Key 缺失报错构造ChatDeepSeek时若既未传apiKey也没有DEEPSEEK_API_KEY环境变量会直接抛错请先完成第二节的密钥配置。结构化输出约束DeepSeek 暂不支持 JSON Schema 方法withStructuredOutput会被强制走 functionCalling 路径若所选模型structuredOutput: false如deepseek-chat实际输出可靠性取决于模型自身。推理模型的内容结构使用deepseek-reasoner时请从additional_kwargs.reasoning_content或contentBlocks中的reasoning块读取思考过程从content读取最终回答流式场景下think标签可能被 SSE 拆分本包已内置处理无需手动拼接。baseURL 覆盖默认请求https://api.deepseek.com可通过构造参数configuration.baseURL指向代理或兼容网关如使用configuration.fetch注入自定义请求实现这也是测试代码模拟响应的方式。【免费下载链接】langchainjsThe agent engineering platform项目地址: https://gitcode.com/GitHub_Trending/la/langchainjs创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考