Resources、Tools 与 Prompts 的分工


提示:在基于大语言模型的智能体开发中,如何合理划分知识供给、动作执行与任务指引是决定系统效率与准确性的核心。本文将深度解析 MCP 协议中的三大原语——Resources、Tools 与 Prompts,并结合 CrewAI 框架给出完整的企业级实现方案。特别针对“静态数据 vs 动态数据”的选型难题,提出可落地的决策标准,助你构建既省钱又聪明的 AI 应用


前言

随着 MCP(Model Context Protocol)的普及,越来越多的企业选择将业务能力封装为 MCP 服务,并集成到 CrewAI 等多智能体框架中。然而,许多开发者对于 “什么时候该用 Resource,什么时候该用 Tool” 感到困惑,对于 “MCP 中的 Prompts 到底给谁用” 也存在误解。本文将逐一澄清这些核心问题,并给出可直接落地的代码示例。


一、核心概念总览

概念本质控制方触发时机典型内容
Resources(资源)只读数据(名词)应用代码(开发者控制)任务执行前主动加载合规文档、产品手册、历史案例库、静态配置
Tools(工具)可执行操作(动词)LLM(Agent)(模型自主决策)Agent 推理过程中按需调用实时查询、数据库更新、发送邮件、计算
Prompts(提示词)对话模板(快捷指令)人类用户(UI 控制)用户手动点选 / 应用上层逻辑触发预设的分析任务模板、斜杠命令

二、Resources(资源)—— 应用控制的静态知识供给

2.1 定义与用途

定义:Resources 是 MCP 中用于暴露只读数据的接口,不产生副作用,类似 RESTful 的 GET 端点。

用途

  • 将不变的或变化极慢的背景知识提前注入 Agent 的上下文,避免 LLM 做不必要的决策。
  • 降低 Token 消耗:省去 Agent 调用 Tool 获取固定信息的往返开销。
  • 作为 RAG 的标准化补充。

2.2 何时优先使用 Resource —— “静态数据金标准”

金标准:如果数据是静态的(或准静态的),且不需要 Agent 实时感知变化,请优先封装为 Resource。

  • 适合 Resource 的数据:广告法合规要点、公司品牌规范、产品技术参数表、固定的定价策略、历史成功的文案模板(摘要)。
  • 不适合 Resource 的数据:实时库存、当日汇率、用户会话状态、动态排行榜。

核心逻辑:将不变的数据提前“喂”给模型,既能减少推理轮次,又能节省 Token,是降本增效的关键

2.3 如何实现

# 服务端定义(FastMCP)

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("EcommerceKnowledge")

# 静态资源(固定 URI)
@mcp.resource("knowledge://compliance/general")
def get_general_compliance() -> str:
    return "通用广告法须知:禁止虚假宣传,需标明广告..."

# 动态资源(URI 模板)—— 可根据参数返回不同内容,但依然由应用控制读取时机
@mcp.resource("knowledge://compliance/{category}")
def get_compliance_by_category(category: str) -> str:
    # 可从数据库读取,但建议缓存
    return f"这是 {category} 类目的特殊合规要求..."

# 二进制资源(如图片、PDF,但注入文本时需转化)
@mcp.resource("file://reports/sales_q1.pdf")
def get_q1_report() -> bytes:
    with open("sales_q1.pdf", "rb") as f:
        return f.read()

由于 CrewAI 的 mcps 字段只自动导入 Tools,对于 Resources,我们需要在代码中显式读取,然后拼接到 Agent 的 backstory 或 Task 的 description 中。

#  客户端读取并注入 CrewAI(FastAPI + 异步读取)
import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
from crewai import Agent, Task, Crew

async def fetch_resource(uri: str) -> str:
    """通用的 MCP 资源读取函数"""
    server_params = StdioServerParameters(
        command="python",
        args=["mcp_server.py"]  # 你的服务端文件
    )
    async with stdio_client(server_params) as (read, write):
        async with ClientSession(read, write) as session:
            await session.initialize()
            result = await session.read_resource(uri)
            return result.contents[0].text

