🤠

LLMエージェントのインタラクションによるweb開発

2024/08/01に公開

はじめに

人工知能技術の急速な発展により、ChatGPTやClaudeなどの大規模言語モデル(LLM)がソフトウェア開発の現場で用いられています。私自身も、これらのLLMを活用してプロジェクトの要件定義やフレームワークの構築を行うようになりました。
しかし、LLMの活用には課題もあります。AIの初期出力は必ずしも完璧ではなく、開発者との対話を通じて徐々に改善していきます。この過程は時間と労力を要し、LLMの能力を最大限に引き出せていない可能性があります。
そこで本記事では、複数のLLMエージェントを作成し、それらのエージェント同士が自律的にインタラクションを行うシステムを構築することで、開発者との対話回数を最小限に抑えつつ、高精度なweb開発を実現できるかを検証しました。
また今回のLLMモデルは、Anthropicのclaude-3-sonnet-20240229を用いました。

結果だけ見たい方はこちら
https://yuyamada0917.github.io/agent-design/

プログラムを見たい方はこちら
https://github.com/YuYamada0917/agent-design

マルチLLMエージェントシステムの概要

従来のLLM利用

通常、ユーザーとLLMの対話は以下のように一対一の関係で行われます。質問と回答を繰り返すことで、徐々に望ましい出力を得ていきます。

構築したマルチエージェントシステム

これに対し、複数のLLMエージェントが相互にインタラクションする、より複雑で効率的な以下のシステムを構築しました。このシステムにより、ユーザーの介入を最小限に抑えつつ、多角的な視点から高品質なWeb開発を実現することができます。

  1. ユーザー → コンサルタント
    役割:要件のヒアリング
    内容:ユーザーのニーズや目的を詳細に聞き取る

  2. コンサルタント → プログラマ:
    役割:プロンプト生成
    内容:ヒアリング結果をもとに、具体的な開発指示を作成

  3. プログラマ → 評価エージェント(デザイナー・ライター・アクセシビリティチェッカー)
    役割:Webページのプログラム提示
    内容:HTML、CSS、JavaScriptを含む完全なWebデザインを生成

  4. 評価エージェント → プログラマ
    役割:多角的評価とフィードバック
    内容:それぞれの専門分野(デザイン、コンテンツ、アクセシビリティ)から評価し、改善点を提案

  5. プログラマ → ユーザー
    役割:最終出力の表示
    内容:改善を重ねた最終的なWebデザインを提示

この流れでweb開発を行いました。各評価エージェント(デザイナー・ライター・アクセシビリティチェッカー)が個別に採点を行い、合計スコアが目標値を超えるまで、ステップ3,4が繰り返されます。

エージェントの設定

コンサルタントエージェント

以下の7項目をヒアリングし、その結果を反映させた指示(プロンプト)をプログラマエージェントに送ります。

  1. Webサイトの目的は何ですか?
  2. ターゲット層はどのような人たちですか?
  3. 含めたい主な機能やセクションは何ですか?
  4. 好みのデザインスタイル(例:モダン、ミニマリスト、カラフル)はありますか?
  5. 希望する色合いはありますか?
  6. その他、デザインに関して伝えたいことがあれば教えてください
  7. webページの言語は何にしますか?
プログラム
import anthropic
import config


class ConsultantAgent:
    def __init__(self):
        self.client = anthropic.Anthropic(api_key=config.ANTHROPIC_API_KEY)

    def generate_prompt(self):
        print("Webデザインの要件を聞き取ります。以下の質問にお答えください。")

        purpose = input("1. Webサイトの目的は何ですか?: ")
        target_audience = input("2. ターゲット層はどのような人たちですか?: ")
        key_features = input("3. 含めたい主な機能やセクションは何ですか?: ")
        style_preference = input("4. 好みのデザインスタイル(例:モダン、ミニマリスト、カラフル)は?: ")
        color_scheme = input("5. 希望する色合いはありますか?: ")
        additional_info = input("6. その他、デザインに関して伝えたいことがあれば教えてください: ")
        language = input("7. webページの言語は何にしますか?: ")

        user_requirements = f"""
        Webサイトの要件:
        1. 目的: {purpose}
        2. ターゲット層: {target_audience}
        3. 主な機能/セクション: {key_features}
        4. デザインスタイル: {style_preference}
        5. 色合い: {color_scheme}
        6. 追加情報: {additional_info}
        7. 言語: {language}
        """

        message = self.client.messages.create(
            model=config.CLAUDE_MODEL,
            max_tokens=3000,
            system="あなたは経験豊富なコンサルタントです。ユーザーの好みを聞き、webページの要件を明確にしてください。",
            messages=[
                {
                    "role": "user",
                    "content": f"以下の要件に基づいて、HTML、CSS、JavaScriptを含むWebデザイン生成のための最適なプロンプトを作成してください。生成されるHTMLファイルにはインラインでCSSとJavaScriptを含める必要があります。:\n\n{user_requirements}",
                }
            ],
        )

        return message.content

    def display_generated_prompt(self, prompt):
        print("\n生成されたプロンプト:")
        print(prompt)
        print("\nこのプロンプトを使用してWebデザインを生成します。")

