LangChain JS 入门:快速搭建前端 AI 开发环境

下面这份梳理按 "环境准备 → 项目搭建 → AI 接入层 → 前端集成 → 安全与调试" 的顺序展开,以 Vue 3 + TypeScript + Vite + LangChain.js 为主线,兼顾两种实际场景:直连 LangGraph 服务器 (最简路径)和自建 BFF 代理(生产推荐)。


一、先理解整体架构:LangChain.js 在前端 AI 应用中的位置

LangChain.js 是 LangChain 的 JavaScript/TypeScript 实现,定位是前端与全栈应用 的 AI 编排层。它不要求你必须有一个独立的后端,但API Key 不能暴露在浏览器中,所以实际落地时通常有两种形态:

形态 前端职责 后端 / 接入层 适用场景
A. 直连 LangGraph 服务器 用 @langchain/vue 的 useStream 连接一个已运行的 Agent 服务 LangGraph 服务器(localhost:2024 或部署地址) 快速原型、内部工具、学习 LangChain 前端 SDK
B. 自建 BFF 代理(推荐) fetch + ReadableStream 消费流式响应 Node.js / Express / 任意后端,持有 API Key,调用 LangChain.js 或任意模型 SDK 生产环境、需要鉴权、限流、审计、成本控制

BFF(Backend for Frontend)的核心原则是:密钥、限流、审计留在服务端,前端只消费稳定的流式事件契约。下面两条路径都会给出可运行的步骤,你按自己的阶段选择即可。


二、环境准备

2.1 Node.js 版本

LangChain.js 当前要求 Node.js 22+(官方 Quickstart 明确注明)。建议直接使用 Node.js 22 LTS 或 24 Active LTS。

bash 复制代码
node --version   # 确认 >= 22
npm --version

2.2 推荐工具链

  • 编辑器:VS Code + Vue 官方扩展(禁用 Vetur)
  • 包管理器:npm / pnpm / yarn 均可,下文以 npm 为例
  • TypeScript 运行工具 :如果需要在 Node 端直接跑 .ts 文件,安装 tsx,省去先编译再运行的步骤:
bash 复制代码
npm install -g tsx

三、搭建 Vue 3 + TypeScript 项目(前端骨架)

3.1 用 Vite 创建项目

Vue 3 新项目目前的标准起点是 Vite,vue-ts 模板是最精简的 TypeScript 起步方式:

bash 复制代码
npm create vite@latest my-ai-app -- --template vue-ts
cd my-ai-app
npm install
npm run dev

创建完成后,建议立刻跑一次生产构建,确认类型检查和构建链路没有问题:

bash 复制代码
npm run build
npm run preview

3.2 保持目录简洁

新手阶段不要一上来就引入 Router、Pinia、UI 库。先把 src/ 维持在可理解的范围:

css 复制代码
src/
├── App.vue
├── main.ts
├── components/
│   └── ChatBox.vue
└── composables/
    └── useChat.ts   # 后续放流式逻辑

3.3 组件写法:统一用 <script setup lang="ts">

vue 复制代码
<script setup lang="ts">
const message = "hello vue"
</script>

<template>
  <h1>{{ message }}</h1>
</template>

script setup 样板代码最少,类型推断也最顺,新组件默认用这个写法即可。


四、路径 A:用 @langchain/vue 直连 LangGraph 服务器(最快出效果)

如果你的目标是最短路径看到"AI 回复在页面上流式出现",这是首选。

4.1 安装依赖

@langchain/vue 提供了 Vue 专用的 useStream 组合式函数,负责流式传输、消息状态和中断管理:

bash 复制代码
npm install @langchain/vue @langchain/core

Peer 依赖要求 Vue ^3.5 和 @langchain/core。

4.2 准备一个运行中的 Agent 服务