async def create_agent_with_context():
    # 读取两个静态资源
    compliance = await fetch_resource("knowledge://compliance/general")
    product_manual = await fetch_resource("knowledge://products/manual")

    agent = Agent(
        role="合规营销专家",
        goal="撰写符合法规的产品文案",
        backstory=f"""
        你是一位资深的电商营销专家,熟悉以下背景知识:
        --- 合规指南 ---
        {compliance}
        --- 产品手册 ---
        {product_manual}
        请结合这些信息,确保文案合法合规。
        """,
        # 注意:这里不包含 mcps,因为 Tools 通过其他方式注入(见后文)
    )
    task = Task(description="为新品撰写营销文案", expected_output="Markdown文案", agent=agent)
    crew = Crew(agents=[agent], tasks=[task])
    return crew.kickoff()

2.4 建议包含的内容

以下类型的静态或准静态数据,非常适合封装为 Resource,在任务开始前注入 Agent 上下文:

  • 法律法规与公司政策:如广告法合规要点、数据安全规范、品牌使用指南等,为 Agent 提供明确的合规边界。
  • 产品技术参数与规格说明:详细的产品特性、性能指标、使用限制等,确保生成内容的技术准确性。
  • 历史成功案例(摘要):过往优秀的营销文案、解决方案或设计案例的精华总结,为 Agent 提供可借鉴的范本。
  • 用户画像(静态快照):目标用户群体的典型特征、偏好与行为模式,帮助 Agent 进行更具针对性的创作。
  • 数据库 Schema 定义:表结构、字段含义及关系说明,辅助 Agent 理解业务数据模型,生成更合理的查询或分析。

三、Tools(工具)—— 模型控制的动态操作

3.1 定义与用途

定义:Tools 是 MCP 中用于执行动作的接口,具有副作用(如修改数据、调用外部 API)。

用途

  • 实时数据获取:让 Agent 能够实时获取变化的数据,如库存、价格、汇率等。
  • 写操作执行:执行创建订单、更新记录等数据修改操作。
  • 外部系统交互:与外部系统进行交互,如发送邮件、调用第三方服务等。

3.2 何时优先使用 Tool —— “动态数据必用 Tool”

金标准:凡是实时性要求高、结果依赖查询参数、需要 Agent 自主决定调用时机的数据操作,请封装为 Tool。

  • 适合 Tool 的操作:搜索商品(关键词动态)、查询库存、获取今日汇率、计算折扣价、发送验证码等。
  • 不适合 Tool 的场景:固定不变的合规条款(应用 Resource 更省)。

核心逻辑:将动态的、需要实时交互的操作交给 Agent 自主决策调用,既能保证数据的时效性,又能充分发挥 Agent 的推理能力。

3.3 如何实现

3.3.1 服务端定义(FastMCP)

@mcp.tool()
def search_products(keyword: str, limit: int = 10) -> str:
    """根据关键词搜索商品,返回名称和价格列表"""
    # 模拟实时数据库查询
    return f"找到 {limit} 个与 '{keyword}' 相关的商品..."

@mcp.tool()
def get_inventory(product_id: str) -> dict:
    """查询某商品的实时库存"""
    # 调用库存微服务
    return {"product_id": product_id, "stock": 100, "updated_at": "2025-01-01T12:00:00"}

@mcp.tool()
async def place_order(product_id: str, quantity: int) -> dict:
    """下单,返回订单 ID"""
    # 异步执行订单创建
    return {"order_id": "ORD-123", "status": "success"}

3.3.2 CrewAI 自动集成(mcps 字段)

CrewAI 通过 mcps 字段自动发现 MCP 服务器中的所有 Tools,并转化为 Agent 可调用的工具。

from crewai import Agent
from crewai.mcp import MCPServerHTTP

agent = Agent(
    role="电商运营专员",
    goal="高效处理客户订单",
    backstory="你可以查询商品、库存并下单。",
    mcps=[
        MCPServerHTTP(
            url="http://localhost:8000/mcp",          # 服务端地址
            headers={"Authorization": "Bearer token"},
            streamable=True,                          # 推荐开启
            cache_tools_list=True,                    # 缓存工具列表,提升性能
            # tool_filter=...                        # 可选工具过滤
        )
    ]
)
# Agent 现在拥有 search_products, get_inventory, place_order 等工具

3.3 工具过滤(安全管控)

from crewai.mcp.filters import create_static_tool_filter

MCPServerHTTP(
    url="...",
    tool_filter=create_static_tool_filter(
        allowed_tool_names=["search_products", "get_inventory"]  # 只允许查询,不允许下单
    )
)

3.4 建议包含的内容

