DocumentationReference

Migrate a LangChain Agent to HazelJS

Move a LangChain / LangGraph-style agent into HazelJS @Agent + @Tool (and optional RAG/memory) so HTTP, auth, and agents share one TypeScript module system.

Quick Reference

  • Purpose: Side-by-side mapping from LangChain agents to HazelJS Agent Runtime.
  • When to use: You have a working LangChain agent and want a production Nest-style backend without dual paradigms.
  • Key concepts: @Agent, @Tool, requiresApproval, memory, RAG, AgentGraph / Supervisor, HCEL.
  • Dependencies: @hazeljs/​core, @hazeljs/​agent, optionally @hazeljs/​rag, @hazeljs/​ai, @hazeljs/​memory.
  • Related: vs LangChain, vs LangGraph, NestJS + LangChain, Agent package.

Should you migrate?

Migrate when:

  • The agent must sit behind authenticated APIs, rate limits, and shared config
  • You are tired of wiring LangChain into Nest/Express manually
  • You want Agent OS loops, policies, and describeAgent tests later

Stay on LangChain/LangGraph when:

  • You depend on specific LangChain integrations HazelJS does not mirror
  • Org process is standardized on LangSmith / LangGraph only
  • The agent is a research script, not a product API

Concept mapping

LangChain / LangGraphHazelJS
ChatOpenAI / chat model@hazeljs/​ai providers / @AITask
Tools / @tool@Tool on agent methods
AgentExecutor / createReactAgent@Agent + Agent Runtime execute
LangGraph nodes / edgesAgentGraph, SupervisorAgent, @Delegate
CheckpointersAgent state + @hazeljs/​flow for durable business WAIT/resume
Retrievers@hazeljs/​rag / .rag() in HCEL
Memory modulesenableMemory + @hazeljs/​memory
Mount on Express/NestNative @Controller in the same app

Before (LangChain-shaped)

/​/​ Illustrative — model + tools + executor, then mounted on Express/​Nest elsewhere
const tools = [lookupOrderTool, refundTool];
const agent = createReactAgent({ llm, tools });
const result = await agent.invoke({ messages: [/​* ... */​] });

After (HazelJS agent)

import { Agent, Tool } from '@hazeljs/​agent';

@Agent({
  name: 'support-agent',
  description: 'Customer support agent',
  systemPrompt: 'You help with orders and refunds. Be concise.',
  enableMemory: true,
  enableRAG: true,
})
export class SupportAgent {
  @Tool({
    description: 'Look up an order by ID',
    parameters: [{ name: 'orderId', type: 'string', required: true }],
  })
  async lookupOrder(input: { orderId: string }) {
    return { orderId: input.orderId, status: 'shipped' };
  }

  @Tool({
    description: 'Process a refund',
    requiresApproval: true,
    parameters: [
      { name: 'orderId', type: 'string', required: true },
      { name: 'amount', type: 'number', required: true },
    ],
  })
  async processRefund(input: { orderId: string; amount: number }) {
    return { success: true, ...input };
  }
}

Register the agent class as a provider in @HazelModule, then execute via Agent Runtime (see Agent package docs for runtime.execute patterns).

Expose over HTTP

import { Controller, Post, Body, HazelModule } from '@hazeljs/​core';
import { SupportAgent } from '.​/support.agent';

@Controller({ path: '/​support' })
export class SupportController {
  @Post('chat')
  async chat(@Body() body: { message: string }) {
    /​/​ Wire to Agent Runtime — see docs/​examples/​support-agent
    return { message: body.message };
  }
}

@HazelModule({
  controllers: [SupportController],
  providers: [SupportAgent],
})
export class SupportModule {}

Full walkthrough: Support agent example.

Multi-agent and graphs

NeedHazelJS approach
Delegate to peer agents@Delegate({ agent: 'ResearchAgent', ... })
DAG / conditional pipelinesAgentGraph
LLM router / supervisorSupervisorAgent
Long-running business WAIT@hazeljs/​flow (not only agent loops)

Details: vs LangGraph, Agent OS.

Incremental migration

  1. Keep LangChain, put a thin HazelJS (or Nest) façade in front — temporary.
  2. Reimplement tools as @Tool methods; parity-test prompts.
  3. Cut over traffic for one vertical (e.g. support) to HazelJS Agent Runtime.
  4. Delete LangChain executor once evals pass (@hazeljs/​eval / @hazeljs/​testing).

Checklist

  • Tools mapped 1:1 with clear JSON schemas
  • System prompt + memory/RAG flags set on @Agent
  • Sensitive tools use requiresApproval: true
  • HTTP auth matches previous gateway behavior
  • Eval set for golden questions before cutover
  • Read HazelJS vs LangChain

Next steps