Documentation•Reference
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
describeAgenttests 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 / LangGraph | HazelJS |
|---|---|
ChatOpenAI / chat model | @hazeljs/ai providers / @AITask |
Tools / @tool | @Tool on agent methods |
| AgentExecutor / createReactAgent | @Agent + Agent Runtime execute |
| LangGraph nodes / edges | AgentGraph, SupervisorAgent, @Delegate |
| Checkpointers | Agent state + @hazeljs/flow for durable business WAIT/resume |
| Retrievers | @hazeljs/rag / .rag() in HCEL |
| Memory modules | enableMemory + @hazeljs/memory |
| Mount on Express/Nest | Native @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
| Need | HazelJS approach |
|---|---|
| Delegate to peer agents | @Delegate({ agent: 'ResearchAgent', ... }) |
| DAG / conditional pipelines | AgentGraph |
| LLM router / supervisor | SupervisorAgent |
| Long-running business WAIT | @hazeljs/flow (not only agent loops) |
Details: vs LangGraph, Agent OS.
Incremental migration
- Keep LangChain, put a thin HazelJS (or Nest) façade in front — temporary.
- Reimplement tools as
@Toolmethods; parity-test prompts. - Cut over traffic for one vertical (e.g. support) to HazelJS Agent Runtime.
- 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
- Agent package
- Migrate NestJS if the host framework is Nest
- Build a TypeScript RAG API
- Installation