Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

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

Avatar for つくぼし

つくぼし

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