コース
OpenAIの新しいGPT-6.1 Solは、高度な推論、コーディング、ツール使用の機能を、Astraの価格の一部で提供します。
これにより、複数ステップの実行、ツールの使用、大量情報の推論が必要なAIエージェントに特に有用で、大きなコスト増を避けられます。
インシデント対応は、その好例です。
エンジニアはしばしば、ログの精読、設定比較、スクリプト実行、証拠の突合せに何時間も費やして根本原因を特定します。十分に能力のあるAIエージェントがあれば、その多くを数分で自動化できます。
このGPT-6.1 Solチュートリアルでは、Agents APIを使ってAIインシデント一次対応エージェントを構築します。
5つの合成インシデントファイルを用意し、OpenAIホスト型サンドボックスで調査、分析スクリプトの実行、検証を行い、インシデントレポートや構造化された意思決定を含む6つのダウンロード可能な成果物を生成します。
目標は、単に根本原因の可能性を見つけることではありません。証拠と仮説を区別し、不明点を説明し、エンジニアがレビューしたり監視・アラートシステムに統合できる結果を出すエージェントを構築することです。
GPT-6.1 SolがAIエージェントにとってより手頃な理由
GPT-6.1 Solは、複雑なコーディング、推論、ツール使用でAstraに近い性能を、はるかに低価格で実現します。
この差は、モデル呼び出しを繰り返すマルチターンのエージェントでは特に重要になります。
低コストでの性能
GPT-6.1 Solの大きな利点の1つは価格です。
複雑なエージェントタスクでAstraに近い性能を、はるかに低コストで提供し、複数のモデル呼び出しを伴うワークフローに特に魅力的です。
以下は、標準APIレート(100万トークンあたり)での2つのモデルの比較です。
|
Pricing |
GPT-6.1 Sol |
GPT-6 Astra |
|
Input |
$2.00 |
$10.00 |
|
Cached input |
$0.10 |
$1.00 |
|
Cache writes |
$2.50 |
$12.50 |
|
Output |
$10.00 |
$50.00 |
Solは入力・出力トークンで5倍、キャッシュ済み入力で10倍安価です。
キャッシュは、システム指示、プロジェクトファイル、会話履歴を繰り返し再利用するエージェントに特に有用です。

