Amazon Bedrock Agentsを使用すると、推論、計画、アクションを実行できるAIアプリケーションを構築できます。エージェントは基盤モデル、Knowledge Base、外部APIをオーケストレーションして複雑なタスクを完了します。
エージェントの仕組み
flowchart TB
A["ユーザーリクエスト"] --> B["Agent"]
B --> C["推論(ReAct)"]
C --> D{"アクション必要?"}
D -->|Yes| E["アクショングループ"]
E --> F["Lambda関数"]
F --> G["外部API/サービス"]
G --> C
D -->|No| H["レスポンス生成"]
C --> I["Knowledge Base"]
I --> C
style B fill:#8b5cf6,color:#fff
style E fill:#3b82f6,color:#fff
style I fill:#22c55e,color:#fff
エージェントのコンポーネント
| コンポーネント | 説明 |
|---|---|
| 基盤モデル | エージェントの頭脳(Claude、Titan) |
| 指示 | 動作を定義するシステムプロンプト |
| アクショングループ | エージェントが使用できるツール |
| Knowledge Bases | RAG用データソース |
エージェントの作成
コンソールでの設定
- Amazon Bedrock → Agents → エージェントを作成
- エージェントの詳細を設定:
- 名前と説明
- 基盤モデル
- 指示
SDKの使用
import boto3
client = boto3.client('bedrock-agent')
# エージェントを作成
response = client.create_agent(
agentName='customer-service-agent',
foundationModel='anthropic.claude-3-sonnet-20240229-v1:0',
instruction="""あなたは親切なカスタマーサービスエージェントです。
以下のことができます:
- 注文状況の確認
- 返品処理
- 製品に関する質問への回答
常に丁寧で親切に対応してください。対応できない場合は、人間のエージェントにエスカレーションしてください。""",
idleSessionTTLInSeconds=1800
)
agent_id = response['agent']['agentId']
アクショングループ
アクショングループは、エージェントが外部システムと対話するために使用できるツールを定義します。
アクショングループの作成
# LambdaでアクショングLoop を作成
response = client.create_agent_action_group(
agentId=agent_id,
agentVersion='DRAFT',
actionGroupName='order-management',
actionGroupExecutor={
'lambda': 'arn:aws:lambda:us-east-1:123456789012:function:order-handler'
},
apiSchema={
'payload': '''
openapi: 3.0.0
info:
title: Order Management API
version: 1.0.0
paths:
/orders/{orderId}:
get:
operationId: getOrderStatus
summary: 注文状況を取得
parameters:
- name: orderId
in: path
required: true
schema:
type: string
responses:
200:
description: 注文詳細
/returns:
post:
operationId: createReturn
summary: 返品リクエストを作成
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
orderId:
type: string
reason:
type: string
responses:
200:
description: 返品作成完了
'''
}
)
アクショングループ用Lambda関数
import json
def lambda_handler(event, context):
agent = event['agent']
action_group = event['actionGroup']
api_path = event['apiPath']
http_method = event['httpMethod']
parameters = event.get('parameters', [])
request_body = event.get('requestBody', {})
# 適切なハンドラーにルーティング
if api_path == '/orders/{orderId}' and http_method == 'GET':
order_id = next(p['value'] for p in parameters if p['name'] == 'orderId')
result = get_order_status(order_id)
elif api_path == '/returns' and http_method == 'POST':
body = request_body.get('content', {}).get('application/json', {})
result = create_return(body.get('properties', {}))
else:
result = {'error': '不明なアクション'}
return {
'messageVersion': '1.0',
'response': {
'actionGroup': action_group,
'apiPath': api_path,
'httpMethod': http_method,
'httpStatusCode': 200,
'responseBody': {
'application/json': {
'body': json.dumps(result)
}
}
}
}
def get_order_status(order_id):
# 注文検索を実装
return {
'orderId': order_id,
'status': '発送済み',
'estimatedDelivery': '2025-01-20'
}
def create_return(properties):
# 返品作成を実装
return {
'returnId': 'RET-123',
'status': '保留中'
}
Knowledge Baseの接続
# Knowledge Baseをエージェントに関連付け
response = client.associate_agent_knowledge_base(
agentId=agent_id,
agentVersion='DRAFT',
knowledgeBaseId='KB_ID',
description='製品ドキュメントとFAQ'
)
エージェントの準備と呼び出し
エージェントを準備
# 使用のためにエージェントを準備
client.prepare_agent(agentId=agent_id)
# 本番用エイリアスを作成
response = client.create_agent_alias(
agentId=agent_id,
agentAliasName='production'
)
alias_id = response['agentAlias']['agentAliasId']
エージェントを呼び出し
runtime_client = boto3.client('bedrock-agent-runtime')
def invoke_agent(session_id: str, prompt: str):
response = runtime_client.invoke_agent(
agentId=agent_id,
agentAliasId=alias_id,
sessionId=session_id,
inputText=prompt
)
# ストリーミングレスポンスを処理
result = ""
for event in response['completion']:
if 'chunk' in event:
result += event['chunk']['bytes'].decode()
return result
# エージェントを使用
session_id = "user-123-session"
response = invoke_agent(session_id, "注文ORD-456の状況は?")
print(response)
ReActフレームワーク
エージェントはReAct(Reasoning + Acting)を使用して問題を解決します:
flowchart LR
A["思考"] --> B["アクション"]
B --> C["観察"]
C --> A
C --> D["最終回答"]
style A fill:#8b5cf6,color:#fff
style B fill:#3b82f6,color:#fff
style C fill:#22c55e,color:#fff
ReActトレースの例
ユーザー:ORD-789の注文状況は?
思考:ORD-789の注文状況を調べる必要があります。
アクション:getOrderStatus(orderId="ORD-789")
観察:{"orderId": "ORD-789", "status": "shipped", "estimatedDelivery": "2025-01-20"}
思考:注文情報を取得しました。注文は発送済みです。
最終回答:ご注文ORD-789は発送済みで、2025年1月20日に届く予定です。
高度な設定
セッション属性
response = runtime_client.invoke_agent(
agentId=agent_id,
agentAliasId=alias_id,
sessionId=session_id,
inputText=prompt,
sessionState={
'sessionAttributes': {
'customerId': 'CUST-123',
'membershipLevel': 'gold'
},
'promptSessionAttributes': {
'currentDate': '2025-01-18'
}
}
)
Return Control
人間確認が必要なシナリオ:
response = runtime_client.invoke_agent(
agentId=agent_id,
agentAliasId=alias_id,
sessionId=session_id,
inputText="注文ORD-123の返金処理をお願いします",
enableTrace=True
)
# エージェントが確認を求めているかチェック
for event in response['completion']:
if 'returnControl' in event:
invocation = event['returnControl']['invocationInputs'][0]
print(f"エージェントの操作: {invocation['apiInvocationInput']['actionGroup']}")
print(f"確認しますか? (y/n)")
# 確認処理...
完全なエージェントの例
import boto3
import uuid
from typing import Optional
class CustomerServiceAgent:
def __init__(self, agent_id: str, alias_id: str):
self.runtime = boto3.client('bedrock-agent-runtime')
self.agent_id = agent_id
self.alias_id = alias_id
self.sessions = {}
def get_session(self, user_id: str) -> str:
if user_id not in self.sessions:
self.sessions[user_id] = str(uuid.uuid4())
return self.sessions[user_id]
def chat(self, user_id: str, message: str, customer_id: Optional[str] = None) -> str:
session_id = self.get_session(user_id)
kwargs = {
'agentId': self.agent_id,
'agentAliasId': self.alias_id,
'sessionId': session_id,
'inputText': message
}
if customer_id:
kwargs['sessionState'] = {
'sessionAttributes': {'customerId': customer_id}
}
response = self.runtime.invoke_agent(**kwargs)
result = ""
for event in response['completion']:
if 'chunk' in event:
result += event['chunk']['bytes'].decode()
return result
def end_session(self, user_id: str):
if user_id in self.sessions:
del self.sessions[user_id]
# 使用例
agent = CustomerServiceAgent(
agent_id='YOUR_AGENT_ID',
alias_id='YOUR_ALIAS_ID'
)
# 会話
print(agent.chat("user1", "注文について助けてほしいのですが", customer_id="CUST-456"))
print(agent.chat("user1", "注文ORD-789の状況は?"))
print(agent.chat("user1", "返品できますか?"))
ベストプラクティス
| プラクティス | 推奨事項 |
|---|---|
| 明確な指示 | エージェントの能力を具体的に |
| エラーハンドリング | Lambda失敗を適切に処理 |
| セッション管理 | 意味のあるセッションIDを使用 |
| テスト | 各アクショングループを個別にテスト |
| モニタリング | デバッグ用にトレースを有効化 |
重要なポイント
- エージェントは推論して行動 - ReActフレームワークを使用
- アクショングループはツール - Lambda経由で外部システムに接続
- Knowledge Baseがコンテキストを提供 - ドメイン知識用RAG
- セッションが状態を維持 - マルチターン会話
- デプロイ前に準備 - 設定を検証