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 → 实时渲染打字机效果
相关推荐
Warson_L26 分钟前
Python的TypedDict
python·langchain·llm
陈随易1 小时前
在Finch用了62亿词元,我认为这是新一代Agent工具之神
前端·人工智能·后端
水域安全老周2 小时前
水趣钓鱼救生衣专利拆解:两级锁紧如何解决落水人衣分离
java·前端·网络
计算机魔术师2 小时前
Anthropic CEO突然喊踩刹车,OpenAI罕见力挺:AI这辆车不能只踩油门了
前端
wing983 小时前
从codex转战workbuddy使用一周的感受
前端·人工智能·后端
EatFan3 小时前
Java接入支付宝 JSAPI 支付保姆教程(二):流程讲解与前后端代码讲解
前端·spring boot·后端·微信小程序·小程序·uni-app
梦想平凡3 小时前
百游棋牌源代码开发搭建教程(五):房间创建、座位分配与请求幂等实现
前端·javascript·数据库·源代码管理
IT_陈寒4 小时前
Redis的Set操作居然能把我的服务整挂了?
前端·人工智能·后端
计算机魔术师4 小时前
Suno 发布 v6 音乐模型,推出 v6、v6-wild、v6-mini 三个版本
前端
OKkankan4 小时前
LangChain能力详解!:从工具调用到 LangSmith——让聊天模型具备实时交互能力!
开发语言·python·langchain