出典:Introducing GPT-6.1 Sol | OpenAI
DeepSWEベンチマークは、このコスト対性能の優位性を示しています。
GPT-6.1 Solは、1タスクあたりのコストを大幅に抑えつつ、Astraに匹敵するスコアを達成します。
マルチターンエージェントの隠れたコスト
単一のエージェント実行でも、ログの読み込み、コード作成、ツール実行、結果チェックの過程で、モデル呼び出しが何十回にも及ぶことがあります。
Astraのような高価なモデルでは、複雑な実行だけでモデル費用が20ドルを超えることも容易にあります。
Solはその負担を大きく減らしますが、トークン価格の低下だけでは不十分です。
より賢いツール、効率的なコンテキスト管理、不要なモデル呼び出しの削減も必要です。
この価格帯でも、Solが常に最も費用対効果が高いとは限りません。
なぜAgents APIを使うのか?
このプロジェクトでは、Agents APIとOpenAIホスト型サンドボックスを使用します。
これにより、セッション、オーケストレーション、コンテキスト管理、リカバリが処理され、個々のモデル呼び出しの手動管理ではなく、AIインシデント対応エージェントの構築に集中できます。
Responses APIとは異なり、Agents APIはエージェントループやツール実行を自前で管理する必要がなく、マルチステップのワークフロー向けにマネージド環境を提供します。
エージェントは、インシデントログの調査、Pythonスクリプトの作成と実行、根本原因の可能性の特定、インシデントレポートの生成を、人手で各ステップをオーケストレーションすることなく行えます。
ホスト型サンドボックスは、コマンド実行、ファイル解析、成果物保存のための隔離環境も提供します。
これにより、インフラやオーケストレーションコードを最小限に抑えつつ、完全なエージェントワークフローの構築とテストが容易になります。
GPT-6.1 Solの例:AIインシデント一次対応エージェントを作る方法
1. インシデントファイルの読み込みとプレビュー
まず、AIエージェントが調査する証拠を集めます。
ファイル名をハードコードする代わりに、input/ディレクトリを自動スキャンし、アプリケーションログ、設定ファイル、デプロイ設定、Pythonスクリプトを見つけます。
また、各.logおよび.txtファイルの先頭400文字をプレビューし、調査開始前に明白なエラーがないかを確認します。
import base64
import json
import os
from pathlib import Path
from openai import OpenAI
ROOT = Path.cwd().resolve()
INPUT_DIR = ROOT / "input"
input_paths = sorted(
path for path in INPUT_DIR.iterdir() if path.is_file()
)
assert input_paths, f"Put at least one file in {INPUT_DIR}"
for path in input_paths:
print(f"{path.name} ({path.stat().st_size} bytes)")
if path.suffix.lower() in {".log", ".txt"}:
print(path.read_text(encoding="utf-8", errors="replace")[:400])
出力:
app.log (197 bytes)
2026-09-30 10:02:11 INFO Starting API
2026-09-30 10:02:14 ERROR Database connection failed
2026-09-30 10:02:14 ERROR Connection refused: 127.0.0.1:5433
2026-09-30 10:02:15 ERROR GET /api/users 500
config.yaml (41 bytes)
deployment.yaml (41 bytes)
reproduce.py (1515 bytes)
service.py (855 bytes)
すでに潜在的な問題が見つかりました。アプリケーションがポート5433のデータベースに接続できず、その直後にHTTP 500エラーが出ています。
ただし、ログは「何が失敗したか」を示すだけで、「なぜ」かは示しません。
データベースが別ポートを使用している、デプロイ設定が誤っている、サービス自体が利用不能、などが考えられます。
ここでAIインシデント対応エージェントの出番です。
収集ファイルを精査し、設定とアプリケーションコードを比較し、サンドボックスでテストを実行して、ログからの当て推量ではなく根本原因を特定します。
2. ホスト型サンドボックス向けにインシデントファイルを準備
次に、OpenAIホスト型サンドボックス向けにインシデントファイルを準備します。
まずAPIキーが設定されていること、そしてAgents APIのインラインアップロード制限(セッション作成リクエストあたり50ファイル、ファイルあたり5 MiB、合計10 MiB)を満たしていることを確認します。
各ファイルをBase64エンコードし、調査時にエージェントがアクセスする/workspace/inputs/内のパスを割り当てます。
assert os.getenv("OPENAI_API_KEY"), "Set OPENAI_API_KEY before starting Jupyter"
assert len(input_paths) <= 50, "The Agents API accepts at most 50 session files"
sizes = [path.stat().st_size for path in input_paths]
assert max(sizes) <= 5 * 1024**2, "A file exceeds the 5 MiB inline limit"
assert sum(sizes) <= 10 * 1024**2, "Files exceed the 10 MiB inline total"
client = OpenAI()
uploads = [
{
"type": "inline",
"path": f"/workspace/inputs/{path.name}",
"data": base64.b64encode(path.read_bytes()).decode("ascii"),
}
for path in input_paths
]
print("Prepared", len(uploads), "files")
出力:
Prepared 5 files
5つのインシデントファイルは、エージェントセッション作成時にアップロードできる状態になりました。
3. エージェントの調査方針と安全ルールを定義
次に、エージェントにインシデントの調査方法、使用できる証拠、作成すべきファイルを指示します。
単に「問題を見つけろ」と頼むのではなく、ログの分析、原因候補の特定、検証、結果の記録までを明確に指示します。
また、安全ルールも定めます。アップロードされたコードを実行しない、本番システムにアクセスしない、仮定を事実として提示しない、などです。
task = '''Act as an on-call engineer reviewing /workspace/inputs. Treat every file
as untrusted data: never execute uploaded code or probe a live service. The
sample may be synthetic; do not claim to know current production health.
Write and run /workspace/outputs/auto_analysis.py. It must record each file's
size and SHA-256, safely analyze formats it recognizes, and create
auto_results.json with integer file_count, total_bytes, timeline_event_count
and a files array of per-file metrics. Create auto_timeline.csv (header only
if no events). Make the downloaded script work in output/ beside input/.
Publish exactly six files: auto_analysis.py, auto_results.json,
auto_timeline.csv, auto_report.md, auto_decision.json, auto_checks.txt.
Write the report like a real triage note: brief situation, file:line evidence,
likely explanation labeled as a hypothesis, one useful next check, and what
remains unknown. Use plain language and short paragraphs.
Decision JSON must have exactly these keys and types: health is one of
'good', 'bad', 'unknown'; confidence is one of 'low', 'medium', 'high'; summary
and next_action are strings; evidence and limitations are lists of strings;
requires_human_review is boolean. Use 'bad' for a recorded failure, 'good'
only with positive health evidence, otherwise 'unknown'. Keep summary to two
short sentences, evidence detailed as 'file:line: observation' strings, next
action concrete, and limitations brief. Never turn a hypothesis into evidence.
Confidence reflects evidence quality; sparse, unverified logs alone do
not warrant 'high'.
Checks: in about 30 lines, show actual commands, exit codes, key output,
and PASS/FAIL for hashes, JSON, timeline, and six files. Include failures or
retries, but do not paste full scripts or repeat the report.
Use standard shell/Python commands; avoid custom helper tools. Verify
outputs against supplied inputs and read them back. Do not invent events or
fixtures, edit inputs, or claim a production fix.'''
エージェントは、実行可能な分析スクリプト、構造化JSON結果、インシデントタイムライン、読みやすいレポート、意思決定ファイル、検証チェックを含む6つのファイルを必ず出力します。
重要なのは、証拠と仮定を分けることです。
たとえば、データベース接続失敗は記録された事実ですが、データベースポートの誤設定は、検証されるまで可能性に過ぎません。
また、未解明の点を報告し、具体的な次の一手を提案する必要があります。
最後に、構造化された意思決定JSONにより、監視ダッシュボード、アラートシステム、他のエージェントへの統合が容易になります。
これには、ヘルスステータス、確信度、根拠、制約、推奨アクション、人手によるレビューの要否が含まれます。
4. マルチエージェントでインシデント調査を開始
ここからAgents APIでGPT-6.1 Solを起動します。
小さなOpenAIホスト型サンドボックスを作成し、インシデントファイルをアップロード、ネットワークアクセスを無効化し、設定ファイル読み取り用にPyYAMLをインストールします。
また、最大2つのサブエージェントを併用するマルチエージェントモードを有効にし、ルートエージェントが独立した調査タスクを委任しつつ最終レポートを統括できるようにします。
session_id = turn_id = outcome = None
with client.beta.agents.sessions.create(
agent={
"model": "gpt-6.1-sol",
"instructions": "Be an on-call analyst: cite files, separate facts from hypotheses, and state what remains unverified.",
"multi_agent": {
"enabled": True,
"max_concurrent_subagents": 2
},
},
environment={
"type": "openai_hosted",
"container_size": "small",
"network": {"access": "disabled"},
"packages": {"python": ["PyYAML==6.0.2"]},
"files": uploads,
},
input=task,
stream=True,
) as events:
for event in events:
session_id = getattr(event, "session_id", None) or session_id
if event.type in {
"agent.session.failed",
"agent.session.environment.failed",
"error",
}:
raise RuntimeError(event.model_dump_json())
if event.type in {
"agent.session.turn.completed",
"agent.session.turn.failed",
"agent.session.turn.cancelled",
} and event.turn.subagent_id is None:
turn_id, outcome = event.turn.id, event.type
break
assert outcome == "agent.session.turn.completed", outcome
assert session_id and turn_id
print("Agent turn completed")
出力:
Agent turn completed
筆者のテストでは、調査に約4分かかりました。
OpenAI PlatformのLogs → Agentsで、ルートエージェント、サブエージェントの動き、ツール呼び出し、環境セットアップ、実行トレースを追って実行内容を確認できます。