useStream 需要一个 LangGraph API 地址 (默认 http://localhost:2024)和一个 assistantId(对应 LangGraph 配置中的 graph 名称)。这一步的具体部署方式取决于你使用的 LangGraph 模板,但形式上只要有一个暴露 /threads、/runs/stream 等端点的服务即可。

4.3 在 Vue 组件中使用 useStream

vue 复制代码
<script setup lang="ts">
import { useStream } from "@langchain/vue"

const { messages, submit, isLoading } = useStream({
  assistantId: "agent",
  apiUrl: "http://localhost:2024",
})
</script>

<template>
  <div v-for="(msg, i) in messages" :key="msg.id ?? i">
    {{ msg.content }}
  </div>
  <button
    :disabled="isLoading"
    @click="submit({ messages: [{ type: 'human', content: 'Hello!' }] })"
  >
    Send
  </button>
</template>

useStream 返回的 messages 和 isLoading 是响应式引用,流式增量会自动更新到 UI。注意:messages 是 ComputedRef,在模板中自动解包;如果在 <script> 中访问,需要使用 .value。

4.4 这条路径的边界

@langchain/vue 定位是 LangChain / LangGraph 的前端 SDK,它适合与 LangGraph 服务器配套使用。如果你暂时不想引入 LangGraph 服务器,或者后端是自建的 Express 接口,就走路径 B。


五、路径 B:自建 BFF 代理 + LangChain.js(生产推荐)

5.1 为什么必须走后端代理

前端直连模型 API 会将 API Key 写入浏览器代码,构建产物中一旦泄露,任何人都可以直接消耗你的额度。安全实践非常明确:Never expose API keys in browser code,始终使用后端代理或边缘函数。

BFF 同时承担限流、超时、审计和模型切换的职责,前端只依赖稳定的流式事件契约,不感知上游供应商。

5.2 后端最小结构(Express + LangChain.js 或模型 SDK)

在项目根目录建一个 server/ 目录(与 Vue 前端分离部署):

bash 复制代码
mkdir server && cd server
npm init -y
npm install express cors dotenv
npm install langchain @langchain/core @langchain/openai

server/index.ts(最小流式接口,NDJSON 输出):

ts 复制代码
import express from "express"
import cors from "cors"
import "dotenv/config"
import { ChatOpenAI } from "@langchain/openai"

const app = express()
app.use(cors())
app.use(express.json())

const model = new ChatOpenAI({
  model: "gpt-4o-mini",
  apiKey: process.env.OPENAI_API_KEY,
  streaming: true,
})

app.post("/api/chat", async (req, res) => {
  res.setHeader("Content-Type", "application/x-ndjson; charset=utf-8")
  res.setHeader("Cache-Control", "no-cache")

  try {
    const stream = await model.stream(req.body.input)
    for await (const chunk of stream) {
      res.write(JSON.stringify({ type: "delta", text: chunk.content }) + "\n")
    }
    res.write(JSON.stringify({ type: "done" }) + "\n")
  } catch (e) {
    res.write(JSON.stringify({ type: "error", message: "UPSTREAM_ERROR" }) + "\n")
  } finally {
    res.end()
  }
})

app.listen(3001, () => console.log("BFF on http://localhost:3001"))

这份实现采用了与 BFF 文章一致的 NDJSON 逐行事件契约 (delta / done / error),前端按行解析即可,不需要额外引入 SSE 库。如果生产环境使用 SSE,只需把 Content-Type 改为 text/event-stream,并在代理层关闭缓冲。

.env 文件(只放在 server 目录,不要提交到 Git):

ini 复制代码
OPENAI_API_KEY=sk-...

5.3 前端消费流式响应(Vue 3 + TS)

EventSource 只支持 GET,无法携带 POST body,因此对话场景推荐用 fetch + response.body.getReader() 逐块读取流。

在 src/composables/useChat.ts 中:

ts 复制代码
import { ref } from "vue"

interface ChatEvent {
  type: "delta" | "done" | "error"
  text?: string
  message?: string
}

export function useChat(apiUrl = "http://localhost:3001/api/chat") {
  const output = ref("")
  const loading = ref(false)

  async function send(input: string) {
    output.value = ""
    loading.value = true

    const res = await fetch(apiUrl, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ input }),
    })

    if (!res.body) {
      loading.value = false
      throw new Error("No response body")
    }

    const reader = res.body.getReader()
    const decoder = new TextDecoder()
    let buffer = ""

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

      buffer += decoder.decode(value, { stream: true })
      const lines = buffer.split("\n")
      buffer = lines.pop() ?? ""

      for (const line of lines) {
        if (!line.trim()) continue
        const event: ChatEvent = JSON.parse(line)
        if (event.type === "delta") {
          output.value += event.text ?? ""
        } else if (event.type === "error") {
          output.value = `[错误] ${event.message ?? "未知错误"}`
        }
      }
    }

    loading.value = false
  }

  return { output, loading, send }
}

在 ChatBox.vue 中使用:

vue 复制代码
<script setup lang="ts">
import { ref } from "vue"
import { useChat } from "@/composables/useChat"

const input = ref("")
const { output, loading, send } = useChat()

