DEV Community

Cover image for NestJS + LangChain: Build an AI Agent in 5 Minutes
Martin-Bruel
Martin-Bruel

Posted on

NestJS + LangChain: Build an AI Agent in 5 Minutes

To add an AI agent to a NestJS app, register it as a module with nestjs-langchain, inject it like any provider, and call run(). This tutorial goes from nest new to a working POST /ask endpoint in about 30 lines of TypeScript.
Tested with NestJS 12, LangChain 1.x, nestjs-langchain 2.0 and Node 22.12.

How do I add LangChain to a NestJS project?

Create the app, then install the library and a model provider:

npx @nestjs/cli new my-app --package-manager npm
cd my-app
npm install nestjs-langchain @langchain/openai
Enter fullscreen mode Exit fullscreen mode

@langchain/openai is the provider: @langchain/anthropic, @langchain/ollama, @langchain/mistralai or any other LangChain chat integration works the same way.

The provider reads its key from the environment:
export OPENAI_API_KEY=sk-...

How do I register the agent?

Import LangChainModule in app.module.ts:

import { Module } from '@nestjs/common';
import { LangChainModule } from 'nestjs-langchain';
import { AppController } from './app.controller.js';
import { AppService } from './app.service.js';
import { AskController } from './ask.controller.js';

@Module({
  imports: [
    LangChainModule.register({
      // `provider:model`; the provider reads OPENAI_API_KEY.
      model: { model: 'openai:gpt-5-mini' },
      systemPrompt: 'You are a helpful assistant. Answer in one paragraph.',
    }),
  ],
  controllers: [AppController, AskController],
  providers: [AppService],
})
export class AppModule {}
Enter fullscreen mode Exit fullscreen mode


ts
model names the provider and the model: switching to Claude is anthropic:claude-sonnet-5-5, with @langchain/anthropic installed. The agent is built when the app starts, so a wrong configuration shows up there, not on the first request.

How do I call the agent from a controller?

Inject Agent like any provider, in a new ask.controller.ts:

import { Body, Controller, Post } from '@nestjs/common';
import { Agent } from 'nestjs-langchain';

@Controller('ask')
export class AskController {
  constructor(private readonly agent: Agent) {}

  @Post()
  async ask(@Body('question') question: string): Promise<string> {
    const { output } = await this.agent.run(question);
    return output;
  }
}
Enter fullscreen mode Exit fullscreen mode

Besides output, the answer, run() returns the tools the model called, the tokens it used and how long the run took.
Start the app and ask it something:

npm run start:dev

curl -X POST http://localhost:3000/ask \
  -H 'Content-Type: application/json' \
  -d '{"question": "What is dependency injection?"}'
Enter fullscreen mode Exit fullscreen mode

The response is the model's answer, as plain text.

Next: give the agent tools

An agent becomes useful when it can act on your app. With @tool(), a service method becomes a tool the model can call:

@Injectable()
export class MathService {
  @Tool({ description: 'Adds two numbers.' })
  add(
    @ToolParam({ name: 'a' }) a: number,
    @ToolParam({ name: 'b' }) b: number,
  ): number {
    return a + b;
  }
}
Enter fullscreen mode Exit fullscreen mode

Then tools: [MathModule] in register() hands it to the agent. The next article in this series covers tools in detail.

• Full sample: samples/chat
• Package: nestjs-langchain on npm
• Source, issues and stars: GitHub

Top comments (0)