NestJS + LangChain SSE 流式输出 + 前端实时渲染打字机效果

整体流程

  1. 后端:NestJS 开启 SSE 接口 → 调用 LangChain 流式 LLM → 逐块推送到前端
  2. 前端:监听 SSE 流 → 实时拼接文字 → 实现打字机效果

一、后端实现(NestJS + LangChain + SSE)

1. 安装依赖

bash 复制代码
# Nest 核心
npm install @nestjs/common @nestjs/core @nestjs/platform-express

# LangChain
npm install langchain @langchain/openai

2. 后端 SSE 流式接口(核心代码)

src/ai/ai.controller.ts

typescript 复制代码
import { Controller, Post, Body, Sse } from '@nestjs/common';
import { Observable } from 'rxjs';
import { ChatOpenAI } from '@langchain/openai';
import { HumanMessage } from '@langchain/core/messages';

@Controller('ai')
export class AiController {
  // SSE 流式输出 AI 回答
  @Post('stream')
  @Sse('sse') // 声明这是 SSE 接口
  async streamChat(@Body() body: { message: string }) {
    const { message } = body;

    // 1. 初始化流式 LLM
    const llm = new ChatOpenAI({
      model: 'gpt-3.5-turbo',
      apiKey: '你的 OPENAI_API_KEY',
      configuration: {
      	baseURL: '你的 OPENAI_BASE_URL',
      },
    });

    // 2. from 接收流式迭代器 → map 包装成 SSE 格式
    const stream = await llm.stream([new HumanMessage(message)]);
    return from(stream).pipe(
      map((chunk) => ({
        data: chunk.content,
      }))
    );
  }
}

二、前端实现

  • 使用浏览器原生 EventSourcefetch + ReadableStream 接收 SSE,从而实现实时拼接内容 → 打字机效果
javascript 复制代码
async function chat(message) {
  const res = await fetch('http://localhost:3000/ai/stream', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ message }),
  });

  const reader = res.body.getReader();
  const decoder = new TextDecoder();
  let text = '';

  while (true) {
    const { done, value } = await reader.read();
    if (done) break;

		// 解析 SSE 流
    for (const line of decoder.decode(value).split('\n')) {
      if (!line.startsWith('data:')) continue;
      const data = line.replace('data:', '').trim();
      text += data;
      document.getElementById('result').innerText = text; // 打字机效果
    }
  }
}

三、补充:原生 EventSource

EventSource 只支持 GET,不能 POST。无需 fetch、无需解析流、无需 TextDecoder,因为 EventSource 本身就是 SSE 专用对象,最简洁。

html 复制代码
<script>
const res = document.getElementById('result');
let text = '';
// 创建 SSE 连接
const es = new EventSource('http://localhost:3000/ai/stream?message=你好');
// 接收流式消息
es.onmessage = e => {
  text += e.data;
  res.innerText = text;
};
// 结束
es.onend = () => es.close();;
// 错误
es.onerror = es.close;
</script>

四、总结

  • 后端:NestJS @Sse + LangChain stream() + RxJS Observable 推流
  • 前端:fetch 读取流 → 解析 SSE → 实时渲染打字机效果
相关推荐
leslie11812 分钟前
webpack笔记
前端·webpack
宁风NF17 分钟前
JavaScript:内存、垃圾回收、性能优化
开发语言·前端·javascript·学习·性能优化·es6
勾勾圈圈蛋蛋18 分钟前
DOM、BOM、DOM操作详解 + 结合Vue响应式关联梳理
前端
打妖妖灵滴哪吒1 小时前
IOS模态窗口的作用与设计原则
前端·ui
午安~婉1 小时前
挑战二:博客预览卡片
前端·javascript·html
环境栈笔记1 小时前
指纹浏览器安全评测方法:核对环境、数据与权限后再选型
前端·人工智能·后端·自动化
打妖妖灵滴哪吒1 小时前
前端开发/UI设计师-APP中如何进行可发现性设计
前端·ui
Kinghiee1 小时前
从使用场景切入前端常见设计模式
前端·设计模式
元Y亨H2 小时前
LangChain API 调用语言模型
langchain·llm
元Y亨H2 小时前
大模型技术 LangChain 概述
langchain·llm