プログラマエージェント

コンサルタントエージェントから指示された要件に従って、プログラムを作成します。今回は画像はプレースホルダーを用いるように設定しました。

プログラム
import anthropic
import config


class ProgrammerAgent:
    def __init__(self):
        self.client = anthropic.Anthropic(api_key=config.ANTHROPIC_API_KEY)
        self.modification_count = 0
        self.version_dir = None

    def set_version_dir(self, dir_path):
        self.version_dir = dir_path

    def generate_design(self, prompt):
        message = self.client.messages.create(
            model=config.CLAUDE_MODEL,
            max_tokens=4000,
            system="あなたは経験豊富なWebプログラマーです。与えられた要件に基づいてプログラムを作成してください",
            messages=[
                {
                    "role": "user",
                    "content": f"""以下のプロンプトに基づいて、HTML、CSS、JavaScriptを含む完全なWebデザインを生成してください。
                HTMLファイルの中にインラインでCSSとJavaScriptを含めてください。
                必ず<!DOCTYPE html>から始まる完全なHTMLドキュメントを生成してください。
                HTMLドキュメント以外は出力しないでください。
                画像はプレースホルダーとして、以下のようなURLを使用してください:
                <img src="https://via.placeholder.com/500x300" alt="placeholder">

                プロンプト:
                {prompt}

                生成されたデザインは、ブラウザで直接開いて表示できる形式にしてください。""",
                }
            ],
        )
        return message.content

    def modify_design(self, design, feedback):
        if self.modification_count >= config.MAX_MODIFICATIONS:
            return design

        self.modification_count += 1
        message = self.client.messages.create(
            model=config.CLAUDE_MODEL,
            max_tokens=4000,
            system="あなたは経験豊富なWebプログラマーです。他のエージェントのフィードバックに基づいてプログラムをより良いものに修正してください",
            messages=[
                {
                    "role": "user",
                    "content": f"""以下のWebデザイン(HTML、CSS、JavaScript)を、次のフィードバックに基づいて修正してください。HTMLドキュメント以外は絶対に出力しないでください。

                重要な注意点:
                1. CSSとJavaScriptは必ずインラインのままにしてください。
                2. レスポンシブデザインを維持し、モバイル対応を忘れないでください。
                3. 機能性を損なわないように注意しながら、視覚的な改善を行ってください。
                4. 元の良い部分は保持しつつ、フィードバックに沿って修正してください。
                5. 完全なHTMLドキュメントを提供してください。ブラウザで直接開いて表示できる形式にしてください。
                6. 大幅にデザインを変えるのを恐れないでください。改善のために必要な変更を行ってください。
                7.十分な量のコンテンツがあることを確認し、必要に応じて追加してください。
                8. 画像はプレースホルダーとして、以下のようなURLを使用してください
                   <img src="https://via.placeholder.com/500x300" alt="placeholder">

                現在のデザイン:
                {design}

                フィードバック:
                {feedback}

                修正後のデザインを完全なHTML形式(<!DOCTYPE html>から始まる)で提供してください。""",
                }
            ],
        )
        return message.content

デザイナーエージェント

以下の5項目を各10点の50点満点で採点し、デザインの良かった点と改善点をプログラマエージェントにフィードバックします。

  1. 色彩のバランス:配色の調和、ブランドカラーの効果的な使用
  2. レイアウトの整合性:要素の配置、空白の効果的な利用、全体的な構造
  3. タイポグラフィの適切さ:フォントの選択、サイズ、行間、読みやすさ
  4. ビジュアル要素の質:画像、アイコン、グラフィックスの品質と適切さ
  5. ブランドアイデンティティとの一貫性:ロゴ、色彩、スタイルのブランドとの整合性
