langchain(node.js)输出解析器

输出解析器

在v1版本之后由于langchain对包的调整引入方式有所调整

常用解析器

在实际开发当中,我们最常用的就是json,list,或者string类型,所以我这边只写了这三种

  1. string
  2. json
  3. list

字符串

ts 复制代码
import dotenv from "dotenv";
import {StringOutputParser} from "@langchain/core/output_parsers";
import {PromptTemplate, ChatPromptTemplate} from "@langchain/core/prompts";
dotenv.config();
function getModel(modelName) {
    return new ChatOpenAI({
        apiKey: process.env.API_KEY,
        model: modelName || "gpt-4o-mini",
        configuration: {
            baseURL: process.env.BASE_URL,
        },
    });
}
cosnt model = getModel();
// 创建解析器
const strParser = new StringOutputParser();
// 方式1.
const chain = RunnableSequence.from([
    prompt,
    model,
    strParser,
]);

const chain2 =prompt.pipe(model).pipe(strParser);

async function translate(question) {
    return await chain.invoke({job: "英语人员", question});
}
translate('hello langchain');  // 这样就返回字符串

返回数组

ts 复制代码
import { CommaSeparatedListOutputParser } from '@langchain/core/output_parsers';
import { PromptTemplate } from "@langchain/core/prompts"
import { getModel } from "../model/index.js";
import { RunnableSequence } from '@langchain/core/runnables';


const model = getModel();
// 创建解析器
const parser = new CommaSeparatedListOutputParser();

const formatInstruction = parser.getFormatInstructions();

const prompt = new PromptTemplate({
     template:'请生成5个{text},\n\n{formatInstructions}',
     inputVariables: ['text'],
     partialVariables:{
       // 这里用上面的
        formatInstructions :formatInstruction
     }
})

const chain = prompt.pipe(model).pipe(parser);
const res = await chain.invoke('水果');

//当然了,也可以
const prompt2 = await new PromptTemplate({
     template:'请生成5个{text},\n\n{formatInstructions}',
     inputVariables: ['text'],
}).partial({
    formatInstructions: formatInstruction
});

const chain2 = prompt.pipe(model).pipe(parser);
const res2 = await chain2.invoke('电影');

返回json1

ts 复制代码
// 返回json用这个
import { StructuredOutputParser } from '@langchain/core/output_parsers';
import { RunnableSequence } from '@langchain/core/runnables'
import { PromptTemplate } from '@langchain/core/prompts';
import { getModel } from "../model/index.js"
import { z } from 'zod';

// 描述键值对
const personSchema = z.object({
    question: z.string().describe("The customer's question"),
    answer: z.string().describe("The AI's answer to the customer's question"),
});
// 这样你可以配合zod来控制输入的格式,比如必须是字符串等
const parser = StructuredOutputParser.fromZodSchema(personSchema);

const formatInstructions = parser.getFormatInstructions();

const prompt = new PromptTemplate({
    template: `you're a helpful AI assistant. you will answer this {description} {format_instruction}`,
    inputVariables: ['description'],
    partialVariables: { format_instruction: formatInstructions },
});

const model = getModel();
// 方式1
const chain = prompt.pipe(model).pipe(parser);

// 方式2
// const chain = RunnableSequence.from([prompt, model, parser]);

async function generatePersonInfo(description) {
    const result = await chain.invoke({ description });
    console.log("Generated Person Info:", result);
}

generatePersonInfo('什么是ai?');

返回json2

ts 复制代码
import { getModel } from "../model/index.js"
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { RunnableSequence } from '@langchain/core/runnables'
import { StructuredOutputParser } from "@langchain/core/output_parsers"

const model = getModel()

const chatPrompt = ChatPromptTemplate.fromMessages([
    ["system", "你是一个靠谱的{role}"],
    ["human", "{question}"],
]);
// 这种方式没法控制
const structuredParser = StructuredOutputParser.fromNamesAndDescriptions({
    q: "问题内容",
    a: "回答内容"
});

const chatChain = RunnableSequence.from([
    chatPrompt,
    model,
    structuredParser,
])

async function query(params) {
    const result = await chatChain.invoke({ role: params.role, question: params.question })
    console.log(result, typeof result);
}

const formatInstructions = structuredParser.getFormatInstructions();
query({
    role: "助手",
    question: `人工智能用英语怎么说?\n\n${formatInstructions}`
})

流式输出

ts 复制代码
async function streamWithJsonParser(description) {
    const rawStream = await prompt.pipe(model).stream({ description });
    
    let bufferedJson = '';
    
    for await (const chunk of rawStream) {
        const content = chunk.content;
        bufferedJson += content;
    }
    
    // 如果是前后端交互,需要返回bufferedJson 而不是解析之后的,这么做的目的是为了我们好看结果
     return await parser.invoke(bufferedJson);
     // 这么做,会直接把结果一下子返回来
}

	streamWithJsonParser('什么是ai?').then((res) => {
	    console.log(res);
	});
js 复制代码
        async function streamMode(question) {
            try {
                const response = await fetch('/api/stream', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ question })
                });
               
                const reader = response.body.getReader();
                const decoder = new TextDecoder();
                let fullContent = '';
                resultDiv.innerHTML = '';
                
                while (true) {
                    const { done, value } = await reader.read();
                    if (done) break;
                    
                    const chunk = decoder.decode(value);
                    const lines = chunk.split('\n');
                    
                    for (const line of lines) {
                        if (line.startsWith('data: ')) {
                            try {
                                const data = JSON.parse(line.slice(6));
                                
                                if (data.done) {
                                    resultDiv.classList.remove('loading');
                                } else if (data.content) {
                                    fullContent += data.content;
                    
                            } catch (e) {
                                console.error('解析行失败:', e);
                            }
                        }
                    }
                }
            } 
相关推荐
iDao技术魔方3 小时前
Node.js v26.5.0 深度解读:import Text、流式 ReadableStreamTee、以及隐藏的安全加固浪潮
安全·node.js
吃饱了得干活5 小时前
别只会传 temperature!一文挖透 LangChain 模型配置:Profile、全参数与运行时动态覆盖
python·langchain
BAIGAOa5 小时前
还在手写 if-else 响应按键?我用 React-Ink 搭配键盘引擎解决了
node.js
龙腾亚太6 小时前
基础差/零基础人员具身智能学习路线
langchain·qlora·大模型培训·智能体培训·具身智能培训·llm 实战教程
Excel效率人7 小时前
飞书自动回复机器人开发:@机器人自助查询物流信息
机器人·node.js·飞书
xywww16812 小时前
大模型 API 选型实战:GPT、Gemini、Claude 接入时该看哪些指标?
运维·服务器·人工智能·python·gpt·langchain
糖果店的幽灵1 天前
从 GPT Researcher 学习 LangChain
gpt·学习·langchain
吃饱了得干活1 天前
LangChain 模型调用方案:invoke、stream、batch 的同步与异步
langchain·llm
先吃饱再说1 天前
从“地狱”到“楼梯”再到“同步写法”:Node.js 异步的二十年与Node内置fs模块详解
node.js
知识收割者1 天前
Nodejs也能写Agent - 10.LangChain篇 - 初识LangChain
node.js