Slide 1

Slide 1 text

AWS構成図から
 CloudFormationとパラメータシートを
 自動生成するシステムを作ってみた
 1 2024.6.18
 
 Bedrock Claude Night 2


Slide 2

Slide 2 text

2 自己紹介 ★ ハンドルネーム ○ つくぼし ★ 所属 ○ AWS事業本部コンサルティング部 ○ ソリューションアーキテクト ★ 最近ハマっているAWSサービス ○ AWS Application Composer ★ SNS/ブログ ○ X(@tsukuboshi0755) ○ DevelopersIO(つくぼし)

Slide 3

Slide 3 text

3 はじめに

Slide 4

Slide 4 text

4 生成AIではメジャーモデルとして挙げられるClaude ● 日本語の文章生成能力が高いと評判 ● 多種多様なモデルの中でも最上級のパフォーマンス ● 画像認識(Vision)にも対応

Slide 5

Slide 5 text

5 メジャーなモデルであるClaudeは エンジニアの仕事をどこまで奪えるのか?

Slide 6

Slide 6 text

6 やってみよう! 自己流のAIクラウドエンジニア を作ってみました

Slide 7

Slide 7 text

7 AIクラウドエンジニアに任せる事 1. 事前にAWS構成図を作成しpngファイルとして与える 2. その構成図に沿ったCloudFormationテンプレートを出力 3. CloudFormationテンプレートに沿ったパラメータシートを出力

Slide 8

Slide 8 text

8 AIクラウドエンジニアの解説

Slide 9

Slide 9 text

9 構成図

Slide 10

Slide 10 text

10 システムプロンプトの生成 ● CFnテンプレートの内容が最大 トークン数以上になる場合でも 回答可能にする処理 ● 最大トークン数を取得し、その 80%となるトークン数を計算 ● プロンプト内で指定したトークン 数の80%以上になったら回答を 分割するよう指示 def create_system_prompt() -> str: max_token = int(os.environ["MAX_TOKEN"]) eighty_percent_token = int(max_token / 10 * 8) system_prompt = f""" \n回答は以下の条件全てを満たすようにしてください: \n- 必ず回答で出力するCloudFormationテンプレート(yaml形式)の先頭 は"```yaml"、末尾は"```"とする。 \n- 必要に応じて補足を付与したい場合は、回答で出力するCloudFormationテン プレート内に#を付けてコメントとして記載する。 \n- もし回答が{eighty_percent_token}トークンを超えたら、{max_token} トークンに達するまでに一旦回答を分割し、ユーザーが「続き」と入力したら続きの 回答を作成する。 """ logger.info("System Prompt: %s", system_prompt) return system_prompt

Slide 11

Slide 11 text

11 ユーザープロンプトの生成 ● 存在しないリソースタイプを用い てテンプレートが生成されないよ う回答させる処理 ● CFn ListTypes APIを用いて、 AWS::から始まるリソースタイプ リストを取得 ● プロンプト内で取得したリソース タイプ以外のものを使用しない よう指示 # 一部省略 def generate_yaml(system_prompt: str, tmp_image_path: str) -> Any: while True: response = cfn.list_types( Visibility="PUBLIC", **({"NextToken": next_token} if next_token else {}) ) type_summaries.extend(response["TypeSummaries"]) next_token = response.get("NextToken") if not next_token: break type_list = [ summary["TypeName"] for summary in type_summaries if summary["TypeName"].startswith("AWS::") ] first_generate_text = f""" (中略) \n- 以下の<リソースタイプリスト>に存在しないリソースタイプは、回答で出力 するCloudFormationテンプレートのリソースタイプとして使用してはいけない。 \n\n<リソースタイプリスト> \n{type_list} """

Slide 12

Slide 12 text

