Amazon Q Developer CLI で構成をレビューするエージェントを作ってみる

記事タイトルとURLをコピーする

はじめに

Amazon Q Developer CLI のカスタムエージェントを利用して、Backlog Wiki で管理する詳細設計書の内容が実リソースに反映されているかを確認する作業をエージェントにオフロードする1例を紹介します。

カスタムエージェントの内容については、下記ブログを参照ください。

blog.serverworks.co.jp

また、本ブログはすでに Amazon Q Developer CLI がインストールされ、対話が開始できる前提で記載されています。インストールがまだの方は、下記ブログを参照ください。

blog.serverworks.co.jp

カスタムエージェントを作成する

以下のコマンドを実行し、Q の対話モードに入ります。その後、カスタムエージェントを現在のディレクトリで作成します。

$ q
...
> /agent create --name project-1-agent --directory .

次回からはカスタムエージェントを指定して起動するため、対話モードを抜けておきます。

> /quit

シェルに戻り現在のディレクトリを表示すると、エージェント設定用のディレクトリがカレントディレクトリに作成されていることが確認できます。

$ ls -a
.  ..  .amazonq

エージェントに渡すコンテキストを準備する

context ディレクトリを作り、そこにエージェントに渡すマークダウン形式のコンテキストを配置します※。

$ tree context
context
├── CONFIG.md
└── PROJECT_1.md

それぞれ以下のような内容を記載しています。

CONFIG.md

# 対象 Backlog Project のキー
PROJECT_1

PROJECT_1.md

# 構成レビュー観点
Backlog Wiki に記載された設計レビューの指示があった場合、以下の観点を考慮してください。

## 必須要件
- 2つ以上のAZで冗長化されている
- 東京リージョンと大阪リージョンでDR対策が講じられている

※ ディレクトリ名やファイルは独自で準備したもので、Q の制限や制約に従っているわけではありません。

カスタムエージェントを設定する

ここまでの操作で .amazonq/cli-agents/project-1-agent.json が作成されています。

エージェント設定ファイルの各項目については カスタムエージェント構成要素 を参照ください。

JSON ファイルの内容を以下に編集します。

{
  "$schema": "https://raw.githubusercontent.com/aws/amazon-q-developer-cli/refs/heads/main/schemas/agent-v1.json",
  "name": "project-1-agent",
  "description": "",
  "prompt": null,
  "mcpServers": {
      "backlog-wiki": {
          "command": "bash",
          "env": {
              "FASTMCP_LOG_LEVEL": "DEBUG"
          },
          "args": [
              "-lc",
              "uv --directory \"$(realpath mcp_servers)\" run backlog_wiki_mcp.py"
          ]
      }
  },
  "tools": [
    "*"
  ],
  "toolAliases": {},
  "allowedTools": [
    "fs_read"
  ],
  "resources": [
    "file://AmazonQ.md",
    "file://README.md",
    "file://context/CONFIG.md",
    "file://context/PROJECT_1.md",
    "file://.amazonq/rules/**/*.md"
  ],
  "hooks": {},
  "toolsSettings": {},
  "useLegacyMcpJson": true
}

ここでは独自定義したコンテキストを resources セクションに追加しました。

また、MCP サーバーの設定を追加しました。ここでは Backlog の Wiki データを取得する MCP サーバーを実装しています。以下に記載するように、Nulab 社により MCP サーバーが提供されていますが、Wiki だけを扱う機能に絞りたく、今回は簡易的に独自実装しました。

nulab.com

以下は MCP サーバーの実装の一部抜粋です。

from fastmcp import FastMCP
import requests
from typing import List, Dict, Optional, Any
import os
from dotenv import load_dotenv

# .env ファイルから環境変数を読み込む
load_dotenv()

mcp = FastMCP("Backlog Wiki")

# 環境変数から設定を読み込む
BACKLOG_SPACE = os.environ.get("BACKLOG_SPACE", "")
BACKLOG_API_KEY = os.environ.get("BACKLOG_API_KEY", "")
BACKLOG_BASE_URL = f"https://{BACKLOG_SPACE}.backlog.com/api/v2"

def _get_headers():
    """APIリクエスト用のヘッダーを取得"""
    return {
        "Content-Type": "application/json"
    }

def _make_request(endpoint: str, params: Dict[str, Any] = None) -> Dict:
    """
    Backlog APIにリクエストを送信する共通関数
    
    Args:
        endpoint: APIエンドポイント(/api/v2/ 以降の部分)
        params: リクエストパラメータ
    
    Returns:
        APIレスポンス(JSON)
    """
    if params is None:
        params = {}
    
    # APIキーをパラメータに追加
    params["apiKey"] = BACKLOG_API_KEY
    
    url = f"{BACKLOG_BASE_URL}/{endpoint}"
    response = requests.get(url, params=params, headers=_get_headers())
    
    if response.status_code == 200:
        return response.json()
    elif response.status_code == 400 and "Undefined resource" in response.text:
        # リソースが存在しない場合は空の配列を返す
        print(f"Warning: Resource not found or empty: {endpoint}")
        return []
    else:
        raise Exception(f"API request failed: {response.status_code} - {response.text}")

