NestJS + LangChain 实现 AI 接口:从后端架构到 AI 服务实践

3 阅读5分钟

随着大模型应用的发展,越来越多的 AI 功能开始融入到 Web 应用中。例如:

  • AI 聊天助手
  • AI 文档总结
  • AI 代码生成
  • AI 搜索 / RAG

在这些场景中,一个非常常见的技术架构是:

Frontend
   ↓
Backend API(NestJS)
   ↓
LangChain
   ↓
LLM(OpenAI / DeepSeek / Ollama)

也就是说,大多数 AI Agent 实际上是运行在后端服务中的。前端只负责界面和交互,而真正的 AI 调用、Prompt 处理、数据访问都在后端完成。

在 Node.js 技术栈中,NestJS + LangChain 是一个非常常见的组合。本文将通过一个简单示例,介绍如何使用 NestJS 构建 AI API 服务,同时梳理其中涉及到的后端架构设计思想。


NestJS:Node.js 的企业级框架

NestJS 是一个基于 Node.js 和 TypeScript 的后端框架,它的设计灵感来自 Angular,强调 模块化架构和依赖注入

从技术实现上来说,NestJS 的底层其实是:

NestJS
   ↓
Express / Fastify

也就是说,NestJS 本质上是对 Express 的封装,但它在上层提供了完整的工程化能力,例如:

  • MVC 架构
  • 模块化系统
  • 依赖注入(DI)
  • 装饰器
  • RESTful API 设计

这些能力使得 NestJS 非常适合构建 企业级后端服务


NestJS 的模块化架构

NestJS 项目通常采用模块化结构。一个典型项目结构如下:

src
 ├── app.module.ts
 ├── ai
 │   ├── ai.module.ts
 │   ├── ai.controller.ts
 │   └── ai.service.ts
 └── book
     ├── book.module.ts
     ├── book.controller.ts
     └── book.service.ts

在 NestJS 中,每个业务功能通常会被拆分成一个 模块(Module)

模块中通常包含三个核心部分:

Controller
Service
Module

Controller 负责处理请求,Service 负责业务逻辑,而 Module 则负责组织这些组件。

这种设计可以让系统结构更加清晰,也更适合大型项目的扩展。


MVC 架构在 NestJS 中的体现

MVC 是后端开发中非常经典的设计模式:

Model
View
Controller

在现代 Web 开发中,大多数项目都采用 前后端分离架构,因此 View 通常由前端框架(React / Vue)实现,而 NestJS 主要负责 Model 和 Controller 部分。

在 NestJS 中:

MVCNestJS
ModelService
View前端应用
ControllerController

Controller 负责处理 HTTP 请求,例如:

@Controller('ai')
export class AiController {

  constructor(private readonly aiService: AiService) {}

  @Get('chat')
  async chat(@Query('query') query: string) {
    const answer = await this.aiService.runChain(query)

    return {
      answer
    }
  }

}

这里的 Controller 做了两件事:

  1. 接收请求参数
  2. 调用 Service 处理业务逻辑

真正的 AI 调用逻辑则放在 Service 中。


依赖注入(DI)与 IoC 容器

NestJS 的一个核心特性是 依赖注入(Dependency Injection)

在传统开发中,如果 Controller 需要使用 Service,通常需要手动创建实例:

const service = new AiService()

但在 NestJS 中,这个过程由 IoC 容器自动完成。

例如:

constructor(private readonly aiService: AiService) {}

Nest 会自动:

创建 AiService 实例
管理生命周期
注入 Controller

这种设计的好处是:

  • 降低耦合
  • 更容易测试
  • 更方便扩展

依赖注入是很多现代框架(Spring、Angular、Nest)都会使用的重要设计思想。


装饰器:NestJS 的核心语法

NestJS 大量使用 装饰器(Decorator) 来描述系统结构。

装饰器是一种设计模式,可以在不修改原有代码的情况下,对类或方法进行增强。

例如:

Controller 装饰器

@Controller('ai')

表示这个类是一个控制器,并且路由前缀是 /ai


HTTP 方法装饰器

@Get('chat')

表示该方法处理:

GET /ai/chat

参数装饰器

@Query('query')

用于获取 URL 查询参数:

/ai/chat?query=hello

Service 装饰器

@Injectable()

表示该类可以被 Nest 的 依赖注入系统管理

装饰器的存在让 NestJS 的代码结构非常清晰,也非常符合面向对象设计思想。


RESTful API 设计

NestJS 默认推荐使用 RESTful API 风格

REST 的核心思想是:

一切皆资源

资源通常使用 名词 表示,例如:

user
book
article

而操作则通过 HTTP Method 表达:

Method作用
GET查询
POST创建
PUT更新
DELETE删除

例如:

GET /book
POST /book
PUT /book/1
DELETE /book/1

这种设计方式可以让 API 结构更加清晰,也更符合 Web 标准。


使用 Nest CLI 快速生成资源

NestJS 提供了一个非常方便的 CLI 工具,可以快速生成模块代码。

例如:

nest g res book

这条命令会自动生成:

book.module.ts
book.controller.ts
book.service.ts
book.dto.ts

如果不需要测试文件,可以使用:

nest g res book --no-spec

这样可以避免生成 .spec.ts 文件,让项目结构更加简洁。


使用 LangChain 实现 AI 接口

接下来,我们可以在 Service 中接入 LangChain,实现 AI 能力。

示例代码如下:

@Injectable()
export class AiService {

  private readonly chain: Runnable

  constructor(configService: ConfigService) {

    const prompt = PromptTemplate.fromTemplate(
      `请回答以下问题:\n\n{query}`
    )

    const model = new ChatOpenAI({
      temperature: 0.7,
      modelName: configService.get('MODEL_NAME'),
      apiKey: configService.get('OPENAI_API_KEY'),
      configuration: {
        baseURL: configService.get('OPENAI_BASE_URL')
      }
    })

    this.chain = prompt
      .pipe(model)
      .pipe(new StringOutputParser())

  }

  async runChain(query: string) {
    return this.chain.invoke({ query })
  }

}

LangChain 的执行流程实际上是一条 处理链(Chain)

用户输入
   ↓
PromptTemplate
   ↓
LLM Model
   ↓
OutputParser
   ↓
返回结果

通过这种方式,可以非常方便地构建 AI 接口服务。


总结

在 AI 应用开发中,后端往往承担着非常重要的角色。通过 NestJS 可以构建结构清晰、可扩展的 API 服务,而 LangChain 则可以帮助我们快速接入大模型能力。

整个系统的调用流程可以总结为:

Frontend
   ↓
NestJS Controller
   ↓
Service
   ↓
LangChain
   ↓
LLM API

NestJS 提供的 模块化架构、依赖注入、装饰器机制以及 RESTful 设计,让 Node.js 后端开发具备了接近传统企业级框架(如 Spring)的工程能力。

在实际 AI 项目中,这样的架构已经成为一种非常常见的实践方式。