乐闻世界logo
搜索文章和话题

如何在 MCP 中管理和使用提示词(Prompts)?

2月19日 21:38

MCP 的提示词(Prompts)管理功能允许预定义和管理可重复使用的提示词模板,提高开发效率和一致性。以下是详细的实现方法:

提示词定义

MCP 提示词包含名称、描述和参数化模板:

python
{ "name": "prompt_name", "description": "提示词描述", "arguments": [ { "name": "param1", "description": "参数1的描述", "required": true } ] }

1. 提示词注册

python
from mcp.server import Server server = Server("my-mcp-server") @server.prompt( name="code_review", description="代码审查提示词模板" ) async def code_review_prompt( code: str, language: str = "python" ) -> str: """生成代码审查提示词""" return f""" 请审查以下 {language} 代码,并提供改进建议: 代码: {code} 请关注以下方面: 1. 代码质量和可读性 2. 性能优化建议 3. 安全性问题 4. 最佳实践 5. 潜在的 bug """ @server.prompt( name="data_analysis", description="数据分析提示词模板" ) async def data_analysis_prompt( data: str, analysis_type: str = "summary" ) -> str: """生成数据分析提示词""" return f""" 请对以下数据进行 {analysis_type} 分析: 数据: {data} 请提供: 1. 数据摘要 2. 关键洞察 3. 趋势分析 4. 可视化建议 """

2. 提示词模板引擎

python
from string import Template import json from typing import Dict, Any class PromptTemplateEngine: def __init__(self): self.templates = {} def register_template(self, name: str, template: str, parameters: list): """注册提示词模板""" self.templates[name] = { "template": template, "parameters": parameters } def render(self, name: str, **kwargs) -> str: """渲染提示词模板""" if name not in self.templates: raise ValueError(f"模板 '{name}' 不存在") template_info = self.templates[name] template = template_info["template"] # 验证必需参数 required_params = [ p["name"] for p in template_info["parameters"] if p.get("required", False) ] missing_params = [ param for param in required_params if param not in kwargs ] if missing_params: raise ValueError( f"缺少必需参数: {', '.join(missing_params)}" ) # 使用 Template 渲染 t = Template(template) return t.substitute(**kwargs) def list_templates(self) -> list: """列出所有模板""" return [ { "name": name, "description": info.get("description", ""), "parameters": info["parameters"] } for name, info in self.templates.items() ]

3. 提示词版本管理

python
from datetime import datetime from typing import Optional class PromptVersionManager: def __init__(self): self.versions = {} self.current_versions = {} def save_version( self, prompt_name: str, version: str, template: str, metadata: dict = None ): """保存提示词版本""" if prompt_name not in self.versions: self.versions[prompt_name] = {} self.versions[prompt_name][version] = { "template": template, "metadata": metadata or {}, "created_at": datetime.now().isoformat() } def set_current_version(self, prompt_name: str, version: str): """设置当前版本""" if prompt_name not in self.versions or \ version not in self.versions[prompt_name]: raise ValueError(f"版本 '{version}' 不存在") self.current_versions[prompt_name] = version def get_current_version(self, prompt_name: str) -> Optional[str]: """获取当前版本""" return self.current_versions.get(prompt_name) def get_version( self, prompt_name: str, version: str ) -> Optional[dict]: """获取指定版本""" if prompt_name not in self.versions: return None return self.versions[prompt_name].get(version) def list_versions(self, prompt_name: str) -> list: """列出所有版本""" if prompt_name not in self.versions: return [] return list(self.versions[prompt_name].keys())

4. 提示词缓存

python
from functools import lru_cache import hashlib class PromptCache: def __init__(self, max_size: int = 1000): self.cache = {} self.max_size = max_size def _generate_key( self, prompt_name: str, params: dict ) -> str: """生成缓存键""" param_str = json.dumps(params, sort_keys=True) combined = f"{prompt_name}:{param_str}" return hashlib.md5(combined.encode()).hexdigest() def get(self, prompt_name: str, params: dict) -> Optional[str]: """获取缓存的提示词""" key = self._generate_key(prompt_name, params) return self.cache.get(key) def set(self, prompt_name: str, params: dict, prompt: str): """设置缓存""" # 如果缓存已满,删除最旧的条目 if len(self.cache) >= self.max_size: oldest_key = next(iter(self.cache)) del self.cache[oldest_key] key = self._generate_key(prompt_name, params) self.cache[key] = prompt def clear(self): """清空缓存""" self.cache.clear() def invalidate(self, prompt_name: str): """使指定提示词的缓存失效""" keys_to_remove = [ key for key in self.cache if key.startswith(hashlib.md5(prompt_name.encode()).hexdigest()[:16]) ] for key in keys_to_remove: del self.cache[key]

5. 提示词测试和验证

python
class PromptTester: def __init__(self, template_engine: PromptTemplateEngine): self.engine = template_engine def test_template( self, template_name: str, test_cases: list ) -> dict: """测试提示词模板""" results = { "template": template_name, "total_tests": len(test_cases), "passed": 0, "failed": 0, "errors": [] } for i, test_case in enumerate(test_cases): try: # 渲染提示词 prompt = self.engine.render( template_name, **test_case["params"] ) # 验证输出 if "expected_contains" in test_case: for expected in test_case["expected_contains"]: if expected not in prompt: results["errors"].append({ "test": i, "error": f"期望包含 '{expected}' 但未找到" }) results["failed"] += 1 break else: results["passed"] += 1 else: results["passed"] += 1 except Exception as e: results["errors"].append({ "test": i, "error": str(e) }) results["failed"] += 1 return results def validate_parameters( self, template_name: str, params: dict ) -> tuple[bool, str]: """验证参数""" try: # 尝试渲染提示词 self.engine.render(template_name, **params) return True, "" except Exception as e: return False, str(e)

6. 提示词分析和优化

python
import re from collections import Counter class PromptAnalyzer: def analyze(self, prompt: str) -> dict: """分析提示词""" return { "length": len(prompt), "word_count": len(prompt.split()), "sentence_count": len(re.split(r'[.!?]+', prompt)), "token_estimate": self._estimate_tokens(prompt), "complexity": self._calculate_complexity(prompt), "variables": self._extract_variables(prompt) } def _estimate_tokens(self, text: str) -> int: """估算 token 数量""" # 粗略估算:英文约 4 字符/token,中文约 1.5 字符/token chinese_chars = len(re.findall(r'[\u4e00-\u9fff]', text)) english_chars = len(re.findall(r'[a-zA-Z]', text)) return int(chinese_chars / 1.5 + english_chars / 4) def _calculate_complexity(self, prompt: str) -> float: """计算复杂度""" words = prompt.split() unique_words = set(words) # 词汇多样性 diversity = len(unique_words) / len(words) if words else 0 # 平均句子长度 sentences = re.split(r'[.!?]+', prompt) avg_sentence_length = sum(len(s.split()) for s in sentences) / len(sentences) if sentences else 0 return (diversity + min(avg_sentence_length / 20, 1)) / 2 def _extract_variables(self, prompt: str) -> list: """提取变量""" return re.findall(r'\{(\w+)\}', prompt)

最佳实践:

  1. 参数化设计:使用参数化模板提高复用性
  2. 版本控制:对重要提示词实施版本管理
  3. 缓存策略:缓存渲染结果提高性能
  4. 测试覆盖:编写测试用例确保提示词质量
  5. 性能监控:监控提示词的 token 使用和性能
  6. 文档完善:为每个提示词提供清晰的文档

通过完善的提示词管理机制,可以提高 MCP 系统的开发效率和一致性。

标签:MCP