Kiro Powersのパワーは如何に

こんにちは!POSSEでエンジニアインターンをしている井上岳です。

最近CDKを実装する機会が多く、AIを使いながら実装していますが、最新の情報をインプットしたうえでの実装はなかなかやってくれないものです。自分の勉強不足ではあるのですが、AIを使いながら、成果も出しながら、勉強もしながらできないかなぁと思っていたところ、Kiro Powersというものがあると知ったので試してみました。

Kiro Powersとは

Kiro Powersとは、Kiroの機能を拡張するためのプラグインシステムで、MCP(Model Context Protocol)サーバー、ステアリングファイル(指示・ルールファイル)、フックなどを1つのパッケージにまとめたものです。

Kiro powers の紹介 | Amazon Web Services
AI アシスタントは、フレームワークの専門知識への即座のアクセスを提供し、より速くリリースできるようにすべきです。しかし、今日の AI エージェントも同じ課題に直面しています。組み込みの知識がなければ、あなたと同じように推測と反復を繰り返します。Kiro powers は、幅広い開発とデプロイメントのユースケースに対して、その統一されたアプローチを提供します。MCP ツールとフレームワークの専門知識を一緒にパッケージ化し、動的に読み込みます。

従来は個別に設定が必要だった外部ツールとの連携やプロジェクトのルール設定を、インストールするだけで一括してセットアップできます。

主な特徴とメリット

  1. コンテキスト問題の解消(動的読み込み):従来のMCPサーバーは全てのツールを事前に読み込むため、AIの記憶領域(コンテキスト)を圧迫する課題がありました。Kiro Powersは、プロンプトに含まれる「キーワード」を検知したときだけ必要な機能を動的に読み込むため、効率的なコンテキストの利用が可能です。
  2. 専門知識の即時活用:汎用的なAIの回答ではなく、FigmaやTerraformといった各サービス固有の最新ベストプラクティスに基づいた、精度の高いコード生成が可能になります。
  3. セットアップの自動化:インストールすると、必要なディレクトリ構成やMCP設定が自動で行われ、AIエージェントによるオンボーディング(初期設定の自動実行)が開始されます。
  4. 将来的なクロス互換性:現在はKiro IDE専用ですが、将来的にはCursorやClaude Code、Clineといった他の主要なAI開発ツールでも動作する標準規格を目指して開発されています。

今回使うKiro Powers 💪

今回はCDKの実装のため、Build AWS infrastructure with CDK and CloudFormationを使ってみました!

環境構築

まず最新のバージョンにアップデートすることをお忘れなく!

次に、Kiro IDEの左サイドバーからPowes(⚡が付いた可愛いKiroマーク)を選択し、Build AWS infrastructure with CDK and CloudFormationをインストールします。

インストールはすぐに完了します。ノーマルKiroアイコンをクリックしてインストールされたかどうか確認することができます。

9個のツールが提供されていることがわかりますね。

次に、Try Powerボタンを押してチュートリアルを開始してみましょう。

こんな感じでチュートリアルが始まります。

概要
aws-infrastructure-as-code パワーは、CDK と CloudFormation を使用して AWS インフラストラクチャを構築し、検証するのに役立ちます。このパワーには以下の機能があります。

CDK 開発:
- 最新の CDK ドキュメントと API リファレンスを検索
- TypeScript、Python、Java、C#、Go で動作するコードサンプルを見つける
- セキュリティとアーキテクチャに関する包括的なベストプラクティスを入手する
- 完全なコンストラクト ドキュメントを読む

CloudFormation 検証:
- テンプレートの構文とスキーマを検証 (cfn-lint)
- AWS Guard ルールに対するセキュリティコンプライアンスをチェック (cfn-guard)
- デプロイ前の検証ガイダンスを入手する

トラブルシューティング:
- パターンマッチングによる CloudFormation デプロイの失敗を分析
- 詳細な調査のための CloudTrail ディープリンクを入手する
- エラー解決のために CloudFormation ドキュメントを検索する

オンボーディング
朗報です!ほとんどの機能は AWS クレデンシャルなしで動作します。クレデンシャルが必要なのは、CloudFormation デプロイの失敗をトラブルシューティングする場合のみです。

これで環境構築は完璧です!!

実際に使ってみる

今回は、Step Functionsの実装で使ってみたいと思います。

なんでStep Functionsをやってみたいかというと、先日あるAIにCDKの実装をお願いしたところ、ASL(Amazon States Language) で実装されてしまい複雑なコードになってしまいました。(自分が指示してないのが悪いですが、、)

これまでStep FunctionsではASLを用いて定義するのが主流だったので、そのデータをたくさん学習していてそうなったのかなと思います。

AWSのドキュメントでは、Step Functionsでは、ASLではなくJSONataの利用が推奨されています。