12 YAMLフォーマットと会話履歴によるファイル連結 ● Claudeで生成された回答の 内、YAML内容のみを抜き出し て正しく連結する処理 ● Claudeが生成した回答から YAMLファイルの箇所のみを抽 出し、改行を入れて連結 ● 次のYAML量が最初の80%を超 える場合のみ、Claudeへの質 問・抽出・連結を繰り返す # 一部省略 for yaml_count in range(max_yaml_count): next_res_message = request_bedrock(model_id, messages, next_content_text, system_prompt) next_row_content = next_res_message["content"][0]["text"] logger.info(f"Next Response {yaml_count}: %s", next_row_content) next_yaml_content = format_yaml(next_row_content) yaml_content += "\n" + next_yaml_content next_yaml_length = len(next_yaml_content) if next_yaml_length > eighty_percent_first_yaml_length: messages.append(next_res_message) else: break def format_yaml(row_content: str) -> str: match = re.search(r"```yaml\n(.*?)\n```", row_content, re.DOTALL) if match: response_text = match.group(1) return response_text else: return ""

Slide 13

Slide 13 text

13 CFnテンプレートとしてのレビューとバリデーション ● バリデーション結果が正常とな るまで、テンプレートをClaudeで レビューさせる処理 ● CFn ValidateTemplate APIを用 いて、テンプレートにエラーがな いか確認 ● エラーがある場合のみエラー メッセージを含めて、Claudeに 繰り返しレビューさせる # 一部省略 def lambda_handler(event: Dict[Any, Any], context: Any) -> Dict[str, Any]: for review_count in range(max_review_count): logger.info(f"Validation Status: {status}") if status == "normally": break else: reviewed_yaml = review_yaml( system_prompt, tmp_image_path, target_yaml, cfn_res ) status, cfn_res = cfn_validate(reviewed_yaml) target_yaml = reviewed_yaml def review_yaml(system_prompt: str, tmp_image_path: str, yaml_content: str, cfn_err: Any) -> Any: first_review_text = f""" \nもしエラーメッセージが何かしら追加で提示されている場合は、エラーを解消 できるように更新したテンプレートを全て出力してください。 \n\n \n{yaml_content} \n\n<エラーメッセージ> \n{cfn_err} """

Slide 14

Slide 14 text

14 サンプルCSVを元にしたパラメータシート生成 ● 事前に与えたCSVファイルとテ ンプレートを元にパラメータシー トを生成する処理 ● CSVファイルには生成したい表 形式のサンプル項目を事前に記 載 ● プロンプト内で取得したCSVファ イルの形式を参考にするよう指 示 # 一部省略 def request_bedrock(tmp_template_path: str) -> Any: with open(prompt_path, "rt") as csv_file: complement_prompt = csv_file.read() content_text = f""" \n\nHuman: \n<質問> \n提示されたサンプルパラメータシートの形式を参考にしながら、提示された CloudFormationテンプレートを反映するパラメータシート(CSV形式)を作成してく ださい。 \nパラメータシートには、以下の条件全てを満たすようにしてください: \n- 必要なすべてのリソースとそれらの設定を含める \n- テンプレートに基づきリソース間の依存関係や参照を適切に記載する \n\n<サンプルパラメータシート> ```csv {complement_prompt} ``` \n\n \n```yaml \n{yaml_content} \n``` """

Slide 15

Slide 15 text

15 AIクラウドエンジニアの紹介デモ

Slide 16

Slide 16 text

16 入力する構成図の例

Slide 17

Slide 17 text

17 生成されたテンプレート(Application Composerより)

Slide 18

Slide 18 text

18 生成されたパラメータシート

Slide 19

Slide 19 text

19 最後に

Slide 20

Slide 20 text

20 Claudeは仕事を代替できるのか?(個人的感想) ● 現時点では全てが代替されるという事はなさそう ○ 個人的には70-80%くらいの完成度ならできそう、一方で90%以上の正確さを求め るのは正直厳しい印象 ○ 与えられるインプット(構成図)も完璧ではないので、何かとブレは生じがち ● Claudeの特性をアプリ側の処理で上手く補助すると、求めるものにより近 づける事ができる ○ 動的なプロンプトの生成 ○ 会話履歴を用いたテンプレートのフォーマットと連結 ○ エラーを考慮したレビューとバリデーションの繰り返し ○ サンプルファイルを元にしたパラメータシート生成

Slide 21

Slide 21 text

21 まとめ AIクラウドエンジニアに仕事を任せて サボれるようになりたい!

Slide 22

Slide 22 text

22 宣伝 6/28(金)〜7/31(水)で社外イベントやります 生成AI関連のオンライン登壇ももりだくさん!

Slide 23

Slide 23 text

23