$30 off During Our Annual Pro Sale. View Details »

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

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

つくぼし

June 16, 2024
Tweet

More Decks by つくぼし

Other Decks in Technology

Transcript

  1. 2 自己紹介 ★ ハンドルネーム ◦ つくぼし ★ 所属 ◦ AWS事業本部コンサルティング部

    ◦ ソリューションアーキテクト ★ 最近ハマっているAWSサービス ◦ AWS Application Composer ★ SNS/ブログ ◦ X(@tsukuboshi0755) ◦ DevelopersIO(つくぼし)
  2. 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
  3. 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} """
  4. 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 ""
  5. 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<CloudFormationテンプレート> \n{yaml_content} \n\n<エラーメッセージ> \n{cfn_err} """
  6. 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<CloudFormationテンプレート> \n```yaml \n{yaml_content} \n``` """
  7. 20 Claudeは仕事を代替できるのか?(個人的感想) • 現時点では全てが代替されるという事はなさそう ◦ 個人的には70-80%くらいの完成度ならできそう、一方で90%以上の正確さを求め るのは正直厳しい印象 ◦ 与えられるインプット(構成図)も完璧ではないので、何かとブレは生じがち •

    Claudeの特性をアプリ側の処理で上手く補助すると、求めるものにより近 づける事ができる ◦ 動的なプロンプトの生成 ◦ 会話履歴を用いたテンプレートのフォーマットと連結 ◦ エラーを考慮したレビューとバリデーションの繰り返し ◦ サンプルファイルを元にしたパラメータシート生成
  8. 23