はじめに
近年、AIエージェントの開発現場では「フレームワーク依存」が大きな議論の的となっています。LangChainやCrewAIのような大規模なオーケストレーションフレームワークは、複雑なマルチエージェント連携やツール呼び出しを容易にする一方で、ブラックボックス化された内部ロジックにより、本番環境でのデバッグやパフォーマンスチューニングにおいて深刻な障壁となるケースが増えています。
この記事では、なぜ「フレームワークなし」でAIエージェントを実装することが、中級以上のエンジニアにとって重要なのかを解説します。特に、数百行のコードで実装可能な最小限のエージェントアーキテクチャに着目し、依存関係の排除による透明性の確保と、フレームワーク使用時のトレードオフについて深く掘り下げていきます。
フレームワークが隠蔽する「魔法」の正体
多くの開発者は、AIエージェントを構築する際、会話履歴の管理、ツール実行の再試行ロジック、フォールバック処理などを一から実装することを避け、既存のフレームワークに頼りがちです。しかし、これらの機能は実は複雑な魔法ではなく、極めて単純なループと条件分岐の集合体です。
フレームワークを使わない場合、まず直面するのは「何を実装すべきか」という設計判断です。エージェントの本質は、以下のサイクルを繰り返す制御ロジックに過ぎません。
- 推論(Reasoning): LLMに対して現在の状態とタスクを提示し、次のアクション(テキスト出力またはツール呼び出し)を決定させる。
- 実行(Execution): 決定されたアクションを実行し、その結果を取得する。
- 記憶(Memory): 対話履歴に新しい状態と結果を追加し、次の推論のコンテキストとする。
この基本構造を理解すれば、フレームワークが提供している「抽象化レイヤー」が何をしているのかを明確に把握できます。例えば、CrewAIやLangGraphは、エージェント間の役割分担や状態遷移図を宣言的に記述させることで、上記のループを暗黙的に管理しています。しかし、その代償として、エラー発生時にどこで制御フローが分岐しているのかを追跡するのが困難になる場合があります。
数百行での実装:最小限のエージェント構造
では、実際にフレームワークに依存しないエージェントをどのように構築すべきでしょうか。ここでは、Node.jsを用いたコードレビューエージェントの実装例を通じて、その核心部分を見ていきます。重要なのは、複雑なクラス階層を作らず、単一の「メインループ」を持つことです。
// 簡易的なAIエージェントの核心ロジック(擬似コード)
async function runAgentLoop(userInput, context) {
let currentContext = [...context];
// 最大反復回数(無限ループ防止)
for (let i = 0; i < MAX_ITERATIONS; i++) {
// 1. LLMへのプロンプト構築
const prompt = buildPrompt(currentContext, userInput);
// 2. LLMからのレスポンス取得
const response = await llm.generate(prompt);
// 3. アクションの解析(テキスト出力か、ツール呼び出しか)
const action = parseAction(response);
if (action.type === 'FINISH') {
return action.result;
}
if (action.type === 'TOOL_CALL') {
// 4. ツールの実行
const toolResult = await executeTool(action.name, action.args);
// 5. 結果をコンテキストに追加(重要なステップ)
currentContext.push({
role: 'assistant',
content: `Called ${action.name} with result: ${toolResult}`
});
} else {
// 6. 通常テキスト出力の場合も履歴に加える
currentContext.push({
role: 'assistant',
content: response.text
});
}
}
throw new Error('Max iterations reached');
}
この実装のポイントは、「状態」を明示的に変数(配列)として管理している点です。フレームワークを使わない場合、このコンテキストリストの状態遷移を自分で監視・デバッグできます。例えば、「なぜLLMが特定のツールを呼ばないのか?」という問題が発生した際、プロンプトの内容や履歴の長さを直接確認しやすくなります。
設計判断:なぜ「単純さ」を選ぶのか
フレームワークを使わない選択には、明確な技術的根拠があります。それは「デバッグ可能性(Debuggability)」と「依存関係の最小化」**です。
1. エラーハンドリングの透明性
大規模フレームワークでは、SDKの内部エラーや非同期処理の競合により、「200 OKだが中身が空」といった静かな失敗(Silent Failure)が発生することがあります。自作エージェントの場合、API呼び出し部分は単純なHTTPリクエストであるため、レスポンスボディを直接ログ出力し、検証ロジックを自前で書くことができます。これにより、LLMの出力形式とコードの期待値のミスマッチを即座に特定できます。
2. バージョン管理とセキュリティ
LangChainやCrewAIのような依存パッケージは頻繁にメジャーバージョンアップを行います。また、間違ったパッケージ名(例:プレースホルダーのパッケージ)をインストールしてしまうと、ビルドは成功してもランタイムで壊れるといったトラップに陥るリスクがあります。フレームワークに依存しない実装であれば、必要なAPIクライアント(例:OpenAI SDKやAnthropic SDK)のみを管理すればよく、攻撃対象面(Attack Surface)を大幅に減らすことができます。
3. パフォーマンスの制御
フレームワークは「万能な中間層」を提供しますが、それは裏を返せばオーバーヘッドでもあります。カスタムエージェントでは、ストリーミング処理の実装や、トークン制限の厳密なカウント、不要なプロンプト構築のスキップなどを細かく制御できます。特にコストが敏感なビジネス用途では、この制御能力が重要です。
フレームワークを使うべきケースとの使い分け
とはいえ、「フレームワークは常に悪」というわけではありません。適切な使い分けが求められます。以下の基準で判断することをお勧めします。
- 自作(Bare-metal)を選ぶ場合:
- ロジックの透明性とデバッグ容易性が最優先事項である場合。
- エージェントのフローが比較的単純(単一エージェント、または固定されたマルチエージェント連携)である場合。
- 既存フレームワークのバージョンアップやAPI変更による影響を受けたくない場合。
- フレームワークを選ぶ場合:
- 動的にエージェントの数や接続関係を変化させる必要がある複雑なオーケストレーションである場合。
- チーム規模が大きく、標準化された「共通言語」としてのフレームワーク利用が合意されている場合。
- プロトタイピング速度を最優先し、初期コストを抑えたい場合(ただし、本番環境での移行リスクは認識する)。
実装におけるよくある落とし穴と対策
フレームワークなしで実装する場合、以下の点に注意する必要があります。
1. 無限ループの防止
LLMが「ツールを呼ぶ」ことだけを繰り返し、完了条件を満たさないことがあります。必ずMAX_ITERATIONSのような上限設け、それを超えた場合は強制的に終了し、エラーまたは最終的な推論結果を返すようにしてください。
2. コンテキストの肥大化対策
対話履歴が長くなりすぎると、トークンコストが増加し、重要な情報がコンテキストの端の方で切り捨てられる可能性があります(Lost in the Middle 現象)。対策として、古いメッセージを要約して圧縮する機能や、重要度の高いメッセージのみを残すフィルタリングロジックを実装する必要があります。
3. ツール呼び出しの堅牢性
LLMが誤った引数形式でツールを呼ぶことがあります。JSONパースのエラーハンドリングや、引数の型チェックを厳密に行うラッパー関数を用意し、失敗した場合はそのエラーメッセージを再度LLMにフィードバックして修正させる仕組み(Self-Correction)を組み込むと安定性が向上します。
まとめ
AIエージェント開発において、フレームワークからの脱却は「複雑さの排除」ではなく、「制御可能性の獲得」です。LangChainやCrewAIのようなツールはプロトタイピングに強力ですが、本番環境での堅牢性や保守性を追求するなら、内部動作を完全に理解した上で、必要最小限のコードでエージェントを構築するアプローチが有効です。
数百行のコードで実装可能なエージェントアーキテクチャを理解しておくことは、AIアプリケーションの開発者にとって、単なる実装スキル以上の「システム設計眼」を養うことにつながります。まずは小さなプロトタイプから始め、フレームワークが何を提供しているのか(そして何を隠蔽しているのか)を肌で体験することをお勧めします。
参考
本記事は海外の技術トレンド「The Dirty Secret Behind AI Agents (Demo 🚀)」(DEV)で話題のテーマをもとに、両儀システムソリューションズが独自に解説したものです。