@mcp.tool()
def get_wiki_page(wiki_id: str) -> Dict:
    """
    特定のWikiページの内容を取得する
    
    Args:
        wiki_id: WikiページのID
    
    Returns:
        Wikiページの詳細情報(内容、作成者、更新日時など)
    """
    endpoint = f"wikis/{wiki_id}"
    return _make_request(endpoint)

カスタムエージェントを起動して構成チェックする

Backlog Wiki の取得

詳細設計書の内容が正しく環境に反映されているかを確認します。

エージェントを起動して Backlog Wiki に記載されている詳細設計の内容を読み込みます。

$ q chat --agent project-1-agent
...
[project-1-agent] > 詳細設計書をリストしてください。

以下は返答の抜粋です。

> プロジェクトの詳細設計書をリストするために、まず現在のディレクトリ構造を確認します。

...

> プロジェクト「PROJECT_1」の詳細設計書一覧を取得しました。以下が詳細設計書のリストです:

## 詳細設計書一覧

### メインドキュメント
• **ドキュメント/詳細設計書** (ID: 1234330)

### Global リソース
• **ドキュメント/詳細設計書/global/route53** (ID: 1234397)
• **ドキュメント/詳細設計書/global/cloudfront** (ID: 1234399)

### North Virginia リージョン
• **ドキュメント/詳細設計書/north-virginia/s3** (ID: 1234410)
• **ドキュメント/詳細設計書/north-virginia/acm** (ID: 1234413)

### 大阪リージョン
• **ドキュメント/詳細設計書/osaka/vpc** (ID: 1234419)
• **ドキュメント/詳細設計書/osaka/target-group** (ID: 1234424)
• **ドキュメント/詳細設計書/osaka/subnets** (ID: 1234429)
• **ドキュメント/詳細設計書/osaka/security-groups** (ID: 1234431)

Backlog Wiki には詳細設計以外にも議事録や運用手順書が含まれますが、詳細設計に関わる Wiki のみリストされました。

実環境のチェック

[project-1-agent] > ネットワーク回りの設定が適切にされているか、実リソースをチェックしてください。

以下はエージェントの初回の返答です。初めに詳細設計に関連する Wiki を取得しているため、エージェントはネットワーク関連の Wiki の ID を把握しています。その ID をもとに Wiki の内容を取得するために、get_wiki_page メソッドを実行しようとしています。

> ネットワーク関連のリソースについて、設計書の内容を確認します。主要なネットワークコンポーネントを順次チェック
していきます。

## 1. VPC設計の確認

### Tokyo リージョン


🛠️  Using tool: get_wiki_page from mcp server backlog-wiki
 ⋮ 
 ● Running get_wiki_page with the param:
 ⋮  {
 ⋮    "name": "get_wiki_page",
 ⋮    "arguments": {
 ⋮      "wiki_id": "1234453"
 ⋮    }
 ⋮  }

Allow this action? Use 't' to trust (always allow) this tool for the session. [y/n/t]:

[project-1-agent] > t

また、実リソースのデータをクエリするために Q がデフォルトで持っている use_aws ツールを使用してリソース情報を取得する API を実行しようとします。

> 設計書から東京リージョンのネットワーク情報を確認しました。次に実際のAWSリソースと照合します。


🛠️  Using tool: use_aws (trusted)
 ⋮ 
 ● Running aws cli command:

Service name: ec2
Operation name: describe-vpcs
Parameters: 
- vpc-ids: ["vpc-0fdf6cb94b29xxxxxxxx"]
Region: ap-northeast-1
Label: 東京リージョンVPC確認
 ⋮ 
 ● Execution failed after 1.971s:

An error occurred (InvalidVpcID.NotFound) when calling the DescribeVpcs operation: The vpc ID 'vpc-0fdf6cb94b296d5de' does not exist

この結果からわかるように、設計書に記載されているリソースが構築されていないことが示唆されました(実際にリソースは構築されていません)。

まとめ

前章でみたように、構築すべきものができていなかったり、命名や各種設定値が設計書と異なる場合には、エージェントを活用することによりその差異をレポートする作業負荷を削減することができるかもしれません。自然言語により設計書の内容をクエリして、レビューする体験も良かったです。

2021年4月新卒入社。目に見えて、動かせるものが好き。