
⚙️AIエージェント実装の技術深掘り:LLMオーケストレーション、ツール実行、ガバナンスを“本番品質”に落とす設計パターン
Be A Racer Team
Author
1. Executive Summary(技術的要約・300文字)

AIエージェントは、LLMを中核に「計画(Plan)→実行(Act)→観測(Observe)→反省/学習(Reflect)」のループを回し、外部ツール/APIを呼び出してタスクを自律遂行するソフトウェアである。RPA/IAが“手順の自動化”に強い一方、エージェントは不確実性下での探索・分岐・例外処理を扱える。しかし本番導入では、暴走(過剰実行・コスト膨張)、権限逸脱、データ漏洩、再現性欠如がボトルネックになる。本稿では、ツール実行サンドボックス、状態管理、評価指標、監査ログ、段階的自律化の設計を、具体的なバージョン/設定値とともに提示する。📊
2. 技術的背景と課題(アーキテクチャ図の説明、既存の問題点)
参考記事が示す通り、2025年は「AIエージェント元年」と言われる一方、現場の設計課題は“概念理解”ではなく“運用可能なアーキテクチャ”に集約される。従来の生成AI(チャット)は基本的に単発の推論で完結するが、AIエージェントは状態(state)と外部作用(side effect)を持つ。ここがRPA/IAと同じく「事故が起きる」領域であり、従来のLLMガードレールだけでは足りない。
技術フロー図(文章による説明):ユーザー要求は①API Gatewayで受付→②Policy/Prompt Routerでユースケース・権限・データ分類を判定→③Planner(LLM)でタスク分解→④Tool Routerが許可済みツールを選択→⑤Sandbox Executor(ブラウザ/CLI/HTTP)で実行→⑥Observation Collectorが結果・証跡を収集→⑦Verifier(ルール/LLM/テスト)で妥当性検証→⑧State Storeへ状態を永続化→⑨必要なら再計画、完了なら監査ログへ記録、という閉ループ。
既存の問題点:
- 🔧 ツール呼び出しが“自由すぎる”:誤送信・二重発注・大量予約などの副作用が起きる
- ⚙️ 状態管理が曖昧:途中失敗時のリトライで同じ操作を再実行し、重複更新が発生
- 📊 評価が困難:正解ラベルがない業務で、品質をどうSLO化するかが未整理
- 🔐 セキュリティ:PII/機密の取り扱い、越権アクセス、プロンプトインジェクション
- 💸 コスト:自律探索がトークンと外部API費用を指数的に増やす
3. 技術セクション1:エージェントの参照アーキテクチャ(Plan/Act/Observeの分離)⚙️
3.1 コンポーネント分割:Planner / Executor / Verifier
本番では「LLM=全部入り」にしない。Plannerは推論(分解・優先度・停止条件)に専念させ、Executorは副作用を持つ操作を決定論的に実行、Verifierはルール/テスト/二重化LLMで結果を検証する。これにより、LLMの確率的出力を“境界”で封じ込める。
3.2 状態モデル:Run / Step / Artifact
エージェント実行はRun(1要求)→Step(1ツール実行)→Artifact(生成物/証跡)に分ける。特にStepにidempotency_keyを必須化し、再試行で副作用を重複させない。
3.3 参照スタック例(バージョン固定)
LLM: GPT-4.1 / GPT-4.1-mini(例)
Orchestration: LangGraph 0.2.x もしくは Semantic Kernel 1.2.x
Vector DB: pgvector 0.7 + PostgreSQL 16
Cache/Queue: Redis 7.2 / Kafka 3.7
Observability: OpenTelemetry Collector 0.96 + Prometheus 2.51 + Grafana 10.4
Runtime: Python 3.12 + FastAPI 0.110
Sandbox: Playwright 1.49(ブラウザ操作) + gVisor(コンテナ隔離)
4. 技術セクション2:ツール実行(Tool Use)設計—関数呼び出しの“安全な型付け”🔧
4.1 JSON Schemaでの厳格な引数制約
ツール引数は自然文ではなく、JSON Schemaで型・範囲・列挙を固定する。LLMの出力をパースできても、値域が自由だと事故る。たとえば送金上限、メール宛先ドメイン制限、検索クエリ長などをスキーマで縛る。
{
"name": "create_purchase_order",
"description": "Create PO in ERP (dry-run supported)",
"parameters": {
"type": "object",
"required": ["supplier_id", "items", "dry_run", "idempotency_key"],
"properties": {
"supplier_id": {"type": "string", "pattern": "^SUP-[0-9]{6}$"},
"items": {
"type": "array",
"minItems": 1,
"maxItems": 20,
"items": {
"type": "object",
"required": ["sku", "qty"],
"properties": {
"sku": {"type": "string", "pattern": "^[A-Z0-9-]{3,32}$"},
"qty": {"type": "integer", "minimum": 1, "maximum": 1000}
}
}
},
"dry_run": {"type": "boolean"},
"idempotency_key": {"type": "string", "minLength": 16, "maxLength": 64}
}
}
}
4.2 二段階コミット(dry-run → confirm)
“自律化”は段階的に上げるべきで、最初はdry-runで差分を提示し、人間承認(HITL)またはポリシー承認を通してからcommitする。RPA/IAの「確定操作」文化を、エージェントにも持ち込むのが現実的。
def execute_po(tool_args, policy):
# 1) validate schema
validate_jsonschema(tool_args)
# 2) enforce policy
if tool_args["dry_run"] is False and not policy.can_commit_po:
raise PermissionError("commit not allowed")
# 3) idempotency
if store.exists(tool_args["idempotency_key"]):
return store.get(tool_args["idempotency_key"])
# 4) call ERP
result = erp.create_po(**tool_args)
store.put(tool_args["idempotency_key"], result)
return result
4.3 ブラウザ操作(Operator系)に必要な制限
ブラウザ自動操作は柔軟だが、DOM変化で脆い。Playwright等で実装する場合、(1) 操作可能ドメインallowlist、(2) クリック/送信のリミット(例:1 runあたり最大20操作)、(3) 添付ファイル禁止、(4) 認証情報はVault経由で短命トークン、を最低ラインとする。
5. 技術セクション3:メモリと知識注入(RAG + State)—“覚える”の実装境界🧠
5.1 会話メモリ vs 作業メモリ vs 組織知識
エージェントの「継続的学習」を誤解しやすい。実装上は、(a) 会話ログ(短期)、(b) Run状態(中期:ToDo/進捗/制約)、(c) RAG対象の文書(長期:規程/設計書)を分離する。LLMに“全部突っ込む”と漏洩とコストが増える。
5.2 pgvector + PostgreSQL 16 の最小構成例
CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE rag_chunks (
id bigserial PRIMARY KEY,
doc_id text NOT NULL,
chunk_no int NOT NULL,
content text NOT NULL,
embedding vector(1536) NOT NULL,
data_class text NOT NULL DEFAULT 'internal',
created_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX rag_chunks_ivfflat
ON rag_chunks USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 200);
設定値の目安:lists=200は中規模(〜数百万chunk)での起点。クエリ時はSET ivfflat.probes=10;から始め、再現率とレイテンシのトレードオフを取る。
5.3 取得文書の“データ分類”をプロンプトより先に適用
RAGは便利だが、機密文書を誤って投入するリスクがある。検索前にABAC(属性ベース)でdoc_id/data_classをフィルタし、LLMに渡す前段で削る。プロンプトで「機密は出さないで」は統制にならない。
6. 技術セクション4:評価とベンチマーク—エージェントをSLOに落とす📊
6.1 指標設計:成功率だけでは不十分
本番で見るべきは、(1) タスク成功率、(2) 手戻り率(人が修正した割合)、(3) 外部API呼び出し回数、(4) コスト(トークン+外部課金)、(5) ツール失敗率、(6) 安全違反(ポリシーブロック件数)である。特に“安全違反がゼロ”は、単に何もしていない可能性もあるため、成功率とセットで監視する。
6.2 ベンチマーク例(社内ヘルプデスク自動化)
| 構成 | 平均レイテンシ(P50) | 平均レイテンシ(P95) | 成功率 | 平均ツール呼び出し数 | 推定コスト/Run |
|---|---|---|---|---|---|
| チャット(RAGのみ) | 1.8s | 4.9s | 71% | 0.0 | $0.006 |
| 単一エージェント(Plan+Tool) | 6.4s | 22.0s | 84% | 2.7 | $0.028 |
| マルチエージェント(Planner/Verifier分離) | 7.9s | 24.5s | 90% | 3.1 | $0.041 |
示唆:成功率は上がるが、P95とコストは確実に悪化する。したがって「どの業務をエージェント化するか」は、レイテンシ許容と外部作用の価値で選別すべきで、RPA/IA的に“全部自動化”を狙うと破綻する。
6.3 回帰テスト:ゴールデンRunとツールモック
エージェントは非決定的なので、テストは(1) LLMを固定(temperature=0, top_p=1.0)、(2) ツール呼び出しをVCR方式で記録/再生、(3) 最終成果物の差分検証、が現実解。モデル更新時は“成功率”より“副作用の差分”を重視する。
7. 技術セクション5:セキュリティ—プロンプトインジェクションから越権まで🔐
7.1 脅威モデル:LLMは入力を信じる
Webページやメール本文に「機密を送れ」「このURLを踏め」が混入するプロンプトインジェクションは、ブラウザ操作系エージェントで顕在化する。対策は“注意して”ではなく、(a) ツール権限を最小化、(b) 外部入力を非信頼データとしてラベル付け、(c) 重要操作は二段階コミット、(d) DLPで出力を検査、の多層防御が必要。
7.2 権限設計:OAuthスコープ + 短命クレデンシャル
エージェントに長期APIキーを持たせない。例:Google/Microsoft/社内APIはOAuth 2.1でスコープを最小化し、トークンTTLを15分程度、Refreshはサーバ側で管理。KubernetesではIRSA/Workload Identity(クラウド依存)でPodに権限を付与し、Secrets直置きを避ける。
7.3 監査ログ:誰が、何を、なぜ実行したか
監査に必要なのは「LLMの出力全文」ではなく、決定点(承認の有無、選択ツール、引数、対象リソース、結果、idempotency_key、実行時刻、実行者)である。PIIが混じる会話ログは別系統(暗号化・保管期間短縮)に分離する。
8. 技術セクション6:スケーラビリティ—並列化は“エージェント数”ではなく“副作用”で詰まる📈
8.1 並列実行モデル:Queue + Concurrency Cap
エージェントは外部APIやUIを叩くため、CPUより外部I/Oが律速になる。Kafka/Redis QueueでRunを分配しつつ、ツールごとに同時実行数を制限(例:ERPはmax=5、メール送信はmax=20)。LLM側もRPM/TPM制限があるため、トークンバジェットでスロットリングする。
8.2 レート制御の設定例(YAML)
rateLimits:
llm:
provider: openai
requests_per_minute: 300
tokens_per_minute: 200000
tools:
erp_api:
concurrency: 5
retry:
max_attempts: 3
backoff_ms: [200, 800, 2000]
email_send:
concurrency: 20
daily_cap: 2000
allow_domains: ["example.co.jp"]
8.3 状態ストアの設計:イベントソーシング寄りが強い
Run/Step/Artifactをイベントとして積むと、途中からの再開(resume)と監査が楽になる。特にマルチエージェントでは、各エージェントの意思決定を時系列で追えることが重要。RDBで十分だが、更新中心の単一テーブルに寄せると運用時に破綻しやすい。
9. 技術セクション7:RPA/IAとの統合—置き換えではなく“責務分離”🧩
9.1 役割分担:決定はエージェント、実行はRPA
参考記事2が述べるIA(AIがRPAに指示)を、より厳密に設計すると「エージェントは判断と例外処理」「RPAは決定論的なUI操作」に分けるのが安定する。エージェントにUI操作まで丸投げすると、画面変更・タイムアウト・多要素認証で脆くなる。
9.2 “ツール”としてRPAを呼ぶ
RPA(例:UiPath/Power Automate)はエージェントから見ると1つのツールである。引数を型付けし、RPA側のワークフローはバージョン管理し、戻り値(成功/失敗/エラーコード/スクリーンショット)をArtifactとして保存する。
9.3 失敗時のフォールバック設計
エージェントが失敗したら人に渡すだけでは“運用が詰む”。(1) RPAの既存フローへ切替、(2) チャット回答のみで暫定対応、(3) チケット起票、の優先順を決め、SRE的にエラーバジェットで改善を回す。
10. 比較分析テーブル(3つ以上の選択肢を比較)
| 選択肢 | 主用途 | 強み | 弱み/リスク | 適用の目安 |
|---|---|---|---|---|
| 生成AIチャット + RAG | 問い合わせ回答、ナレッジ検索 | 低コスト、低リスク、導入が速い | 外部作用がない(自動化になりにくい) | まずはここ。SLA厳しい業務の入口 |
| RPA(ルールベース) | 定型UI操作、転記、バッチ | 決定論的、監査しやすい | 例外に弱い、画面変更に脆い | 手順固定・例外少のバックオフィス |
| IA(AIがRPAに指示) | 判断+実行の連携 | 人の介入を減らせる | 責務が曖昧だと事故る(AIがUIまで暴走) | 判断はAI、実行はRPAに寄せる設計が前提 |
| AIエージェント(Tool Use + 状態管理) | 不確実な業務、自律的タスク遂行 | 探索・分岐・例外処理、複雑問題に強い | コスト、再現性、セキュリティ、監査が難しい | 価値が高い“外部作用”に限定して段階導入 |
11. ベストプラクティス・アンチパターン(箇条書き)
✅ ベストプラクティス
- ⚙️ Planner/Executor/Verifierを分離し、ツール実行を決定論的にする
- 🔧 ツール引数はJSON Schemaで型付け、値域制約・allowlistを持つ
- 🔐 二段階コミット(dry-run→confirm)で副作用を抑える
- 📊 成功率+コスト+安全違反+手戻り率をSLO化する
- 🧾 監査ログは“決定点”中心に設計し、PIIログと分離する
- 📈 ツールごとにConcurrency Capと日次キャップを設定する
❌ アンチパターン
- 「プロンプトで禁止したから安全」:DLP/ABAC/スコープ制御なしは危険
- UI操作を万能ツール化:ブラウザに全部やらせると脆弱で保守不能
- 状態を持たない自律実行:リトライで二重実行・二重課金が起きる
- 評価なしで本番投入:モデル更新で静かに劣化し、気づいた時には事故
- “全業務を自動化”のKPI:価値の薄い探索がコストだけ増やす
12. 実装ロードマップとチェックリスト
12.1 ロードマップ(段階的自律化)
- Phase 0:チャット+RAG(外部作用なし)。データ分類、検索フィルタ、ログ設計を固める
- Phase 1:Read-onlyツール(検索、参照API)。監査ログとレート制御を導入
- Phase 2:Writeツールをdry-runのみ。差分提示と承認フロー(HITL)
- Phase 3:限定領域でcommit解禁(上限/allowlist/日次キャップ)。SLO運用開始
- Phase 4:マルチエージェント(専門エージェント分割)。Verifier強化、回帰テスト自動化
12.2 チェックリスト
- 🔐 OAuthスコープは最小化され、Secrets直置きがない
- 🔧 ツール定義はSchema化され、idempotency_keyが必須
- 📊 主要KPI(成功率/手戻り率/コスト/安全違反)がダッシュボード化
- 🧪 ゴールデンRunで回帰テストが回る(temperature=0)
- 📈 ツール別の並列数・日次キャップ・リトライが設定済み
- 🧾 監査ログ(決定点)が保全され、保管期間とマスキングが定義済み
13. 参考リソース・次のステップ
- IPA SDS技術コラム:AIエージェント(概観と社会実装の論点)
- Gartner:AIエージェントの特性(自律性・適応性・目標指向などの整理)
- OpenTelemetry(分散トレーシングでRun/Stepを可観測化)
- LangGraph / Semantic Kernel(状態機械としてのエージェント実装)
次のステップ:自社の“外部作用が高価値”な業務(例:チケット起票、在庫引当、見積作成)を1つ選び、Read-only→dry-run→commitの順に段階導入する。RPA資産がある場合は、RPAをツール化して責務分離し、UI脆弱性をエージェント側に持ち込まない設計から始めるのが近道である。⚙️
Tags
コメント
🗣️ コメントするにはログインしてください
Sign in to leave a comment and join the discussion