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
@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 {}
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;
}
}
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?"}'
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;
}
}
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)