プログラム
import anthropic
import config
import re


class DesignerAgent:
    def __init__(self):
        self.client = anthropic.Anthropic(api_key=config.ANTHROPIC_API_KEY)

    def evaluate_design(self, design):
        if isinstance(design, list) and len(design) > 0 and hasattr(design[0], "text"):
            design = design[0].text
        elif isinstance(design, str):
            pass
        else:
            raise ValueError("Unexpected design format")

        message = self.client.messages.create(
            model=config.CLAUDE_MODEL,
            max_tokens=1000,
            system="あなたは経験豊富なデザイナーです。webページのデザインを評価し、改善のためのフィードバックを提供してください",
            messages=[
                {
                    "role": "user",
                    "content": f"""以下のWebデザインを視覚的な観点から評価し、改善のためのフィードバックを提供してください。

                以下の5つの項目について、各10点満点で評価してください:
                1. 色彩のバランス:配色の調和、ブランドカラーの効果的な使用
                2. レイアウトの整合性:要素の配置、空白の効果的な利用、全体的な構造
                3. タイポグラフィの適切さ:フォントの選択、サイズ、行間、読みやすさ
                4. ビジュアル要素の質:画像、アイコン、グラフィックスの品質と適切さ
                5. ブランドアイデンティティとの一貫性:ロゴ、色彩、スタイルのブランドとの整合性

                各項目の評価点とその理由を述べてください。

                フィードバックは具体的で建設的なものにしてください。デザインの良い点も言及し、改善点については具体的な提案をしてください。

                デザイン:
                {design}

                回答は以下の形式で返してください:

                色彩のバランス: X/10
                レイアウトの整合性: X/10
                タイポグラフィの適切さ: X/10
                ビジュアル要素の質: X/10
                ブランドアイデンティティとの一貫性: X/10

                合計点数: XX/50

                フィードバック:
                (詳細なフィードバックをここに記述)
                """,
                }
            ],
        )

        content = (
            message.content[0].text
            if isinstance(message.content, list)
            else message.content
        )

        # 正規表現を使用して点数を抽出
        scores = {}
        score_pattern = (
            r"(色彩のバランス|レイアウトの整合性|タイポグラフィの適切さ|ビジュアル要素の質|ブランドアイデンティティとの一貫性):\s*(\d+)/10"
        )
        matches = re.findall(score_pattern, content)
        for category, score in matches:
            scores[category] = int(score)

        # 合計点数を抽出
        total_score_match = re.search(r"合計点数:\s*(\d+)/50", content)
        total_score = (
            int(total_score_match.group(1))
            if total_score_match
            else sum(scores.values())
        )

        # フィードバックを抽出
        feedback_match = re.search(r"フィードバック:\s*([\s\S]*)", content)
        feedback = (
            feedback_match.group(1).strip() if feedback_match else "フィードバックを抽出できませんでした。"
        )

        return total_score, feedback

ライターエージェント

以下の5項目を各10点の50点満点で採点し、コンテンツの良かった点と改善点をプログラマエージェントにフィードバックします。

  1. メッセージの明確さ:主要なメッセージや価値提案の明確さと簡潔さ
  2. コンテンツの関連性:ターゲットオーディエンスにとっての情報の適切さと有用性
  3. 文章の読みやすさ:文章構造、段落分け、専門用語の適切な使用
  4. 説得力:コンテンツの論理的な流れ、証拠や事例の効果的な使用
  5. コールトゥアクションの効果:明確で魅力的な行動喚起の提示
プログラム
import anthropic
import config
import re