Step Functions での JSONata を使用したデータ変換 - AWS Step Functions
JSONata を使用すると、ステート間でデータを変換できます。

Build AWS infrastructure with CDK and CloudFormationを使ったら、指示しなくてもJSONataで実装してくれるのでは??と思い試してみることにしました。

こんな指示を与えてみた

I want to create an AWS Step Function using AWS CDK (TypeScript). The workflow should take an input list of 'orders', filter only the orders where 'status' is 'PAID', and then calculate the total sum of all 'price' fields in those paid orders. Please implement this data transformation directly within the Step Function definition without using an external Lambda function.
AWS CDK (TypeScript) を使用して AWS Step Functions を作成したいと考えています。ワークフローは、「orders」の入力リストを受け取り、「status」が「PAID」の注文のみをフィルタリングし、その後、それらの支払済み注文のすべての「price」フィールドの合計を計算します。このデータ変換を、外部の Lambda 関数を使用せずに、Step Functions の定義内で直接実装してください。

Kiroの応答を見ると、search_cdk_documentationsearch_cdk_samples_and_constructs read_iac_documentation_page を実行していることがわかります。

それぞれ何をしているのか

  1. search_cdk_documentation:AWS CDKの公式ドキュメントを検索する。

検索対象:

  • AWS CDK API リファレンス
  • AWS CDK ベストプラクティスガイド
  • AWS CDK コードサンプル&パターン
  • CDK-NAG バリデーションルール(セキュリティチェック)

使用例:

search_cdk_documentation({
  query: "Lambda function with DynamoDB"
})

返ってくる情報:

  • ドキュメントのタイトル
  • URL
  • 関連するコンテンツの抜粋
  • ランキング(関連度順)

いつ使う?

  • CDKコンストラクトのAPIや使い方を調べたい時
  • 特定のAWSサービスの統合方法を知りたい時
  • ベストプラクティスを確認したい時

2. search_cdk_samples_and_constructs:実際に動作するCDKのコードサンプルとコミュニティ製のコンストラクトを検索する。

検索対象:

  • CDKコードサンプル(実装例)
  • コミュニティコンストラクト
  • 実装パターン
  • 完全なCDKアプリケーション例

対応言語:

  • TypeScript(デフォルト)
  • Python
  • Java
  • C#
  • Go

使用例:

search_cdk_samples_and_constructs({
  query: "Lambda DynamoDB CRUD",
  language: "typescript"
})


返ってくる情報:

  • サンプルコードのタイトル
  • GitHubなどのURL
  • コードの抜粋
  • 実装パターンの説明

いつ使う?

  • 実際のコード例を見たい時
  • 特定のユースケースの実装方法を知りたい時
  • L3コンストラクト(高レベルな抽象化)を探している時

3. read_iac_documentation_page:AWSドキュメントの特定のページを取得して、マークダウン形式に変換するツール。

対応URL:

  • docs.aws.amazon.com
  • aws.amazon.com
  • GitHub(aws-samples、awslabs など)
  • constructs.dev

使用例:

read_iac_documentation_page({
  url: "https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda-readme.html"
})

返ってくる情報:

  • ページの完全なコンテンツ(マークダウン形式)
  • 目次(Table of Contents)
  • コードブロック
  • 表やリスト

特徴:

  • 長いドキュメントは分割して取得可能
  • start_index パラメータで続きを読める
  • 最大文字数を指定可能

いつ使う?

  • 検索結果から特定のページの詳細を読みたい時
  • コンストラクトの完全なAPIリファレンスが必要な時
  • 長いガイドを段階的に読みたい時

今回のStep Functions実装では以下のように使われた

  1. search_cdk_documentation
  • "Step Functions Map state filter transform data" を検索
  • JSONataの使い方に関するドキュメントを発見

2. search_cdk_samples_and_constructs

  • "Step Functions JSONata filter array transform" を検索
  • TypeScriptでの実装例を探索

3. read_iac_documentation_page

  • https://docs.aws.amazon.com/step-functions/latest/dg/transforming-data.html を読み込み
  • JSONataの詳細な使い方とフィルタリング例を取得

最終的に実装されたStackは以下です。

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as sfn from 'aws-cdk-lib/aws-stepfunctions';
import * as logs from 'aws-cdk-lib/aws-logs';

export class OrderProcessingStepFunctionStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const logGroup = new logs.LogGroup(this, 'StateMachineLogGroup', {
      logGroupName: '/aws/vendedlogs/states/order-processing',
      retention: logs.RetentionDays.ONE_WEEK,
      removalPolicy: cdk.RemovalPolicy.DESTROY,
    });

    const filterPaidOrders = new sfn.Pass(this, 'FilterPaidOrders', {
      comment: 'Filter orders to include only those with status=PAID',
      parameters: {
        'paidOrders.$': "$.orders[status='PAID']",
      },
    });

    const calculateTotal = new sfn.Pass(this, 'CalculateTotal', {
      comment: 'Calculate the sum of all paid order prices',
      parameters: {
        'paidOrders.$': '$.paidOrders',
        'totalPrice.$': '$sum($.paidOrders[].price)',
      },
    });

    const formatOutput = new sfn.Pass(this, 'FormatOutput', {
      comment: 'Format the final output with all required fields',
      parameters: {
        'paidOrders.$': '$.paidOrders',
        'totalPrice.$': '$.totalPrice',
        'orderCount.$': '$count($.paidOrders)',
      },
    });

    const definition = filterPaidOrders
      .next(calculateTotal)
      .next(formatOutput);

    const stateMachine = new sfn.StateMachine(this, 'OrderProcessingStateMachine', {
      stateMachineName: 'OrderProcessingStateMachine',
      definitionBody: sfn.DefinitionBody.fromChainable(definition),
      logs: {
        destination: logGroup,
        level: sfn.LogLevel.ALL,
        includeExecutionData: true,
      },
      tracingEnabled: true,
    });

    new cdk.CfnOutput(this, 'StateMachineArn', {
      value: stateMachine.stateMachineArn,
      description: 'ARN of the Order Processing State Machine',
      exportName: 'OrderProcessingStateMachineArn',
    });

    new cdk.CfnOutput(this, 'StateMachineName', {
      value: stateMachine.stateMachineName,
      description: 'Name of the Order Processing State Machine',
      exportName: 'OrderProcessingStateMachineName',
    });
  }
}

コード解説

FiterPaidOrdersステート

const filterPaidOrders = new sfn.Pass(this, 'FilterPaidOrders', {
  comment: 'Filter orders to include only those with status=PAID',
  parameters: {
    'paidOrders.$': "$.orders[status='PAID']",
    //         ↑ .$サフィックス = JSONPath式として評価
  },
});

JSONPath式: "$.orders[status='PAID']"

  • $ = 入力データのルート
  • .orders = ordersフィールドにアクセス
  • [status='PAID'] = statusが'PAID'の要素のみをフィルタ

動作

// 入力
{
  "orders": [
    {"orderId": "1", "status": "PAID", "price": 100},
    {"orderId": "2", "status": "PENDING", "price": 50},
    {"orderId": "3", "status": "PAID", "price": 200}
  ]
}

// 出力
{
  "paidOrders": [
    {"orderId": "1", "status": "PAID", "price": 100},
    {"orderId": "3", "status": "PAID", "price": 200}
  ]
}

CalculateTotal ステート

const calculateTotal = new sfn.Pass(this, 'CalculateTotal', {
  comment: 'Calculate the sum of all paid order prices',
  parameters: {
    'paidOrders.$': '$.paidOrders',
    //         ↑ 前のステートの出力を参照
    'totalPrice.$': '$sum($.paidOrders[].price)',
    //         ↑ JSONata集約関数を使用
  },
});

JSONata式: '$sum($.paidOrders[].price)'

  • $sum() = JSONata集約関数(合計を計算)
  • $.paidOrders[] = paidOrders配列の全要素
  • .price = 各要素のpriceフィールドを抽出

動作

// 入力
{
  "paidOrders": [
    {"orderId": "1", "status": "PAID", "price": 100},
    {"orderId": "3", "status": "PAID", "price": 200}
  ]
}

// 出力
{
  "paidOrders": [...],
  "totalPrice": 300  // 100 + 200
}

FormatOutput ステート

const formatOutput = new sfn.Pass(this, 'FormatOutput', {
  comment: 'Format the final output with all required fields',
  parameters: {
    'paidOrders.$': '$.paidOrders',
    'totalPrice.$': '$.totalPrice',
    'orderCount.$': '$count($.paidOrders)',
    //         ↑ JSONata関数で配列の長さを取得
  },
});

JSONata式: '$count($.paidOrders)'

  • $count() = JSONata関数(配列の要素数を返す)
  • $.paidOrders = paidOrders配列を参照

動作

// 入力
{
  "paidOrders": [
    {"orderId": "1", "status": "PAID", "price": 100},
    {"orderId": "3", "status": "PAID", "price": 200}
  ],
  "totalPrice": 300
}

// 出力
{
  "paidOrders": [...],
  "totalPrice": 300,
  "orderCount": 2  // 配列の長さ
}

まとめ

今回は、Build AWS infrastructure with CDK and CloudFormation というKiro Powersを使ってみました。ベストプラクティスをもとに実装を進めてくれるので、AWS関連のタスクを行うのに最適だなと思いました。また、チャットを見て、Kiro Powersが調査したものをもとに勉強すると、AIを使いながら、成果を出しながら、勉強しながらやっていけるのではないかと思いました。これからもっと使っていきたいと思います!