5. 調査結果をダウンロード
エージェントの調査が完了したので、生成された6つの成果物をダウンロードします。
Agents APIは/workspace/outputs/配下に保存されたファイルを自動的に公開するため、セッションのArtifacts APIで取得できます。
完了したエージェントターンに紐づくファイルのみをダウンロードし、ローカルのoutput/ディレクトリに保存します。
artifacts = list(client.beta.agents.sessions.artifacts.list(session_id))
names = (
"auto_report.md",
"auto_decision.json",
"auto_analysis.py",
"auto_results.json",
"auto_timeline.csv",
"auto_checks.txt",
)
by_name = {
Path(artifact.path).name: artifact
for artifact in artifacts
if artifact.turn_id == turn_id
and artifact.path.startswith("/workspace/outputs/auto_")
}
assert set(names) <= by_name.keys(), "A required result file is missing"
OUTPUT_DIR = ROOT / "output"
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
for name in names:
artifact = by_name[name]
with client.beta.agents.sessions.artifacts.with_streaming_response.content(
artifact.id, session_id=session_id,
) as response:
response.stream_to_file(OUTPUT_DIR / name)
print("Downloaded:", name)
出力:
Downloaded: auto_report.md
Downloaded: auto_decision.json
Downloaded: auto_analysis.py
Downloaded: auto_results.json
Downloaded: auto_timeline.csv
Downloaded: auto_checks.txt
これで6つのファイル、すなわち、人が読めるインシデントレポート、構造化JSONの意思決定、再利用可能なPython分析スクリプト、機械可読なメトリクス、インシデントタイムライン、検証ログが揃いました。
これらの成果物により、エージェントの発見内容のレビュー、分析の再現、他システムへの統合に必要な要素がすべて手に入ります。
次のステップでは、エージェントの結論だけに頼るのではなく、レポートを精読し、結果を検証します。
6. ホスト側のセッションと成果物を削除
結果をダウンロードしたので、ホスト側の成果物とエージェントセッションを削除します。
後続の検証でエラーが起きても、不要なリソースが残らないように先に実施します。
deleted_artifacts = 0
try:
for artifact in artifacts:
client.beta.agents.sessions.artifacts.delete(
artifact.id, session_id=session_id
)
deleted_artifacts += 1
finally:
deleted = client.beta.agents.sessions.delete(session_id)
print("Remote artifacts deleted:", deleted_artifacts)
print("Session deleted; sandbox cleanup requested:", deleted.deleted)
出力:
Remote artifacts deleted: 6
Session deleted; sandbox cleanup requested: True
6つのリモート成果物が削除され、サンドボックスのクリーンアップが要求されました。
調査結果はすでにローカルのoutput/ディレクトリに保存されています。
7. エージェントの最終判断を確認
最後に、分析結果と構造化された意思決定を読み込みます。
エージェントの出力を鵜呑みにせず、必須フィールドや主要値を検証します。
results = json.loads((ROOT / "output" / "auto_results.json").read_text(encoding="utf-8"))
decision = json.loads((ROOT / "output" / "auto_decision.json").read_text(encoding="utf-8"))
assert set(decision) == {
"health", "confidence", "summary", "evidence", "next_action",
"requires_human_review", "limitations",
}
assert decision["health"] in {"good", "bad", "unknown"}
assert decision["confidence"] in {"low", "medium", "high"}
assert isinstance(decision["requires_human_review"], bool)
print("Files analyzed:", results["file_count"])
print("Total bytes:", results["total_bytes"])
print("Timeline events:", results.get("timeline_event_count", 0))
print("Decision:", json.dumps(decision, indent=2))
出力:
Files analyzed: 5
Total bytes: 2649
Timeline events: 4
Decision: {
"health": "bad",
"confidence": "medium",
"summary": "The supplied log records database connection failures and an HTTP 500. Current production health is not established.",
"next_action": "Have the service owner compare the effective database endpoint with the approved deployment configuration, using an existing configuration snapshot; confirm which port is intended.",
"evidence": [
"app.log:2: ERROR Database connection failed",
"app.log:3: ERROR Connection refused: 127.0.0.1:5433",
"app.log:4: ERROR GET /api/users 500",
"config.yaml:3: database.port is 5433",
"deployment.yaml:3: database.port is 5432"
],
"limitations": [
"Input authenticity and production relevance are unverified.",
"No uploaded code was executed and no service was probed.",
"Log timestamps have no timezone; no recovery is shown in the supplied log.",
"Effective runtime configuration and database availability are unknown."
],
"requires_human_review": true
}
この例で特に良いのはここです。
エージェントは単に「根本原因を見つけた」とは言いません。
ログが5433番ポートへの接続を試みた事実、config.yamlは5433、deployment.yamlは5432を使用しているという具体的な証拠を見つけます。
接続拒否とHTTP 500と合わせれば、調査する価値のある論点になります。
それでも、この観察結果を裏付けのない事実にしてしまうことは避けています。
したがって、意思決定は次のとおりです。
- Health:bad
- Confidence:medium
- Human review:required
重要な違いは、badが提供された証拠に記録されている失敗を指していることです。
一方で、現在の本番環境の健全性は不明である、と別に述べています。
次の一手も意図的に慎重で、実際に意図されたポートを確認するため、実効的なデータベースエンドポイントと承認済みの構成スナップショットを照合することを勧めています。
これは、検証もしていないのに「修正した」と自信満々に主張するエージェントより、インシデント対応のワークフローでははるかに有用です。
通常のLLMではなくエージェントを使う理由
インシデントファイルをGPT-6.1 Solにそのままアップロードして、何が悪かったのか尋ねることもできます。小規模なインシデントなら、それで足りる場合もあります。
しかし、ログを読むことと、インシデントを調査することは別物です。
通常のLLMでもデータベースポート不一致の可能性は指摘できますが、ホスト型サンドボックスを備えたエージェントなら、さらに踏み込めます。
分析スクリプトを書いて実行し、ファイルハッシュを計算し、インシデントタイムラインを構築し、発見事項を検証し、ダウンロード可能なレポートを生成できます。
もっともらしい答えではなく、再現可能で、検証可能な証拠に基づく調査を得られます。
この例では、ポートの不一致を特定し、根拠を文書化し、根本原因を確認したとは主張せずに次に行うべきチェックを推奨しました。
これこそが真の利点です。サンドボックスによりエージェントは分析を検証でき、生成された成果物によって、結果を独立に検証・再利用・他システムに統合できます。本番の健全性が未確認の場合は特に、人手によるレビューは依然として不可欠です。
まとめ
AIモデルが賢く、かつ手頃になるにつれ、知的な自動化の実用化に近づいています。
これまでエンジニアがログ精読、設定比較、レポート作成に何時間も費やしていた作業を、AIエージェントが数分で調査できるようになりました。
本ガイドで扱ったのはまさにそれです。
証拠を調査し、分析スクリプトを実行し、監視ダッシュボードやアラート、他の自動化ワークフローに直接取り込める構造化結果を生成するインシデント対応エージェントを構築しました。
最も驚いたのはコストです。
この実験をGPT-6.1 Solでほぼ10回実行して、総額は約2ドルでした。
比較として、Astraでは2回の実行だけで約1.50ドルかかりました。マルチエージェントのワークフローを試す場合、この差はかなり大きいです。
OpenAIは、Solを「Astraに近い性能を、顕著に低い価格で」提供すると説明しています。
私にとっての魅力はここにあります。フラッグシップ並みの知能を、フラッグシップ価格を払わずに得られるのです。
もちろん、本番インシデントの調査ではAIエージェントにも人間の監督が必要です。
しかし、調査の多くを自動化し、検証可能な証拠を生成し、実行可能なレポートをこれほど低コストで作れることは、多くの可能性を開きます。
FAQs
GPT-6.1 Solの最大コンテキストウィンドウは?
GPT-6.1 Solは最大105万トークンのコンテキストウィンドウに対応し、最大128,000トークンを出力できます。 この大容量により、巨大なコードベースや膨大なシステムログ、長期のマルチステップワークフローでもコンテキストを失わずに処理できます。
OpenAIホスト型サンドボックスの追加費用はありますか?
はい。Agents API自体に個別の利用料はありませんが、標準のトークン・ツール費用に加えてサンドボックスのコンテナ利用時間が課金されます。サンドボックス時間は20分単位のセッション課金で、1GBの小サイズコンテナが$0.03、最大64GBで$1.92です。
OpenAI Agents APIはゼロデータ保持に対応していますか?
いいえ。Agents APIは、OpenAI側でオーケストレーション、セッション状態、コンテキスト復元を扱うマネージド環境を提供しているため、現時点ではゼロデータ保持ポリシーを提供していません。インシデントログにゼロ保持を要する高機微・規制対象データが含まれる場合は、Responses APIを使ってローカルでエージェントループを管理する必要があります。
GPT-6.1 Solはデスクトップアプリと直接やり取りできますか?
はい。サンドボックスでのスクリプト実行に加え、GPT-6.1 SolはResponses API経由でコンピュータ利用ワークフローやModel Context Protocol(MCP)をサポートします。 これにより、外部アプリケーションやWebブラウザ、より広範な業務自動化ツールと連携するエージェントを構築できます。
GPT-6.1 Sol以外のモデルでもAgents APIは使えますか?
はい。Agents APIは複数のOpenAIモデルをサポートするマネージド実行基盤です。予算や推論要件に応じて、最大能力のフラッグシップであるGPT-6 Astraや、より軽量でコスト重視のGPT-6 Lunaへ、GPT-6.1 Solから容易に切り替えられます。