class WriterAgent:
    def __init__(self):
        self.client = anthropic.Anthropic(api_key=config.ANTHROPIC_API_KEY)

    def evaluate_content(self, design):
        if isinstance(design, list) and len(design) > 0 and hasattr(design[0], "text"):
            design = design[0].text
        elif isinstance(design, str):
            pass
        else:
            raise ValueError("Unexpected design format")

        message = self.client.messages.create(
            model=config.CLAUDE_MODEL,
            max_tokens=1000,
            system="あなたは経験豊富なライターです。webページのコンテンツを評価し、改善のためのフィードバックを提供してください",
            messages=[
                {
                    "role": "user",
                    "content": f"""以下のWebデザインのコンテンツを評価し、改善のためのフィードバックを提供してください。

                以下の5つの項目について、各10点満点で評価してください:
                1. メッセージの明確さ:主要なメッセージや価値提案の明確さと簡潔さ
                2. コンテンツの関連性:ターゲットオーディエンスにとっての情報の適切さと有用性
                3. 文章の読みやすさ:文章構造、段落分け、専門用語の適切な使用
                4. 説得力:コンテンツの論理的な流れ、証拠や事例の効果的な使用
                5. コールトゥアクションの効果:明確で魅力的な行動喚起の提示

                各項目の評価点とその理由を述べてください。

                フィードバックは具体的で建設的なものにしてください。コンテンツの良い点も言及し、改善点については具体的な提案をしてください。

                デザイン:
                {design}

                回答は以下の形式で返してください:

                メッセージの明確さ: X/10
                コンテンツの関連性: X/10
                文章の読みやすさ: X/10
                説得力: X/10
                コールトゥアクションの効果: X/10

                合計点数: XX/50

                フィードバック:
                (詳細なフィードバックをここに記述)
                """,
                }
            ],
        )

        content = (
            message.content[0].text
            if isinstance(message.content, list)
            else message.content
        )

        # 正規表現を使用して点数を抽出
        scores = {}
        score_pattern = r"(メッセージの明確さ|コンテンツの関連性|文章の読みやすさ|説得力|コールトゥアクションの効果):\s*(\d+)/10"
        matches = re.findall(score_pattern, content)
        for category, score in matches:
            scores[category] = int(score)

        # 合計点数を抽出
        total_score_match = re.search(r"合計点数:\s*(\d+)/50", content)
        total_score = (
            int(total_score_match.group(1))
            if total_score_match
            else sum(scores.values())
        )

        # フィードバックを抽出
        feedback_match = re.search(r"フィードバック:\s*([\s\S]*)", content)
        feedback = (
            feedback_match.group(1).strip() if feedback_match else "フィードバックを抽出できませんでした。"
        )

        return total_score, feedback

アクセシビリティチェッカーエージェント

以下の5項目を各10点の50点満点で採点し、webデザインのアクセシビリティの良かった点と改善点をプログラマエージェントにフィードバックします。

  1. スクリーンリーダー対応:適切な見出し構造、ARIAラベルの使用、フォーム要素のラベリング
  2. キーボードナビゲーション:全ての機能へのキーボードアクセス、フォーカスの視覚的表示
  3. コントラストと可読性:テキストと背景のコントラスト比、フォントサイズの適切さ
  4. 代替テキストの適切さ:画像、アイコン、ボタンなどの意味を伝える代替テキストの提供
  5. レスポンシブデザインの実装:異なる画面サイズでのレイアウト調整、タッチターゲットのサイズ
プログラム
import anthropic
import config
import re


class AccessibilityAgent:
    def __init__(self):
        self.client = anthropic.Anthropic(api_key=config.ANTHROPIC_API_KEY)

    def evaluate_accessibility(self, design):
        if isinstance(design, list) and len(design) > 0 and hasattr(design[0], "text"):
            design = design[0].text
        elif isinstance(design, str):
            pass
        else:
            raise ValueError("Unexpected design format")

        message = self.client.messages.create(
            model=config.CLAUDE_MODEL,
            max_tokens=1000,
            messages=[
                {
                    "role": "user",
                    "content": f"""以下のWebデザインのアクセシビリティを評価し、改善のためのフィードバックを提供してください。

                以下の5つの項目について、各10点満点で評価してください:
                1. スクリーンリーダー対応:適切な見出し構造、ARIAラベルの使用、フォーム要素のラベリング
                2. キーボードナビゲーション:全ての機能へのキーボードアクセス、フォーカスの視覚的表示
                3. コントラストと可読性:テキストと背景のコントラスト比、フォントサイズの適切さ
                4. 代替テキストの適切さ:画像、アイコン、ボタンなどの意味を伝える代替テキストの提供
                5. レスポンシブデザインの実装:異なる画面サイズでのレイアウト調整、タッチターゲットのサイズ

                各項目の評価点とその理由を述べてください。

                フィードバックは具体的で建設的なものにしてください。アクセシビリティの良い点も言及し、改善点については具体的な提案をしてください。

                デザイン:
                {design}

                回答は以下の形式で返してください:

                スクリーンリーダー対応: X/10
                キーボードナビゲーション: X/10
                コントラストと可読性: X/10
                代替テキストの適切さ: X/10
                レスポンシブデザインの実装: X/10

                合計点数: XX/50

                フィードバック:
                (詳細なフィードバックをここに記述)
                """,
                }
            ],
        )

        content = (
            message.content[0].text
            if isinstance(message.content, list)
            else message.content
        )

        # 正規表現を使用して点数を抽出
        scores = {}
        score_pattern = r"(スクリーンリーダー対応|キーボードナビゲーション|コントラストと可読性|代替テキストの適切さ|レスポンシブデザインの実装):\s*(\d+)/10"
        matches = re.findall(score_pattern, content)
        for category, score in matches:
            scores[category] = int(score)

        # 合計点数を抽出
        total_score_match = re.search(r"合計点数:\s*(\d+)/50", content)
        total_score = (
            int(total_score_match.group(1))
            if total_score_match
            else sum(scores.values())
        )

        # フィードバックを抽出
        feedback_match = re.search(r"フィードバック:\s*([\s\S]*)", content)
        feedback = (
            feedback_match.group(1).strip() if feedback_match else "フィードバックを抽出できませんでした。"
        )

        return total_score, feedback

