各位掘友,大家好!我是你们的 AI 效率教练。
在使用 DeepSeek 或者 GPT 开发应用时,你是否遇到过这样的尴尬:
你:请给我输出一个关于“Promise”的 JSON。
AI:好的,没问题!这是一个关于 Promise 的 JSON 格式:
json { "name": "Promise" ... }记得给点赞哦!
焯! 那个“好的,没问题”和 Markdown 的反引号直接让 JSON.parse 报错了,有没有?在生产环境下,我们需要的不是对话,而是纯净、稳定、符合 Schema 的 API 响应。
今天,我们就以一个“前端概念知识库生成器”为例,深度拆解 LangChain 中的四大金刚:ChatDeepSeek、Zod、JsonOutputParser 和 PromptTemplate。
🛠️ 核心装备清单
在开始撸代码前,先看看我们的武器库:
- ChatDeepSeek: 目前国产大模型之光,性价比极高,推理能力(Reasoner)直接对标顶级模型。
- Zod: 前端界 Schema 校验的霸主,定义数据结构的“法律条文”。
- JsonOutputParser: LangChain 的“翻译官”,负责将 AI 的长篇大论修剪成规整的 JSON。
- PromptTemplate: 提示词模板,解决 Prompt 复用的关键。
终端运行
npm i langchain @langchain/deepseek @langchain/core zod导入上述所有依赖,pnpm一样看个人选择
🏗️ 第一步:定义规则(Zod)
在 LangChain 的工作流中,先定规矩,再写逻辑。我们希望模型生成的每一个概念都包含:名称、核心要点、使用场景和难度。
TypeScript
import { z } from 'zod';
// 使用 Zod 定义前端概念的“数字身份证”
const FrontendConceptSchema = z.object({
name: z.string().describe('概念名称'),
core: z.string().describe('核心要点'),
usecase: z.array(z.string()).describe('场景使用场景'),
difficulty: z.enum(['简单', '中等', '复杂']).describe('学习难度')
});
💡 为什么是 Zod?
Zod 不仅仅是做类型检查,它最强大的地方在于 .describe()。
这个方法描述的文字会被 JsonOutputParser 自动提取并喂给 AI。AI 看到这些描述,就知道该字段具体的含义,极大提高了生成的准确性。
🧬 第二步:初始化解析器(JsonOutputParser)
有了规矩,我们需要一个执行官来监督 AI 的输出。
javaScript
import { JsonOutputParser } from '@langchain/core/output_parsers';
// 将我们刚才定义的 Zod Schema 传给解析器
const jsonParser = new JsonOutputParser(FrontendConceptSchema);// 从z提取生成格式约束prompt
知识点解析:
JsonOutputParser 扮演了两个角色:
- 指导者:它提供了一个
getFormatInstructions()方法,能自动生成一段“严厉”的提示词,告诉 AI 必须输出什么样的 JSON。 - 质检员:当模型返回字符串时,它会自动运行校验逻辑。如果格式不对,它会直接抛出错误或尝试修复。
🎨 第三步:构建动态 Prompt 模板
写 Prompt 最忌讳硬编码。我们要写一个万能模板,让它可以动态生成任何概念的词条。
javaScript
import { PromptTemplate } from '@langchain/core/prompts';
const prompt = PromptTemplate.fromTemplate(`
你是一个专业的前端技术专家,只会输出 JSON 的 API,不允许输出任何解释性文字。
⚠️ 你必须【只返回】符合以下 Schema 的 JSON:
- 不允许增加字段
- 不允许减少字段
- 字段名必须完全一致
- 返回结果必须可以被 JSON.parse 成功解析
{format_instructions}
你要解析的前端概念是:{topic}
`);
🧠 深度思考:{format_instructions} 是什么?
当你调用 jsonParser.getFormatInstructions() 时,它会生成类似下面这段话:
"The output should be formatted as a JSON instance that conforms to the JSON schema below. As an example, for the schema..."
“输出应格式化为符合以下 JSON Schema 的 JSON 实例。例如,对于该 Schema……”
这就是 LangChain 的迷人之处:自动化。 你不需要手动手写那冗长的 JSON 定义。
🤖 第四步:召唤 DeepSeek 推理引擎
DeepSeek 的 deepseek-reasoner(R1 模型)在逻辑推理上非常出色,非常适合处理结构化数据的提取。
javaScript
import { ChatDeepSeek } from '@langchain/deepseek';
import 'dotenv/config';
const model = new ChatDeepSeek({
model: 'deepseek-reasoner',
temperature: 0, // 设为 0,保证输出的稳定性,不要让 AI 太“浪”
});
注意: 对于解析 JSON 的任务,temperature 务必设为 0。我们要的是确定性,而不是诗情画意。
🔗 第五步:组装 LCEL 链(终极合体)
LangChain 最引以为傲的就是其 LCEL (LangChain Expression Language) 。我们可以像搭积木一样用 .pipe() 将各个组件连接起来。
javaScript
// 1. 提示词编译 -> 2. 模型调用 -> 3. JSON 解析器验证
const chain = prompt.pipe(model).pipe(jsonParser);
// 执行工作流
const response = await chain.invoke({
topic: 'Promise',
format_instructions: jsonParser.getFormatInstructions(),
});
console.log('✨ 最终解析到的结构化数据:');
console.log(response);
🔄 工作流原理解析
- 输入阶段:我们将
topic和format_instructions注入模板。 - 模型阶段:
ChatDeepSeek接收到 Prompt。由于 Prompt 里明确要求“只输出 JSON”,加上 DeepSeek 强大的指令遵循能力,它会返回一个 JSON 字符串。 - 解析阶段:
JsonOutputParser拿到字符串,去掉可能存在的 Markdown 标签(如 ```json),然后用Zod进行校验。 - 输出阶段:你拿到的不再是字符串,而是一个可以直接调用的 JavaScript 对象。
完整代码
javaScript
import {ChatDeepSeek} from '@langchain/deepseek'
import {PromptTemplate} from '@langchain/core/prompts'
import {JsonOutputParser} from '@langchain/core/output_parsers'// 引入 json 解析器
import {z} from 'zod'
import 'dotenv/config'
const model = new ChatDeepSeek({
model: 'deepseek-reasoner',
temperature: 0,
});
// 前端概念 zod 校验 对象
const FrontendConceptSchema = z.object({
name: z.string().describe('概念名称'),
core: z.string().describe('核心要点'),
usecase: z.array(z.string()).describe('场景使用场景'),
difficulty: z.enum(['简单', '中等', '复杂']).describe('学习难度')
});
// console.log(FrontendConceptSchema);
const jsonParser = new JsonOutputParser(FrontendConceptSchema);
const prompt = PromptTemplate.fromTemplate(`
你是一个只会输出 JSON 的 API,不允许输出任何解释性文字。
⚠️ 你必须【只返回】符合以下 Schema 的 JSON:
- 不允许增加字段
- 不允许减少字段
- 字段名必须完全一致,使用name、core、useCase、difficulty
- 返回结果必须可以被 JSON.parse 成功解析
{format_instructions} // 类似于schema的描述告诉ai输出的json格式
前端概念:{topic}
`);
// chain 提示词编译->模型调用->json解析器验证
const chain = prompt.pipe(model).pipe(jsonParser);
console.log(jsonParser.getFormatInstructions(),'zod');
const response = await chain.invoke({
topic:'promise',
format_instructions: jsonParser.getFormatInstructions(),// 在这里传入一段严格的格式约束prompt
})
console.log(response);
🛠️ 实战避坑指南
1. 字段名大小写敏感
注意 Zod 中的 usecase 和 Prompt 里如果手写了 useCase,可能会导致校验失败。建议始终以 Zod 定义为准,并使用 getFormatInstructions 自动生成说明,减少人肉拼写的失误。
2. DeepSeek 的思考过程
如果你使用的是 deepseek-reasoner,它会包含一段 reasoning_content(思考过程)。LangChain 的 ChatDeepSeek 适配器通常会自动处理,但如果你发现输出中夹杂了思考逻辑,可以在 Prompt 中通过 JsonOutputParser 的指令强制约束其输出范围。
🌟 总结
通过这一套组合拳,我们完成了一个从非结构化需求到结构化数据的转化。
- Zod 负责定义数据的“骨架”。
- PromptTemplate 负责包装“灵魂”。
- DeepSeek 提供强大的“脑力”。
- JsonOutputParser 则是最后的“质检员”。
这不仅是一个简单的脚本,更是所有复杂 AI Agent 的基石。当你学会了如何让 AI 输出可预测的数据,你就真正掌握了构建生产级 AI 应用的钥匙!