SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

AIエージェント開発の最前線!現場で使える開発術

【AIエージェント開発入門】開発前に知るべき概念・基本設計と実装パターン

AIエージェント開発の最前線!現場で使える開発術 第1回

AIエージェントを実装するための基本パターン

 一口にAIエージェントといっても、構成パターンは多岐にわたります。共通項として認識される構成要素としては、Profile、Memory、Planning、Actionなどが挙げられます。

  • Profile:タスクを担当するAIエージェントに付与される役割や性格
  • Memory:背景情報を保持する短期記憶や、ユーザ情報など長期で保存される記憶
  • Planning:目的を達成するためのタスクばらしや、行動/観測結果からの再計画
  • Action:コード生成や検索など外部の計算/知識資源にアクセスしたり、環境に作用するもの
出典:Building effective agents(左)、Agents(右)
出典:Building effective agents(左)/Agents(右)

 以降の節では、構成パターンを具体的にイメージいただくため、OpenAI Agents SDKを用いて3つの構成パターンを紹介します。

行動(ツール実行)と観測

 まずは最もシンプルなエージェントの構成パターンです。ユーザーからの入力にもとづいて、事前に定義した「ツール」を必要に応じて呼び出し、その結果を解釈してユーザーに返します。

 「ツール」とは、言語モデルの外部で実行されるコンピュータプログラムや関数インターフェースを指します。AIエージェントが呼び出し対象のツールと、ツールの実行に必要な情報を引数として生成することで、任意の関数を実行することができます。このパターンは、どの業務を代替するときも用いられることが非常に多いです。

from agents import Agent, Runner, function_tool

@function_tool
def get_weather(city: str) -> str:
    """与えられた都市の現在の天気を返す"""
    return f"The weather in {city} is sunny"  # ダミー

async def main(user_message: str) -> str:
    agent = Agent(name="Agent",
                 instructions="You are a helpful assistant",
                 model="gpt-5-mini",
                 tools=[get_weather],  # エージェントが呼び出し可能な関数
                 tool_use_behavior="run_llm_again")  # 関数の実行結果をLLMが解釈して返す
    result = await Runner.run(agent, user_message)
    return result.final_output

ルーティングを伴うワークフロー

 先のスライド作成のステップ例のように、業務の流れ(ワークフロー)が事前に決定している場合もあります。これらのワークフローでは、順番にフローが定義される場合もあれば、特定の条件で次の行動対象が決定する場合もあります。たとえば「導入と結論が結びついていないため全体の構成を見直す」といった差し戻しが該当します。

 OpenAI Agents SDK では「handoffs」機能を用いて、次の遷移先となるエージェントを事前に設定することができます。このパターンは、関心ごとでフローを分離したいときに利用します。

 たとえばカスタマーサポートでは、部署や機能単位で異なるエージェントを用意し、ユーザーの問い合わせ内容に応じてルーティングを適用します。

from agents import Agent, Runner, CodeInterpreterTool, WebSearchTool
from agents import enable_verbose_stdout_logging
enable_verbose_stdout_logging()

async def main(user_message: str) -> str:
   researcher = Agent(
       name="Researcher",
       handoff_description="Web検索をともなう情報調査と要約の専門家",
       instructions="Webから信頼できる情報を取得し、ユーザの質問に分かりやすく回答する",
       tools=[WebSearchTool()]
   )
   programmer = Agent(
       name="Programmer",
       handoff_description="コーディングとプログラミングの専門家",
       instructions="要件を満たす効率的なコードを実行し、ロジックについて説明を加える",
       tools=[CodeInterpreterTool(tool_config={"type": "code_interpreter"})]
   )
   triage_agent = Agent(
       name="Triage",
       instructions="ユーザーの質問にもとづいて、どのエージェントを選択するかを決定する",
       handoffs=[researcher, programmer],
   )
   result = await Runner.run(triage_agent, user_message)
   return result.final_output

ループを伴うマルチエージェント

 執筆などのアウトプットをともなうタスクでは、試行錯誤を繰り返すことによる質の向上を期待することがあります。複数のエージェントが協力/競争することで複雑なタスクを達成するのを目的としたのがマルチエージェントシステムになります。

 また複数の機能を搭載するとその分だけ管理すべき要素が増えてしまいます。「単一責任化」や「関心の分離」といった設計思想を考慮し、プロジェクトの成熟度に応じて段階的に導入すると、システム全体の能力をより引き出しやすくなります。

from agents import Agent, Runner
from agents import enable_verbose_stdout_logging
enable_verbose_stdout_logging()

async def main(user_message: str) -> str:
   moderator = Agent(
       name="Moderator",
       handoff_description="討論全体を管理し、進行する司会者",
       instructions=(
           "以下の手順で議論を進行します。\n"
           "1. テーマの決定: ユーザー入力をもとに、討論の公式な論題を再定義します\n"
           "2. 肯定的な立論: はじめに proponent_agent に肯定的な立論を指示します\n"
           "3. 否定的な立論: 次に opponent_agent に否定的な立論を指示します\n"
           "4. 弁論の指示: proponent_agent, opponent_agent 間で、弁論を行うよう指示します\n"
           "5. 結論づけ: 弁論が終了したら summarizer_agent に議論の要約を指示します"
       ),
   )
   proponent_agent = Agent(
       name="Proponent",
       handoff_description="テーマに対し、肯定の立場から論点を提示します。",
       instructions="肯定の立場から具体的な根拠・事例を挙げて、説得力のある主張を行う",
   )
   opponent_agent = Agent(
       name="Opponent",
       handoff_description="テーマに対し、否定の立場から反論や代替案を提示します。",
       instructions="否定の立場から具体的な根拠・事例を挙げて、説得力のある主張を行う",
   )
   summarizer = Agent(
       name="Summarizer",
       handoff_description="討論終了時に、これまでの議論をまとめます。",
       instructions="議論全体を公平に評価し、主要な論点と結論を客観的に要約する",
   )
   moderator.handoffs = [proponent_agent, summarizer]
   proponent_agent.handoffs = [opponent_agent]
   opponent_agent.handoffs = [moderator]
   display(draw_graph(moderator))
   result = await Runner.run(moderator, user_message)
   return result.final_output

次のページ
価値を最大化するためのAIエージェント開発戦略

この記事は参考になりましたか?

AIエージェント開発の最前線!現場で使える開発術連載記事一覧

もっと読む

この記事の著者

宮脇峻平(@catshun_)(ミヤワキ シュンペイ)

 企業でのR&D・アカデミアでの学術研究を経て、株式会社AlgomaticにAI/MLエンジニアとして入社。LLM/AIエージェントを用いた戦略設計、プロダクト開発、MLOps構築に従事。あらゆる不確実性を技術で解決し、AIと人の共生を目指す。 採用を支援するAIエージェント『リクルタAI』...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/22260 2025/10/22 11:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー