0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Amazon Bedrock AgentCoreとは何か ― AIエージェントを「作る」から「運用する」への転換点

0
Posted at

はじめに

ChatGPTが登場した2022年末以降、多くの企業がLLMを業務に組み込もうとしてきました。最初はチャットボット、次にRAG、そして今はAIエージェント——LLMが自律的にツールを呼び出し、判断し、タスクを完遂する仕組みへと関心が移っています。

ただ、エージェントを「動かす」ことと「運用する」ことの間には、想像以上に深い溝があります。PoC段階では気にならなかった問題が、本番環境に持ち込んだ途端に噴出するのです。

  • エージェントが外部APIを叩くとき、誰の権限で実行するのか?
  • 推論のループが暴走したとき、どうやって止めるのか?
  • 1人のユーザーに応答している間、他のリクエストはどうなるのか?
  • エージェントが「なぜその判断をしたか」をどうやって追跡するのか?

2025年10月にGAとなったAmazon Bedrock AgentCoreは、まさにこの「運用の溝」を埋めるために設計されたサービスです。本記事では、AgentCoreの設計思想から9つのコンポーネントの詳細、既存のBedrock Agentsとの使い分け、そして実際のコード例まで、一本の記事で全体像を掴めるように整理します。

対象読者

  • AIエージェントのPoC→本番移行に課題を感じているエンジニア
  • Amazon Bedrock Agentsは知っているが、AgentCoreとの違いが分からない方
  • LangGraph・CrewAI等のフレームワークをAWS上で本番運用したい方

なぜAIエージェントに「専用インフラ」が必要なのか

従来のWebアプリとの決定的な違い

AIエージェントの実行特性は、従来のリクエスト/レスポンス型のWebアプリケーションとは根本的に異なります。

特性 従来のWebアプリ AIエージェント
実行時間 数百ms〜数秒 数十秒〜数分(複数ステップ)
リソース消費パターン CPU集中 or I/O集中 LLM推論待ち(I/O)とツール実行(CPU)が交互に発生
状態管理 ステートレスが基本 会話履歴・中間結果の保持が必要
外部連携 事前定義されたAPI呼び出し 実行時にLLMが動的にツールを選択
安全性 入力バリデーションが中心 LLMの判断そのものを制御する必要がある

ECSやLambdaにエージェントを載せること自体は可能です。しかし、LLMの応答を待っている間もCPUリソースに課金され続け、セッション管理は自前で実装し、エージェントの行動ログは独自に設計する——こうした「インフラのミスマッチ」が、運用コストと開発工数を押し上げます。

エージェント運用で避けて通れない5つの課題

  1. スケーリングとコスト効率 — LLM応答待ちの間もリソースを確保し続けるのは無駄が大きい
  2. アイデンティティとアクセス制御 — エージェントがユーザーに代わってAPIを叩くとき、適切な権限境界が必要
  3. オブザーバビリティ — 「なぜエージェントがその行動を取ったか」をステップ単位で追跡したい
  4. ガードレール — エージェントの自律性を活かしつつ、意図しない行動を防ぎたい
  5. メモリ管理 — 短期的な会話コンテキストと、長期的なユーザー情報の両方を扱いたい

AgentCoreは、これら5つの課題それぞれに対応するコンポーネントを提供しています。

Amazon Bedrock AgentCoreの全体像

ポジショニング

AgentCoreは「AIエージェントの本番運用基盤」です。重要なのは、特定のフレームワークやモデルに依存しないという設計思想です。

┌─────────────────────────────────────────────────┐
│           アプリケーション / エージェント            │
│  (Strands Agents, LangGraph, CrewAI, Google ADK,  │
│  OpenAI Agents SDK, 自作 etc.)                    │
├─────────────────────────────────────────────────┤
│            Amazon Bedrock AgentCore              │
│  ┌────────┐ ┌────────┐ ┌────────┐ ┌──────────┐  │
│  │Runtime │ │Gateway │ │Memory  │ │Identity  │  │
│  ├────────┤ ├────────┤ ├────────┤ ├──────────┤  │
│  │Observe │ │Policy  │ │Browser │ │Code Intp.│  │
│  └────────┘ └────────┘ └────────┘ └──────────┘  │
│  └── Evaluations ──┘                             │
├─────────────────────────────────────────────────┤
│          任意のLLM (Claude, GPT, Gemini,          │
│           Nova, Llama, Mistral ...)              │
└─────────────────────────────────────────────────┘

どのLLMを使っていても、どのフレームワークで構築していても、AgentCoreの各コンポーネントを組み合わせて利用できます。これは「AWS囲い込み」ではなく、エージェント運用のインフラ層を標準化するというアプローチです。

9つのコンポーネント

AgentCoreは9つのコンポーネントで構成されており、それぞれを独立して利用することも、組み合わせて使うことも可能です。

コンポーネント詳解

1. Runtime — エージェントのサーバーレス実行基盤

Runtimeは、エージェントをサーバーレスでデプロイ・スケーリングするための実行環境です。

特徴:

  • 高速コールドスタート: リクエストに応じて即座にエージェントを起動
  • セッション分離: エージェントごとに独立した実行環境を提供
  • 非同期エージェント対応: 長時間実行されるエージェントにも対応
  • I/O待ち中のCPU非課金: LLM推論の応答待ち中はCPUコストが発生しない

最後の点が特に重要です。AIエージェントの実行時間の大半はLLMの応答待ちです。従来のコンテナベースの構成では、この待ち時間にもCPUリソースの課金が発生していました。Runtimeではこの問題を構造的に解決しています。

料金(us-east-1):

リソース 単価
CPU $0.0895 / vCPU-hour
メモリ $0.00945 / GB-hour

※I/O待ち中はCPU課金なし

2. Gateway — ツール接続のハブ

Gatewayは、エージェントが利用するツール(API、Lambda関数、MCPサーバーなど)を一元管理するコンポーネントです。

対応するツールソース:

  • REST API / OpenAPI仕様
  • AWS Lambda関数
  • MCPサーバー(Model Context Protocol)
  • SaaS連携(Salesforce、Slack、Jira、Asana、Zendesk)

Gatewayは単なるプロキシではなく、APIスキーマからツールの説明を自動生成し、エージェントが適切なツールを選択できるようにセマンティック検索機能も提供します。数百のツールを登録しても、エージェントが各リクエストに最適なツールを見つけられるようになっています。

3. Memory — 短期記憶と長期記憶のマネージド基盤

エージェントが「文脈を覚えている」ためには、メモリ管理が不可欠です。AgentCoreのMemoryは2種類の記憶を提供します。

種類 用途
短期記憶 セッション内の会話履歴・中間状態 「さっき頼んだファイルの名前は?」に答える
長期記憶 セッションをまたぐユーザー情報・学習 「この顧客は過去に○○の問い合わせをしている」

長期記憶では、カスタム記憶戦略を定義でき、「何を覚えて、何を忘れるか」をビジネスロジックに合わせて制御できます。

4. Identity — エージェントのアイデンティティ管理

エージェントが外部サービスにアクセスする際の認証・認可を管理します。

対応IdP:

  • Amazon Cognito
  • Okta
  • Microsoft Entra ID
  • Auth0

「エージェントがユーザーのGoogleカレンダーを読む」場合、ユーザーの同意に基づくOAuthトークンの取得から、トークンの安全な保管・更新までをIdentityが担います。エージェント開発者がOAuthフローを自前で実装する必要はありません。

5. Observability — OpenTelemetry互換のトレーシング

エージェントの各ステップを可視化するオブザーバビリティ基盤です。内部では**AWS Distro for OpenTelemetry(ADOT)**を採用しており、AWSネイティブのサービスとサードパーティの監視ツールの両方にテレメトリデータを送信できます。

自動収集されるメトリクス

計装コードを書かなくても、以下のメトリクスが1分間隔で自動的に収集されます。

  • セッション数 — 同時実行中のエージェントセッション
  • レイテンシ — リクエストからレスポンスまでの応答時間
  • Duration — ツール呼び出しを含むエンドツーエンドの処理時間
  • トークン使用量 — 入力/出力トークン数
  • エラー率 — エージェント実行の失敗率

ADOTによる計装を追加すると、LLM呼び出し・ツール実行・フレームワーク内部ステップまで、分散トレースのスパンとして可視化できます。

AWS上での具体的な活用方法