実行結果

3つの評価エージェントの各50点満点の150点採点で、120点を超えるとループを抜け出すうように設定して大阪の観光案内サイトを作成しました。
イテレーションが進むごとに点数が改善し、3回目のイテレーションでインタラクションのループを抜け出しました。

イテレーション デザイン コンテンツ アクセシビリティ 合計点
1 36 39 35 110
2 36 40 35 111
3 43 42 41 126

https://yuyamada0917.github.io/agent-design/

このページから分かるようにエージェント同士のインタラクションによって改良されています。

デザイン1とデザイン2の比較

デザイン1

デザイン2

デザイン1

デザイン2

デザイン2とデザイン3の比較

デザイン2

デザイン3

デザイン2

デザイン3

1回目のインタラクション

コンサルタントエージェント

ユーザーによる入力

Webデザインの要件を聞き取ります。以下の質問にお答えください。
1. Webサイトの目的は何ですか?: 大阪の観光案内サイト
2. ターゲット層はどのような人たちですか?: 観光客
3. 含めたい主な機能やセクションは何ですか?: 観光地の紹介・グルメの紹介・問い合わせフォーム
4. 好みのデザインスタイル(例:モダン、ミニマリスト、カラフル)は?: モダン
5. 希望する色合いはありますか?: なし
6. その他、デザインに関して伝えたいことがあれば教えてください: 十分なコンテンツの量にしてください。落ち着きのあるデザインにしてください。
7. webページの言語は何にしますか?: 日本語

ヒアリング内容から生成したプロンプト

生成する内容: モダンデザインの大阪観光案内Webサイト。ターゲットは観光客。要素は観光地の紹介、グルメ紹介、問い合わせフォーム。デザインは落ち着いた雰囲気で、適度な量のコンテンツを含める。言語は日本語。

技術的要件: 
- HTML、CSS、JavaScriptをインラインで含める
- レスポンシブデザイン
- アクセシビリティに配慮
- モダンなCSSフレームワーク(Bootstrap等)を使用
- 高度な機能は不要(簡単なJavaScriptのみ)

評価エージェントによる採点・フィードバック

評価結果:
デザイン評価: 36/50
コンテンツ評価: 39/50
アクセシビリティ評価: 35/50
合計点数: 110/150

デザインフィードバック:
色彩のバランス:
- ヘッダーとフッターのダークな色調と、コンテンツ部分の明るい色調のコントラストが良い。
- ただし、ジャンボトロンの背景画像がプレースホルダーのため、実際の画像との色調の調和は不明。

レイアウトの整合性:  
- グリッドレイアウトを効果的に使用して、要素を整然と配置している。
- 適切な余白が設けられており、全体的な構造がすっきりしている。

タイポグラフィの適切さ:
- 読みやすいサンセリフフォントを使用している。
- 適切なフォントサイズと行間が設定されている。

ビジュアル要素の質:
- プレースホルダー画像が使用されているため、実際の画像の品質が不明。より高品質の画像を使用することが望ましい。
- アイコンやグラフィックスがないため、ビジュアル的な魅力が不足している。

ブランドアイデンティティとの一貫性:
- ロゴやブランドカラーの使用が不明確。より強いブランドアイデンティティが必要。
- スタイルは全体的に統一されているが、ブランド独自のデザイン要素が少ない。

