准备好node,pnpm环境 – LangChain Demo

释放双眼,带上耳机,听听看~!
本文介绍了如何准备node和pnpm环境,并使用LangChain进行数据摄取和切割的步骤。

准备好node,pnpm环境。

初始化项目

先创建一个空的文件夹langchain-demo,执行命令以下命令初始化一个项目。

cd langchain-demo/
pnpm init

接下来,我们准备一个测试数据,然后将数据摄取到向量数据库中。具体步骤如下:
首先在根目录下创建一个 ingest-data.js
然后在项目根目录下执行如下命令:

# 安装LangChain
pnpm i langchain

安装完成后:修改package.json文件,如图所示,增加"type": "module"
准备好node,pnpm环境 - LangChain Demo

读取数据

准备数据

先准备一个markdown格式的文件。可以直接在网上找一个,比如Vue3的官方文档。然后在页面文档选中一部分,打开F12通过输入命令$0.innerHTML并回车后即可获得数据。简单如图所示:
准备好node,pnpm环境 - LangChain Demo

准备好node,pnpm环境 - LangChain Demo

或者自行准备数据也可。
将网页中爬取的文本内容copy到 html-to-markdown网站上,转换成markdown。并将转换后的文件放在项目根目录下的vue3-document.md中,如图所示
准备好node,pnpm环境 - LangChain Demo

读取数据

编辑我们在之前已经准备好的文件ingest-data.js,文件内容如下:

// 读取markdown文件
import { UnstructuredLoader } from "langchain/document_loaders/fs/unstructured";

// 实例化  并传入数据的路径
const unstructuredLoader = new UnstructuredLoader("./vue3-document.md");

// 读取文件,这是个promise 使用await
const docs = await unstructuredLoader.load()

console.log(docs)

然后通过如下命令进行验证:

cd langchain-demo/
node ingest-data.js

执行成功结果如图所示:
准备好node,pnpm环境 - LangChain Demo

切割数据

继续编写ingest-data.js具体如下:

// 1. 读取markdown文件
import { UnstructuredLoader } from "langchain/document_loaders/fs/unstructured";

// 2. 文档拆分,将文档拆分成一块一块的
// 2.1 导入langchain提供的拆分工具
import { RecursiveCharacterTextSplitter } from "langchain/text_splitter"


// 1.1 实例化UnstructuredLoader  并传入数据的路径
const unstructuredLoader = new UnstructuredLoader("./vue3-document.md");

// 1.2 读取文件,这是个promise 使用await
const rawDocs = await unstructuredLoader.load()
// 1.3
console.log(rawDocs)

// 2.2 实例化 RecursiveCharacterTextSplitter
const splitter = new RecursiveCharacterTextSplitter({
    // 一段文本按照1000的大小去拆分
    chunkSize: 1000,
    // 当前一段文本与上一段文本重叠的大小为200
    chunkOverlap: 200
});
// 2.3 切分数据
const docs = await splitter.splitDocuments(rawDocs);

// 打印
console.log(docs);

然后通过如下命令进行验证:

cd langchain-demo/
node ingest-data.js

成功结果如图所示:对比之前多了一个 loc: [Object]
准备好node,pnpm环境 - LangChain Demo

接入向量数据库

这里选择的向量数据库是:pinecone
具体可参考官网文档自行选择:

python.langchain.com/docs/get_st…

准备好node,pnpm环境 - LangChain Demo
根据官网安装手册进行安装

python.langchain.com/docs/module…

准备好node,pnpm环境 - LangChain Demo

pip install pinecone-client openai tiktoken
# dotenv用来读取环境变量 安装向量数据库
pnpm install -S dotenv langchain @pinecone-database/pinecone

将数据写入向量数据库

这里采用的是Pinecone向量数据库。
首先我们要注册一个Pinecone的数据库。官网地址:

www.pinecone.io/

注册完成后我们需要创建一个Index,如图所示操作:
准备好node,pnpm环境 - LangChain Demo
准备好node,pnpm环境 - LangChain Demo

注意文中的数字1536不要写错。

同时我们要记住自己创建的Index Name并找到,API Key,以及environment� 记下来,后面会用到。
准备好node,pnpm环境 - LangChain Demo
完成上述操作后 接下来继续编辑ingest-data.js文件,如下所示:

// 1. 读取markdown文件
import { UnstructuredLoader } from "langchain/document_loaders/fs/unstructured";

// 2. 文档拆分,将文档拆分成一块一块的
// 2.1 导入 langchain 提供的拆分工具
import { RecursiveCharacterTextSplitter } from "langchain/text_splitter";
// 利用这个将数据放入向量数据库里面
import { PineconeStore } from "langchain/vectorstores/pinecone"
import { OpenAIEmbeddings } from "langchain/embeddings/openai"

// 3. 导入向量数据库
import { PineconeClient } from "@pinecone-database/pinecone";

// 读取环境变量
import dotenv from "dotenv";
dotenv.config();


// 1.1 实例化UnstructuredLoader  并传入数据的路径
const unstructuredLoader = new UnstructuredLoader("./vue3-document.md");

// 1.2 读取文件,这是个promise 使用await
const rawDocs = await unstructuredLoader.load();
// 1.3
//console.log(rawDocs);

// 2.2 实例化 RecursiveCharacterTextSplitter
const splitter = new RecursiveCharacterTextSplitter({
    // 一段文本按照1000的大小去拆分
    chunkSize: 1000,
    // 当前一段文本与上一段文本重叠的大小为200
    chunkOverlap: 200
});
// 2.3 切分数据
const docs = await splitter.splitDocuments(rawDocs);

// 打印
//console.log(docs);

// 3.1 初始化 pinecone
const pineconeClient = new PineconeClient();
await pineconeClient.init({
    apiKey: process.env.PINECONE_API_KEY,
    environment: process.env.PINECONE_ENV,
});

const pineconeIndex = pineconeClient.Index(process.env.PINECONE_INDEX);

try {
    PineconeStore.fromDocuments(docs, new OpenAIEmbeddings(),{
        // 向量数据库的信息
        pineconeIndex,
        textKey: "text",
        namespace: "teach-vue3-document",
    });
}catch (e) {
    console.log(e)
}

同时在项目根目录下创建一个.env文件,文件内容如下:

OPENAI_API_KEY="your openai key"
PINECONE_API_KEY="pinecone api key"
PINECONE_ENV="environment"
PINECONE_INDEX="index name"

完成上述操作后,执行如下命令:

cd langchain-demo/
node ingest-data.js

运行成功结果如图所示:
准备好node,pnpm环境 - LangChain Demo
准备好node,pnpm环境 - LangChain Demo
通过Pinecone的控制台我们可以看到,文档数据已经成功的写入到了向量数据库中。

构建chains

创建一个chain.js,内容如下:

import { ConversationalRetrievalQAChain } from "langchain/chains";
// 导入大语言模型
import {OpenAI} from "langchain/llms/openai"
import { PineconeClient } from "@pinecone-database/pinecone";
import { PineconeStore } from "langchain/vectorstores/pinecone"
import { OpenAIEmbeddings } from "langchain/embeddings/openai"
// 读取环境变量
import dotenv from "dotenv";
dotenv.config();

// 创建大语言模型
const model = new OpenAI({
    // 准确度,越小越精准,越大越具有创造性
    temperature: 0,
});

// 创建向量数据库
const pineconeClient = new PineconeClient();
await pineconeClient.init({
    apiKey: process.env.PINECONE_API_KEY,
    environment: process.env.PINECONE_ENV,
});
const pineconeIndex = pineconeClient.Index(process.env.PINECONE_INDEX);
const pineconeStore = await PineconeStore.fromExistingIndex(new OpenAIEmbeddings(), {
    // 向量数据库的信息
    pineconeIndex,
    textKey: "text",
    namespace: "teach-vue3-document",
});

const chain = ConversationalRetrievalQAChain.fromLLM(
    model,
    pineconeStore.asRetriever(),{
        // 返回信息是参考了什么资料的开关 sourceDocuments:
        returnSourceDocuments: true,
    });
const res = await chain.call({
    question: "vue3 如何为为 reactive() 标注类型  请给我写一个demo",
    // 聊天历史,也就是记忆的功能
    chat_history: [],
});

console.log(res);

// langchain 0.90版本这样写有问题,具体可参考:

// const secondRes = await chain.call({
//     question: "能否提供更多的demo",
//     // 聊天历史,也就是记忆的功能
//     chat_history: [
//         "vue3 如何为 ref() 标注类型 请给我写一个demo",
//         res.text
//     ],
// });

console.log(secondRes);

完成上述操作后,执行如下命令:

cd langchain-demo/
node ingest-data.js

运行结果如下:
准备好node,pnpm环境 - LangChain Demo
其实我个人认为这个结果不如人意,但是至少这样做的方向是正确的。

构建后端

  1. 使用koa-setup构建后端
# 安装koa-setup
npm install -g koa-setup

koa-setup

如图:
准备好node,pnpm环境 - LangChain Demo

  1. 然后修改生成的server文件夹中的package.json文件中的type为module。并添加**”dev”: “nodemon index.js”�**如图:

准备好node,pnpm环境 - LangChain Demo

  1. 修改server文件夹下的index.js文件,如下:

import Koa from "koa"
import Router from "koa-router"
import { koaBody } from "koa-body";


// const Koa = require("koa")
// const Router = require("koa-router")
// const koaBody = require("koa-body")


const app = new Koa()

app.use(koaBody({
    multipart:true
}))


