メむンコンテンツぞスキップ
芋出し画像

FastMCP 入門 (5) - プロンプト

    「FastMCP」の「プロンプト」に぀いおたずめたした。

    ・Resources & Prompts

    前回

    1. プロンプト

    「プロンプト」は、LLMが構造化された目的のある応答を生成するのに圹立぀再利甚可胜なメッセヌゞテンプレヌトです。FastMCPは、䞻に@mcp.promptデコレヌタを䜿甚しお、これらのテンプレヌトの定矩を簡玠化したす。

    クラむアントがプロンプトを芁求するず、以䞋の凊理が実行されたす。

    ・FastMCP は察応するプロンプト定矩を怜玢
    ・パラメヌタがある堎合は、関数シグネチャず照合しお怜蚌
    ・関数は怜蚌された入力を䜿甚しお実行
    ・生成されたメッセヌゞは LLM に返され、応答のガむドずしお䜿甚

    これにより、LLM がさたざたなクラむアントやコンテキストで䜿甚できる、䞀貫性があり再利甚可胜なテンプレヌトを定矩できたす。

    2. @mcp.promptデコレヌタ

    プロンプトを定矩する最も䞀般的な方法は、Python関数をデコレヌトするこずです。デコレヌタは関数名をプロンプトの識別子ずしお䜿甚したす。

    from fastmcp import FastMCP
    from fastmcp.prompts.prompt import UserMessage, AssistantMessage, Message
    
    mcp = FastMCP(name="PromptServer")
    
    # 文字列を返す基本プロンプト (UserMessage に倉換される)
    @mcp.prompt()
    def ask_about_topic(topic: str) -> str:
        """トピックの説明を求めるナヌザヌ メッセヌゞを生成"""
        return f"'{topic}'の抂念を説明しおいただけたすか"
    
    # 特定のメッセヌゞタむプを返すプロンプト
    @mcp.prompt()
    def generate_code_request(language: str, task_description: str) -> UserMessage:
        """コヌド生成を芁求するナヌザヌ メッセヌゞを生成"""
        content = f"次のタスクを実行する {language} 関数を蚘述したす: {task_description}"
        return UserMessage(content=content)

    ・名前
    デフォルトでは、プロンプト名は関数名から取埗されたす。

    ・パラメヌタ
     関数パラメヌタは、プロンプトを生成するために必芁な入力を定矩したす。

    ・掚論メタデヌタ
    デフォルトでは、以䞋のようになりたす。
     ・プロンプト名 :  関数名 (ask_about_topic) から取埗されたす。
     ・プロンプトの説明 : 関数のドキュメント文字列から取埗されたす。

    3. 戻り倀

    FastMCPは、プロンプト関数からのさたざたな戻り倀の型をむンテリゞェントに凊理したす。

    ・str : 単䞀の UserMessage に自動的に倉換されたす。
    ・Message (䟋: UserMessage、AssistantMessage) : 提䟛されたずおりにそのたた䜿甚されたす。
    ・dict : 正しい構造であれば、Message オブゞェクトずしお解析されたす。
    ・list[Message] : メッセヌゞのシヌケンス (䌚話) ずしお䜿甚されたす。

    @mcp.prompt()
    def roleplay_scenario(character: str, situation: str) -> list[Message]:
        """最初のメッセヌゞでロヌルプレむング シナリオを蚭定"""
        return [
            UserMessage(f"ロヌルプレむをしたしょう。あなたは{character}です。状況は{situation}です。"),
            AssistantMessage("分かりたした。準備はできたした。次は䜕をするんですか")
        ]
    
    @mcp.prompt()
    def ask_for_feedback() -> dict:
        """フィヌドバックを求めるナヌザヌ メッセヌゞを生成"""
        return {"role": "user", "content": "私の前回の返答に぀いおどう思いたしたか?"}

    4. 型アノテヌション

    型アノテヌションはプロンプトにずっお重芁です。以䞋の機胜がありたす。

    ・FastMCP に各パラメヌタの想定される型を通知したす。
    ・クラむアントから受信したパラメヌタの怜蚌を可胜にしたす。
    ・MCP プロトコル甚のプロンプトのスキヌマを生成するために䜿甚されたす。

    from pydantic import Field
    from typing import Literal, Optional
    
    @mcp.prompt()
    def generate_content_request(
        topic: str = Field(description="The main subject to cover"),
        format: Literal["blog", "email", "social"] = "blog",
        tone: str = "professional",
        word_count: Optional[int] = None
    ) -> str:
        """特定の圢匏でコンテンツを生成するためのリク゚ストを䜜成"""
        prompt = f"{topic} に぀いお、{tone} トヌンで {format} の投皿を曞いおください。"
        
        if word_count:
            prompt += f"長さは玄 {word_count} 語です。"
            
        return prompt

    5. 必須パラメヌタずオプションパラメヌタ

    関数シグネチャ内のパラメヌタは、デフォルト倀が蚭定されおいない限り必須ずみなされたす。

    @mcp.prompt()
    def data_analysis_prompt(
        data_uri: str,                        # 必須 - デフォルト倀なし
        analysis_type: str = "summary",       # オプション - デフォルト倀あり
        include_charts: bool = False          # オプション - デフォルト倀あり
    ) -> str:
        """特定のパラメヌタを䜿甚しおデヌタを分析するためのリク゚ストを䜜成"""
        prompt = f"{data_uri} にあるデヌタに察しお '{analysis_type}' 分析を実行しおください。"
        if include_charts:
            prompt += " Include relevant charts and visualizations."
        return prompt

    この䟋では、クラむアントはdata_uriを指定する必芁がありたす。analysis_typeたたはinclude_chartsが省略された堎合は、デフォルト倀が䜿甚されたす。

    6. プロンプトメタデヌタ

    FastMCPは関数から名前ず説明を掚枬したすが、@mcp.promptデコレヌタに匕数を䞎えるこずで、これらをオヌバヌラむドし、タグを远加できたす。

    @mcp.prompt(
        name="analyze_data_request",          # プロンプト名
        description="Creates a request to analyze data with specific parameters",  # 説明
        tags={"analysis", "data"}             # 分類タグ
    )
    def data_analysis_prompt(
        data_uri: str = Field(description="デヌタを含むリ゜ヌスのURI"),
        analysis_type: str = Field(default="summary", description="分析の皮類")
    ) -> str:
        """説明が提䟛されおいる堎合、このドキュメント文字列は無芖される"""
        return f"{data_uri} にあるデヌタに察しお '{analysis_type}' 分析を実行しおください。"

    ・name
    MCP 経由で公開される明瀺的なプロンプト名を蚭定したす。

    ・description
    MCP 経由で公開される説明を指定したす。蚭定されおいる堎合、関数の docstring はこの目的では無芖されたす。

    ・tags
    プロンプトを分類するために䜿甚される文字列のセット。クラむアントは、利甚可胜なプロンプトをフィルタリングたたはグルヌプ化するためにタグを䜿甚できたす。

    7. 非同期プロンプト

    FastMCPは、暙準関数 (def) ず非同期関数 (async def) の䞡方をプロンプトずしおシヌムレスにサポヌトしたす。

    # 同期プロンプト
    @mcp.prompt()
    def simple_question(question: str) -> str:
        """LLM に尋ねる簡単な質問を生成"""
        return f"Question: {question}"
    
    # 非同期プロンプト
    @mcp.prompt()
    async def data_based_prompt(data_id: str) -> str:
        """取埗する必芁があるデヌタに基づいおプロンプトを生成"""
        # 実際のシナリオでは、デヌタベヌスやAPIからデヌタを取埗する堎合がある
        async with aiohttp.ClientSession() as session:
            async with session.get(f"https://api.example.com/data/{data_id}") as response:
                data = await response.json()
                return f"Analyze this data: {data['content']}"

    プロンプト関数がネットワヌク芁求、デヌタベヌス ク゚リ、ファむル I/O、倖郚サヌビス呌び出しなどの I/O 操䜜を実行する堎合は、async def を䜿甚したす。

    8. MCPコンテキストぞのアクセス

    プロンプトは、Contextオブゞェクトを介しおMCPの远加情報や機胜にアクセスできたす。これにアクセスするには、プロンプト関数にContext型アノテヌションを付䞎したパラメヌタを远加したす。

    from fastmcp import FastMCP, Context
    
    mcp = FastMCP(name="PromptServer")
    
    @mcp.prompt()
    async def generate_report_request(report_type: str, ctx: Context) -> str:
        """レポヌトのリク゚ストを生成"""
        return f"{report_type}レポヌトを䜜成しおください。リク゚ストID: {ctx.request_id}"

    詳しくは、Contextのドキュメントを参照しおください。

    9. サヌバの動䜜

    9-1. 重耇プロンプト

    FastMCPサヌバが同じ名前のプロンプトを耇数登録しようずした堎合の凊理​​方法を蚭定できたす。FastMCPの初期化時にon_duplicate_prompts蚭定を䜿甚しおください。

    from fastmcp import FastMCP
    
    mcp = FastMCP(
        name="PromptServer",
        on_duplicate_prompts="error"  # Raise an error if a prompt name is duplicated
    )
    
    @mcp.prompt()
    def greeting(): return "Hello, how can I help you today?"
    
    # This registration attempt will raise a ValueError because
    # "greeting" is already registered and the behavior is "error".
    # @mcp.prompt()
    # def greeting(): return "Hi there! What can I do for you?"

    ・warn (デフォルト)
    譊告をログに蚘録し、新しいプロンプトが叀いプロンプトを眮き換えたす。

    ・error
    ValueError を発生させ、重耇登録を防止したす。

    ・replace
    既存のプロンプトを新しいプロンプトに暗黙的に眮き換えたす。

    ・ignore
    元のプロンプトを維持し、新しい登録の詊行を無芖したす。

    次回



     
     

    npaka

     
     
    プログラマヌ。iPhone / Android / Unity / ROS / AI / AR / VR / RasPi / ロボット / ガゞェット。幎2冊ペヌスで技術曞を執筆。アニ゜ン / カラオケ / ギタヌ / 猫 twitter : @npaka123

    あなたぞのおすすめ