AgentCore ObservabilityはAWSネイティブの監視サービスと直接連携します。

Amazon CloudWatch連携(デフォルト)

テレメトリデータはデフォルトでCloudWatchに送信されます。CloudWatchコンソールの生成AI向けオブザーバビリティページでは、3つのビューでエージェントの動作を確認できます。

ビュー 用途
Agents View エージェントごとのパフォーマンス概要(セッション数、レイテンシ、エラー率)
Sessions View 個別セッションの詳細(会話の流れ、ツール呼び出し履歴)
Traces View 分散トレースの詳細(各ステップの実行時間、入出力)

AWS X-Ray連携

分散トレーシングにはX-Rayも利用できます。X-Amzn-Trace-Idヘッダーによるトレースコンテキストの伝播に対応しており、エージェントから呼び出された下流のAWSサービス(Lambda、DynamoDBなど)のトレースとも自動的に紐づきます。

利用には、事前にアカウントでCloudWatch Transaction Searchを有効化する必要があります(一度だけの設定)。

セットアップ

AgentCore Runtime上で動作するエージェントの場合、requirements.txtに依存パッケージを追加するだけです。

bedrock-agentcore
aws-opentelemetry-distro
strands-agents[otel]

ADOT関連の環境変数はRuntimeが自動的に設定するため、個別の設定は不要です。

AgentCore Runtime(EC2やECSなど)で動作するエージェントの場合は、環境変数を明示的に設定します。

export AGENT_OBSERVABILITY_ENABLED=true
export OTEL_PYTHON_DISTRO=aws_distro
export OTEL_PYTHON_CONFIGURATOR=aws_configurator
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
export OTEL_TRACES_EXPORTER=otlp

サードパーティとの併用

OpenTelemetry互換であることの最大のメリットは、AWS純正の監視とサードパーティツールを併用できる点です。OpenTelemetry Collectorに複数のExporterを設定することで、同じテレメトリデータをCloudWatch/X-Rayとサードパーティの両方に同時送信できます。

公式に動作確認されているサードパーティ:

  • Datadog
  • Grafana Cloud
  • Langfuse
  • LangSmith
  • Arize Phoenix
  • Elastic Observability
  • Dynatrace

既にDatadogやGrafanaで監視基盤を構築している組織でも、AgentCoreのテレメトリをそのまま既存のダッシュボードに統合できます。「エージェント監視のためだけに別の監視ツールを導入する」必要はありません。

6. Policy — エージェントの行動制御

Policyは、エージェントがどのツールを、どの条件で呼び出せるかを制御するコンポーネントです。2025年12月のre:Inventでプレビュー発表され、2026年3月にGAとなりました。

何を制御するのか ― 「行動」と「発言」の区別

ここで重要な区別があります。

制御対象 担当サービス
行動(Action) — どのツールを呼べるか AgentCore Policy 「返金APIは500ドル未満のみ許可」
発言(Expression) — 何を言えるか Amazon Bedrock Guardrails 「個人情報を含む応答をマスクする」

AgentCore Policyはツール呼び出しの制御に特化しています。エージェントの最終的な出力内容(PII漏洩防止、有害コンテンツのフィルタリングなど)は、別サービスであるAmazon Bedrock Guardrailsの担当領域です。両者は補完関係にあり、併用が推奨されています。

動作の仕組み

Policyの制御はLLMの推論ループの外側で、Gatewayと連携して決定論的に行われます。

エージェント → Gateway → Policy Engine → 許可/拒否を判定 → ツール実行
                              ↓
                     Cedar言語で定義されたルールを評価
                     (LLMに依存しない確定的な判定)
  1. エージェントがツール呼び出しリクエストを送信
  2. GatewayがPolicy Engineにルーティング
  3. Cedarポリシー(AWSのオープンソースポリシー言語)に基づき評価
  4. forbidルールにマッチ → 拒否
  5. permitルールにマッチ → 許可
  6. どちらにもマッチしない → 拒否(デフォルト拒否)

プロンプトに「○○してはいけない」と書くアプローチとは根本的に異なり、LLMが無視できないインフラレベルの強制力を持ちます。

具体的な制御の例

特定ツールの許可/拒否(ホワイトリスト方式):

自然言語で意図を記述すると、StartPolicyGeneration APIがCedarポリシーを自動生成します。