function handleSend() {
  if (!input.value.trim()) return
  send(input.value)
  input.value = ""
}
</script>

<template>
  <div class="chat">
    <div class="output">{{ output }}</div>
    <div class="input-row">
      <input v-model="input" :disabled="loading" @keyup.enter="handleSend" />
      <button :disabled="loading" @click="handleSend">发送</button>
    </div>
  </div>
</template>

这里的关键点是 TextDecoder 的 { stream: true } 参数:二进制流可能在任意字节边界切开,必须让解码器在流模式下保留跨块状态,否则中文或 emoji 会出现乱码。


六、API Key 与安全清单(新手最容易踩的坑)

无论走路径 A 还是 B,以下几条建议直接作为上线前的检查项:

  1. API Key 永远不出现在 Vue 代码、import.meta.env 前端变量或构建产物中 。VITE_ 前缀的环境变量会被打包进浏览器代码,不能用于密钥。
  2. 后端 .env 加入 .gitignore;构建产物中可用脚本扫描是否泄露了 key 形态的字符串。
  3. 前端请求走同源 /api 路径 (Vite dev 用 server.proxy,生产用 Nginx 反向代理),避免 CORS 和硬编码域名。
  4. BFF 必须设置单请求超时 和输入长度上限,避免上游拖垮 Node 进程。
  5. 系统提示词不要从客户端接收,只能在后端拼接。

七、调试与验证步骤

路径 A(@langchain/vue) 的验证:

  • 先确认 LangGraph 服务器在 http://localhost:2024 可访问;
  • 在浏览器 Network 面板观察 useStream 是否建立了流式连接;
  • 如果 messages 不更新,检查 assistantId 是否与 LangGraph 配置中的 graph 名一致。

路径 B(BFF) 的验证:

  • 先用 curl 直接测后端流式接口是否逐行输出:

    bash 复制代码
    curl -N -X POST http://localhost:3001/api/chat \
      -H "Content-Type: application/json" \
      -d '{"input":"你好"}'
  • 再在前端 Network 面板确认 Response 是 application/x-ndjson 且逐块到达;

  • 如果 UI 一次性出现完整回复而不是逐字出现,检查是否在某处把流"攒完再渲染"了。


八、新手学习路径建议

如果你希望在完成环境搭建后继续深入 LangChain.js,可以按以下顺序推进:

  1. Chat Models & 流式交互 :理解消息类型、stream() 的迭代方式;
  2. Prompts + Structured Output:用 Zod 定义输出 schema,获得类型安全的结构化返回;
  3. Function Calling / Tools:让模型调用你定义的函数;
  4. Agents :用 createAgent 组装模型 + 工具;
  5. RAG:文档加载、切分、向量检索,再与 Agent 结合。

微软维护的 LangChain.js for Beginners 课程(9 章,含 setup)和 Dan Wahlin 的同名课程都可以作为系统跟练材料,前者侧重 Microsoft Foundry,后者覆盖 MCP、Agentic RAG 等较新主题。


两条路径的选择建议 :如果只是今天就想看到 AI 在 Vue 页面里流式打字 ,走路径 A;如果目标是能上线、能交给别人用,直接按路径 B 把 BFF 骨架搭起来,后续换模型、加鉴权、加限流都不需要改前端。

相关推荐
郝学胜-神的一滴3 小时前
AI 编程智能体 17:四步搞定专属AI智能体
大数据·人工智能·python·神经网络·算法·langchain·强化学习
咚咚咚小柒3 小时前
【前端】LangChain.js学习
前端·javascript·人工智能·typescript·langchain·vue·ai编程
clz13145215 小时前
RAG 文档切分实战:从语义分层到长度优化
langchain
寻道码路7 小时前
AI Agent 工程化开发实战(四):工具调用循环——解构 create_agent 背后的机制
人工智能·langchain·ai agent·工具调用·langgraph
染指11109 小时前
160.Agent-LangGraph-自定义主管架构智能体
人工智能·windows·microsoft·langchain·1024程序员节·agents
lambo mercy1 天前
核心组件8——检索器(Retrievers)
langchain
小易老师AI实战1 天前
LangChain create_agent 与 LangGraph 底层原理及实战对比
langchain·agent·大模型应用开发·langgraph
杰克尼1 天前
今日面试题总结
java·开发语言·人工智能·langchain
郝学胜-神的一滴1 天前
AI 编程智能体 16:从零基础搭建到精细化优化
人工智能·python·算法·语言模型·langchain·pip