以下类型的动态操作,非常适合封装为 Tool,由 Agent 在推理过程中按需调用:

  • 实时查询类:商品搜索、库存查询、价格查询、汇率查询等。
  • 更新类:创建订单、更新用户信息、修改配置等。
  • 计算类:折扣计算、税费计算、运费计算等。
  • 通知类:发送邮件、短信、推送通知等。

四、Prompts(提示词)—— 用户控制的快捷模板

4.1 MCP 的设计哲学:用户控制(User-Controlled)

MCP 中的 Prompts 并非为 Agent 自动调用而设计,其真正角色是:为终端用户(或上层应用)提供可复用的对话模板。它类似于聊天软件中的斜杠命令(Slash Commands),用户输入 / 即可选择预设任务,填写参数后发送。客户端(如 Claude Desktop)通过 prompts/list 发现可用模板,通过 prompts/get 获取填充后的完整消息。

4.2 如何在 MCP 中定义 Prompt

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("EcommerceAssistant")

@mcp.prompt()
def analyze_sales(product_category: str) -> str:
    """生成销售分析报告模板(用户可调用)"""
    return f"请分析 {product_category} 类目最近30天的销售数据,包括趋势、Top 5 热卖品和滞销品。"

@mcp.prompt()
def draft_marketing_copy(product_name: str, target_audience: str) -> str:
    """撰写营销文案模板"""
    return f"请为 '{product_name}' 撰写针对 '{target_audience}' 的营销文案,需突出核心卖点并包含行动呼吁。"

4.3 与 CrewAI 的关系及实际使用

CrewAI 目前不自动消费 MCP Prompts,因此你不能指望 Agent 在运行时自动选择调用。正确的用法是:在 UI 层(如 FastAPI 前端),通过 MCP 客户端列出所有 Prompts,并呈现给用户选择。当用户选择一个模板并填写参数后,应用代码将该模板的内容拼接到 CrewAI 的 Task 的 description 或 Agent 的 goal 中,再由 Agent 执行。

# 应用层代码示例(FastAPI)
@app.post("/run_task")
async def run_task(prompt_name: str, params: dict):
    # 1. 通过 MCP 客户端获取对应的 Prompt 内容
    prompt_text = await get_prompt(prompt_name, params)  # 假设已实现
    # 2. 创建 CrewAI Agent 和 Task,将 prompt_text 作为任务描述的一部分
    task = Task(description=prompt_text, expected_output="...")
    # 3. 执行
    result = crew.kickoff()
    return result

4.4 注意事项

  • 不要试图让 Agent 自动调用 Prompts,这不是 MCP 的设计目标。
  • Prompts 是给人类使用的便捷工具,帮助用户充分利用 MCP 服务的能力。

五、三者的分工与协作 —— 架构师决策树

5.1 何时用 Resource,何时用 Tool —— 决策流程图

数据是否需要 Agent 实时感知变化?
  │
  ├─ 否(静态/准静态)→ 数据量是否过大(超过上下文窗口)?
  │   ├─ 否 → 封装为 **Resource**(启动时注入)
  │   └─ 是 → 拆分为:Resource(摘要/方法论)+ Tool(按需检索)
  │
  └─ 是(动态/实时)→ 必须封装为 **Tool**,由 Agent 自主调用

5.2 协作模式:Resource 提供背景,Tool 执行检索

对于大型知识库(如历史案例 10 万条),建议组合使用:

  • Resource 提供“如何撰写案例”的方法论模板(几百字)。
  • Tool 提供“根据关键词搜索案例”的功能,让 Agent 带条件去向量库检索。

5.3 Prompts 的位置

Prompts 不与 Resources/Tools 直接协作,它们作用于用户交互层,为用户提供快捷入口。在后台,Prompts 填充的内容最终会转化为 Task 描述,引导 Agent 使用对应的 Resources 和 Tools。

六、企业级最佳实践清单

实践点说明
降本增效静态数据用 Resource,省去不必要的 Tool 调用和 Token 消耗
时效性保障动态数据必须用 Tool,确保 Agent 在关键时刻拿到最新值
大知识库处理Resource 提供结构,Tool 提供检索,避免上下文溢出
权限控制使用 tool_filter 限制 Agent 可调用的工具范围
缓存策略启用 cache_tools_list=True 减少工具发现延迟
监控与日志记录 Agent 调用了哪些 Tools,便于优化提示词
Prompt 管理将常用任务模板定义为 MCP Prompts,提升用户交互体验
Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