自然言語: 「返金エージェントは、返金処理ツールのみ実行を許可する。
            ただし返金額が500ドル未満の場合に限る」

パラメータ条件付き制御:

  • 「予約取得は UTC 9:00〜21:00 の間のみ許可する」
  • 「保険のカバレッジ変更は liability と collision タイプのみ許可する」
  • 「本番S3バケットからのオブジェクト削除は禁止する」

プリンシパルベースの制御:

OAuthトークンのクレームやスコープに基づき、呼び出し元のユーザーごとに異なるツールアクセス権を設定できます。

例: OAuthスコープ「insurance:claim」を持つユーザーのみ保険請求APIを実行可能

Enforce / Log-only モード

本番適用前にポリシーの影響を確認できるよう、Log-onlyモードが用意されています。実際にはブロックせずにログだけを出力するため、既存エージェントへのポリシー導入を段階的に進められます。

Bedrock Guardrailsとの併用

繰り返しになりますが、本番運用では両方を組み合わせるのがベストプラクティスです。

  • Policy: 「このエージェントは顧客データベースの読み取りのみ許可し、削除は一切禁止する」
  • Guardrails: 「応答に顧客の電話番号やメールアドレスが含まれる場合はマスクする」

Policyが「何をさせるか」を制御し、Guardrailsが「何を言わせるか」を制御する——この二層構造により、エージェントの自律性を活かしつつ安全性を確保できます。

7. Evaluations(Preview)— AWS完結のエージェント品質評価

エージェントの動作品質を、LangSmithやLangfuseなどのサードパーティツールなしで、AWS上で完結して評価できるコンポーネントです。2025年12月のre:Inventでプレビュー発表されました。

AWS内で完結する評価パイプライン

評価の全工程がAWSサービス内で閉じています。

エージェント実行 → OpenTelemetryトレース → CloudWatch → Evaluations → スコア → CloudWatchダッシュボード

外部の評価プラットフォームへのデータ送信は不要です。トレースデータの収集からスコアリング、結果の可視化まで、AgentCore + CloudWatchで完結します。

2つの評価モード

モード 用途 仕組み
On-demand 開発中・デプロイ前の品質確認 特定のセッションやトレースを指定して評価を実行
Online 本番環境の継続的な品質モニタリング サンプリングルール(例: セッションの10%)を設定し、本番トラフィックを自動評価

On-demandは「リリース前のゲート」、Onlineは「本番環境の品質監視」として使い分けます。

13の組み込み評価指標

LLM-as-a-Judge方式で、以下の観点からエージェントを評価します。

品質:

評価指標 評価レベル 概要
Builtin.Correctness トレース 回答の正確性
Builtin.Completeness トレース 回答の網羅性
Builtin.Faithfulness トレース 提供された情報に対する忠実性

ユーザー体験:

評価指標 評価レベル 概要
Builtin.Helpfulness トレース 回答の有用性
Builtin.Coherence トレース 回答の一貫性・論理性
Builtin.Relevance トレース 質問に対する関連性

エージェント固有:

評価指標 評価レベル 概要
Builtin.GoalSuccessRate セッション タスクを最後まで完遂できたか
Builtin.ToolSelectionAccuracy ツール呼び出し 適切なツールを選択できたか
Builtin.FollowingInstructions トレース システムプロンプトの指示に従えたか

特にGoalSuccessRateToolSelectionAccuracyは、エージェント特有の評価観点として重要です。チャットボットの評価では「回答の品質」だけを見れば十分ですが、エージェントでは「正しいツールを選び、タスクを完遂できたか」まで評価する必要があります。

カスタム評価指標の作成

組み込み評価指標で足りない場合は、独自の評価基準を定義できます。

import boto3

client = boto3.client("bedrock-agentcore-control")

