Resources、Tools 与 Prompts 的分工
提示:在基于大语言模型的智能体开发中,如何合理划分知识供给、动作执行与任务指引是决定系统效率与准确性的核心。本文将深度解析 MCP 协议中的三大原语------Resources、Tools 与 Prompts,并结合 CrewAI 框架给出完整的企业级实现方案。特别针对"静态数据 vs 动态数据"的选型难题,提出可落地的决策标准,助你构建既省钱又聪明的 AI 应用
文章目录
- [Resources、Tools 与 Prompts 的分工](#Resources、Tools 与 Prompts 的分工)
- 前言
- 一、核心概念总览
- [二、Resources(资源)------ 应用控制的静态知识供给](#二、Resources(资源)—— 应用控制的静态知识供给)
-
- [2.1 定义与用途](#2.1 定义与用途)
- [2.2 何时优先使用 Resource ------ "静态数据金标准"](#2.2 何时优先使用 Resource —— “静态数据金标准”)
- [2.3 如何实现](#2.3 如何实现)
- [2.4 建议包含的内容](#2.4 建议包含的内容)
- [三、Tools(工具)------ 模型控制的动态操作](#三、Tools(工具)—— 模型控制的动态操作)
-
- [3.1 定义与用途](#3.1 定义与用途)
- [3.2 何时优先使用 Tool ------ "动态数据必用 Tool"](#3.2 何时优先使用 Tool —— “动态数据必用 Tool”)
- [3.3 如何实现](#3.3 如何实现)
-
- [3.3.1 服务端定义(FastMCP)](#3.3.1 服务端定义(FastMCP))
- [3.3.2 CrewAI 自动集成(mcps 字段)](#3.3.2 CrewAI 自动集成(mcps 字段))
- [3.3 工具过滤(安全管控)](#3.3 工具过滤(安全管控))
- [3.4 建议包含的内容](#3.4 建议包含的内容)
- [四、Prompts(提示词)------ 用户控制的快捷模板](#四、Prompts(提示词)—— 用户控制的快捷模板)
-
- [4.1 MCP 的设计哲学:用户控制(User-Controlled)](#4.1 MCP 的设计哲学:用户控制(User-Controlled))
- [4.2 如何在 MCP 中定义 Prompt](#4.2 如何在 MCP 中定义 Prompt)
- [4.3 与 CrewAI 的关系及实际使用](#4.3 与 CrewAI 的关系及实际使用)
- [4.4 注意事项](#4.4 注意事项)
- [五、三者的分工与协作 ------ 架构师决策树](#五、三者的分工与协作 —— 架构师决策树)
-
- [5.1 何时用 Resource,何时用 Tool ------ 决策流程图](#5.1 何时用 Resource,何时用 Tool —— 决策流程图)
- [5.2 协作模式:Resource 提供背景,Tool 执行检索](#5.2 协作模式:Resource 提供背景,Tool 执行检索)
- [5.3 Prompts 的位置](#5.3 Prompts 的位置)
- 六、企业级最佳实践清单
前言
随着 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 如何实现
python
# 服务端定义(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 中。
python
# 客户端读取并注入 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)
python
@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 可调用的工具。
python
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 工具过滤(安全管控)
python
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
python
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 执行。
python
# 应用层代码示例(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 ------ 决策流程图
text
数据是否需要 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,提升用户交互体验 |