AIエージェントのOpenAIのCodex CLIを使ってOpenAIのAgent SDKを使ったAIエージェントを作ってみます。
Q.「openAIのAgetSDKを使ってAIエージェントプログラムを作ってください。与えられた目的からタスクを考えてそれを解決するために実
行するAIエージェントプログラムを作るにはどのような要求仕様が必要ですか?」
A.
codex
AIエージェント(OpenAI Agent SDK)を使って「与えられた目的からタスクを自動生成し、実行して解決する」プログラムを作る
ためには、下記のような要求仕様(Requirements Specification)があると考えられます。
- 概要
-
本システムは、ユーザーから与えられた「高レベルの目的(ゴール)」を受け取り、内部で必要なサブタスクに分解し
、順次実行してゴール達成を支援するAIエージェントを提供する。 -
エージェントのコアには OpenAI の Agent SDK
を利用し、プランナー→実行→検証→メモリ更新…というループで動作する。
- 利害関係者
-
エンドユーザー(ゴールを与えて結果を得たい人)
-
システム管理者/DevOps(デプロイ・運用)
-
開発者(エージェントのロジックやプラグインを追加・拡張する)
- 前提条件/制約
-
OpenAI API キーが発行済みで、環境変数(例:OPENAI_API_KEY)に設定されている
-
Node.js(または Python)ランタイムの LTS バージョン
-
Agent SDK のバージョン(例:
@openai/agent-sdk ^1.0.0
) -
ネットワーク経由でツール(検索エンジン、データベース、外部APIなど)呼び出しが可能
-
機能要件
-
ゴール入力
- ユーザーが自然言語(日本語/英語)で目的を入力できる
- タスク分解(プランニング)
-
目的を達成するためのサブタスクの列挙(例:To‑Doリスト)
-
各タスクの優先度や依存関係を判断
- タスク実行(アクション)
-
必要に応じて外部ツール(HTTP API/DBクエリ/検索など)を呼び出す
-
実行結果を受け取り、次タスクの判断に反映
- メモリ・コンテキスト管理
-
途中経過や中間結果を保持(短期メモリ/長期メモリ)
-
再実行時のリトライやフォールバックをサポート
- 結果出力
-
最終的な処理結果やログをユーザーに返却
-
実行済みタスクのレポート生成
- 非機能要件
-
レイテンシ:1タスクあたりの平均応答時間は n 秒以内
-
可用性:99.9% 以上
-
スケーラビリティ:同時並列エージェント数 M まで対応
-
セキュリティ:
• API キーや認証情報は Vault/環境変数で厳格管理
• ログに秘匿情報が残らない -
障害耐性:
• 外部API障害時のリトライ/タイムアウト設定
• 異常終了時の自動ロールバック
- 外部インターフェース
-
REST / WebSocket / CLI など、ユーザーからゴールを受け取る入口
-
Agent SDK → OpenAI ChatCompletion API
-
Agent → プラグイン/ツール呼び出しポイント
-
ロギング:JSON形式で ELK / Datadog へ送信
- システム構成(高レベル)
┌─────────┐ ┌───────────────┐
│ User UI │◀────▶│ Agent Core │
└─────────┘ │(Planner,Memory)│
└───────────────┬┘
│
┌──────────────────┴────────────┐
│ OpenAI Agent SDK / API │
└──────────────────┬────────────┘
│
┌──────────┴──────────┐
│ Tools & Plugins API │
└─────────────────────┘ - 依存関係・ライブラリ
-
@openai/agent-sdk
-
axios(HTTP クライアント)
-
dotenv(環境変数ロード)
-
winston などのロギングライブラリ
- テスト要件
-
ユニットテスト:プランナー、メモリ管理、ツール呼び出しラッパー
-
統合テスト:エンドツーエンドでのゴール→結果パス検証
-
モック:OpenAI API モック、外部ツールモック
- 運用・保守
- モニタリング:エージェント処理件数、成功率、レイテンシ
- アラート:エラー率閾値超過時に通知
- バージョン管理:AgentSDK や Node.js のバージョンアップ対応
- ドキュメント:利用手順、プラグイン追加手順、トラブルシューティング
――――――――――
付録:要求仕様テンプレート(YAMLイメージ)
project:
name: goal-driven-ai-agent
description: "ユーザーの目的から自動でタスク生成・実行するAIエージェント"
stakeholders:
- user: "サービス利用者"
- devops: "運用チーム"
- dev: "開発チーム"
environments:
runtime: "Node.js >=16.x"
agentSdk: "@openai/agent-sdk ^1.0.0"
openaiApiKey: "env:OPENAI_API_KEY"
functional_requirements:
FR1: "自然言語入力でゴールを受け取る"
FR2: "ゴールを分解してタスクリスト生成"
FR3: "ツール呼び出しを実行して成果を取得"
FR4: "メモリに中間結果を保存/参照"
FR5: "最終レポートを出力"
nonfunctional_requirements:
NFR1: "平均応答時間 < 3秒"
NFR2: "可用性 99.9%"
NFR3: "ログは 90日間保持"
interfaces:
- type: REST
endpoint: POST /api/agent/run - type: WebSocket
endpoint: /ws/agent - type: Plugin
spec: https://...
dependencies:
- name: "axios"
- name: "dotenv"
- name: "winston"
testing:
unit: true
integration: true
operations:
monitoring: ["latency", "error_rate"]
alerts: ["error_rate > 5%"]
———
上記仕様をベースに、Agent SDK の初期化→ツール登録→Planner/Executor
のループ実装、インターフェース層の構築、環境・運用設定を進めていく流れがスムーズに設計・開発できます。
Q.「最初の要求仕様をequipment.mdに書き出してください。また私はopenAIのAgent SDKを使いたいのでpythonで書いてください。」
A.
Requirements Specification for Goal-Driven AI AgentOverview
本システムは、ユーザーから与えられた「高レベルの目的(ゴール)」を受け取り、内部で必要なサブタスクに分解し、順次実行してゴールを達成するAIエージェントを提供する。
Agent SDK(Python)を利用し、プランニング→実行→検証→メモリ更新のループで動作する。
Stakeholders
エンドユーザー: ゴールを与えて結果を得る。
システム管理者/DevOps: デプロイ・運用。
開発者: エージェントのロジックやプラグインを追加・拡張。
Preconditions / Constraints
OpenAI API キーが発行済みで、環境変数 OPENAI_API_KEY に設定されている。
Python 3.8 以上。
openai パッケージ(関数呼び出し対応版)がインストール済み。
ネットワーク経由で外部 API 呼び出しが可能。
Functional Requirements
FR1: ユーザーが自然言語(日本語/英語)でゴールを入力できる。
FR2: 目的を達成するためのサブタスクをプランニングし、外部ツール(関数呼び出し)で実行。
FR3: サブタスク実行結果を取得し、次のプランニングに反映。
FR4: 中間結果をメモリ(短期/長期)に保存し、リトライやフォールバックをサポート。
FR5: 最終的な処理結果と実行ログをユーザーに出力。
Non-Functional Requirements
レイテンシ: サブタスクあたりの平均応答時間は 3秒以内。
可用性: 99.9%以上。
スケーラビリティ: 同時並列エージェント数 10 まで対応。
セキュリティ: API キーは環境変数で厳格管理。ログに秘匿情報を出力しない。
障害耐性: 外部 API 障害時はリトライ・タイムアウト機能を実装。
External Interfaces
CLI: python agent.py "" でゴールを受け取り、結果を標準出力。
OpenAI ChatCompletion API (function calling)。
Optional: Web/UI や REST API を将来追加可能。
System Architecture (概要)
User CLI ←→ Agent Core ←→ OpenAI API ←→ External Tools
Agent Core:
Planner: LLM でタスク分解。
Executor: 関数呼び出しでサブタスク実行。
Memory: 中間結果・履歴管理。
Dependencies / Libraries
openai (関数呼び出し対応版)
python-dotenv
Testing Requirements
ユニットテスト: プランニング、関数呼び出しラッパー。
統合テスト: E2E でゴール→実行→結果を検証。
モック: OpenAI API、外部ツールをモック。
Operations & Maintenance
モニタリング: レイテンシ、成功率、エラー率。
アラート: エラー率が閾値を超えた場合に通知。
ドキュメント: セットアップ手順、拡張手順、トラブルシューティング
出来たコード
import os
import sys
import asyncio
from dotenv import load_dotenv
from agents import Agent, Runner
import json
async def main():
load_dotenv()
api_key = os.getenv("OPENAI_API_KEY")
if not api_key:
print("Please set OPENAI_API_KEY in .env")
sys.exit(1)
if len(sys.argv) < 2:
print("Usage: python sdk_agent.py <goal>")
sys.exit(1)
goal = " ".join(sys.argv[1:])
agent = Agent(
name="assistant",
model="gpt-4o-mini"
)
runner = Runner()
# FR2: Planning stage - decompose goal into tasks
from openai import OpenAI
client = OpenAI(api_key=api_key)
loop = asyncio.get_running_loop()
def plan_call():
return client.chat.completions.create(
model=agent.model,
temperature=0,
messages=[
{"role": "system", "content": (
"You are a planner that decomposes a user goal into a JSON array of tasks. "
"Allowed actions: write_file (to create files), run_command (to execute shell commands), and search (to lookup web information). "
"If the goal requests execution of a command (such as ping), use run_command. "
"If the goal requires information, use search. "
"For code generation, use write_file, then run_command to compile and execute. "
"Respond with only valid JSON array of task objects, without any additional text."
)},
{"role": "user", "content": goal}
]
)
plan_resp = await loop.run_in_executor(None, plan_call)
try:
tasks = json.loads(plan_resp.choices[0].message.content)
except Exception:
# Fallback to single-step
tasks = [{"action": "run_command", "args": {"command": goal}}]
# If planner suggests a run_command for non-shell goal, switch to search
if len(tasks) == 1 and tasks[0].get('action') == 'run_command':
cmd = tasks[0].get('args', {}).get('command', '')
# heuristics: if command contains non-latin (Japanese) or spaces >5, use search
if any(ord(c) > 127 for c in cmd) or len(cmd.split()) > 3:
tasks = [{"action": "search", "args": {"query": goal}}]
print(f"Planner: {len(tasks)} tasks generated.")
# Execute each task sequentially
import re
for i, task in enumerate(tasks, 1):
action = task.get("action")
args = task.get("args", {})
# Fallback: handle ping command if needed
if action == "run_command":
cmd = args.get("command", "")
if not cmd and "ping" in goal.lower():
# extract hostname after 'ping'
m = re.search(r'ping\s+([\w\.-]+)', goal)
if not m:
m = re.search(r'([\w\.-]+)\s*に.*?ping', goal)
host = m.group(1) if m else goal
args['command'] = f"ping -c 4 {host}"
print(f"Ping fallback: command set to '{args['command']}'")
print(f"[{i}/{len(tasks)}] {action} {args}")
# Describe subtask as instruction for runner
inst = f"Call {action} with args {args}"
result = await runner.run(agent, inst)
print(result.final_output)
return
if __name__ == "__main__":
asyncio.run(main())
Q.「良くなりました。sdk_agent.pyはequipment.mdの要求仕様を何パーセントくらい満たしていますか?」
A.「 codex
ざっくり見積もると、sdk_agent.py は equipment.md に対して次のようなカバー率になります。
• FR1(CLI から自然言語ゴールを入力)……✓(100%)
• FR2(プランニング→実行ループ)……部分的(関数呼び出しでコード生成→実行はやっているが、LLM
によるタスク分解ループは未実装)⇒約 30%
• FR3(サブタスク結果のフィードバック反映)……最低限(function‐calling の単一ループ)⇒約 20%
• FR4(メモリ管理)……未実装⇒ 0%
• FR5(最終結果+実行ログ出力)……部分的(最終結果は出力するが詳細ログは出していない)⇒約 40%
非機能要件・テスト・運用要件は未実装のため 0%。
総合すると、機能要件カバー率でおよそ 20~30% 程度、全体要求としては約 20% 程度の実装状況と言えます。
次のステップとしては、
* FR2 を課題分解(プランナー)+多段ループで強化
* FR3 のリトライ・条件分岐を導入
* FR4 のメモリ(チェイン・オブ・ソート)実装
* ロギング/テストを追加
といった部分を進めると、要求仕様をさらに満たせます。
Q.「FR2 を課題分解(プランナー)+多段ループで強化をお願いします。」
といった感じで進めています。