2025年現在、AIエージェント開発は急速に進歩し、Node.jsエコシステムでも多くの実用的なツールが登場しています。本記事では、実際にコードを書きながらAIエージェントを構築する方法を段階的に解説します。
Source - AI Agent Development Trends 2025 by OpenAI Research Team (2025年1月)
AIエージェント開発の基本概念
AIエージェントは、環境を観察し、目標に向かって自律的に行動するソフトウェアシステムです。Node.jsでは、以下の要素を組み合わせて構築できます:
- LLM(大規模言語モデル): 思考と判断の中核
- ツール: 外部システムとの連携機能
- メモリ: 過去の対話や学習内容の保持
- 実行エンジン: エージェントのライフサイクル管理
Source - Building Intelligent Agents with JavaScript by Microsoft AI Team
(2025年2月)
プロジェクトの初期設定
まず、基本的なNode.jsプロジェクトを作成しましょう:
mkdir ai-agent-tutorial
cd ai-agent-tutorial
npm init -y
# 必要な依存関係をインストール
npm install openai langchain axios dotenv mathjs
npm install -D typescript @types/node ts-node nodemon
環境変数を設定するため、.envファイルを作成:
# .env
OPENAI_API_KEY=your_openai_api_key_here
CLAUDE_API_KEY=your_anthropic_api_key_here
Source - Setting up AI Development Environment by Node.js Foundation (2025年1月)
基本的なAIエージェントの実装
Step 1: シンプルなチャットエージェント
最初に、基本的なチャット機能を持つエージェントを作成しましょう:
// src/simple-agent.js
const { OpenAI } = require('openai');
require('dotenv').config();
class SimpleAgent {
constructor() {
this.openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
this.conversationHistory = [];
}
async chat(userMessage) {
// 対話履歴に追加
this.conversationHistory.push({ role: 'user', content: userMessage });
try {
const response = await this.openai.chat.completions.create({
model: 'gpt-3.5-turbo',
messages: this.conversationHistory,
max_tokens: 500,
temperature: 0.7,
});
const assistantMessage = response.choices[0].message.content;
this.conversationHistory.push({
role: 'assistant',
content: assistantMessage,
});
return assistantMessage;
} catch (error) {
console.error('エラーが発生しました:', error.message);
return '申し訳ありません、エラーが発生しました。';
}
}
// 会話履歴をリセット
resetConversation() {
this.conversationHistory = [];
}
}
module.exports = SimpleAgent;
Step 2: エージェントのテスト
作成したエージェントをテストしてみましょう:
// test/test-simple-agent.js
const SimpleAgent = require('../src/simple-agent');
async function testAgent() {
const agent = new SimpleAgent();
console.log('=== AIエージェントテスト ===');
const response1 = await agent.chat('こんにちは!あなたの名前を教えて');
console.log('Response 1:', response1);
const response2 = await agent.chat(
'JavaScriptについて簡単に説明してください'
);
console.log('Response 2:', response2);
const response3 = await agent.chat('先ほどの質問を覚えていますか?');
console.log('Response 3:', response3);
}
testAgent();
実行してみましょう:
node test/test-simple-agent.js
Source - OpenAI API Best Practices by OpenAI Documentation Team (2025年2月)
ツール機能を持つ高度なエージェント
Step 3: 外部ツールを使用するエージェント
実用的なエージェントには、外部のAPIやサービスと連携する機能が必要です:
// src/tool-agent.js
const { OpenAI } = require('openai');
const axios = require('axios');
const math = require('mathjs');
require('dotenv').config();
class ToolAgent {
constructor() {
this.openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
this.tools = {
getCurrentWeather: this.getCurrentWeather.bind(this),
searchNews: this.searchNews.bind(this),
calculateMath: this.calculateMath.bind(this),
};
}
// 天気情報を取得するツール
async getCurrentWeather(location) {
try {
// 実際にはOpenWeatherMap APIなどを使用
console.log(`天気情報を取得中: ${location}`);
return `${location}の現在の天気: 晴れ、気温20度`;
} catch (error) {
return '天気情報の取得に失敗しました';
}
}
// ニュース検索ツール
async searchNews(query) {
try {
console.log(`ニュース検索中: ${query}`);
// 実際にはNews APIなどを使用
return `${query}に関する最新ニュースを3件見つけました`;
} catch (error) {
return 'ニュース検索に失敗しました';
}
}
// 計算ツール
calculateMath(expression) {
try {
// math.jsを使用した安全な数式評価
const result = math.evaluate(expression);
return `計算結果: ${expression} = ${result}`;
} catch (error) {
return '計算に失敗しました';
}
}
async processWithTools(userMessage) {
const systemPrompt = `
あなたは実用的なAIアシスタントです。以下のツールを使用できます:
1. getCurrentWeather(location) - 指定された場所の天気を取得
2. searchNews(query) - 指定されたキーワードでニュースを検索
3. calculateMath(expression) - 数式を計算
ユーザーのリクエストに応じて適切なツールを使用してください。
ツールを使用する場合は、[TOOL:toolName:parameter] の形式で指定してください。
例:
- 天気を知りたい場合: [TOOL:getCurrentWeather:東京]
- ニュースを検索したい場合: [TOOL:searchNews:AI技術]
- 計算したい場合: [TOOL:calculateMath:2 + 3 * 4]
`;
try {
const response = await this.openai.chat.completions.create({
model: 'gpt-3.5-turbo',
messages: [
{ role: 'system', content: systemPrompt },
{ role: 'user', content: userMessage },
],
max_tokens: 500,
temperature: 0.3,
});
let assistantMessage = response.choices[0].message.content;
// ツール呼び出しの処理
const toolPattern = /\[TOOL:(\w+):([^\]]+)\]/g;
let match;
while ((match = toolPattern.exec(assistantMessage)) !== null) {
const [fullMatch, toolName, parameter] = match;
if (this.tools[toolName]) {
const toolResult = await this.tools[toolName](parameter);
assistantMessage = assistantMessage.replace(fullMatch, toolResult);
}
}
return assistantMessage;
} catch (error) {
console.error('エラー:', error.message);
return '申し訳ありません、処理中にエラーが発生しました。';
}
}
}
module.exports = ToolAgent;
Step 4: ツールエージェントのテスト
// test/test-tool-agent.js
const ToolAgent = require('../src/tool-agent');
async function testToolAgent() {
const agent = new ToolAgent();
console.log('=== ツール機能付きエージェントテスト ===');
const tests = [
'東京の今日の天気はどうですか?',
'10 + 5 * 3を計算してください',
'AI技術に関する最新ニュースを教えて',
'大阪の天気と、15 + 27の計算結果を教えてください',
];
for (const test of tests) {
console.log(`\\n質問: ${test}`);
const response = await agent.processWithTools(test);
console.log(`回答: ${response}`);
}
}
testToolAgent();
Source - AI Agent Tool Integration Patterns by LangChain Team (2025年1月)
メモリ機能を持つ永続化エージェント
Step 5: 会話履歴とコンテキスト管理
実用的なエージェントには記憶機能が必要です:
// src/memory-agent.js
const { OpenAI } = require('openai');
const fs = require('fs').promises;
const path = require('path');
class MemoryAgent {
constructor(memoryPath = './data/agent-memory.json') {
this.openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
this.memoryPath = memoryPath;
this.conversationHistory = [];
this.longTermMemory = {};
this.loadMemory();
}
// メモリをファイルから読み込み
async loadMemory() {
try {
const memoryData = await fs.readFile(this.memoryPath, 'utf8');
const parsed = JSON.parse(memoryData);
this.conversationHistory = parsed.conversationHistory || [];
this.longTermMemory = parsed.longTermMemory || {};
console.log('メモリを読み込みました');
} catch (error) {
console.log('新しいメモリファイルを作成します');
await this.saveMemory();
}
}
// メモリをファイルに保存
async saveMemory() {
try {
const dir = path.dirname(this.memoryPath);
await fs.mkdir(dir, { recursive: true });
const memoryData = {
conversationHistory: this.conversationHistory.slice(-10), // 最新10件のみ保存
longTermMemory: this.longTermMemory,
lastUpdated: new Date().toISOString(),
};
await fs.writeFile(this.memoryPath, JSON.stringify(memoryData, null, 2));
} catch (error) {
console.error('メモリ保存エラー:', error.message);
}
}
// 重要な情報を長期記憶に保存
rememberInformation(key, value) {
this.longTermMemory[key] = {
value: value,
timestamp: new Date().toISOString(),
};
this.saveMemory();
}
// 長期記憶から情報を取得
recallInformation(key) {
return this.longTermMemory[key] || null;
}
async chat(userMessage) {
// コンテキストを構築
let systemPrompt = `
あなたは記憶機能を持つAIアシスタントです。
重要な情報は記憶し、後で参照することができます。
過去の会話で覚えている重要な情報:
${Object.entries(this.longTermMemory)
.map(([key, data]) => `- ${key}: ${data.value}`)
.join('\\n')}
ユーザーが重要な情報(名前、好み、専門分野など)を教えてくれた場合、
それを記憶するために [REMEMBER:key:value] の形式で記録してください。
`;
this.conversationHistory.push({ role: 'user', content: userMessage });
try {
const messages = [
{ role: 'system', content: systemPrompt },
...this.conversationHistory.slice(-5), // 最新5件の会話のみコンテキストに含める
];
const response = await this.openai.chat.completions.create({
model: 'gpt-3.5-turbo',
messages: messages,
max_tokens: 500,
temperature: 0.7,
});
let assistantMessage = response.choices[0].message.content;
// 記憶処理
const rememberPattern = /\[REMEMBER:([^:]+):([^\]]+)\]/g;
let match;
while ((match = rememberPattern.exec(assistantMessage)) !== null) {
const [fullMatch, key, value] = match;
this.rememberInformation(key, value);
assistantMessage = assistantMessage.replace(fullMatch, '');
console.log(`記憶しました: ${key} = ${value}`);
}
this.conversationHistory.push({
role: 'assistant',
content: assistantMessage,
});
await this.saveMemory();
return assistantMessage;
} catch (error) {
console.error('エラー:', error.message);
return '申し訳ありません、エラーが発生しました。';
}
}
// メモリ統計を取得
getMemoryStats() {
return {
conversationCount: this.conversationHistory.length,
longTermMemoryCount: Object.keys(this.longTermMemory).length,
rememberedItems: Object.keys(this.longTermMemory),
};
}
}
module.exports = MemoryAgent;
Step 6: メモリエージェントのテスト
// test/test-memory-agent.js
const MemoryAgent = require('../src/memory-agent');
async function testMemoryAgent() {
const agent = new MemoryAgent();
console.log('=== メモリ機能付きエージェントテスト ===');
console.log('初期メモリ状態:', agent.getMemoryStats());
const conversations = [
'私の名前は田中太郎です。職業はソフトウェアエンジニアです。',
'JavaScriptが得意で、特にNode.jsでのAPI開発をしています。',
'私の名前を覚えていますか?',
'私の専門分野について教えてください。',
'新しいプロジェクトでReactを使うことになりました。',
];
for (const message of conversations) {
console.log(`\\n質問: ${message}`);
const response = await agent.chat(message);
console.log(`回答: ${response}`);
// 少し待機(実際の会話のシミュレーション)
await new Promise(resolve => setTimeout(resolve, 1000));
}
console.log('\\n最終メモリ状態:', agent.getMemoryStats());
}
testMemoryAgent();
Source - Conversational AI Memory Management by Google AI Research (2025年2月)
実用的なCLIアプリケーションの作成
Step 7: 対話型CLIアプリ
最後に、実際に使える対話型アプリケーションを作成しましょう:
// cli-agent.js
const readline = require('readline');
const MemoryAgent = require('./src/memory-agent');
class CLIAgent {
constructor() {
this.agent = new MemoryAgent();
this.rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
}
async start() {
console.log('🤖 AIエージェントCLI を起動しました!');
console.log('終了するには "exit" または "quit" と入力してください。');
console.log('メモリ統計を見るには "stats" と入力してください。');
console.log('----------------------------------------');
await this.chatLoop();
}
async chatLoop() {
return new Promise(resolve => {
const askQuestion = async () => {
this.rl.question('\\n👤 あなた: ', async input => {
const trimmedInput = input.trim().toLowerCase();
if (trimmedInput === 'exit' || trimmedInput === 'quit') {
console.log('\\n👋 ご利用ありがとうございました!');
this.rl.close();
resolve();
return;
}
if (trimmedInput === 'stats') {
const stats = this.agent.getMemoryStats();
console.log('\\n📊 メモリ統計:');
console.log(`- 会話数: ${stats.conversationCount}`);
console.log(`- 記憶項目数: ${stats.longTermMemoryCount}`);
console.log(`- 記憶内容: ${stats.rememberedItems.join(', ')}`);
askQuestion();
return;
}
try {
console.log('\\n🤖 考え中...');
const response = await this.agent.chat(input);
console.log(`\\n🤖 エージェント: ${response}`);
} catch (error) {
console.log('\\n❌ エラーが発生しました:', error.message);
}
askQuestion();
});
};
askQuestion();
});
}
}
// アプリケーション実行
if (require.main === module) {
const cli = new CLIAgent();
cli.start().catch(console.error);
}
module.exports = CLIAgent;
使用方法
# CLIアプリを実行
node cli-agent.js
実際の対話例:
🤖 AIエージェントCLI を起動しました!
終了するには "exit" または "quit" と入力してください。
----------------------------------------
👤 あなた: 私の名前は山田花子です。データサイエンティストをしています。
🤖 エージェント: はじめまして、山田花子さん!データサイエンティストとして働かれているのですね。
👤 あなた: Pythonでの機械学習が専門です。
🤖 エージェント: Pythonでの機械学習が専門でいらっしゃるのですね。
👤 あなた: stats
📊 メモリ統計:
- 会話数: 4
- 記憶項目数: 2
- 記憶内容: name, profession
Source - Building Interactive CLI Applications with Node.js by npm Team
(2025年1月)
まとめ
本チュートリアルでは、Node.jsを使用してAIエージェントを段階的に構築する方法を実践的に学びました:
学習内容
- 基本エージェント: OpenAI APIを使った簡単な対話システム
- ツール統合: 外部API連携機能の実装
- メモリ機能: 永続化とコンテキスト管理
- CLIアプリ: 実用的な対話型アプリケーション
次のステップ
- Webアプリ化: Express.jsを使ったWeb API化
- データベース統合: より高度なメモリ管理
- マルチエージェント: 複数エージェントの協調動作
- プラグインシステム: 動的なツール追加機能
関連リソース
このガイドで作成したコードは実際に動作し、さらなる拡張の土台として活用できます。AIエージェント開発の基礎を理解し、独自のアプリケーション開発に挑戦してみてください。
Source - AI Development Best Practices 2025 by Node.js Community (2025年2月)