改善点:
1. ヒーローセクション(ジャンボトロン)の背景画像を、大阪を代表する高品質の画像に変更する。
2. 観光地やグルメのアイコンやイラストを追加し、ビジュアル的な魅力を高める。
3. ブランドロゴやカラーパレットを明確に定義し、一貫性のあるブランドアイデンティティを構築する。
4. フォントやタイポグラフィをカスタマイズし、ブランド独自のスタイルを追加する。
5. フッターにSNSリンクやその他の関連情報を追加し、ユーザーエンゲージメントを高める。

コンテンツフィードバック:
良い点:
- メッセージは簡潔で分かりやすい。「大阪を体験しよう」というキャッチコピーは魅力的です。
- コンテンツはターゲットオーディエンス(観光客)に合っており、有用な情報が含まれています。
- 文章は簡潔で読みやすく、専門用語は適切に使用されています。
- カードデザインを使ってコンテンツを整理しており、視覚的にも分かりやすくなっています。

改善点:
- メッセージをもう少し具体的にし、大阪の魅力をより良く伝えることができます。
- 観光地やグルメについて、もっと詳細な情報や写真を追加すると、より魅力的になります。
- コンテンツの論理的な流れをもう少し工夫し、大阪の良さをよりうまく説得できるようにするとよいでしょう。
- コールトゥアクションとしての「お問い合わせ」フォームは良いですが、観光客を実際に行動に移すような、もっと具体的な呼びかけが必要かもしれません。

提案:
- キャッチコピーに「古き良き伝統と最新のトレンドが融合する街」などの言葉を加え、大阪の魅力を強調します。
- 各観光地やグルメについて、歴史や由来、おすすめポイントなど、より詳細な説明を追加します。
- 大阪の雰囲気や人々の温かさなども織り交ぜ、大阪への親しみを持ってもらえるよう心がけます。
- 「今すぐ大阪に行こう!」といった具体的な行動喚起を追加し、直接的に観光客を呼びかけます。

アクセシビリティフィードバック:
このWebサイトには良い点もありますが、アクセシビリティの観点から改善の余地があります。

スクリーンリーダー対応:
- ナビゲーションメニューにARIAのランドマークロールが設定されていないため、スクリーンリーダーユーザーがコンテンツの構造を把握しづらい。
- フォーム入力欄に適切なラベルが付いているものの、`<label>`要素と`<input>`要素が関連付けられていない。
- 見出しの構造がわかりにくい。適切な見出しレベルを使用することをお勧めします。

キーボードナビゲーション:
- ほとんどの機能がキーボードで操作可能である点は良い。
- ただし、現在のフォーカスの視覚的なスタイルがわかりにくいため、改善が必要。

コントラストと可読性:
- 背景色と文字色のコントラスト比は概ね適切である。
- フォントサイズも十分な大きさで読みやすい。

代替テキストの適切さ:
- 画像にはプレースホルダーの代替テキストしか設定されていない。コンテンツに関連した適切な代替テキストを提供することが重要。

レスポンシブデザインの実装:
- Bootstrap を使用しているため、異なる画面サイズに対応できている点は良い。
- ただし、タッチターゲットのサイズについては確認が必要。

改善のための提案:
1. ナビゲーションメニューとメインコンテンツにARIAのランドマークロールを設定し、構造をわかりやすくする。
2. `<label>`要素と`<input>`要素を適切に関連付けて、フォームのラベリングを改善する。
3. 見出しの構造を整理し、適切なレベルの見出しを使用する。
4. フォーカスの視覚的なスタイルを改善し、現在の位置がわかりやすくなるようにする。
5. 代替テキストを適切に設定し、コンテンツの意味を伝える。
6. タッチターゲットのサイズを確認し、必要に応じて調整する。

このように改善すれば、よりアクセシブルでユーザーフレンドリーなWebサイトになると期待できます。

2回目のインタラクション

評価エージェントによる採点・フィードバック

評価結果:
デザイン評価: 36/50
コンテンツ評価: 40/50
アクセシビリティ評価: 35/50
合計点数: 111/150

デザインフィードバック:
良い点:
- ブランドカラーの赤と黒のコントラストが効果的に使われている
- レスポンシブデザインが適切に実装されており、さまざまな画面サイズに対応できる
- ヘッダーとフッターのデザインがシンプルで統一感がある
- 観光地とグルメを分けて紹介するレイアウトが分かりやすい

