「AIエージェントって、実際どうやってPythonで作るの?」
AIエージェントという言葉が飛び交うなかで、多くの開発者から繰り返し届く質問がこれです。概念はわかった、でも実際に手を動かして動くものを作れる人は、まだ少ない。
実際に10社以上のAIエージェント導入支援をしてきて気づいたのは、「入門記事を読んだ後の実装の壁」が思った以上に高いということでした。使うフレームワークが多すぎて選べない。コードを書いてみてもうまく動かない。そこで止まってしまうケースを何度も見てきました。
この記事では、AIエージェントをPythonでゼロから作る方法を、コピペ可能なコード・設定例つきで全公開します。フレームワークなしのスクラッチ実装から始め、OpenAI Agents SDK・LangChainといった主要フレームワークへの移行まで、5分で試せるセットアップを起点に順を追って紹介していきます。
AIエージェントの概念・定義については、当サイトの「AIエージェントとは?仕組み・種類・活用事例」で詳しく解説しています。この記事は「実装」にフォーカスします。
まず5分で動かす——スクラッチAIエージェント3選
最初の壁を超えるために、今すぐコピペして動く実装から始めましょう。環境変数 OPENAI_API_KEY さえ設定してあれば、以下は全て動きます。
即効実装1:フレームワークなし、素のPythonエージェント(ReActパターン)
まず「エージェントとは何か」を体で理解するために、外部ライブラリなしでReActループを実装してみましょう。これを自分で書いた人は、LangChainの内部で何が起きているかが一瞬でわかるようになります。
# 動作環境: Python 3.11+, openai>=1.30.0
# pip install openai
# 注意: 本番環境で使用する前に、必ずテスト環境で動作確認してください。
import os
import json
from openai import OpenAI
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
# ツール定義(エージェントが使える「手」)
TOOLS = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "指定した都市の天気を取得します",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "都市名(例: 東京、大阪)"}
},
"required": ["city"]
}
}
}
]
def get_weather(city: str) -> str:
"""ダミーの天気API(実際はOpen-Meteo等に差し替え)"""
weather_data = {"東京": "晴れ、気温22℃", "大阪": "曇り、気温19℃"}
return weather_data.get(city, f"{city}の天気情報は取得できません")
def run_agent(user_message: str) -> str:
"""ReAct(Reasoning + Acting)ループの実装"""
messages = [
{"role": "system", "content": "ユーザーの質問に日本語で答えるアシスタントです。必要であれば天気ツールを使ってください。"},
{"role": "user", "content": user_message}
]
# ReActループ: Think → Act → Observe → 繰り返す
for _ in range(5): # 最大5回まで(無限ループ防止)
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=messages,
tools=TOOLS,
tool_choice="auto"
)
msg = response.choices[0].message
messages.append(msg)
# ツール呼び出しが必要なら実行(Actフェーズ)
if msg.tool_calls:
for call in msg.tool_calls:
if call.function.name == "get_weather":
args = json.loads(call.function.arguments)
result = get_weather(args["city"])
messages.append({
"role": "tool",
"tool_call_id": call.id,
"content": result
})
else:
# ツール呼び出しなし → 最終回答
return msg.content
return "エラー: ループ上限に達しました"
# 実行例
if __name__ == "__main__":
answer = run_agent("東京と大阪、今日はどっちが暖かい?")
print(answer)
ポイント:
for _ in range(5)のループ上限は必ず設定する。設定しないと無限ループになるケースがあるtool_callsがNoneなら「エージェントが最終回答を出した」サインgpt-4o-miniを使うとコストを1/30以下に抑えながら開発できる
即効実装2:OpenAI Agents SDKで10行エージェント
スクラッチ実装の仕組みを理解したら、OpenAI公式のAgents SDKに乗り換えましょう。コードが劇的に短くなります。
# 動作環境: Python 3.11+
# pip install openai-agents
# 注意: 本番環境で使用する前に、必ずテスト環境で動作確認してください。
import asyncio
from agents import Agent, Runner, function_tool
@function_tool
def get_weather(city: str) -> str:
"""指定した都市の天気を返します。"""
weather_data = {"東京": "晴れ、気温22℃", "大阪": "曇り、気温19℃"}
return weather_data.get(city, f"{city}の天気情報は取得できません")
agent = Agent(
name="天気エージェント",
instructions="ユーザーの質問に日本語で丁寧に回答してください。天気の質問にはget_weatherツールを使ってください。",
model="gpt-4o-mini",
tools=[get_weather],
)
async def main():
result = await Runner.run(agent, "東京の今日の天気は?")
print(result.final_output)
asyncio.run(main())
ポイント:
@function_toolデコレータでPython関数を即ツール化できる- スクラッチ実装で書いた30行のReActループが、SDK内部で自動実行される
- 同期実行が必要なら
Runner.run_sync()を使う
即効実装3:LangChainでツール連携エージェント
複数ツールを組み合わせた実用的なエージェントが必要なら、LangChainが安定した選択肢です。エラーハンドリングと会話メモリを含む実装例を示します。
# 動作環境: Python 3.11+
# pip install langchain langchain-openai
# 注意: 本番環境で使用する前に、必ずテスト環境で動作確認してください。
import os
from langchain_openai import ChatOpenAI
from langchain.agents import AgentExecutor, create_openai_functions_agent
from langchain.tools import tool
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain.memory import ConversationBufferWindowMemory
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0, api_key=os.environ["OPENAI_API_KEY"])
@tool
def get_weather(city: str) -> str:
"""指定した都市の天気を取得します。"""
weather_data = {"東京": "晴れ、気温22℃", "大阪": "曇り、気温19℃"}
return weather_data.get(city, f"{city}の天気情報は取得できません")
@tool
def calculate(expression: str) -> str:
"""数式を計算します。例: '2 + 3 * 4'"""
try:
# evalは本番では使わないこと(セキュリティリスク)— numexprを推奨
result = eval(expression, {"__builtins__": {}}, {})
return str(result)
except Exception as e:
return f"計算エラー: {str(e)}"
tools = [get_weather, calculate]
prompt = ChatPromptTemplate.from_messages([
("system", "ユーザーの質問に日本語で回答するアシスタントです。ツールを積極的に活用してください。"),
MessagesPlaceholder(variable_name="chat_history"),
("human", "{input}"),
MessagesPlaceholder(variable_name="agent_scratchpad"),
])
memory = ConversationBufferWindowMemory(k=5, memory_key="chat_history", return_messages=True)
agent = create_openai_functions_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools, memory=memory, verbose=True)
# 実行例(会話の連続性が保たれる)
response1 = executor.invoke({"input": "東京の天気は?"})
print(response1["output"])
response2 = executor.invoke({"input": "さっき言った都市に関係する数式、15 + 7 を計算して"})
print(response2["output"])
ポイント:
ConversationBufferWindowMemory(k=5)で直近5ターンの会話を記憶するevaluateは本番ではセキュリティリスク。数値計算にはnumexprライブラリを使うことverbose=TrueにするとReActの思考過程がコンソールに出力されるため、デバッグに便利
AIエージェントの仕組みを”3つの型”で理解する
実装を始める前に、「何を作るか」を明確にしておきましょう。AIエージェントは構造によって大きく3つの型に分かれます。
| 型 | 構造 | 難易度 | 典型的なユースケース | 参考フレームワーク |
|---|---|---|---|---|
| シングルエージェント | LLM 1体 + ツール群 | ★☆☆ | 問い合わせ対応、情報収集、データ変換 | OpenAI Agents SDK |
| マルチエージェント(逐次) | 複数LLMを直列に連結 | ★★☆ | 文章生成→レビュー→修正の自動化 | LangGraph, LangChain |
| マルチエージェント(並列) | 複数LLMが並列で協調 | ★★★ | 大規模データ処理、複数タスクの同時実行 | CrewAI, OpenAI Agents SDK |
初めて作るなら「シングルエージェント+2〜3ツール」からスタートするのが正解です。いきなり並列マルチエージェントを構築しようとすると、デバッグで詰まってプロジェクトが止まります。
フレームワーク選定ガイド:2026年版比較表
Pythonで使える主要AIエージェントフレームワークを整理しました。2026年3月時点の情報です。
| フレームワーク | GitHub Stars | 特徴 | 向いているケース | 向かないケース |
|---|---|---|---|---|
| OpenAI Agents SDK | ※注1 | 軽量・公式・マルチエージェント対応 | OpenAIモデルを使った本番開発 | マルチモデル環境(Claudeも使いたい等) |
| LangChain | 126,000+ | 700以上のインテグレーション・最大エコシステム | 外部サービス連携が多いエージェント | シンプルな単機能エージェント(オーバースペック) |
| LangGraph | 24,600+ | グラフ構造でワークフローを精密制御 | 複雑な条件分岐・ループのある処理 | プロトタイプ・PoC(学習コストが高い) |
| Pydantic AI | ※注1 | 型安全・モデル不依存・Pythonicな設計 | 型安全性が重要な本番環境 | エコシステムの広さが必要なケース |
| スクラッチ(フレームワークなし) | — | 完全な制御・依存関係ゼロ | 学習目的・超軽量エージェント | 本番開発(メンテナンスコストが高い) |
料金情報(最終確認: 2026-03-18): いずれのフレームワークも本体は無料・オープンソース。APIコストはOpenAI GPT-4o-miniが入力$0.15/百万トークン・出力$0.60/百万トークン(出典: OpenAI公式料金ページ)。GitHubスター数は2026年3月時点の概算値(※注1: OpenAI Agents SDK・Pydantic AIは急成長中のためアクセス時点で変動します)。
ユースケース別実装パターン3選
フレームワークを選んだら、実際のビジネスユースケースに即した実装例を見ていきましょう。
ユースケース1:Webスクレイピング+要約エージェント
日次のニュース収集を自動化するエージェントです。「URL一覧を渡したら要約レポートを作って返す」という処理を実装します。
# 動作環境: Python 3.11+
# pip install openai-agents requests beautifulsoup4
# 注意: 本番環境で使用する前に、必ずテスト環境で動作確認してください。
import os, requests
from bs4 import BeautifulSoup
from agents import Agent, Runner, function_tool
@function_tool
def fetch_page_text(url: str) -> str:
"""指定URLのページ本文テキストを取得します(最大3,000文字)。"""
try:
resp = requests.get(url, timeout=10, headers={"User-Agent": "Mozilla/5.0"})
resp.raise_for_status()
soup = BeautifulSoup(resp.text, "html.parser")
# scriptとstyleを除去
for tag in soup(["script", "style", "nav", "footer"]):
tag.decompose()
text = soup.get_text(separator="n", strip=True)
return text[:3000] # トークン節約のため3,000文字に制限
except Exception as e:
return f"ページ取得エラー: {str(e)}"
news_agent = Agent(
name="ニュース要約エージェント",
instructions="""
渡されたURLのページを取得し、以下の形式でレポートを作成してください。
フォーマット:
## [記事タイトル]
- 要点1
- 要点2
- 要点3
- AIエージェント開発者へのインパクト: [1文で]
""",
model="gpt-4o-mini",
tools=[fetch_page_text],
)
async def summarize_urls(urls: list[str]) -> str:
prompt = "以下のURLの記事を要約してください:n" + "n".join(f"- {u}" for u in urls)
result = await Runner.run(news_agent, prompt)
return result.final_output
# 実行例
if __name__ == "__main__":
import asyncio
urls = ["https://openai.com/blog/", "https://anthropic.com/news/"]
report = asyncio.run(summarize_urls(urls))
print(report)
ポイント:
text[:3000]でトークン上限に引っかかるリスクを下げる。長いページは重要部分だけ抽出する処理を追加するとよいUser-Agentを設定しないとブロックされるサイトが多い- スクレイピング対象サイトの利用規約を必ず確認すること
ユースケース2:データ分析+可視化エージェント
CSVデータをアップロードして「分析してグラフを作って」を自動化します。
# 動作環境: Python 3.11+
# pip install openai-agents pandas matplotlib
# 注意: 本番環境で使用する前に、必ずテスト環境で動作確認してください。
import os, json
import pandas as pd
import matplotlib
matplotlib.use("Agg") # 非GUIバックエンドを使用(サーバー環境対応)
import matplotlib.pyplot as plt
from agents import Agent, Runner, function_tool
@function_tool
def analyze_csv(csv_path: str) -> str:
"""CSVファイルを読み込み、基本統計情報を返します。"""
try:
df = pd.read_csv(csv_path)
stats = {
"行数": len(df),
"列数": len(df.columns),
"列名": list(df.columns),
"数値列の統計": df.describe().to_dict()
}
return json.dumps(stats, ensure_ascii=False, default=str)
except Exception as e:
return f"CSV読み込みエラー: {str(e)}"
@function_tool
def plot_bar_chart(csv_path: str, x_column: str, y_column: str, output_path: str) -> str:
"""CSVから棒グラフを生成してファイルに保存します。"""
try:
df = pd.read_csv(csv_path)
fig, ax = plt.subplots(figsize=(10, 6))
ax.bar(df[x_column], df[y_column])
ax.set_xlabel(x_column)
ax.set_ylabel(y_column)
ax.set_title(f"{x_column} × {y_column}")
plt.xticks(rotation=45)
plt.tight_layout()
plt.savefig(output_path)
plt.close()
return f"グラフを保存しました: {output_path}"
except Exception as e:
return f"グラフ生成エラー: {str(e)}"
analyst_agent = Agent(
name="データ分析エージェント",
instructions="CSVデータを分析し、適切なグラフを生成して、洞察をわかりやすく説明してください。",
model="gpt-4o", # 複雑な分析はgpt-4oを推奨
tools=[analyze_csv, plot_bar_chart],
)
ユースケース3:Slackへの自動報告エージェント
分析結果をSlackチャンネルに自動送信する実装です。定期実行のcronジョブと組み合わせると、朝のデイリーレポートを完全自動化できます。
# 動作環境: Python 3.11+
# pip install openai-agents slack-sdk
# 注意: 本番環境で使用する前に、必ずテスト環境で動作確認してください。
import os
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError
from agents import Agent, Runner, function_tool
slack_client = WebClient(token=os.environ["SLACK_BOT_TOKEN"])
@function_tool
def post_to_slack(channel: str, message: str) -> str:
"""Slackチャンネルにメッセージを送信します。"""
try:
slack_client.chat_postMessage(channel=channel, text=message)
return f"Slackに送信しました: {channel}"
except SlackApiError as e:
return f"Slack送信エラー: {e.response['error']}"
reporter_agent = Agent(
name="Slack報告エージェント",
instructions="""
与えられたデータを分析し、以下の形式でSlackレポートを作成して送信してください。
チャンネル: #daily-report
フォーマット:
【デイリーレポート】{日付}
✅ 完了: [内容]
⚠️ 注意事項: [内容]
📊 数値サマリー: [主要KPI]
""",
model="gpt-4o-mini",
tools=[post_to_slack],
)
マルチエージェント設計:オーケストレーターとワーカーの分離
業務が複雑になってきたら、「指示役(オーケストレーター)」と「実行役(ワーカー)」を分けたマルチエージェント構成を検討しましょう。
OpenAI Agents SDKのハンドオフ機能を使った実装例です。
# 動作環境: Python 3.11+
# pip install openai-agents
# 注意: 本番環境で使用する前に、必ずテスト環境で動作確認してください。
import asyncio
from agents import Agent, Runner, function_tool, handoff
# ワーカーエージェント1:リサーチ担当
research_agent = Agent(
name="リサーチャー",
instructions="与えられたトピックについて調査し、重要な情報を箇条書きでまとめてください。",
model="gpt-4o-mini",
)
# ワーカーエージェント2:ライター担当
writer_agent = Agent(
name="ライター",
instructions="提供された情報をもとに、ブログ記事の本文(500字程度)を書いてください。",
model="gpt-4o",
)
# オーケストレーター:全体制御
orchestrator = Agent(
name="オーケストレーター",
instructions="""
ユーザーのリクエストを分析し、適切なエージェントに作業を依頼してください。
1. まずリサーチャーに情報収集を依頼する
2. 収集した情報をライターに渡して記事を作成させる
""",
model="gpt-4o",
handoffs=[
handoff(research_agent),
handoff(writer_agent),
]
)
async def main():
result = await Runner.run(orchestrator, "AIエージェントの最新トレンドについての記事を作成してください")
print(result.final_output)
asyncio.run(main())
ポイント:
handoff()でオーケストレーターがワーカーに会話を引き継ぎできる- ワーカーは専門特化することで精度が上がる(ジェネラリスト1体より専門家2体)
- オーケストレーターにはより高性能なモデル(gpt-4o)を使い、ワーカーには軽量モデルを使ってコストを下げる設計が有効
より複雑なワークフロー制御が必要な場合は、「LangGraph・CrewAI・AutoGen徹底比較」でグラフ型のオーケストレーションパターンを詳しく解説しています。
本番運用前に必須:セキュリティと運用設計
正直に言うと、AIエージェントのセキュリティはまだ発展途上の領域です。「動くものを作れた」で止まらず、以下の対策を本番前に必ず実装してください。
| リスク | 対策 | 実装の目安 |
|---|---|---|
| プロンプトインジェクション | ユーザー入力のサニタイズ、システムプロンプトの分離 | PoC段階から必須 |
| APIキー漏洩 | 環境変数管理(.envやSecret Manager)、ハードコード禁止 | 開発開始前に設定 |
| ツール実行の暴走 | ループ回数の上限設定、ツール実行ログの保存 | PoC段階から必須 |
| コスト超過 | 月額上限の設定、モデルのダウングレード検討 | 本番移行前に設定 |
| ハルシネーション | ツール出力の優先(LLMの生成より実データを信頼) | 設計時に意識 |
# セキュリティ実装例: APIキーの安全な管理
# 注意: 本番環境で使用する前に、必ずテスト環境で動作確認してください。
# ❌ NG: ハードコード
# client = OpenAI(api_key="sk-abc123...")
# ⭕ OK: 環境変数から取得
import os
from dotenv import load_dotenv
load_dotenv() # .envファイルから読み込み(開発時)
api_key = os.environ.get("OPENAI_API_KEY")
if not api_key:
raise ValueError("OPENAI_API_KEY が設定されていません")
# .envファイル(.gitignoreに必ず追加)
# OPENAI_API_KEY=sk-your-key-here
# コスト管理: OpenAIダッシュボードで月額上限を設定すること
# https://platform.openai.com/settings/organization/limits
【要注意】よくある失敗パターンと回避策
10社以上のAIエージェント導入支援を経て蓄積した「引っかかりやすいポイント」を共有します。
失敗1:ツールの説明文が曖昧すぎる
ツールの description はエージェントへの「説明書」です。ここが曖昧だと、エージェントが適切なタイミングでツールを使えなくなります。
# ❌ NG: 説明が抽象的
@function_tool
def get_data(query: str) -> str:
"""データを取得します。""" # エージェントが使い方を判断できない
...
# ⭕ OK: いつ・何を・どうやって使うかを明記
@function_tool
def search_product_db(product_name: str) -> str:
"""社内製品データベースから製品情報を検索します。
製品の仕様・価格・在庫状況を確認する際に使用してください。
引数: product_name — 製品名(例: 'AIエージェントPro', 'DataSync v2')
返値: JSON形式の製品情報(name, price, stock, specs)
"""
...
失敗2:一度に複雑なエージェントを作ろうとする
❌ 最初から10個のツールと複雑なワークフローを実装しようとする
⭕ まず1つのツールだけで動かし、1本ずつ追加していく
ツールが増えるほどエージェントの挙動が予測しにくくなります。1ツールずつ追加して「意図通りに使われているか」を確認するプロセスを省略しないことが重要です。
失敗3:会話履歴の管理を忘れる
❌ ステートレスな実装で「さっきの話を踏まえて」が機能しない
⭕ セッション単位でメッセージ履歴を保持する
# 会話履歴を維持する基本パターン
# 注意: 本番環境で使用する前に、必ずテスト環境で動作確認してください。
conversation_history = [] # セッション中は永続
def chat(user_message: str) -> str:
conversation_history.append({"role": "user", "content": user_message})
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": "あなたは便利なアシスタントです。"},
*conversation_history # 全履歴を渡す
],
tools=TOOLS,
tool_choice="auto"
)
assistant_msg = response.choices[0].message
conversation_history.append(assistant_msg) # 返答も履歴に追加
return assistant_msg.content
失敗4:本番環境でのモニタリングを後回しにする
❌ ログを取らずに本番投入 → 問題が起きても原因特定できない
⭕ 最低限、入力・出力・ツール実行結果をログに保存する
AIエージェントはハルシネーションやツール誤用が発生します。「何をどんな順で実行したか」のトレースを残さないと、障害対応が不可能になります。LangChainなら verbose=True、OpenAI Agents SDKならトレーシング機能を活用しましょう。
PoC→本番移行の3フェーズ
AIエージェントの導入は「動いた!」で終わりではありません。本番で価値を出すまでのロードマップを示します。
フェーズ1: PoC(1〜2週間)
- 最もシンプルなシングルエージェント+2ツールで動作確認
- モデルはGPT-4o-miniで十分(コスト最小化)
- エラーハンドリングは最低限。まず動くことを優先
フェーズ2: パイロット運用(1〜2ヶ月)
- 実ユーザー10〜20人に使わせてフィードバック収集
- ツールの説明文・システムプロンプトを継続改善
- ログ・モニタリング体制を整備
- コスト実績をもとにモデル選定を見直す
フェーズ3: 本番展開(3ヶ月〜)
- セキュリティレビュー(プロンプトインジェクション・APIキー管理)
- スケーリング設計(並列実行・レート制限対応)
- ヒューマン・イン・ザ・ループの実装(重要判断は人間が確認)
- コスト管理・上限アラートの設定
参考・出典
- OpenAI Agents SDK 公式ドキュメント(日本語) — OpenAI(参照日: 2026-03-18)
- OpenAI Agents SDK クイックスタート — OpenAI(参照日: 2026-03-18)
- OpenAI API Pricing — OpenAI(参照日: 2026-03-18)
- openai-agents-python — GitHub — OpenAI(参照日: 2026-03-18)
- LangChain Agents — 公式ドキュメント — LangChain(参照日: 2026-03-18)
- ReAct Prompting — Prompt Engineering Guide(参照日: 2026-03-18)
まとめ:今日から始める3つのアクション
- 今日やること: 「即効実装1」のスクラッチReActエージェントをコピペして動かす。自分で実装した30行のコードがLangChainの中で何をやっているかを体感する
- 今週中: 自分の業務で「繰り返しやっている作業」を1つ特定して、シングルエージェント+1ツールでPoC実装する
- 今月中: PoCの結果をチームに共有し、パイロット運用対象を決定する。フレームワーク選定はこの段階でよい
あわせて読みたい:
- AIエージェントとは?仕組み・種類・活用事例をわかりやすく解説 — 概念・定義の理解から始めたい方はこちら
- LangGraph・CrewAI・AutoGen徹底比較|AIエージェントフレームワーク勢力図 — 複雑なマルチエージェント構成を検討している方はこちら
著者: 佐藤傑(さとう・すぐる)
株式会社Uravation代表取締役。早稲田大学法学部在学中に生成AIの可能性に魅了され、X(旧Twitter)で活用法を発信(@SuguruKun_ai、フォロワー10万人超)。100社以上の企業向けAI研修・導入支援。著書累計3万部突破。SoftBank IT連載7回執筆(NewsPicks最大1,125ピックス)。
ご質問・ご相談はお問い合わせフォームからお気軽にどうぞ。