Appearance
3.3.VueJS高级助理:基于langchainjs+express的实现
LangChain.js 是 LangChain 提供的 JavaScript版本框架,用于构建基于大语言模型(LLM)的应用程序。LangChain.js + Express 是打造本地化、工程化、可落地的 AI 助手系统的理想组合,特别适合我们前端开发者构建贴近实际开发流程的智能体应用。
简单介绍
最近我一直在尝试打造一个能真正辅助 Vue 开发的 AI 助理。这个“VueJS 高级助理”需要具备以下能力:
- 能理解 Vue3 官方文档和最佳实践(知识库)
- 记住你之前问过的问题,对话更连贯(记忆能力)
- 帮你生成组件代码、查 API、执行命令等(工具调用)
技术上我选择了 LangChain.js + Express + MongoDB + Vue3 的组合。这套方案轻量灵活,而且易于扩展。
系统架构概览
系统整体结构如下:
[Vue3 前端] <-> [Express 后端] <-> [LangChain.js AI引擎] <-> [MongoDB]
其中各模块职责如下:
- 前端 UI 层(Vue3):负责用户输入输出交互
- 后端服务层(Express):接收请求、调用模型、处理逻辑
- AI 处理层(LangChain.js):构建提示词、调用 LLM、执行工具
- 数据存储层(MongoDB):保存对话记录、记忆信息、知识库向量等
环境准备与项目初始化
- 初始化 Express 项目 创建目录并安装基础依赖:
bash
mkdir vuejs-assistant-api
cd vuejs-assistant-api
npm init -y
npm install express cors dotenv mongoose axios
创建 server.js 并启动服务:
js
const express = require('express');
const app = express();
const PORT = 3000;
app.get('/', (req, res) => {
res.send('VueJS 助理服务已启动!');
});
app.listen(PORT, () => {
console.log(`服务运行在 http://localhost:${PORT}`);
});
测试访问 http://localhost:3000
是否正常。
- 初始化 Vue3 前端项目 使用 Vite 创建项目:
bash
npm create vite@latest vuejs-assistant-ui --template vue
cd vuejs-assistant-ui
npm install
npm run dev
访问 http://localhost:5173
确认页面加载成功。
安装常用依赖:
bash
npm install axios pinia vue-router
搭建基础界面:输入框、回复展示区、历史记录面板。
- 配置 MongoDB 连接本地或 Atlas 数据库,并创建基本模型:
js
// models/ChatHistory.js
const mongoose = require('mongoose');
const chatSchema = new mongoose.Schema({
userId: String,
question: String,
answer: String,
timestamp: { type: Date, default: Date.now }
});
module.exports = mongoose.model('ChatHistory', chatSchema);
连接数据库:
js
// server.js
require('dotenv').config();
mongoose.connect(process.env.MONGO_URI, {
useNewUrlParser: true,
useUnifiedTopology: true
});
- 安装 LangChain.js 及 LLM 支持 安装 LangChain:
bash
npm install langchain
不再使用 OpenAI,改为使用本地 Ollama 提供的 DeepSeek 模型。确保你已经部署好 Ollama,并加载了 DeepSeek 模型。
创建一个封装类用于调用 DeepSeek:
js
// utils/LocalLLM.js
const { BaseLLM } = require("langchain/dist/llms/base");
const axios = require("axios");
class LocalLLM extends BaseLLM {
constructor(options = {}) {
super(options);
}
async _call(prompt, options) {
const response = await axios.post("http://localhost:11434/api/generate", {
model: "deepseek",
prompt: prompt,
stream: false
});
return response.data.response;
}
_llmType() {
return "local";
}
}
module.exports = { LocalLLM };
然后在主程序中使用:
js
// server.js
const { LocalLLM } = require('./utils/LocalLLM');
const model = new LocalLLM();
测试一下是否能调用模型:
js
app.get('/test', async (req, res) => {
const response = await model.call("请帮我写一个 Vue 组件,显示当前时间");
res.json({ response });
});
访问 /test 接口看是否有返回内容。
输入与输出处理机制
- 接收用户输入
前端通过输入框获取用户的指令,发送 POST 请求到 /api/chat 接口。
js
// Vue3 中调用
axios.post('/api/chat', { input: userMessage })
.then(res => {
setResponse(res.data.answer);
});
- LLM 推理处理 后端接收到请求后,调用 LangChain Chain 或 Agent 处理逻辑。
js
app.post('/api/chat', async (req, res) => {
const { input } = req.body;
const result = await model.call(input);
res.json({ answer: result });
});
可以结合 Prompt Template 构造更清晰的提示词,提高输出质量。
输出格式化与返回 对结果进行解析、过滤、渲染, 返回 JSON 或 Markdown 格式给前端展示
错误处理机制 统一错误处理中间件:
js
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: '服务器内部错误' });
});
加载知识库(Knowledge)
准备知识文档 收集 Vue3 开发资料、API 文档、最佳实践等文本 转换为 .txt、.md、.pdf 等格式
文本预处理与嵌入生成 使用 LangChain 的分割器将文档切片:
js
const { RecursiveCharacterTextSplitter } = require('langchain/text_splitter');
const splitter = new RecursiveCharacterTextSplitter({ chunkSize: 1000 });
const docs = await splitter.splitDocuments([new Document({ pageContent: content })]);
由于我们不使用 OpenAI Embedding,而是本地模型,你可以使用 HuggingFace 提供的本地 Embedding 模型或 FAISS 自带的简单向量化方式。
存储到向量数据库 使用 MongoDB Atlas Vector Search 或本地 FAISS 存储向量数据,并建立检索接口。
语义检索集成到对话中 当用户提问时,自动触发相似度匹配,把最相关的知识片段传给 LLM:
js
const relevantDocs = await vectorStore.similaritySearch(userInput, 2);
const context = relevantDocs.map(d => d.pageContent).join('\n\n');
添加记忆能力(Memory)
- 会话状态管理 使用 LangChain 的 BufferMemory 缓存最近几轮对话:
js
const { BufferMemory } = require('langchain/memory');
const memory = new BufferMemory();
也可以用 MongoDBChatMessageHistory 实现长期记忆:
js
const { MongoDBChatMessageHistory } = require('langchain/stores/message/mongodb');
const history = new MongoDBChatMessageHistory({ collection: 'chat_history' });
- 记忆的读取与写入 每次对话前读取历史,对话后写入新记录:
js
const messages = await history.getMessages();
await history.addUserMessage(input);
await history.addAIMessage(response);
- 示例场景 用户连续提问:
text
“什么是 Composition API?”
“怎么在 setup 中使用 props?”
系统会根据上下文自动补充记忆,给出连贯的回答。
集成工具(Tools)
- 工具定义与注册 定义多个实用工具,如生成代码、查询 GitHub、执行 Shell 命令等:
js
const { DynamicTool } = require('langchain/tools');
const generateComponentTool = new DynamicTool({
name: "generate-component",
description: "根据描述生成 Vue 组件代码",
func: async (description) => {
return await generateComponent(description);
}
});
- 使用 AgentExecutor 自动决策 LangChain Agent 自动判断是否需要调用工具:
js
const { initializeAgentExecutor } = require('langchain/agents');
const executor = await initializeAgentExecutor(
[generateComponentTool],
model,
"structured-chat-zero-shot-react-description",
true
);
const result = await executor.call({ input: "帮我生成一个按钮组件" });
- 示例工具实现 自动生成 Vue 组件模板 调用 GitHub API 获取开源项目信息 执行 Shell 命令安装依赖包(需权限控制)
前端界面设计与交互
- 页面结构设计 主界面包含三个主要区域:
- 输入框:用户输入问题
- 回答区:展示 AI 的回答内容
- 历史记录:展示之前的对话记录
- 与后端接口对接 使用 Axios 发送请求并处理响应:
js
function sendMessage() {
axios.post('/api/chat', { input: message.value })
.then(res => {
response.value = res.data.answer;
});
}
添加加载动画和错误提示,提升用户体验。
- 实时通信方案(可选) 如果希望看到流式输出效果,可以用 WebSocket 或 SSE:
js
const eventSource = new EventSource('http://localhost:3000/stream');
eventSource.onmessage = (event) => {
appendToResponse(event.data);
};
- 展示增强功能 显示知识库检索结果 展示记忆内容 工具调用过程可视化
部署与优化
- 本地运行调试流程
依次启动 MongoDB、Express 和 Vue 服务,确保三者之间能正常通信。
- Docker 化部署建议 编写 Dockerfile 和 docker-compose.yml,一键启动所有服务。
yaml
version: '3'
services:
db:
image: mongo
ports:
- "27017:27017"
ollama:
image: ollama/ollama:latest
ports:
- "11434:11434"
deepseek:
image: your-deepseek-image
depends_on:
- ollama
api:
build: ./vuejs-assistant-api
ports:
- "3000:3000"
web:
build: ./vuejs-assistant-ui
ports:
- "5173:5173"
- 性能优化策略
- 缓存高频查询结果
- 控制模型输入长度
- 异步处理复杂任务
- 安全性考虑
- 用户身份认证(JWT)
- 输入内容校验
- 工具调用权限控制