1. はじめに
こんにちは、DataRobotの長野です。前回の「DataRobot AIエージェントテンプレート入門」では、テンプレートの全体像をご紹介しました。今回はその続編として、多くの方が最初に知りたいと考える「AIエージェントの具体的な構築方法」に焦点を当て、実際のコードを交えながら一歩ずつ解説していきます。何かと話題のAIエージェントですが、実際に手を動かして学ぶことで、その可能性と実力の肌感覚を掴んでいただければ幸いです。
なお、本ブログ(前編)ではAIエージェントテンプレートの中身を読み解くことでAIエージェント構築の基本を理解していただきます。また、後編では別のユースケースを用いた実装を確認しながらより複雑なAIエージェントを構築します。
2. AIエージェントのフレームワーク
AIエージェントの構築には、その土台となる「フレームワーク」の選定が欠かせません。現在、世の中には多種多様なフレームワークが存在します。NVIDIAと共同開発した、DataRobotのエージェントワークフォースプラットフォームは、CrewAI、LangGraph、Llama-index、Pydantic AIといった主要な選択肢に標準で対応しているほか、その他のフレームワークも柔軟に利用できる設計になっています。
本ブログでは、その中でもシンプルな概念で扱いやすく、世界的に注目を集めているCrewAIをベースに解説を進めます。CrewAIは、その手軽さから最初のステップとして最適ですが、国内の技術記事ではLangChainと関連の深いLangGraphの事例が多いのも事実です。AIエージェントの世界はまさに日進月歩の世界です。まずはCrewAIや、日本語コミュニティが活発なLangGraphで基本を掴み、ご自身のプロジェクトや好みに応じて最適なフレームワークを選んでいくことをお勧めします。
3. CrewAIとは
CrewAIは、「Crew」「AI Agents」「Process」「Task」という4つのシンプルな要素から成り立ちます。この分かりやすさがCrewAIの最大の魅力であり、プロンプトエンジニアリングを中心に据えたいプロジェクトには最適です。非技術者でも比較的扱いやすいと言われています(参考記事: Choosing the Right AI Agent Framework: LangGraph vs CrewAI vs OpenAI Swarm)
CrewAIのもう一つの優れた点は、公式ドキュメントが非常に明快であることです。 全体でもそれほど分量が多くないため、さらに理解を深めたいと思った方は、気軽に目を通してみると良いでしょう。
CrewAIのコンセプトはシンプルですが、概念の説明だけではまだ少し抽象的に聞こえるかもしれません。そこで、実際のコードを見て理解の解像度を一気に上げていきましょう。 DataRobotのAIエージェントテンプレート(agent.py)を例に、CrewAIの各要素が具体的にどう定義されているのかを確認します。
3.1 エージェントを定義する
それでは、コードの中核である「AI Agents」を定義する部分を見ていきましょう。ここでは、以下3体のエージェントが登場します。
- コンテンツプランナー
- コンテンツライター
- 編集者
それぞれのエージェントにrole(役割)、goal(ゴール)、backstory(背景)を設定することで、人格や専門性を持たせているのが分かります。
このようにエージェントを複数配置する「マルチエージェント」構成も、CrewAIなら驚くほどシンプルに実現できます。エージェントを1体追加するのも、10体にするのも、基本は同じ作業の繰り返しに過ぎません。
@property
def agent_planner(self) -> Agent:
return Agent(
role="コンテンツプランナー",
goal="{topic}に関する、エンゲージングで事実に基づいた正確なコンテンツを計画する",
backstory="あなたは{topic}というトピックについてのブログ記事の計画に取り組んでいます。"
"読者が何かを学び、情報に基づいた意思決定を行えるような情報を収集します。"
"あなたの仕事は、コンテンツライターがこのトピックに関する記事を執筆するための基礎となります。",
...
)
@property
def agent_writer(self) -> Agent:
return Agent(
role="コンテンツライター",
goal="{topic}について、洞察に満ち、事実に基づいた正確な意見記事を書く",
backstory="あなたは{topic}というトピックについての新しい意見記事の執筆に取り組んでいます。"
"執筆は、トピックに関するアウトラインと関連コンテキストを提供するコンテンツプランナーの仕事に基づいています。"
"コンテンツプランナーが提供するアウトラインの主要な目的と方向に従います。"
"また、客観的で公平な洞察を提供し、コンテンツプランナーが提供した情報でそれを裏付けます。"
"あなたの意見記事では、自身の記述が客観的な事実と対比して意見である場合には、そのことを明記します。",
...
)
@property
def agent_editor(self) -> Agent:
return Agent(
role="編集者",
goal="与えられたブログ投稿を、組織のライティングスタイルに合わせて編集する。",
backstory="あなたはコンテンツライターからブログ投稿を受け取る編集者です。"
"あなたの目標は、そのブログ投稿がジャーナリズムのベストプラクティスに従っているか、"
"意見や主張を提供する際にバランスの取れた視点を提供しているかを確認し、"
"また、可能な限り大きな論争を呼ぶトピックや意見を避けることです。",
...
)
3.2 タスクを定義する
エージェントという「実行者」を定義したら、次は彼らに依頼する「作業内容(タスク)」を設定します。
各タスクには、主に2つの重要な情報を与えます。
- description: AIに何をしてほしいかの具体的な指示
- expected_output: どのような形式で成果物を出してほしいかの定義
今回は「プランニング」「ライティング」「編集」という3つのタスクを定義し、それぞれを専門のエージェントに割り当てます。
ここで一点、エージェントとタスクを別々に定義する点に疑問に感じませんでしょうか。このように「実行者(エージェント)」と「作業内容(タスク)」が別々に定義されているのがCrewAIの設計のポイントです。これにより、例えば一人の優秀なエージェントに複数の異なるタスクを連続で任せるなど、柔軟なワークフローを組むことが可能になっています。
@property
def task_plan(self) -> Task:
return Task(
description=(
"1. {topic}に関する最新のトレンド、主要な関係者、注目すべきニュースを優先的に調査する。\n"
"2. ターゲット読者を特定し、その興味や課題を考慮する。\n"
"3. 導入、主要なポイント、行動喚起(CTA)を含む詳細なコンテンツのアウトラインを作成する。\n"
"4. SEOキーワードと関連データや情報源を含める。"
),
expected_output="アウトライン、読者分析、SEOキーワード、リソースを含む包括的なコンテンツ計画書。",
...
)
@property
def task_write(self) -> Task:
return Task(
description=(
"1. コンテンツ計画書を使用して、{topic}に関する魅力的なブログ投稿を作成する。\n"
"2. SEOキーワードを自然に組み込む。\n"
"3. セクションやサブタイトルは、読者の興味を引くように適切に命名する。\n"
"4. 投稿が、魅力的な導入、洞察に富んだ本文、そして要約となる結論で構成されていることを確認する。\n"
"5. 文法的な誤りがないか、またブランドのトーンと一致しているか校正する。\n"
),
expected_output="出版準備が整った、マークダウン形式で書かれた質の高いブログ投稿。"
"各セクションは2〜3パラグラフで構成されること。",
...
)
@property
def task_edit(self) -> Task:
return Task(
description=(
"与えられたブログ投稿の文法的な誤りを校正し、"
"ブランドのトーンと一致しているか確認する。"
),
expected_output="出版準備が整った、マークダウン形式で書かれた質の高いブログ投稿。"
"各セクションは2〜3パラグラフで構成されること。",
...
)
3.3 クルーとプロセスを定義する
個々のエージェントとタスクを定義したら、最後にそれらを一つの「Crew(チーム)」としてまとめ、実行の準備をします。ここが、AIエージェントシステム全体を動かす司令塔の部分です。
コード上での作業は非常にシンプルで、これまで作成したエージェントのリストとタスクのリストをCrewオブジェクトに渡すだけでチームが結成されます。
また、processという設定でタスクの進め方を定義します。今回はsequential(逐次実行)を選択しました。これは、定義したタスクがリストの順番通りに、一つずつ実行されるシンプルなプロセスです。
def crew(self) -> Crew:
return Crew(
agents=[self.agent_planner, self.agent_writer, self.agent_editor],
tasks=[self.task_plan, self.task_write, self.task_edit],
verbose=self.verbose,
process=Process.sequential
)
3.4 ワンポイントTips:生成AIでさっとアーキテクチャを可視化する
いくらCrewAIがシンプルとは言っても設計の全体像を知りたくるケースがあります。残念ながら、本記事の執筆時点でCrewAIには公式の可視化機能が提供されていません。しかし、心配は無用です。エージェントの定義が書かれたagent.pyファイルの内容を生成AIに読み込ませるだけで、簡単な構成図を作成させることができます。
例えば、agent.pyのコード全文と一緒に、以下のようなプロンプトを入力してみてください。
プロンプト一部抜粋(agent.pyと合わせて入力)
アスキーアートで各AIエージェントがどの順番や体制で連携しているか表現してください。
出力例
ユーザー入力: {topic}
│
▼
┌───────────────────┐
│ agent_planner │ (Content Planner)
└───────────────────┘
│ 企画・構成案の作成 (task_plan)
▼
┌───────────────────┐
│ agent_writer │ (Content Writer)
└───────────────────┘
│ 構成案に基づき執筆 (task_write)
▼
┌───────────────────┐
│ agent_editor │ (Editor)
└───────────────────┘
│ 執筆された記事を編集 (task_edit)
▼
最終的な成果物
今回のアーキテクチャはシンプルな逐次型エージェントでしたが、より複雑になってきた際にはこのテクニックを是非使ってみてください。
4. DataRobot AIエージェントテンプレート入門:CrewAIを用いたAIエージェントの構築(前編)まとめ
この記事では、AIエージェントの構築方法を理解するために、AIエージェントテンプレートを解説させていただきました。今回はブログ記事を作成するAIエージェントを例に挙げましたが、DataRobot AIエージェントテンプレート入門:CrewAIを用いたAIエージェントの構築(後編)ではこの基本を応用し、AIエージェントテンプレートのカスタマイズに挑戦します。