response = client.create_evaluator(
    evaluatorName="domain_accuracy",
    level="TRACE",
    evaluatorConfig={
        "llmAsAJudge": {
            "modelConfig": {
                "bedrockEvaluatorModelConfig": {
                    "modelId": "global.anthropic.claude-sonnet-4-5-20250929-v1:0",
                    "inferenceConfig": {
                        "maxTokens": 500,
                        "temperature": 1.0,
                    },
                }
            },
            "instructions": (
                "以下のエージェント応答が、社内ナレッジベースの内容と"
                "整合しているか評価してください。\n"
                "コンテキスト: {context}\n"
                "エージェントの応答: {assistant_turn}"
            ),
            "ratingScale": {
                "numerical": [
                    {"value": 1.0, "label": "完全に整合", "definition": "..."},
                    {"value": 0.5, "label": "部分的に整合", "definition": "..."},
                    {"value": 0.0, "label": "不整合", "definition": "..."},
                ]
            },
        }
    },
)

Judge用のモデル、評価プロンプト、スコアリング基準をすべて自由に設定できます。

評価の実行例

from bedrock_agentcore_starter_toolkit import Evaluation

eval_client = Evaluation()
results = eval_client.run(
    agent_id="YOUR_AGENT_ID",
    session_id="YOUR_SESSION_ID",
    evaluators=[
        "Builtin.Helpfulness",
        "Builtin.GoalSuccessRate",
        "Builtin.ToolSelectionAccuracy",
    ],
)

for result in results.get_successful_results():
    print(
        f"{result.evaluator_name}: "
        f"Score={result.value:.2f}, "
        f"Label={result.label}"
    )

評価結果はCloudWatchのAgentCore Observabilityダッシュボードに集約され、スコアの推移やセッション単位の品質をドリルダウンで確認できます。

Bedrock Model Evaluationとの違い

AWS Bedrockには既存の「Model Evaluation」機能もありますが、対象が異なります。

観点 AgentCore Evaluations Bedrock Model Evaluation
対象 AIエージェントの動作全体 基盤モデル単体の品質
入力 実際のエージェント実行トレース プロンプト-レスポンスのデータセット
本番監視 対応(Onlineモード) 非対応(バッチ評価のみ)
用途 開発中〜本番の継続的品質改善 モデル選定時の比較評価

端的に言えば、Model Evaluationは「どのモデルを使うか」を決めるためのもの、AgentCore Evaluationsは「エージェントが本番で期待通りに動いているか」を監視するためのものです。

8. Browser — セキュアなブラウザランタイム

エージェントがWebブラウザ操作を行うための隔離された実行環境です。Webアプリケーションへのログイン、フォーム入力、データ収集など、ブラウザベースの複雑なワークフローをエージェントに委任できます。

9. Code Interpreter — サンドボックスコード実行

エージェントがPythonコードを安全に実行するための隔離環境です。データ分析、可視化の生成、計算処理などをエージェントが自律的に行えるようになります。

Bedrock Agentsとの使い分け

AgentCoreを理解する上で最も混乱しやすいのが、既存のAmazon Bedrock Agentsとの関係です。

両者の位置づけ

Bedrock AgentsとAgentCoreは、同じ「AIエージェント」という領域に対する補完的なアプローチです。Bedrock Agentsは設定ベースで素早くエージェントを構築できるフルマネージドサービス、AgentCoreは任意のフレームワーク・モデルで構築したエージェントを本番運用するためのインフラ基盤です。

┌──────────────────────────────────────────────────┐
│              AIエージェント構築・運用               │
│                                                  │
│  ┌─────────────────┐  ┌──────────────────────┐   │
│  │  Bedrock Agents  │  │  Bedrock AgentCore   │   │
│  │                 │  │                      │   │
│  │  設定ベース      │  │  コードベース         │   │
│  │  フルマネージド   │  │  柔軟なインフラ基盤    │   │
│  │  Bedrockモデル   │  │  任意のモデル         │   │
│  └─────────────────┘  └──────────────────────┘   │
│         ↑ シンプル          カスタマイズ性 ↑       │
└──────────────────────────────────────────────────┘

選択の指針

観点 Bedrock Agents Bedrock AgentCore
構築方法 コンソールやAPI設定で構築 任意のコードで自由に構築
対応モデル Bedrock上のモデル 任意のモデル(OpenAI, Gemini含む)
対応フレームワーク AWS独自 Strands, LangGraph, CrewAI, Google ADK, OpenAI Agents SDK等
カスタマイズ性 限定的 高い
運用負荷 低い(フルマネージド) 中程度(インフラは管理不要、設計は自由)
適するケース 標準的なRAG・ツール呼び出し 複雑なマルチエージェント、独自ロジック