改善点:
- ヒーローイメージの配色が暗く、テキストの可読性が低い。背景画像を明るい色調のものに変更するとよい
- 観光地とグルメの画像がプレースホルダーのままなので、実際の写真に差し替える必要がある
- フォントの種類とサイズのバリエーションが少ない。見出しとボディテキストでフォントを変えるなどすると良い
- SNSのアイコンがベクターグラフィックスではなく、ビットマップ画像なので品質が低下する。SVGアイコンに変更をおすすめする
- お問い合わせフォームのデザインが他のセクションとスタイルが合っていない。フォームデザインを全体のデザインに統一させる必要がある

全体的にシンプルでミニマルなデザインは良いが、画像の品質が低いこと、配色とタイポグラフィに改善の余地があることが指摘できる。これらの点を改善すれば、より魅力的でブランドイメージに沿ったWebサイトになると考えられる。

コンテンツフィードバック:
全体として、このWebサイトは大阪の観光情報を適切に提供しています。主要なメッセージは明確で、ターゲット層に合わせたコンテンツが用意されています。文章も読みやすく、観光地やグルメの魅力が上手く伝わっています。

良い点:
- メインメッセージが簡潔で明確
- 代表的な観光地やグルメが適切に紹介されている
- 写真やカードデザインで視覚的にも魅力的
- 問い合わせフォームが用意されていてアクセスしやすい
- フッターにSNSリンクがあり情報収集が容易

改善点と提案:
- コールトゥアクションがやや控えめ。「大阪を体験する」ようなより強力なCTAが望ましい
- 観光地やグルメの情報がやや平板。より具体的な魅力を紹介するとよい
- メインヒーロー画像はプレースホルダーなので実際の大阪の風景写真に変更を
- フォームにプライバシーポリシーへのリンクを追加するとよい
- 外国人観光客向けの多言語対応を検討してみてはどうか

総じて適切なコンテンツですが、さらなる魅力の強調と利便性の向上によりユーザー体験が改善できると思われます。

アクセシビリティフィードバック:
- スクリーンリーダー対応
  - 適切な見出し構造が使用されており、良好です。
  - ARIAラベルの使用が不十分です。ナビゲーションメニューとフォームの一部要素に適用されていますが、その他の対話型要素にも適用する必要があります。
  - フォームの入力欄にラベルが付いていますが、それ以外の対話型要素にラベルがない点が改善の余地があります。

- キーボードナビゲーション
  - すべての機能へのキーボードアクセスが可能で、良好です。
  - フォーカスの視覚的表示のためのスタイルが適用されており、良好です。

- コントラストと可読性
  - テキストと背景のコントラスト比が適切で、可読性が確保されています。
  - フォントサイズも適切で、良好です。

- 代替テキストの適切さ
  - 画像に代替テキストが提供されていません。意味のあるテキストを追加する必要があります。
  - ブランドロゴとソーシャルメディアアイコンに代替テキストがありますが、適切とは限りません。

- レスポンシブデザインの実装
  - レスポンシブデザインが適切に実装されており、異なる画面サイズで適切にレイアウトが調整されています。
  - タッチターゲットのサイズも適切で、良好です。

改善提案:
- スクリーンリーダー対応の向上
  - すべての対話型要素にARIAラベルを適用し、スクリーンリーダーユーザーが容易にナビゲーションできるようにする。
  - 画像やアイコンなどの非テキスト要素に適切な代替テキストを提供する。

- 代替テキストの改善
  - 画像に意味のあるテキストを追加する。
  - ブランドロゴとソーシャルメディアアイコンの代替テキストを適切なものに変更する。

- その他の提案
  - フォームのバリデーションエラーメッセージをスクリーンリーダーフレンドリーにする。
  - フォーカスが移動した際の視覚的なフィードバックを強化する。
  - カラーコントラストチェッカーを使用して、コントラスト比を確認し、必要に応じて調整する。

このウェブサイトは、全体的にアクセシビリティを意識したデザインになっており、良好な点が多くあります。しかし、一部の改善点もあるため、上記の提案を取り入れることで、より包括的でアクセシブルなウェブサイトになると考えられます。

3回目のインタラクション

評価エージェントによる採点・フィードバック

評価結果:
デザイン評価: 43/50
コンテンツ評価: 42/50
アクセシビリティ評価: 41/50
合計点数: 126/150

デザインフィードバック:
全体的に素晴らしいデザインで、大阪のイメージを上手く表現しています。色彩のバランスは良く、赤、黒、白を効果的に使用し、エネルギッシュでダイナミックな印象を与えています。レイアウトは見やすく、適切な空白を使用して要素を整理しています。