const router = new Router()
router.get("/",(ctx)=>{
    ctx.body = "hello server"
})
app.use(router.routes())


app.listen(8080,()=>{
    console.log("open server localhost:8080")
})

  1. 安装nodemon
cd server/
pnpm i nodemon -D

nodemon类似于热部署,修改代码无需重新启动。

准备好node,pnpm环境 - LangChain Demo

  1. 启动项目
pnpm dev

启动成功:
准备好node,pnpm环境 - LangChain Demo
准备好node,pnpm环境 - LangChain Demo

构建API

chat.js ingest-data.js vue3-document.md .env文件移动到server文件夹下,如图:
准备好node,pnpm环境 - LangChain Demo
然后修改index.js和chat.js,详情如下:
index.js

import Koa from "koa"
import Router from "koa-router"
import { koaBody } from "koa-body";
import { chat } from "./chain.js";


// const Koa = require("koa")
// const Router = require("koa-router")
// const koaBody = require("koa-body")


const app = new Koa()

app.use(koaBody({
    multipart:true
}))


const router = new Router()
router.get("/",(ctx)=>{
    ctx.body = "hello server"
})

// 编写接口
router.post("/chat",async (ctx) => {
    const { message } = ctx.request.body;
    const result  = await chat(message)

    ctx.body = {
        data: result,
        state: 1,
    }
})

app.use(router.routes())


app.listen(8080,()=>{
    console.log("open server localhost:8080")
})

�chat.js

import { ConversationalRetrievalQAChain } from "langchain/chains";
// 导入大语言模型
import {OpenAI} from "langchain/llms/openai"
import { PineconeClient } from "@pinecone-database/pinecone";
import { PineconeStore } from "langchain/vectorstores/pinecone"
import { OpenAIEmbeddings } from "langchain/embeddings/openai"
// 读取环境变量
import dotenv from "dotenv";
dotenv.config();

// 创建大语言模型
const model = new OpenAI({
    // 准确度,越小越精准,越大越具有创造性
    temperature: 0,
});

// 创建向量数据库
const pineconeClient = new PineconeClient();
await pineconeClient.init({
    apiKey: process.env.PINECONE_API_KEY,
    environment: process.env.PINECONE_ENV,
});
const pineconeIndex = pineconeClient.Index(process.env.PINECONE_INDEX);
const pineconeStore = await PineconeStore.fromExistingIndex(new OpenAIEmbeddings(), {
    // 向量数据库的信息
    pineconeIndex,
    textKey: "text",
    namespace: "teach-vue3-document",
});

const chain = ConversationalRetrievalQAChain.fromLLM(
    model,
    pineconeStore.asRetriever(),{
        // 返回信息是参考了什么资料的开关 sourceDocuments:
        returnSourceDocuments: true,
    });

export async function chat(message) {
    const res = await chain.call({
        question: message,
        // 聊天历史,也就是记忆的功能
        chat_history: [],
    });
    return res;
}

然后启动运行pnpm dev并使用postman访问接口 “/chat” 如图:

构建前端

pnpm create vite

准备好node,pnpm环境 - LangChain Demo
安装组件tailwindcss

cd client/


pnpm install -D tailwindcss@latest postcss@latest autoprefixer@latest

# 执行init
npx tailwindcss init -p

# 安装axios 后续使用
pnpm i axios

# 安装 marked marked 是一个流行的 JavaScript 库,用于将 Markdown 文本转换为 HTML
pnpm install marked

pnpm install --save-dev @types/marked

pnpm install typescript --save-dev

tailwind.config.js添加配置(参考官网:v2.tailwindcss.com/docs/guides…

purge: ["./index.html", "./src/**/*.{vue,js,ts,jsx,tsx}"],

修改style.css 文件(参考官网:v2.tailwindcss.com/docs/guides…

@tailwind base;
@tailwind components;
@tailwind utilities;

然后在App.vue中编写Hello World。

<script setup>
</script>

<template>
  <div class="text-blue-400">
    Hello World
  </div>
</template>

<style scoped>
</style>

启动

cd client/
pnpm dev

页面如下:
准备好node,pnpm环境 - LangChain Demo
接下来编写视图,(前端组件、js等)
viteproxy文档:cn.vitejs.dev/config/serv…

源码获取:微信搜索【码上遇见你】回复【langchain-demo】

上述文章也是依据网络整理的。侵权删之。

本网站的内容主要来自互联网上的各种资源,仅供参考和信息分享之用,不代表本网站拥有相关版权或知识产权。如您认为内容侵犯您的权益,请联系我们,我们将尽快采取行动,包括删除或更正。
AI教程

AIGC大模型时代:智能互联网的冲击与应用探索

2023-12-22 16:46:00

AI教程

深度学习生成模型:扩散模型原理与应用详解

2023-12-22 16:48:00

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索