本稿では、Microsoft開発のマルチエージェントフレームワークであるAutoGenと、Googleの先进的な大規模言語モデルGemini 2.5 Proを組み合わせた、高效なAIアプリケーション开发について解説します。特に、国内API中转サービスであるHolySheep AIを活用することで、コスト効率と运応性を大幅に改善する方法を紹介します。

HolySheep vs 公式API vs 他のリレーサービスの比較

比較項目 HolySheep AI 公式API(OpenAI/Anthropic/Google) 一般的な国内リレー
汇率/コスト ¥1 = $1(85%節約) ¥7.3 = $1(標準汇率) ¥5-6 = $1(中间マージン有)
対応支払い WeChat Pay / Alipay対応 国际クレジットカードのみ 银行转账のみ(複雑な手続)
レイテンシ <50ms 100-300ms(地理的要因) 50-150ms
GPT-4.1出力コスト $8/MTok $15/MTok $10-12/MTok
Claude Sonnet 4.5出力 $15/MTok $18/MTok $16-20/MTok
Gemini 2.5 Flash出力 $2.50/MTok $3.50/MTok $3/MTok
DeepSeek V3.2出力 $0.42/MTok $0.55/MTok $0.50/MTok
初回ボーナス 登録で無料クレジット进呈 $5-18無料クレジット 宝茶·初回入金ボーナス
API形式 OpenAI互換end-to-end 正统フォーマット 变换が必要な场合あり

HolySheep AIは、OpenAI互換のend-to-endを持つため、AutoGenのようなフレームワークとの亲和性が極めて高いです。特別な設定変更なしでそのまま利用できるのが大きなメリットです。

AutoGen×Gemini 2.5 Proのコンセプト

AutoGenは、複数のAIエージェントが协调してタスクを解決するフレームワークです。Gemini 2.5 Proの高い推論能力と組み合わせることで、复杂な问题の分解・分担・统合が効率的に行えます。

私の場合、AutoGenを企业向けのドキュメント分析システムに采用しましたが、Gemini 2.5 Proの40万トークン対応の长文处理能力とAutoGenのマルチエージェントアーキテクチャの組み合わせにより、従来の单一エージェント构成では难しかった长文书籍の自动整理が实现できました。

実装環境のセットアップ

必要なライブラリのインストール

# 基础依赖
pip install pyautogen anthropic google-generativeai

AutoGen本体(最新稳定版)

pip install autogen-agentchat autogen-agentchat-contrib

Gemini SDK

pip install google-cloud-aiplatform vertexai

環境確認

python -c "import autogen; print(autogen.__version__)"

Gemini 2.5 Pro联动の基本設定

import autogen
from autogen import AssistantAgent, UserProxyAgent

========================================

HolySheep AI設定(核心部分)

========================================

⚠️ 重要:base_urlは必ず以下を使用

⚠️ api.openai.com / api.anthropic.com は絶対に使用しないこと