しかし、一部のタイポグラフィは見づらいところがあります。特に本文のフォントサイズが小さすぎるため、読みづらい部分があります。行間を広げるとさらに読みやすくなるでしょう。

ビジュアル要素の品質は高く、画像が鮮明で魅力的です。しかし、ヒーローイメージの解像度がやや低いため、大きなサイズで表示すると粗くなる可能性があります。

ブランドアイデンティティとの一貫性はよく保たれており、ロゴ、カラーパレット、タイポグラフィがブランドイメージと調和しています。ただし、一部のアイコンがブランドの雰囲気とやや違うため、それらを調整する必要があるかもしれません。

提案:
- 本文のフォントサイズを14px程度に大きくし、行間を1.5程度に広げると読みやすくなります。
- ヒーローイメージの解像度を上げると、大きなサイズでも鮮明に表示できます。
- 一部のアイコンをブランドイメージに合わせて調整することで、ブランドアイデンティティがより一貫性を持つでしょう。

コンテンツフィードバック:
全体として、このWebサイトのコンテンツは非常に良くできています。観光地やグルメ情報が分かりやすくまとめられており、訪問者のニーズに合っています。

メッセージの明確さについては、8点と評価しました。メインメッセージが「大阪の魅力を体験する」ことであり、それが上手く伝わっています。ただし、サブヘッドラインで、具体的にどのような魅力があるのかをもう少し明確にするとより良いでしょう。

コンテンツの関連性は9点です。ターゲットオーディエンス(大阪観光に興味のある人)に適した内容が盛り込まれています。観光地、グルメ、問い合わせ方法が網羅されており、非常に有用な情報が提供されています。

文章の読みやすさは8点です。全体として簡潔で分かりやすい文章ですが、一部の箇所で長い文や複雑な表現があり、読みづらさを感じました。短めの文章と段落分けを心がけると、より読みやすくなるでしょう。

説得力は8点です。大阪の魅力が伝わってくる記述がありますが、もう少し具体的な事例やデータを盛り込むと、より説得力が増すと思われます。例えば、人気の理由や歴史的背景、口コミなどを加えると良いでしょう。

コールトゥアクションの効果は9点です。「大阪を体験する」というCTAが分かりやすく、問い合わせフォームへのリンクも適切に設置されています。ただし、より魅力的なデザインにするとより効果的になると考えられます。

総合して、このコンテンツはよくできており、大阪観光の価値を適切に伝えています。一部の改善点はありますが、既に非常に質の高いコンテンツであると評価できます。

アクセシビリティフィードバック:
良い点:
- 見出しの適切な使用と、ARIAラベルの活用でスクリーンリーダーでの操作性が高い
- フォーカスインジケーターが視認性よく設計されており、キーボードナビゲーションが容易
- コントラストが高く、フォントサイズも適切で可読性が確保されている
- レスポンシブデザインが実装されており、異なる画面サイズで適切にレイアウトが調整される

改善点:
- 一部の画像に代替テキストが設定されていないため、スクリーンリーダーユーザーは内容を完全に理解できない可能性がある
- アイコン画像には意味を伝える適切な代替テキストが必要
- モバイル画面サイズでは、一部のタッチターゲットが小さすぎるため操作しづらい

提案:
- 全ての画像とアイコンに、内容を適切に伝える代替テキストを設定する
- モバイル画面サイズでは、ボタンやリンクのサイズを大きくし、指でタップしやすくする  
- フォームのラベルとコントロールの関連性を、aria-describedbyなどのARIA属性で明示的に示す
- ページの主要なランドマークにロール属性を付与し、ナビゲーションをより簡単にする

総合的に見ると、かなりのアクセシビリティ対応がなされており、一部の改善点に対処すれば、より包括的でアクセシブルなWebサイトになるでしょう。

まとめ

LLMエージェントを複数作成し、それらをインタラクションさせることで効率的にweb開発が行えるかを検証しました。通常のLLMを使ってweb開発を行うよりも工数が減ることが期待できそうです。
私の経験的に一つのLLMに多くのタスクをさせるよりも、何かに特化させたエージェントを作成し小さなタスクに分ける方が精度が向上すると感じました。
ただしまだまだ不完全なところが多いので、改良の余地がありそうです。

質問や感想等ございましたら、Xアカウントまでお願いします!

Discussion