Target Keyword: "ai agent node.js tutorial"
Tags: ai-agents,nodejs,artificial-intelligence,programming,developer
Type: Tutorial
Content
Building AI Agents in Node.js: Complete Guide to Autonomous Task Execution
AI agents are one of the most transformative applications of large language models. An AI agent can reason, decide, and take actions — writing code, calling APIs, reading files — without constant human guidance. Here's how to build them in Node.js.
What Is an AI Agent?
An AI agent has three components:
- Planning — The LLM decides what actions to take
- Memory — Stores conversation history and context
- Tools — Functions the agent can call (web search, file I/O, API calls)
The agent loops: observe → plan → act → repeat until the task is complete.
The Core Agent Loop
class SimpleAgent {
constructor(apiKey, tools = []) {
this.client = new ClaudeAPI(apiKey);
this.tools = tools;
this.messages = [];
}
async think(task) {
this.messages.push({ role: 'user', content: task });
// Build system prompt with tool descriptions
const systemPrompt = this.buildSystemPrompt();
const fullMessages = [systemPrompt, ...this.messages];
const response = await this.client.complete(fullMessages);
this.messages.push({ role: 'assistant', content: response });
return response;
}
buildSystemPrompt() {
const toolDescriptions = this.tools.map(t =>
`${t.name}: ${t.description}`
).join('\n');
return {
role: 'system',
content: `You are an AI agent. You have access to these tools:
${toolDescriptions}
When you need to use a tool, respond with:
<Action>
{
"tool": "tool_name",
"input": { ... }
}
</Action>
When you complete the task, respond with:
<Done>your answer</Done>`
};
}
}
Defining Tools
Tools are functions the agent can call. Here's how to define them:
const tools = [
{
name: 'web_search',
description: "'Search the web for information',"
execute: async (query) => {
const response = await fetch(`https://api.example.com/search?q=${encodeURIComponent(query)}`);
return response.json();
}
},
{
name: 'read_file',
description: "'Read contents of a file',"
execute: async (filepath) => {
return fs.readFileSync(filepath, 'utf8');
}
},
{
name: 'write_file',
description: "'Write content to a file',"
execute: async ({ filepath, content }) => {
fs.writeFileSync(filepath, content);
return `Written ${content.length} characters to ${filepath}`;
}
},
{
name: 'run_command',
description: "'Execute a shell command',"
execute: async (command) => {
const { stdout, stderr } = await exec(command);
return stdout + stderr;
}
}
];
Parsing Tool Calls
When the model outputs a tool call, parse and execute it:
async function executeToolCall(response) {
const match = response.match(/<Action>\s*({[\s\S]*?})\s*<\/Action>/);
if (!match) return null;
const { tool, input } = JSON.parse(match[1]);
const selectedTool = tools.find(t => t.name === tool);
if (!selectedTool) {
return { error: `Unknown tool: ${tool}` };
}
try {
const result = await selectedTool.execute(input);
return { tool, result };
} catch (error) {
return { tool, error: error.message };
}
}
Putting It Together: A Code Review Agent
Here's a practical example — an agent that reviews code:
class CodeReviewAgent extends SimpleAgent {
constructor(apiKey) {
const reviewTools = [
{
name: 'read_file',
description: "'Read a source code file',"
execute: async (filepath) => fs.readFileSync(filepath, 'utf8')
},
{
name: 'list_files',
description: "'List files in a directory',"
execute: async (dir) => {
return fs.readdirSync(dir).join('\n');
}
}
];
super(apiKey, reviewTools);
}
async reviewProject(projectPath) {
const files = await this.executeTool({ name: 'list_files', input: projectPath });
const fileList = files.result.split('\n').filter(f => f.endsWith('.js'));
const reviews = [];
for (const file of fileList) {
const content = await this.executeTool({
name: 'read_file',
input: `${projectPath}/${file}`
});
const review = await this.think(
`Review this code for bugs, security issues, and best practices:\n\n${content}`
);
reviews.push({ file, review });
}
return reviews;
}
}
Adding Memory Persistence
For longer tasks, persist memory to disk:
class PersistentAgent extends SimpleAgent {
constructor(apiKey, tools, memoryPath = './agent-memory.json') {
super(apiKey, tools);
this.memoryPath = memoryPath;
this.loadMemory();
}
loadMemory() {
if (fs.existsSync(this.memoryPath)) {
this.messages = JSON.parse(fs.readFileSync(this.memoryPath, 'utf8'));
}
}
saveMemory() {
fs.writeFileSync(this.memoryPath, JSON.stringify(this.messages));
}
async think(task) {
const response = await super.think(task);
this.saveMemory();
return response;
}
}
Safety Considerations
AI agents executing code can be dangerous. Always:
- Sandbox commands — Run in isolated containers
- Limit file access — Only allow specific directories
- Timeout long operations — Prevent infinite loops
- Review before execute — Log all actions for human review
Getting Started
The easiest way to power an AI agent is with ofox.ai — their OpenAI-compatible API gives you Claude's reasoning capabilities at competitive pricing. Set up an API key and start building agents in minutes.
This article contains affiliate links.
Tags: ai-agents,nodejs,artificial-intelligence,programming,developer
Canonical URL: https://dev.to/zny10289
Top comments (0)