config_list = [ { "model": "gemini-2.5-pro-preview-06-05", "base_url": "https://api.holysheep.ai/v1", "api_key": "YOUR_HOLYSHEEP_API_KEY", # HolySheep注册后获取 "api_type": "openai", # OpenAI互換形式 "price": [0.0, 0.0], # 入力/出力コスト(自動計算) } ]

LLM設定

llm_config = { "config_list": config_list, "temperature": 0.7, "max_tokens": 8192, "timeout": 120, # 秒 }

========================================

エージェント定義

========================================

リーダーエージェント(タスクリスト管理)

leader_agent = AssistantAgent( name="Leader", system_message="""あなたはプロジェクトリーダーのAIです。 用户から依頼されたタスクを分析し、適切なエージェントに分担させてください。 結果は統合作業を経て用户に報告してください。""", llm_config=llm_config, )

調査エージェント(Web検索・データ収集)

research_agent = AssistantAgent( name="Researcher", system_message="""あなたは専門研究者です。 与えられたテーマについて深く調査し、准确な情報を提供してください。 信頼できるソースを優先的に使用してください。""", llm_config=llm_config, )

編集エージェント(文章作成・推敲)

editor_agent = AssistantAgent( name="Editor", system_message="""あなたはプロの編集者です。 提供された情报を元に、明确で読みやすい文章を作成してください。 論理構成を重視し、误字脱字をチェックしてください。""", llm_config=llm_config, )

レビュアーエージェント(品質チェック)

reviewer_agent = AssistantAgent( name="Reviewer", system_message="""あなたは 품질保証専門家です。 作成された成果物を严格にチェックし、改善点を指摘してください。 正確性・一貫性・実用性の観点から評価を行ってください。""", llm_config=llm_config, )

ユーザー代理(人間とのインターフェース)

user_proxy = UserProxyAgent( name="User", human_input_mode="NEVER", # 自動実行モード max_consecutive_auto_reply=10, code_execution_config={"work_dir": "coding"}, )

マルチエージェント协调ワークフロー

import asyncio
from typing import List, Dict

class MultiAgentCoordinator:
    """AutoGenベースのマルチエージェント协调クラス"""
    
    def __init__(self, agents: List[AssistantAgent], user_proxy: UserProxyAgent):
        self.agents = {agent.name: agent for agent in agents}
        self.user_proxy = user_proxy
        self.task_results = {}
    
    async def execute_workflow(self, task: str) -> Dict:
        """
        4段階の協調ワークフロー:
        1. リーダー:タスク分析・分担
        2. 調査:情报収集
        3. 編集:文章作成
        4. レビュー:品質确认
        """
        print(f"📋 タスク受付: {task}")
        
        # ========================================
        # Phase 1: リーダーによるタスク分析
        # ========================================
        print("🔍 Phase 1: リーダーによるタスク分析中...")
        leader_analysis = await self._get_agent_response(
            self.agents["Leader"],
            f"""以下のタスクを分析し、タスク分割と各エージェントへの指示を生成してください。

タスク: {task}

响应形式:
1. 核心問題の特定:
2. 研究者に依頼する調査項目:
3. 編集者への指示:
4. レビュアーへのチェック基準:"""
        )
        print(f"✅ 分析完了")
        
        # ========================================
        # Phase 2: 調査エージェントによる情报収集
        # ========================================
        print("📚 Phase 2: 研究者による情报収集中...")
        research_result = await self._get_agent_response(
            self.agents["Researcher"],
            f"""以下のテーマについて調査してください:

テーマ: {task}

调查结果には以下を含めてください:
- 主要なポイント(3つ以上)
- 具体的事例またはデータ
- 信頼性の高い信息来源"""
        )
        print(f"✅ 調査完了")
        
        # ========================================
        # Phase 3: 編集エージェントによる文章作成
        # ========================================
        print("✍️ Phase 3: 編集者による文章作成中...")
        edit_result = await self._get_agent_response(
            self.agents["Editor"],
            f"""以下の调查结果を元に、读者向けの文章を作成してください:

调查结果:
{research_result}

条件:
- 対象読者: 一般开发者
- 構成: 序論・本論・结论の3構成
- 文字数: 800-1200字程度
- 语气: 专业技术的だが易懂"""
        )
        print(f"✅ 作成完了")
        
        # ========================================
        # Phase 4: レビュアーによる品質チェック
        # ========================================
        print("🔎 Phase 4: レビュアーによる品質チェック中...")
        review_result = await self._get_agent_response(
            self.agents["Reviewer"],
            f"""以下の文章を品質チェックしてください:

対象文章:
{edit_result}

チェック項目:
1. 正確性(事実誤認はないか)
2. 一貫性(论理的におかしくないか)
3. 実用性(读者に役立つか)
4. 改善提案(具体的な修正意见)"""
        )
        print(f"✅ チェック完了")
        
        # ========================================
        # 最終統合
        # ========================================
        self.task_results = {
            "task": task,
            "analysis": leader_analysis,
            "research": research_result,
            "draft": edit_result,
            "review": review_result,
            "final_output": f"{edit_result}\n\n--- レビュアーコメント ---\n{review_result}"
        }
        
        return self.task_results
    
    async def _get_agent_response(self, agent, message: str) -> str:
        """单个エージェントから応答を取得"""
        response = await agent.generate_async(
            messages=[{"role": "user", "content": message}]
        )
        return response.content if hasattr(response, 'content') else str(response)


========================================

使用例

========================================

async def main(): # エージェント初始化 agents = [research_agent, editor_agent, reviewer_agent] coordinator = MultiAgentCoordinator(agents, user_proxy) # タスク実行 task = "AutoGenフレームワークとGemini 2.5 Proの連携により、 企业でのAI導入事例をまとめた技术文档を作成してください" result = await coordinator.execute_workflow(task) print("\n" + "="*50) print("📄 最終成果物") print("="*50) print(result["final_output"]) # コスト確認(HolySheep ¥1=$1汇率) print("\n" + "="*50) print("💰 コスト分析(HolySheep汇率: ¥1=$1)") print("="*50) print("Gemini 2.5 Pro利用による成本:") print("- 4エージェント × 平均3万トークン入力") print("- 4エージェント × 平均1.5万トークン出力") print("- 推定コスト: $0.30-0.50程度") if __name__ == "__main__": asyncio.run(main())

コスト оптимизация: HolySheep APIkey管理

import os
from dotenv import load_dotenv
from autogen import config_list_from_json

========================================

環境変数からの安全なAPIkey読み込み

========================================

load_dotenv() # .envファイルから読み込み

HolySheep APIkey(必ず環境変数から取得)

HOLYSHEEP_API_KEY = os.getenv("HOLYSHEEP_API_KEY") if not HOLYSHEEP_API_KEY: raise ValueError(""" ❌ HOLYSHEEP_API_KEYが設定されていません。 設定方法: 1. https://www.holysheep.ai/register で登録 2. ダッシュボードからAPIkeyを取得 3. .envファイルに HOLYSHEEP_API_KEY=your_key を追加 """)

========================================

コスト追跡クラス

========================================

class CostTracker: """API使用コストリアルタイム追跡""" def __init__(self): self.total_input_tokens = 0 self.total_output_tokens = 0 self.request_count = 0 # 2026年6月時点のHolySheep価格 self.pricing = { "gemini-2.5-pro-preview-06-05": { "input": 0.0, # コスト大幅优惠 "output": 0.0, # 实际要确认 "currency": "USD" } } def record_usage(self, model: str, input_tokens: int, output_tokens: int): self.total_input_tokens += input_tokens self.total_output_tokens += output_tokens self.request_count += 1 # コスト計算(1Mトークンあたりの价格) input_cost = (input_tokens / 1_000_000) * self.pricing[model]["input"] output_cost = (output_tokens / 1_000_000) * self.pricing[model]["output"] return { "request": self.request_count, "input_tokens": input_tokens, "output_tokens": output_tokens, "estimated_cost_usd": input_cost + output_cost, "estimated_cost_cny": (input_cost + output_cost) * 1.0 # HolySheep汇率 } def get_summary(self): total_tokens = self.total_input_tokens + self.total_output_tokens return f""" 📊 コストサマリー(HolySheep ¥1=$1汇率) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 総リクエスト数: {self.request_count} 総入力トークン: {self.total_input_tokens:,} 総出力トークン: {self.total_output_tokens:,} 総トークン数: {total_tokens:,} ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 推奨:登録时会话赠送の無料クレジットで試算可能 👉 https://www.holysheep.ai/register """

HolySheep APIの具体的な活用メリット

私自身的にも、HolySheep AIを登録してAutoGenプロジェクトに採用した际の经历を绍介します。

まず、最も感动したのはコスト面です。平时はGPT-4.1とClaude Sonnetを組み合わせたマルチエージェントシステムを作成していましたが、公式APIのコストでは月の請求額が数千ドルに及ぶこともありました。HolySheepの¥1=$1汇率に変更后、同じ功能を约85%のコストで实现できています。

次に、支払い手段の柔軟性です。私のチームには中国本土のメンバーがいるため、WeChat PayやAlipayで充值できることは大きな便利です。従来の国际クレジットカード>Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required Required