<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>LangChain on AI2CORE - AI技術ブログ</title>
    <link>https://www.ai2core.com/tags/langchain/</link>
    <description>Recent content in LangChain on AI2CORE - AI技術ブログ</description>
    <generator>Hugo -- 0.146.4</generator>
    <language>ja</language>
    <lastBuildDate>Tue, 24 Feb 2026 18:00:00 +0900</lastBuildDate>
    <atom:link href="https://www.ai2core.com/tags/langchain/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>2026年のAIエージェント進化論：シングルプロンプトからマルチエージェント協調へ</title>
      <link>https://www.ai2core.com/posts/2026-02-24-ai-agents-evolution/</link>
      <pubDate>Tue, 24 Feb 2026 18:00:00 +0900</pubDate>
      <guid>https://www.ai2core.com/posts/2026-02-24-ai-agents-evolution/</guid>
      <description>LangGraphやAutoGenを活用したマルチエージェントシステムのアーキテクチャと実装のポイント。</description>
      <content:encoded><![CDATA[<h1 id="2026年のaiエージェント進化論シングルプロンプトからマルチエージェント協調へ">2026年のAIエージェント進化論：シングルプロンプトからマルチエージェント協調へ</h1>
<h2 id="はじめに">はじめに</h2>
<p>「この複雑なレポート作成、AIに丸投げできないだろうか？」
「ユーザーからの曖昧な指示を解釈して、コードを書き、テストし、デプロイまで自動化したい。」</p>
<p>AI、特に大規模言語モデル（LLM）の進化に触れたエンジニアなら、一度はこんな夢を描いたことがあるのではないでしょうか。しかし、ChatGPTのような単一のプロンプトで対話するモデルに複雑なタスクを依頼すると、途中で文脈を見失ったり、期待とは異なるアウトプットが出てきたりと、その限界に直面することも少なくありません。</p>
<p>ReAct（Reasoning and Acting）のようなフレームワークを用いてツールを使わせる「シングルエージェント」は大きな進歩でしたが、それでもなお、複雑で多段階のタスクを自律的にこなすには力不足でした。まるで、一人の優秀な新入社員に、いきなり会社の全業務を任せるようなものです。</p>
<p>もし、AIが一人ではなく、「専門家チーム」として協調して働いてくれたらどうでしょう？リサーチ担当、コーディング担当、レビュー担当、そしてプロジェクト全体を管理するマネージャー。それぞれが専門知識を持ち、互いにコミュニケーションを取りながら、一つの大きな目標に向かって自律的にタスクを遂行する。</p>
<p>本記事では、そんな未来を実現する技術として注目を集める**「マルチエージェント・システム」**について、その概念から具体的な実装方法までを深く掘り下げます。特に、この分野を牽引する2大フレームワーク、**Microsoftの「AutoGen」<strong>と</strong>LangChainの「LangGraph」**に焦点を当て、そのアーキテクチャ、実装のポイント、そして現場で活かすための実践的なTipsを、豊富なコード例とともに解説していきます。</p>
<p>この記事を読み終える頃には、あなたはシングルプロンプトの呪縛から解き放たれ、自律的なAIエージェントチームを編成するための確かな知識とインスピレーションを得ているはずです。</p>
<h2 id="なぜ今マルチエージェントシステムなのか">なぜ今、マルチエージェント・システムなのか？</h2>
<p>LLMの能力が飛躍的に向上し、GPT-4oのようなマルチモーダル対応モデルが登場する中で、なぜわざわざ複数のエージェントを協調させる必要があるのでしょうか。その理由は、**「シングルエージェントの限界」<strong>と</strong>「タスクの複雑性への対応」**にあります。</p>
<h3 id="シングルエージェントの限界">シングルエージェントの限界</h3>
<p>従来のシングルエージェントのアーキテクチャは、基本的に一つの「思考の連鎖（Chain of Thought）」に依存しています。これは、直線的な思考プロセスには強いものの、以下のような課題を抱えています。</p>
<ol>
<li><strong>思考の硬直性</strong>: 一つの計画に固執し、途中で問題が発生しても柔軟に軌道修正するのが苦手です。複数の選択肢を並行して検討したり、第三者の視点でレビューしたりといった、人間が行うような複雑な意思決定が困難です。</li>
<li><strong>コンテキストの肥大化</strong>: タスクが複雑になるほど、プロンプトに含めるべき情報（過去のやり取り、ツールの使用履歴、中間生成物）が増大します。これはAPIコストの増加、処理速度の低下、そしてLLMが重要な情報を見失う「Lost in the Middle」問題を引き起こします。</li>
<li><strong>責任範囲の曖昧さ</strong>: 一つのエージェントにあらゆる役割（計画、実行、検証、修正）を詰め込もうとすると、プロンプトが極めて複雑になり、かえって性能が低下します。各ステップで何をすべきかが曖昧になり、幻覚（ハルシネーション）のリスクも高まります。</li>
</ol>
<h3 id="人間の組織に学ぶ専門化と協調">人間の組織に学ぶ「専門化」と「協調」</h3>
<p>これらの課題を解決するヒントは、私たち自身の社会、つまり「組織」にあります。優れた企業は、一人の天才が全てをこなすのではなく、営業、開発、マーケティング、品質管理といった専門部署が互いに連携・協調することで、複雑で大きな目標を達成します。</p>
<p>マルチエージェント・システムは、この組織論をAIの世界に持ち込むアプローチです。</p>
<ul>
<li><strong>専門化 (Specialization)</strong>: 各エージェントに特定の役割と専門知識を与えます。「コードを書くのが得意なエージェント」「書かれたコードを厳しくレビューするエージェント」「ユーザーとの対話を受け持つエージェント」といったように、責任範囲を限定することで、各エージェントのプロンプトをシンプルかつ高性能に保てます。</li>
<li><strong>協調 (Collaboration)</strong>: エージェント同士がメッセージを交換し、対話することで、問題を解決します。例えば、コーディングエージェントが書いたコードをレビューエージェントがチェックし、修正点をフィードバックする。この対話のループを通じて、生成物の品質をスパイラル状に向上させることができます。</li>
<li><strong>自律性 (Autonomy)</strong>: 全体の目標が与えられると、エージェントチームは自律的にタスクを分解し、役割を分担し、協調してタスクを遂行します。これにより、人間がマイクロマネジメントする必要がなくなります。</li>
</ul>
<p>このパラダイムシフトは、単なるAIの性能向上ではなく、<strong>AIによる問題解決の「方法論」そのものの進化</strong>と言えるでしょう。</p>
<h2 id="具体的な解決策autogenとlanggraphによる実装">具体的な解決策：AutoGenとLangGraphによる実装</h2>
<p>それでは、実際にマルチエージェント・システムを構築するためのフレームワークを見ていきましょう。ここでは、特に人気の高いAutoGenとLangGraphを取り上げ、それぞれの思想と実装方法を解説します。</p>
<h3 id="1-autogen対話による自律的タスク解決">1. AutoGen：対話による自律的タスク解決</h3>
<p>AutoGenは、Microsoft Researchが開発したフレームワークで、<strong>エージェント間の対話</strong>を中心に据えた設計が特徴です。複数のエージェント（<code>ConversableAgent</code>）を定義し、それらが互いにチャットを繰り返すことで、タスクが進行していきます。</p>
<h4 id="autogenのアーキテクチャ">AutoGenのアーキテクチャ</h4>
<p>AutoGenの基本的な登場人物は以下の通りです。</p>
<ul>
<li><strong><code>AssistantAgent</code></strong>: LLMを搭載した標準的なAIエージェント。与えられた役割（例：「あなたはPythonの専門家です」）に基づいて発言やコード生成を行います。</li>
<li><strong><code>UserProxyAgent</code></strong>: 人間の代理人として振る舞う特殊なエージェント。他のエージェントからコードを受け取ると、それを<strong>実際に実行</strong>しようと試みます。実行結果（成功、失敗、エラーメッセージ）を次のメッセージとして相手に返すことで、対話のループが生まれます。また、人間の入力を促し、介入（Human-in-the-Loop）を可能にします。</li>
<li><strong><code>GroupChatManager</code></strong>: 3体以上のエージェントが参加するグループチャットを管理し、次に誰が発言するかを制御します。</li>
</ul>
<h4 id="実装例コード生成実行タスク">実装例：コード生成＆実行タスク</h4>
<p>ここでは、「あるURLから株価データを取得し、それをプロットして画像ファイルとして保存する」というタスクを、2体のエージェントで解決する例を見てみましょう。</p>
<p><strong>1. セットアップ</strong></p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>pip install <span style="color:#e6db74">&#34;pyautogen[retrievechat]&#34;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><strong>2. 設定ファイルの準備</strong></p>
<p>プロジェクトのルートに <code>OAI_CONFIG_LIST</code> という名前でJSONファイルを作成し、APIキーを設定します。</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">6
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>[
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&#34;model&#34;</span>: <span style="color:#e6db74">&#34;gpt-4o&#34;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&#34;api_key&#34;</span>: <span style="color:#e6db74">&#34;sk-...&#34;</span>
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>]
</span></span></code></pre></td></tr></table>
</div>
</div><p><strong>3. Pythonコード</strong></p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">20
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">21
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">22
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">23
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">24
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">25
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">26
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">27
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">28
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">29
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">30
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">31
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">32
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">33
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">34
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">35
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">36
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">37
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">import</span> autogen
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># LLMの設定を読み込む</span>
</span></span><span style="display:flex;"><span>config_list <span style="color:#f92672">=</span> autogen<span style="color:#f92672">.</span>config_list_from_json(<span style="color:#e6db74">&#34;OAI_CONFIG_LIST&#34;</span>)
</span></span><span style="display:flex;"><span>llm_config <span style="color:#f92672">=</span> {<span style="color:#e6db74">&#34;config_list&#34;</span>: config_list}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 1. アシスタントエージェント（コーダー）の定義</span>
</span></span><span style="display:flex;"><span>coder <span style="color:#f92672">=</span> autogen<span style="color:#f92672">.</span>AssistantAgent(
</span></span><span style="display:flex;"><span>    name<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;Coder&#34;</span>,
</span></span><span style="display:flex;"><span>    llm_config<span style="color:#f92672">=</span>llm_config,
</span></span><span style="display:flex;"><span>    system_message<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;あなたは優秀なPythonプログラマーです。Pythonコードを生成し、問題を解決します。コードは ```python ... ``` の中に記述してください。&#34;</span>
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 2. ユーザープロキシエージェント（コード実行者・人間の代理）の定義</span>
</span></span><span style="display:flex;"><span>user_proxy <span style="color:#f92672">=</span> autogen<span style="color:#f92672">.</span>UserProxyAgent(
</span></span><span style="display:flex;"><span>    name<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;UserProxy&#34;</span>,
</span></span><span style="display:flex;"><span>    human_input_mode<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;NEVER&#34;</span>,  <span style="color:#75715e"># 人間の入力を介さず自動で進行</span>
</span></span><span style="display:flex;"><span>    max_consecutive_auto_reply<span style="color:#f92672">=</span><span style="color:#ae81ff">10</span>,
</span></span><span style="display:flex;"><span>    is_termination_msg<span style="color:#f92672">=</span><span style="color:#66d9ef">lambda</span> x: x<span style="color:#f92672">.</span>get(<span style="color:#e6db74">&#34;content&#34;</span>, <span style="color:#e6db74">&#34;&#34;</span>)<span style="color:#f92672">.</span>rstrip()<span style="color:#f92672">.</span>endswith(<span style="color:#e6db74">&#34;TERMINATE&#34;</span>),
</span></span><span style="display:flex;"><span>    code_execution_config<span style="color:#f92672">=</span>{
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;work_dir&#34;</span>: <span style="color:#e6db74">&#34;coding&#34;</span>,  <span style="color:#75715e"># コードを実行する作業ディレクトリ</span>
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;use_docker&#34;</span>: <span style="color:#66d9ef">False</span>,  <span style="color:#75715e"># Dockerを使わない場合はFalse (True推奨)</span>
</span></span><span style="display:flex;"><span>    },
</span></span><span style="display:flex;"><span>    system_message<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;あなたはコードの実行者です。Coderから提案されたコードを実行し、その結果を報告します。問題があればエラーを伝えてください。&#34;</span>
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># タスクの定義と対話の開始</span>
</span></span><span style="display:flex;"><span>task <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;&#34;&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">yfinanceとmatplotlibを使って、過去1年間のテスラ(TSLA)の株価を取得し、
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">終値を折れ線グラフでプロットしてください。
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">グラフは &#39;tsla_stock_price.png&#39; という名前でファイルに保存してください。
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">&#34;&#34;&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>user_proxy<span style="color:#f92672">.</span>initiate_chat(
</span></span><span style="display:flex;"><span>    coder,
</span></span><span style="display:flex;"><span>    message<span style="color:#f92672">=</span>task
</span></span><span style="display:flex;"><span>)
</span></span></code></pre></td></tr></table>
</div>
</div><h4 id="実行プロセスの解説">実行プロセスの解説</h4>
<p>このコードを実行すると、<code>user_proxy</code>が最初のタスクを<code>coder</code>に投げます。</p>
<ol>
<li><strong><code>coder</code></strong>: タスクを理解し、<code>yfinance</code>と<code>matplotlib</code>をインストールする必要があると考え、それらを使ったPythonコードを生成して返信します。</li>
<li><strong><code>user_proxy</code></strong>: <code>coder</code>から受け取ったコードブロックを検出し、<code>coding</code>ディレクトリ内でそのコードを実行します。</li>
<li><strong>（成功した場合）</strong>: コードが正常に実行され、<code>tsla_stock_price.png</code>が生成されます。<code>user_proxy</code>は実行結果（標準出力など）を<code>coder</code>に報告します。</li>
<li><strong><code>coder</code></strong>: 成功報告を受け、タスクが完了したと判断し、「TERMINATE」という終了キーワードを含むメッセージを返します。</li>
<li><strong><code>user_proxy</code></strong>: 「TERMINATE」を検知し、対話を終了します。</li>
</ol>
<p>もし途中でエラー（例：ライブラリがインストールされていない）が発生すれば、<code>user_proxy</code>はそのエラーメッセージを<code>coder</code>に伝えます。すると<code>coder</code>は「ライブラリをインストールしてください」といった修正案や、エラーを解決するための新しいコードを提案し、対話が続行されます。この<strong>試行錯誤のループ</strong>こそが、AutoGenの強みです。</p>
<h3 id="2-langgraphグラフによる状態遷移ワークフローの制御">2. LangGraph：グラフによる状態遷移ワークフローの制御</h3>
<p>LangGraphは、人気のLLMフレームワークLangChainから派生したライブラリで、<strong>状態遷移グラフ（Stateful Graphs）<strong>としてエージェントのワークフローを定義します。対話の自律性に重きを置くAutoGenとは対照的に、LangGraphは</strong>ワークフローの制御性</strong>に優れています。</p>
<h4 id="langgraphのアーキテクチャ">LangGraphのアーキテクチャ</h4>
<p>LangGraphの中心的な概念は以下の通りです。</p>
<ul>
<li><strong>State</strong>: グラフ全体で共有される状態オブジェクト。辞書やPydanticモデルで定義し、各ステップの出力がこのStateに蓄積されていきます。</li>
<li><strong>Nodes</strong>: グラフのノード（節点）。Python関数として定義され、それぞれが特定の処理（エージェントの呼び出し、ツールの実行など）を担当します。各ノードは現在の<code>State</code>を受け取り、更新した<code>State</code>の一部を返します。</li>
<li><strong>Edges</strong>: ノード間の繋がり（辺）。どのノードの次にどのノードを実行するかを定義します。</li>
<li><strong>Conditional Edges</strong>: 条件付きの辺。現在の<code>State</code>に基づいて、次に進むべきノードを動的に決定します。これにより、ループや分岐を持つ複雑なワークフローが実現できます。</li>
</ul>
<p><img alt="LangGraphの概念図" loading="lazy" src="https://blog.langchain.dev/content/images/2024/04/image-1.png">
<em>(出典: LangChain Blog)</em></p>
<h4 id="実装例リサーチタスクのワークフロー">実装例：リサーチタスクのワークフロー</h4>
<p>ここでは、「あるテーマについてWebでリサーチし、複数の視点から記事を作成し、それをレビューして最終的なレポートを生成する」というワークフローをLangGraphで構築してみましょう。</p>
<p><strong>1. セットアップ</strong></p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>pip install langgraph langchain langchain_openai duckduckgo-search
</span></span></code></pre></td></tr></table>
</div>
</div><p><strong>2. Pythonコード</strong></p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">  1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">  2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">  3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">  4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">  5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">  6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">  7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">  8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">  9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 19
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 20
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 21
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 22
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 23
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 24
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 25
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 26
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 27
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 28
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 29
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 30
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 31
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 32
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 33
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 34
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 35
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 36
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 37
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 38
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 39
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 40
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 41
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 42
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 43
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 44
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 45
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 46
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 47
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 48
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 49
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 50
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 51
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 52
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 53
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 54
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 55
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 56
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 57
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 58
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 59
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 60
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 61
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 62
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 63
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 64
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 65
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 66
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 67
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 68
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 69
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 70
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 71
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 72
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 73
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 74
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 75
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 76
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 77
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 78
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 79
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 80
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 81
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 82
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 83
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 84
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 85
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 86
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 87
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 88
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 89
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 90
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 91
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 92
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 93
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 94
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 95
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 96
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 97
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 98
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 99
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">100
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">101
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">102
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">103
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">104
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">105
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">106
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">107
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">108
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">109
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">110
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">111
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">112
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">113
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">114
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">115
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">116
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">117
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">118
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">119
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">import</span> os
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> typing <span style="color:#f92672">import</span> TypedDict, Annotated, List
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> langchain_core.messages <span style="color:#f92672">import</span> BaseMessage
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> langchain_openai <span style="color:#f92672">import</span> ChatOpenAI
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> langgraph.graph <span style="color:#f92672">import</span> StateGraph, END
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> langchain_community.tools <span style="color:#f92672">import</span> DuckDuckGoSearchRun
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 環境変数にAPIキーを設定</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># os.environ[&#34;OPENAI_API_KEY&#34;] = &#34;YOUR_API_KEY&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># ツール（Web検索）の準備</span>
</span></span><span style="display:flex;"><span>search_tool <span style="color:#f92672">=</span> DuckDuckGoSearchRun()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># LLMモデルの定義</span>
</span></span><span style="display:flex;"><span>model <span style="color:#f92672">=</span> ChatOpenAI(temperature<span style="color:#f92672">=</span><span style="color:#ae81ff">0</span>, model<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;gpt-4o&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># --- 1. グラフの状態 (State) を定義 ---</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">AgentState</span>(TypedDict):
</span></span><span style="display:flex;"><span>    topic: str
</span></span><span style="display:flex;"><span>    search_results: str
</span></span><span style="display:flex;"><span>    draft: str
</span></span><span style="display:flex;"><span>    review: str
</span></span><span style="display:flex;"><span>    revision_count: int
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># --- 2. グラフのノード (Nodes) を定義 ---</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># リサーチャーエージェント</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">researcher_node</span>(state: AgentState):
</span></span><span style="display:flex;"><span>    print(<span style="color:#e6db74">&#34;--- ノード: Researcher ---&#34;</span>)
</span></span><span style="display:flex;"><span>    topic <span style="color:#f92672">=</span> state[<span style="color:#e6db74">&#34;topic&#34;</span>]
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># LLMに検索クエリを考えさせる</span>
</span></span><span style="display:flex;"><span>    query_generation_prompt <span style="color:#f92672">=</span> <span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;「</span><span style="color:#e6db74">{</span>topic<span style="color:#e6db74">}</span><span style="color:#e6db74">」について調査するための、効果的な検索クエリを3つ考えてください。&#34;</span>
</span></span><span style="display:flex;"><span>    query_response <span style="color:#f92672">=</span> model<span style="color:#f92672">.</span>invoke(query_generation_prompt)
</span></span><span style="display:flex;"><span>    queries <span style="color:#f92672">=</span> query_response<span style="color:#f92672">.</span>content<span style="color:#f92672">.</span>strip()<span style="color:#f92672">.</span>split(<span style="color:#e6db74">&#39;</span><span style="color:#ae81ff">\n</span><span style="color:#e6db74">&#39;</span>)
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    results <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">for</span> query <span style="color:#f92672">in</span> queries:
</span></span><span style="display:flex;"><span>        print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;検索中: </span><span style="color:#e6db74">{</span>query<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span>        results <span style="color:#f92672">+=</span> search_tool<span style="color:#f92672">.</span>run(query) <span style="color:#f92672">+</span> <span style="color:#e6db74">&#34;</span><span style="color:#ae81ff">\n\n</span><span style="color:#e6db74">&#34;</span>
</span></span><span style="display:flex;"><span>        
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> {<span style="color:#e6db74">&#34;search_results&#34;</span>: results}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># ライターエージェント</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">writer_node</span>(state: AgentState):
</span></span><span style="display:flex;"><span>    print(<span style="color:#e6db74">&#34;--- ノード: Writer ---&#34;</span>)
</span></span><span style="display:flex;"><span>    topic <span style="color:#f92672">=</span> state[<span style="color:#e6db74">&#34;topic&#34;</span>]
</span></span><span style="display:flex;"><span>    search_results <span style="color:#f92672">=</span> state[<span style="color:#e6db74">&#34;search_results&#34;</span>]
</span></span><span style="display:flex;"><span>    prompt <span style="color:#f92672">=</span> <span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;&#34;&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    以下の検索結果を基に、「</span><span style="color:#e6db74">{</span>topic<span style="color:#e6db74">}</span><span style="color:#e6db74">」に関するブログ記事のドラフトを作成してください。
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    検索結果:
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    </span><span style="color:#e6db74">{</span>search_results<span style="color:#e6db74">}</span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    &#34;&#34;&#34;</span>
</span></span><span style="display:flex;"><span>    draft <span style="color:#f92672">=</span> model<span style="color:#f92672">.</span>invoke(prompt)<span style="color:#f92672">.</span>content
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> {<span style="color:#e6db74">&#34;draft&#34;</span>: draft}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># レビューアーエージェント</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">reviewer_node</span>(state: AgentState):
</span></span><span style="display:flex;"><span>    print(<span style="color:#e6db74">&#34;--- ノード: Reviewer ---&#34;</span>)
</span></span><span style="display:flex;"><span>    topic <span style="color:#f92672">=</span> state[<span style="color:#e6db74">&#34;topic&#34;</span>]
</span></span><span style="display:flex;"><span>    draft <span style="color:#f92672">=</span> state[<span style="color:#e6db74">&#34;draft&#34;</span>]
</span></span><span style="display:flex;"><span>    prompt <span style="color:#f92672">=</span> <span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;&#34;&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    あなたは優秀な編集者です。以下の「</span><span style="color:#e6db74">{</span>topic<span style="color:#e6db74">}</span><span style="color:#e6db74">」に関するブログ記事のドラフトをレビューしてください。
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    改善点があれば具体的に指摘し、問題がなければ「PERFECT」とだけ回答してください。
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    ドラフト:
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    </span><span style="color:#e6db74">{</span>draft<span style="color:#e6db74">}</span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    &#34;&#34;&#34;</span>
</span></span><span style="display:flex;"><span>    review <span style="color:#f92672">=</span> model<span style="color:#f92672">.</span>invoke(prompt)<span style="color:#f92672">.</span>content
</span></span><span style="display:flex;"><span>    revision_count <span style="color:#f92672">=</span> state<span style="color:#f92672">.</span>get(<span style="color:#e6db74">&#34;revision_count&#34;</span>, <span style="color:#ae81ff">0</span>) <span style="color:#f92672">+</span> <span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> {<span style="color:#e6db74">&#34;review&#34;</span>: review, <span style="color:#e6db74">&#34;revision_count&#34;</span>: revision_count}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># --- 3. 条件付きの辺 (Conditional Edge) を定義 ---</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">should_continue</span>(state: AgentState):
</span></span><span style="display:flex;"><span>    print(<span style="color:#e6db74">&#34;--- 条件分岐 ---&#34;</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> state[<span style="color:#e6db74">&#34;revision_count&#34;</span>] <span style="color:#f92672">&gt;</span> <span style="color:#ae81ff">3</span>:
</span></span><span style="display:flex;"><span>        print(<span style="color:#e6db74">&#34;最大修正回数に達しました。&#34;</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> <span style="color:#e6db74">&#34;end&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> <span style="color:#e6db74">&#34;PERFECT&#34;</span> <span style="color:#f92672">in</span> state[<span style="color:#e6db74">&#34;review&#34;</span>]:
</span></span><span style="display:flex;"><span>        print(<span style="color:#e6db74">&#34;レビューをパスしました。&#34;</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> <span style="color:#e6db74">&#34;end&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">else</span>:
</span></span><span style="display:flex;"><span>        print(<span style="color:#e6db74">&#34;修正が必要です。&#34;</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> <span style="color:#e6db74">&#34;continue&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># --- 4. グラフを構築 ---</span>
</span></span><span style="display:flex;"><span>workflow <span style="color:#f92672">=</span> StateGraph(AgentState)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># ノードを追加</span>
</span></span><span style="display:flex;"><span>workflow<span style="color:#f92672">.</span>add_node(<span style="color:#e6db74">&#34;researcher&#34;</span>, researcher_node)
</span></span><span style="display:flex;"><span>workflow<span style="color:#f92672">.</span>add_node(<span style="color:#e6db74">&#34;writer&#34;</span>, writer_node)
</span></span><span style="display:flex;"><span>workflow<span style="color:#f92672">.</span>add_node(<span style="color:#e6db74">&#34;reviewer&#34;</span>, reviewer_node)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># エッジを追加</span>
</span></span><span style="display:flex;"><span>workflow<span style="color:#f92672">.</span>set_entry_point(<span style="color:#e6db74">&#34;researcher&#34;</span>)
</span></span><span style="display:flex;"><span>workflow<span style="color:#f92672">.</span>add_edge(<span style="color:#e6db74">&#34;researcher&#34;</span>, <span style="color:#e6db74">&#34;writer&#34;</span>)
</span></span><span style="display:flex;"><span>workflow<span style="color:#f92672">.</span>add_edge(<span style="color:#e6db74">&#34;writer&#34;</span>, <span style="color:#e6db74">&#34;reviewer&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 条件付きエッジを追加</span>
</span></span><span style="display:flex;"><span>workflow<span style="color:#f92672">.</span>add_conditional_edges(
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;reviewer&#34;</span>,
</span></span><span style="display:flex;"><span>    should_continue,
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;continue&#34;</span>: <span style="color:#e6db74">&#34;writer&#34;</span>, <span style="color:#75715e"># 修正が必要ならライターに戻る</span>
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;end&#34;</span>: END
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># グラフをコンパイル</span>
</span></span><span style="display:flex;"><span>app <span style="color:#f92672">=</span> workflow<span style="color:#f92672">.</span>compile()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># --- 5. グラフを実行 ---</span>
</span></span><span style="display:flex;"><span>inputs <span style="color:#f92672">=</span> {<span style="color:#e6db74">&#34;topic&#34;</span>: <span style="color:#e6db74">&#34;2024年の生成AIのトレンド&#34;</span>, <span style="color:#e6db74">&#34;revision_count&#34;</span>: <span style="color:#ae81ff">0</span>}
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">for</span> output <span style="color:#f92672">in</span> app<span style="color:#f92672">.</span>stream(inputs):
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">for</span> key, value <span style="color:#f92672">in</span> output<span style="color:#f92672">.</span>items():
</span></span><span style="display:flex;"><span>        print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;ノード &#39;</span><span style="color:#e6db74">{</span>key<span style="color:#e6db74">}</span><span style="color:#e6db74">&#39; の出力:&#34;</span>)
</span></span><span style="display:flex;"><span>        print(<span style="color:#e6db74">&#34;---&#34;</span>)
</span></span><span style="display:flex;"><span>        print(value)
</span></span><span style="display:flex;"><span>    print(<span style="color:#e6db74">&#34;</span><span style="color:#ae81ff">\n</span><span style="color:#e6db74">&#34;</span> <span style="color:#f92672">+</span> <span style="color:#e6db74">&#34;=&#34;</span><span style="color:#f92672">*</span><span style="color:#ae81ff">30</span> <span style="color:#f92672">+</span> <span style="color:#e6db74">&#34;</span><span style="color:#ae81ff">\n</span><span style="color:#e6db74">&#34;</span>)
</span></span></code></pre></td></tr></table>
</div>
</div><h4 id="実行プロセスの解説-1">実行プロセスの解説</h4>
<p>このコードは、以下のような明確なワークフローを実行します。</p>
<ol>
<li><strong><code>researcher</code></strong>: 与えられたトピックに基づいてWeb検索を実行し、結果を<code>State</code>に保存します。</li>
<li><strong><code>writer</code></strong>: <code>researcher</code>が収集した情報をもとに、記事のドラフトを作成し、<code>State</code>に保存します。</li>
<li><strong><code>reviewer</code></strong>: <code>writer</code>が書いたドラフトをレビューします。</li>
<li><strong><code>should_continue</code> (条件分岐)</strong>:
<ul>
<li>レビュー結果が「PERFECT」なら、ワークフローは終了（<code>END</code>）します。</li>
<li>修正点があれば、<code>writer</code>ノードに処理を戻し、ドラフトの修正を促します（ループ）。</li>
<li>ループが3回を超えた場合も、無限ループを避けるために処理を終了します。</li>
</ul>
</li>
</ol>
<p>このように、LangGraphは処理の流れを明示的にグラフとして定義するため、デバッグが容易で、ビジネスロジックのような複雑なフローを堅牢に実装するのに適しています。</p>
<h2 id="メリットとデメリットそしてツールの比較">メリットとデメリット、そしてツールの比較</h2>
<p>マルチエージェント・システムは強力ですが、銀の弾丸ではありません。導入にあたっては、その利点と課題を理解することが重要です。</p>
<h3 id="マルチエージェントシステムのメリット">マルチエージェント・システムのメリット</h3>
<ul>
<li><strong>高度な問題解決能力</strong>: 複雑なタスクを専門家チームのように分業・協調して解決できる。</li>
<li><strong>堅牢性と自己修正</strong>: レビューやフィードバックのループを組み込むことで、生成物の品質を向上させ、エラーから自律的に回復できる。</li>
<li><strong>モジュール性と拡張性</strong>: 新しい役割を持つエージェントをノードや対話者として追加するのが比較的容易。</li>
<li><strong>プロセスの透明性</strong>: エージェント間の対話ログや状態遷移を追跡することで、AIが「どのように」その結論に至ったのかを理解しやすくなる。</li>
</ul>
<h3 id="マルチエージェントシステムのデメリットと課題">マルチエージェント・システムのデメリットと課題</h3>
<ul>
<li><strong>設計の複雑性</strong>: どのような役割のエージェントが必要か、どのようなワークフローや対話プロトコルを設計するかが成功の鍵となり、高度な設計能力が求められる。</li>
<li><strong>制御の難しさ</strong>: 特に自律性の高いシステムでは、エージェントが無限ループに陥ったり、意図しない方向にタスクを進めたりするリスクがある。</li>
<li><strong>コストの増加</strong>: 複数のエージェントが何度もLLM APIを呼び出すため、シングルエージェントに比べてトークン消費量とコストが大幅に増加する可能性がある。</li>
<li><strong>レイテンシーの増大</strong>: エージェント間の通信やLLMの呼び出しが重なるため、最終的な結果を得るまでの時間が長くなる傾向がある。</li>
</ul>
<h3 id="langgraph-vs-autogenどちらを選ぶべきか">LangGraph vs AutoGen：どちらを選ぶべきか？</h3>
<table>
  <thead>
      <tr>
          <th style="text-align: left">特徴</th>
          <th style="text-align: left">LangGraph (by LangChain)</th>
          <th style="text-align: left">AutoGen (by Microsoft)</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td style="text-align: left"><strong>思想</strong></td>
          <td style="text-align: left"><strong>状態遷移グラフ</strong>によるワークフロー制御</td>
          <td style="text-align: left"><strong>対話</strong>による自律的な協調</td>
      </tr>
      <tr>
          <td style="text-align: left"><strong>制御性</strong></td>
          <td style="text-align: left"><strong>高い</strong>。処理の流れを明示的にグラフで定義するため、予測可能でデバッグしやすい。</td>
          <td style="text-align: left"><strong>中程度</strong>。エージェント間の対話に依存するため、創発的な挙動を示すが、制御は難しい。</td>
      </tr>
      <tr>
          <td style="text-align: left"><strong>柔軟性</strong></td>
          <td style="text-align: left"><strong>非常に高い</strong>。ノードはただのPython関数なので、任意のロジックを自由に組み込める。</td>
          <td style="text-align: left"><strong>高い</strong>。Agentクラスを継承してカスタマイズ可能だが、対話の枠組みに従う必要がある。</td>
      </tr>
      <tr>
          <td style="text-align: left"><strong>学習コスト</strong></td>
          <td style="text-align: left">やや高い。グラフ理論や状態管理の概念を理解する必要がある。</td>
          <td style="text-align: left">比較的低い。<code>initiate_chat</code>で始められ、直感的に理解しやすい。</td>
      </tr>
      <tr>
          <td style="text-align: left"><strong>ベストな用途</strong></td>
          <td style="text-align: left">複雑なビジネスプロセス、ETLパイプライン、自己修正ループなど、<strong>手順が明確なタスク</strong>。</td>
          <td style="text-align: left">研究開発、コード生成、ブレーンストーミングなど、<strong>解決策が未知で探索的なタスク</strong>。</td>
      </tr>
  </tbody>
</table>
<p>結論として、「厳密なワークフローを構築したいならLangGraph」「エージェントの自律的な協調に任せてみたいならAutoGen」という使い分けが考えられます。</p>
<h2 id="現場で使える実践的なtips">現場で使える実践的なTips</h2>
<p>マルチエージェント・システムを本番環境で運用するには、いくつかの工夫が必要です。</p>
<ol>
<li><strong>スモールスタートを心がける</strong>: 最初から10体のエージェントチームを作るのではなく、まずは2〜3体のコアな役割のエージェントから始め、徐々に拡張していきましょう。</li>
<li><strong>役割（Role）のプロンプトを磨き込む</strong>: 各エージェントの<code>system_message</code>は、その性能を決定づける最も重要な要素です。「あなたは何者で、何が得意で、何をしてはいけないのか」を可能な限り明確に定義してください。</li>
<li><strong>強力なマネージャー/オーケストレーターを置く</strong>: LangGraphのグラフ定義そのものや、複数のエージェントを統括するマネージャーエージェントの設計は非常に重要です。タスクの分解、進行管理、最終的な成果物の統合といった役割を担わせましょう。</li>
<li><strong>コスト管理戦略を立てる</strong>:
<ul>
<li><strong>モデルの使い分け</strong>: 簡単なタスク（要約、分類など）には安価なモデル（例: GPT-3.5 Turbo, Claude 3 Sonnet）を使い、高度な推論やコーディングが必要な場面では高性能モデル（例: GPT-4o, Claude 3 Opus）を使うハイブリッド構成を検討します。</li>
<li><strong>サーキットブレーカー</strong>: APIコールの回数や対話のターン数に上限を設け、無限ループによるコスト増大を防ぎます。LangGraphの例で示した<code>revision_count</code>がこれにあたります。</li>
</ul>
</li>
<li><strong>人間参加のループ (Human-in-the-Loop) を組み込む</strong>: 全てを自動化するのではなく、重要な意思決定ポイント（例：生成したコードの実行前、顧客へのメール送信前）では、必ず人間の承認を求めるステップをワークフローに組み込みましょう。AutoGenの<code>UserProxyAgent</code>は、このための優れた仕組みを提供しています。</li>
<li><strong>ロギングとトレーサビリティ</strong>: エージェント間の全てのやり取りや状態の変化を詳細にログとして記録します。LangSmithのようなツールを使うと、複雑なエージェントの挙動を可視化し、デバッグを大幅に効率化できます。</li>
</ol>
<h2 id="まとめ">まとめ</h2>
<p>私たちは今、AI開発における大きな転換点に立っています。単一のLLMに完璧な答えを求める「シングルプロンプトの時代」は終わりを告げ、多様な能力を持つAIエージェントが協調して複雑な問題を解決する**「マルチエージェント協調の時代」**が幕を開けようとしています。</p>
<p>この記事では、その中核技術であるマルチエージェント・システムの概念と、それを実現するAutoGenとLangGraphという二つの強力なフレームワークについて解説しました。</p>
<ul>
<li><strong>AutoGen</strong>は、エージェント間の「対話」を通じて、自己修正的なループを生み出し、探索的なタスクを自律的に解決します。</li>
<li><strong>LangGraph</strong>は、「状態遷移グラフ」としてワークフローを明示的に定義することで、複雑なビジネスプロセスを堅牢かつ制御可能に実装します。</li>
</ul>
<p>これらの技術は、まだ発展途上であり、コストや制御性の面で課題も残されています。しかし、そのポテンシャルは計り知れません。もはや私たちの仕事は、単に賢いAIを一つ作ることではなく、<strong>いかにして「優秀なAIチーム」を設計し、編成し、マネジメントするか</strong>という、より高度な次元へとシフトしています。</p>
<p>2026年に向けて、この流れはさらに加速していくでしょう。ぜひ、この記事をきっかけに、まずは簡単な2エージェントシステムから、あなたの身の回りの課題解決に挑戦してみてください。そこに、次世代のAIアプリケーション開発の未来が広がっているはずです。</p>
]]></content:encoded>
      <category>Tech</category>
      <category>AI Agent</category>
      <category>LangChain</category>
      <category>LLM</category>
    </item>
  </channel>
</rss>
