基于 LangChain 与 Ollama 构建本地 LLM 应用实战
介绍使用 LangChain 框架结合 Ollama 本地部署的大语言模型,通过 NestJS 后端和 React 前端搭建支持流式输出的聊天应用。内容涵盖环境配置、模型调用、SSE 协议实现及前后端联调细节,旨在帮助开发者快速掌握私有化部署 LLM 的核心流程。

介绍使用 LangChain 框架结合 Ollama 本地部署的大语言模型,通过 NestJS 后端和 React 前端搭建支持流式输出的聊天应用。内容涵盖环境配置、模型调用、SSE 协议实现及前后端联调细节,旨在帮助开发者快速掌握私有化部署 LLM 的核心流程。

随着大语言模型(LLM)技术的快速发展,本地化部署模型已成为保护数据隐私和降低 API 成本的重要方案。LangChain 作为连接大模型与应用框架的桥梁,配合 Ollama 提供的轻量级本地推理服务,能够高效搭建私有化的 AI 应用。
本文将详细介绍如何使用 LangChain 结合 Ollama 的 Llama3 模型,通过 NestJS 后端和 React 前端,实现一个支持流式输出的本地聊天机器人。
在开始之前,请确保您的开发环境满足以下要求:
Ollama 提供了便捷的模型管理方式。您有两种主要安装途径:
本文以直接安装为例。安装完成后,启动服务:
ollama serve
启动成功后,Ollama 默认监听 11434 端口。此时可以通过终端拉取并运行模型,例如 Llama3:
ollama run llama3
执行该命令后,终端将进入交互模式,验证模型是否正常工作。
后端负责处理业务逻辑、调用大模型接口以及通过 SSE (Server-Sent Events) 协议向客户端推送流式数据。
使用 NestJS 创建新项目并安装 LangChain 社区版依赖:
npm install @langchain/community
# 注意:推荐使用 npm 或 yarn 安装,pnpm 可能存在兼容性问题
我们需要创建一个 Controller 来处理请求,并使用 RxJS 的 Subject 来管理 SSE 流。
import { Controller, Post, Body, Sse, Header } from '@nestjs/common';
import { Observable, Subject } from 'rxjs';
import { Ollama } from '@langchain/community/llms/ollama';
interface MessageEvent {
data: string;
}
@Controller()
export class AppController {
private messageSubject = new Subject<MessageEvent>();
private model: Ollama;
constructor() {
this.model = new Ollama({
baseUrl: 'http://localhost:11434',
model: 'llama3',
});
}
// SSE 接口,用于推送流式数据
@Sse('sse')
@Header('Content-Type', 'text/event-stream')
sse(): Observable<MessageEvent> {
return this.messageSubject.asObservable();
}
// 处理用户提问
@Post('question')
async addList(@Body() body: { question: string }): Promise<any> {
try {
const stream = await this.model.stream(body.question);
for await (const str of stream) {
this.messageSubject.next({
data: JSON.stringify({ answer: str, end: false }),
} as MessageEvent);
}
// 发送结束标记
this.messageSubject.next({
data: JSON.stringify({ answer: '', end: true }),
} as MessageEvent);
} catch (error) {
console.error('Model Error:', error);
this.messageSubject.next({
data: JSON.stringify({ answer: 'Error occurred', end: true }),
} as MessageEvent);
}
}
}
SSE (Server-Sent Events) 是一种基于 HTTP 协议的服务器到客户端单向通信技术。它允许服务器主动向浏览器推送更新,无需客户端轮询。
Content-Type: text/event-stream。EventSource 监听。Observable,利用 Subject 的多播特性,可以将模型生成的片段实时分发给所有订阅者。由于前后端分离,需配置 CORS 允许跨域请求。在 main.ts 中添加:
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.enableCors({
origin: '*', // 生产环境建议指定具体域名
methods: ['GET', 'POST'],
});
await app.listen(3000);
}
bootstrap();
前端主要负责接收用户输入,发送请求给后端,并实时渲染 SSE 返回的内容。
使用 fetch 发起 POST 请求触发后端流,同时建立 EventSource 连接接收 SSE 数据。
import { useRef, useState } from "react";
type Message = {
answer: string;
end: boolean;
};
export default function ChatLayout() {
const [message, setMessage] = useState<Message[]>([]);
const [question, setQuestion] = useState<string>("");
const ref = useRef<HTMLInputElement>(null);
const send = () => {
const inputVal = ref.current?.value as string;
if (!inputVal) return;
setQuestion(inputVal);
ref.current!.value = "";
setMessage((prev) => [...prev, { answer: "", end: false }]);
// 发送问题
fetch("http://localhost:3000/question", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.({ : inputVal }),
});
eventSource = ();
eventSource. = {
{ answer, end } = .(data);
(!end) {
( {
newMessages = [...prev];
lastMsgIndex = newMessages. - ;
newMessages[lastMsgIndex]. += answer;
newMessages;
});
}
(end) {
eventSource.();
}
};
};
(
);
}
部分开源模型对中文的理解能力有限。如果遇到中文回答效果不佳,可以尝试切换为针对中文优化的模型(如 Qwen 等),并在 Prompt 中明确指示使用中文回答。
通过本教程,我们成功搭建了一个基于 LangChain 和 Ollama 的本地 LLM 应用。虽然基础功能已实现,但实际生产中还需考虑稳定性、安全性和扩展性。开发者可根据需求进一步拓展知识库检索(RAG)、多模态支持等功能。掌握这一流程,有助于在 AI 时代提升个人技术竞争力。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online