はじめに
業務において何かアラートが発生した場合、まずは標準的に実施したい手順が何パターンかあったりすると思います。
アラートの情報を生成AIにインプットして、最終的にはreadレベルのみの一次対応は自動化を目指して、まずは生成AIから登録された運用手順を返すようなRAGシステムを構築してみたいと思います。
思い立った背景
既存の手段が個人でやるには高価に感じていたのですが、Amazon S3 Vectorsであれば低コストで実現できそうだなと思って実際にやってみたいと思います。
構築するシステムの概要
今回は標準作業手順書(SOP: Standard Operating Procedure)を検索可能にするナレッジベースを構築します。
アーキテクチャ
- 生成AI用いたアーキ図
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ S3 Bucket │────▶│ Bedrock KB │────▶│ S3 Vectors │
│ (SOPドキュメント) │ │ (データ処理) │ │ (ベクトル保存) │
└─────────────────┘ └──────────────────┘ └─────────────────┘
│ │
▼ ▼
┌──────────────────┐ ┌─────────────────┐
│ Bedrock Models │ │ Vector Index │
│ (Embedding生成) │ │ (類似性検索) │
└──────────────────┘ └─────────────────┘
- aws-diagram-mcp-serverを用いて作成してもらったアーキテクチャ図は以下。アイコンがまだないためか空欄となっています。
- aws-diagram-mcp-serverにて作成してもらったデータフローはわかりやすかったので、そちらも載せておきます。
環境の前提条件
- 最新のAWS CLIがインストールされていること
- リージョン: us-east-1を使用
- Amazon Bedrockで以下のモデルアクセスが可能。
- Amazon Titan Text Embeddings V2
- Anthropic Claude 3 Sonnet
環境構築手順
- 以下にAWS CLIをベースとした環境の構築手順を記載します。
手順1: S3 Vectorバケットの作成
まず、ベクトルデータを保存するための専用バケットを作成します。
# ユニークなバケット名を生成
VECTOR_BUCKET_NAME="bedrock-kb-sop-vectors-$(date +%Y%m%d-%H%M%S)"
# S3 Vectorバケットを作成
aws s3vectors create-vector-bucket \
--vector-bucket-name "$VECTOR_BUCKET_NAME" \
--region us-east-1
# 作成確認
aws s3vectors get-vector-bucket \
--vector-bucket-name "$VECTOR_BUCKET_NAME" \
--region us-east-1
{
"vectorBucket": {
"vectorBucketName": "bedrock-kb-sop-vectors-20250812-210434",
"vectorBucketArn": "arn:aws:s3vectors:us-east-1:<AWS_ACCOUNT_ID>:bucket/bedrock-kb-sop-vectors-20250812-210434",
"creationTime": "2025-08-12T21:06:41+09:00",
"encryptionConfiguration": {
"sseType": "AES256"
}
}
}
手順2: ベクトルインデックスの作成
次に、ベクトルバケット内にインデックスを作成します。
INDEX_NAME="sop-index"
# ベクトルインデックスを作成
aws s3vectors create-index \
--vector-bucket-name "$VECTOR_BUCKET_NAME" \
--index-name "$INDEX_NAME" \
--data-type "float32" \
--dimension 1024 \
--distance-metric "cosine" \
--region us-east-1
# 作成確認
aws s3vectors get-index \
--vector-bucket-name "$VECTOR_BUCKET_NAME" \
--index-name "$INDEX_NAME" \
--region us-east-1
{
"index": {
"vectorBucketName": "bedrock-kb-sop-vectors-20250812-210434",
"indexName": "sop-index",
"indexArn": "arn:aws:s3vectors:us-east-1:<AWS_ACCOUNT_ID>:bucket/bedrock-kb-sop-vectors-20250812-210434/index/sop-index",
"creationTime": "2025-08-12T21:14:01+09:00",
"dataType": "float32",
"dimension": 1024,
"distanceMetric": "cosine"
}
}
手順3: データソース用S3バケットの準備
SOPドキュメントを格納するための通常のS3バケットを作成します。
# データソース用バケットを作成
DATA_BUCKET_NAME="bedrock-kb-sop-data-source-$(date +%Y%m%d-%H%M%S)"
aws s3api create-bucket \
--bucket "$DATA_BUCKET_NAME" \
--region us-east-1
{
"Location": "/bedrock-kb-sop-data-source-20250812-211724"
}
# SOPファイルをアップロード
aws s3 cp sop-samples/ "s3://$DATA_BUCKET_NAME/sop-samples/" \
--recursive \
--exclude "*" \
--include "*.md"
# アップロード確認
aws s3 ls "s3://$DATA_BUCKET_NAME/sop-samples/ec2/"
2025-08-12 21:18:43 9143 EC2-CPU-001.md
2025-08-12 21:18:43 13185 EC2-MEMORY-001.md
2025-08-12 21:18:43 19113 EC2-NETWORK-001.md
サンプルSOPファイルの例(MEMORYのアラートを受けた場合のSOP)
EC2-MEMORY-001.md
# EC2 High Memory Utilization Investigation and Resolution
## Overview
This SOP provides systematic procedures for investigating and resolving high memory usage issues on EC2 instances, including immediate response actions and long-term optimization strategies.
## Symptoms
- High memory utilization alerts from CloudWatch
- Application performance degradation
- Out of Memory (OOM) killer events
- System responsiveness issues
- Application crashes or failures
## Investigation Steps
### CloudWatch Metrics Analysis
/```bash
# Get memory usage data for the last 30 minutes
aws cloudwatch get-metric-statistics \
--namespace CWAgent \
--metric-name mem_used_percent \
--period 300 \
--statistics Average,Maximum \
--dimensions Name=InstanceId,Value=i-1234567890abcdef0 \
--start-time $(date -u -d '30 minutes ago' '+%Y-%m-%dT%H:%M:%SZ') \
--end-time $(date -u '+%Y-%m-%dT%H:%M:%SZ')
# Check memory available metrics
aws cloudwatch get-metric-statistics \
--namespace CWAgent \
--metric-name mem_available_percent \
--period 300 \
--statistics Average,Minimum \
--dimensions Name=InstanceId,Value=i-1234567890abcdef0 \
--start-time $(date -u -d '2 hours ago' '+%Y-%m-%dT%H:%M:%SZ') \
--end-time $(date -u '+%Y-%m-%dT%H:%M:%SZ')
# Get swap usage if configured
aws cloudwatch get-metric-statistics \
--namespace CWAgent \
--metric-name swap_used_percent \
--period 300 \
--statistics Average,Maximum \
--dimensions Name=InstanceId,Value=i-1234567890abcdef0 \
--start-time $(date -u -d '1 hour ago' '+%Y-%m-%dT%H:%M:%SZ') \
--end-time $(date -u '+%Y-%m-%dT%H:%M:%SZ')
/```
### Instance Status Verification
```bash
# Check instance basic information
aws ec2 describe-instances --instance-ids i-1234567890abcdef0 \
--query 'Reservations[0].Instances[0].[InstanceType,State.Name,PublicIpAddress,PrivateIpAddress]' \
--output table
# Verify instance type specifications
aws ec2 describe-instance-types \
--instance-types $(aws ec2 describe-instances --instance-ids i-1234567890abcdef0 \
--query 'Reservations[0].Instances[0].InstanceType' --output text) \
--query 'InstanceTypes[0].[InstanceType,MemoryInfo.SizeInMiB,VCpuInfo.DefaultVCpus]' \
--output table
# Check if instance has enhanced monitoring enabled
aws ec2 describe-instances --instance-ids i-1234567890abcdef0 \
--query 'Reservations[0].Instances[0].Monitoring.State' \
--output text
(以降割愛)
手順4: IAMロールの作成
Bedrock Knowledge Baseが各サービスにアクセスするためのIAMロールを作成します。
# 信頼ポリシーを作成
cat > trust-policy.json << 'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "bedrock.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
# IAMロールを作成
ROLE_NAME="BedrockKnowledgeBaseRole-$(date +%Y%m%d-%H%M%S)"
aws iam create-role \
--role-name "$ROLE_NAME" \
--assume-role-policy-document file://trust-policy.json
{
"Role": {
"Path": "/",
"RoleName": "BedrockKnowledgeBaseRole-20250812-212642",
"RoleId": "<IAM_ROLE_ID>",
"Arn": "arn:aws:iam::<AWS_ACCOUNT_ID>:role/BedrockKnowledgeBaseRole-20250812-212642",
"CreateDate": "2025-08-12T12:26:51+00:00",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "bedrock.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
}
}
必要な権限ポリシーを作成してアタッチ:
# アカウントIDを取得
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
# 権限ポリシーを作成
cat > kb-policy.json << EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:ListBucket"],
"Resource": [
"arn:aws:s3:::${DATA_BUCKET_NAME}",
"arn:aws:s3:::${DATA_BUCKET_NAME}/*"
]
},
{
"Effect": "Allow",
"Action": [
"s3vectors:PutVectors",
"s3vectors:DeleteVectors",
"s3vectors:GetVectors",
"s3vectors:GetIndex",
"s3vectors:ListVectors",
"s3vectors:QueryVectors"
],
"Resource": [
"arn:aws:s3vectors:us-east-1:${ACCOUNT_ID}:bucket/${VECTOR_BUCKET_NAME}",
"arn:aws:s3vectors:us-east-1:${ACCOUNT_ID}:bucket/${VECTOR_BUCKET_NAME}/index/${INDEX_NAME}"
]
},
{
"Effect": "Allow",
"Action": ["bedrock:InvokeModel"],
"Resource": [
"arn:aws:bedrock:us-east-1::foundation-model/amazon.titan-embed-text-v2:0",
"arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0"
]
}
]
}
EOF
# ポリシーを作成してロールにアタッチ
POLICY_NAME="BedrockKnowledgeBasePolicy-$(date +%Y%m%d-%H%M%S)"
POLICY_ARN=$(aws iam create-policy \
--policy-name "$POLICY_NAME" \
--policy-document file://kb-policy.json \
--query 'Policy.Arn' \
--output text)
aws iam attach-role-policy \
--role-name "$ROLE_NAME" \
--policy-arn "$POLICY_ARN"
手順5: Bedrock Knowledge Baseの作成
Knowledge Base本体を作成します。
# Knowledge Base設定
cat > kb-config.json << EOF
{
"type": "VECTOR",
"vectorKnowledgeBaseConfiguration": {
"embeddingModelArn": "arn:aws:bedrock:us-east-1::foundation-model/amazon.titan-embed-text-v2:0",
"embeddingModelConfiguration": {
"bedrockEmbeddingModelConfiguration": {
"dimensions": 1024
}
}
}
}
EOF
# ストレージ設定(S3 Vectorsを指定)
cat > storage-config.json << EOF
{
"type": "S3_VECTORS",
"s3VectorsConfiguration": {
"indexArn": "arn:aws:s3vectors:us-east-1:${ACCOUNT_ID}:bucket/${VECTOR_BUCKET_NAME}/index/${INDEX_NAME}"
}
}
EOF
# ロールARNを取得
ROLE_ARN=$(aws iam get-role \
--role-name "$ROLE_NAME" \
--query 'Role.Arn' \
--output text)
# Knowledge Baseを作成
KB_NAME="sop-knowledge-base"
KB_ID=$(aws bedrock-agent create-knowledge-base \
--name "$KB_NAME" \
--description "Standard Operating Procedures Knowledge Base" \
--role-arn "$ROLE_ARN" \
--knowledge-base-configuration file://kb-config.json \
--storage-configuration file://storage-config.json \
--region us-east-1 \
--query 'knowledgeBase.knowledgeBaseId' \
--output text)
echo "Created Knowledge Base: $KB_ID"
手順6: データソースの設定と同期
最後に、データソースを設定してSOPドキュメントをベクトル化します。
- 同期できないファイルがあったためチャンクサイズを小さくしました。
# データソース設定
cat > datasource-config.json << EOF
{
"type": "S3",
"s3Configuration": {
"bucketArn": "arn:aws:s3:::${DATA_BUCKET_NAME}",
"inclusionPrefixes": ["sop-samples/"]
}
}
EOF
# チャンキング設定
cat > vector-ingestion-config.json << EOF
{
"chunkingConfiguration": {
"chunkingStrategy": "FIXED_SIZE",
"fixedSizeChunkingConfiguration": {
"maxTokens": 200,
"overlapPercentage": 20
}
},
"parsingConfiguration": {
"parsingStrategy": "BEDROCK_FOUNDATION_MODEL",
"bedrockFoundationModelConfiguration": {
"modelArn": "arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0"
}
}
}
EOF
# データソースを作成
DATASOURCE_ID=$(aws bedrock-agent create-data-source \
--knowledge-base-id "$KB_ID" \
--name "sop-datasource" \
--description "SOP markdown files data source" \
--data-source-configuration file://datasource-config.json \
--vector-ingestion-configuration file://vector-ingestion-config.json \
--region us-east-1 \
--query 'dataSource.dataSourceId' \
--output text)
# データソースを同期
INGESTION_JOB_ID=$(aws bedrock-agent start-ingestion-job \
--knowledge-base-id "$KB_ID" \
--data-source-id "$DATASOURCE_ID" \
--region us-east-1 \
--query 'ingestionJob.ingestionJobId' \
--output text)
echo "Started Ingestion Job: $INGESTION_JOB_ID"
同期の進行状況を確認:
# 同期ステータスを確認
aws bedrock-agent get-ingestion-job \
--knowledge-base-id "$KB_ID" \
--data-source-id "$DATASOURCE_ID" \
--ingestion-job-id "$INGESTION_JOB_ID" \
--region us-east-1 \
--query 'ingestionJob.status' \
--output text
手順7: Knowledge Baseのテスト
構築したKnowledge Baseに対してクエリを実行します。
動作確認手順:AWS CLI
QUERY="EC2のメモリの問題が発生した場合のインシデント対応の手順を教えてください"
aws bedrock-agent-runtime retrieve \
--knowledge-base-id "$KB_ID" \
--retrieval-query "{\"text\": \"$QUERY\"}" \
--retrieval-configuration '{
"vectorSearchConfiguration": {
"numberOfResults": 3
}
}' \
--region us-east-1 \
--output json | jq '.retrievalResults[].content.text'
{
"retrievalResults": [
{
"content": {
"text": "--- sop_id: \"EC2-MEMORY-001\" title: \"EC2 High Memory Utilization Investigation and Resolution\" service: \"EC2\" category: \"performance\" severity: \"High\" estimated_time: \"20-30 minutes\" prerequisites: - \"AWS CLI access with EC2 permissions\" - \"CloudWatch metrics access\" - \"SSH/SSM access to instances\" automation_potential: \"Partial\" last_updated: \"2025-06-18\" version: \"1.0\" --- # EC2 High Memory Utilization Investigation and Resolution ## Overview This SOP provides systematic procedures for investigating and resolving high memory usage issues on EC2 instances, including immediate response actions and long-term optimization strategies. ## Symptoms - High memory utilization alerts from CloudWatch - Application performance degradation - Out of Memory (OOM) killer events - System responsiveness issues - Application crashes or failures ## Investigation Steps ### CloudWatch Metrics Analysis ```bash # Get memory usage data for the last 30 minutes",
"type": "TEXT"
},
"location": {
"s3Location": {
"uri": "s3://<S3_Bucket_Name>/sop-samples/ec2/EC2-MEMORY-001.md"
},
"type": "S3"
},
(以降割愛)
動作確認手順:Python
- Strands Agentsを用いた手順にしています。以下の記事を参考にさせていただきました。toolのレスポンスを個別に確認したところ、RAGは機能しているようでした。
from strands import Agent, tool
from strands.models import BedrockModel
import os
import boto3
import json
# 環境変数の取得
KB_ID = os.environ.get('KB_ID')
# サンプルの質問
query = "EC2のメモリの問題が発生した場合のインシデント対応の手順を教えてください。"
# クライアントを初期化
bedrock_runtime = boto3.client('bedrock-agent-runtime', region_name='us-east-1')
# Bedrockのモデル設定
model = BedrockModel(
model_id='us.anthropic.claude-3-5-haiku-20241022-v1:0',
max_tokens=4096,
temperature=0.7
)
@tool
def search_knowledge_base(query: str, max_results: int = None) -> str:
"""ナレッジベースから関連する文書を検索します"""
try:
response = bedrock_runtime.retrieve(
knowledgeBaseId=KB_ID,
retrievalQuery={'text': query},
retrievalConfiguration={
'vectorSearchConfiguration': {
'numberOfResults': 5,
'overrideSearchType': 'SEMANTIC'
}
}
)
# 結果をJSON形式で返す
return json.dumps({'success': True, 'results': response}, ensure_ascii=False)
except Exception as e:
# エラー処理
return json.dumps({'success': False, 'error': str(e)}, ensure_ascii=False)
agent = Agent(
name="knowledgebase-s3-vector-test",
model=model,
tools=[search_knowledge_base],
system_prompt="あなたはアラート発生時にアラート内容に基づいて、次のアクションを推奨するエージェントです。"
)
agent(query)
出力
EC2のメモリ問題に関するインシデント対応の手順について、ナレッジベースを検索して詳細な情報を確認します。
Tool #1: search_knowledge_base
検索結果に基づき、EC2のメモリ問題に対するインシデント対応の手順を以下にまとめます:
1. 症状の確認
- CloudWatchアラートによる高メモリ使用率
- アプリケーションのパフォーマンス低下
- Out of Memory (OOM) キラーイベント
- システムの応答性の問題
- アプリケーションのクラッシュや障害
2. 初期調査
a) CloudWatch メトリクスの分析
- 過去30分のメモリ使用状況を確認
- メモリ使用率、使用可能なメモリ量を調査
b) インスタンス内部の詳細調査
- プロセスの確認
/```bash
# メモリ使用状況の確認
top
# または
free -h
# プロセスごとのメモリ使用状況
ps aux | sort -nrk 4
/```
3. 即時対応策
a) システムキャッシュのクリア
/```bash
# ページキャッシュをクリア
sudo sync
echo 1 | sudo tee /proc/sys/vm/drop_caches
# dentries and inodesキャッシュもクリア
echo 2 | sudo tee /proc/sys/vm/drop_caches
# すべてのキャッシュをクリア
echo 3 | sudo tee /proc/sys/vm/drop_caches
# メモリ解放の確認
free -h
/```
b) 不要なプロセスの停止
- メモリを大量に消費しているプロセスを特定し、停止
4. 長期的な解決策
a) インスタンスタイプのアップグレード
/```bash
# インスタンスを停止
aws ec2 stop-instances --instance-ids i-1234567890abcdef0
# インスタンスタイプを変更(より多くのメモリを持つタイプに)
aws ec2 modify-instance-attribute \
--instance-id i-1234567890abcdef0 \
--instance-type Value=m5.2xlarge
# インスタンスを再起動
aws ec2 start-instances --instance-ids i-1234567890abcdef0
/```
b) アプリケーションの最適化
- メモリリークの修正
- コードの効率化
- キャッシュ戦略の見直し
5. モニタリングと予防
- CloudWatchアラートの設定
- 定期的なパフォーマンス監視
- 予防的なキャパシティ計画
注意点:
- 緊急時は、アプリケーションの可用性を最優先に対応する
- 根本原因を特定し、恒久的な解決策を検討する
- 変更は段階的に行い、影響を最小限に抑える
このガイドラインに従って、EC2のメモリ問題に対して体系的にアプローチすることができます。%
さいごに
- 運用手順の取得をAmazon S3 VecotrsとBedrock Knowledge BasesのRAGから取得できました。(Strands Agentsと組み合わせることまでできました。)
- 今後はもう少し参考とするドキュメントの精度向上などをしていけたらと思います。
参考
- 参考情報として利用した情報と削除手順を載せます
関係リンク
- Amazon S3 Vectors公式ドキュメント
- Amazon Bedrock Knowledge Bases
- AWS CLI S3 Vectorsリファレンス
- Titan Text Embeddings V2
環境削除手順
# データソースを削除
aws bedrock-agent delete-data-source \
--knowledge-base-id "$KB_ID" \
--data-source-id "$DATASOURCE_ID" \
--region us-east-1
# Knowledge Baseを削除
aws bedrock-agent delete-knowledge-base \
--knowledge-base-id "$KB_ID" \
--region us-east-1
# ベクトルインデックスを削除
aws s3vectors delete-vector-index \
--vector-bucket-name "$VECTOR_BUCKET_NAME" \
--index-name "$INDEX_NAME" \
--region us-east-1
# ベクトルバケットを削除
aws s3vectors delete-vector-bucket \
--vector-bucket-name "$VECTOR_BUCKET_NAME" \
--region us-east-1
# S3バケットを削除
aws s3 rm "s3://$DATA_BUCKET_NAME" --recursive
aws s3api delete-bucket --bucket "$DATA_BUCKET_NAME"
# IAMリソースを削除
aws iam detach-role-policy \
--role-name "$ROLE_NAME" \
--policy-arn "$POLICY_ARN"
aws iam delete-policy --policy-arn "$POLICY_ARN"
aws iam delete-role --role-name "$ROLE_NAME"
