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);
                            }
                        }
                    }
                }
            } 
相关推荐
风舞红枫1 小时前
node代理vue打包后的文件,实现本地测试
前端·javascript·vue.js·node.js
Jerry Lau2 小时前
从 Express 到 Cloudflare Workers:一次 POC 验证之旅
node.js·express
千里马-horse2 小时前
CallbackInfo
c++·node.js·napi·callbackinfo
小芳矶4 小时前
【langchain框架—组合链】利用组合链完成客服优先等级的划分
langchain
亮子AI4 小时前
【npm】如何创建自己的npm私有仓库?
前端·npm·node.js
有点笨的蛋5 小时前
LangChain 入门与实践:从 LLM 调用到 AI 工作流的工程化思维
前端·langchain
工藤学编程5 小时前
AI Ping 赋能:基于 GLM-4.7(免费!)+ LangChain + Redis 打造智能AI聊天助手
人工智能·redis·langchain
莫渊博-天下无病5 小时前
node高版本安装
运维·node.js
啊吧怪不啊吧5 小时前
新品限免|国产大模型工程化实战:GLM-4.7与MiniMax M2.1 免费选型对比
人工智能·机器学习·langchain
tmj015 小时前
前端JavaScript(浏览器)与后端JavaScript(Node.js)
javascript·node.js