端的に言えば:

  • 「早く動くものを作りたい」→ Bedrock Agents
  • 「自分たちのやり方で作って、本番で安全に動かしたい」→ AgentCore

両者は排他的ではなく、Bedrock Agentsで始めて、要件が複雑化した段階でAgentCoreの個別コンポーネントを活用する、という段階的な移行も可能です。

実践:Strands Agents × AgentCoreでエージェントをデプロイする

ここでは、AWSが公式に提供するオープンソースSDK「Strands Agents」とAgentCoreを組み合わせた基本的なデプロイ例を紹介します。

基本的なエージェントの定義とデプロイ

from strands import Agent
from bedrock_agentcore.runtime import BedrockAgentCoreApp

app = BedrockAgentCoreApp()

@app.entrypoint
def my_agent(input_text: str) -> str:
    agent = Agent(
        system_prompt="あなたはAWSの技術サポートアシスタントです。"
    )
    result = agent(input_text)
    return str(result)

@app.entrypointデコレータを付けるだけで、AgentCore Runtimeにデプロイ可能なエージェントになります。スケーリング、セッション分離、I/O待ち中のリソース最適化はRuntimeが自動的に処理します。

Memoryとの統合

from strands import Agent
from bedrock_agentcore.memory.integrations.strands import (
    AgentCoreMemorySessionManager,
)

# Memory設定
memory_config = {
    "memory_id": "support-agent-memory",
    "namespace": "customer-support",
}

session_manager = AgentCoreMemorySessionManager(
    config=memory_config,
    region_name="us-east-1",
)

# セッション管理付きエージェント
agent = Agent(
    system_prompt="あなたはカスタマーサポートエージェントです。過去のやり取りを踏まえて回答してください。",
    session_manager=session_manager,
)

AgentCoreMemorySessionManagerを渡すだけで、短期・長期記憶がエージェントに組み込まれます。

Gatewayによるツール登録

from bedrock_agentcore.gateway import GatewayClient

gateway = GatewayClient(region_name="us-east-1")

# MCPサーバーをツールとして登録
gateway.create_tool_source(
    name="internal-api",
    source_type="MCP",
    config={
        "endpoint": "https://mcp.example.com",
        "auth": {"type": "IAM"},
    },
)

MCPサーバーやREST API、Lambda関数をGatewayに登録すれば、エージェントから統一的にツールとして利用できます。

料金体系

AgentCoreは完全従量課金制で、前払いは不要です。

コンポーネント 課金体系 主な単価
Runtime 秒単位(CPU + メモリ) CPU: $0.0895/vCPU-h, Mem: $0.00945/GB-h
Gateway API呼び出し数 $0.005 / 1,000呼び出し
Memory イベント・記憶件数 短期: $0.25/1,000イベント, 長期: $0.75/1,000件
Browser 秒単位(CPU + メモリ) Runtimeと同体系
Code Interpreter 秒単位(CPU + メモリ) Runtimeと同体系

特筆すべきはRuntimeのI/O待ち中CPU非課金です。AIエージェントの実行時間はLLM推論待ちが大半を占めるため、この課金モデルは実質的に大幅なコスト削減になります。ECS/Fargateなどで自前運用する場合との比較では、ワークロードによっては数分の一のコストになり得ます。

まとめ

Amazon Bedrock AgentCoreは、「AIエージェントを作れるようになった」時代から「AIエージェントを安全に運用する」時代への橋渡しとなるサービスです。

押さえておくべきポイント:

  • AgentCoreはエージェントの運用インフラであり、特定のモデルやフレームワークに依存しない
  • 9つのコンポーネントを独立して、または組み合わせて利用できる
  • Bedrock Agentsとは補完関係——シンプルさのAgents、柔軟性のAgentCore
  • I/O待ち中のCPU非課金により、エージェント特有のワークロードに最適化されたコスト構造
  • Strands Agents等のOSSフレームワークとの組み合わせで、柔軟かつ本番品質のエージェント構築が可能

「PoCまでは動いたが、本番に持っていくとなると話が違う」——そう感じたことがあるなら、AgentCoreの各コンポーネントが解決しようとしている課題は、きっと身に覚えのあるものばかりでしょう。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?