CrewAI Flow 开发:Resources、Tools 与 Prompts 的分工

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,提升用户交互体验
相关推荐
练习两年半的攻城狮20 小时前
CrewAI Flow 开发:DSL接入Mcp高级
crewai
koharu1232 个月前
CrewAI :多智能体开发
人工智能·llm·agent·crewai
大龄码农有梦想2 个月前
Spring AI Alibaba和CrewAI:多智能体开源框架对比与选型
spring ai·crewai·多智能体协作框架·spring ai阿里巴巴·spring ai aliba·java智能体框架·python智能体框架
大龄码农有梦想2 个月前
单智能体编排 vs 多智能体协作:AI应用开发技术路线之争
人工智能·dify·langgraph·工作流编排·crewai·单智能体编排·多智能体协助
Java码农也是农3 个月前
Agent编排框架对比:LangGraph vs AutoGen vs CrewAI
langchain·autogen·langgraph·crewai
YuanDaima20484 个月前
[CrewAI] 第15课|构建一个多代理系统来实现自动化简历定制和面试准备
人工智能·python·面试·agent·crewai
七夜zippoe4 个月前
AI Agent 框架选型指南:OpenClaw、LangChain、AutoGPT、CrewAI 深度对比
人工智能·langchain·autogpt·crewai·openclaw
容沁风8 个月前
llama.cpp作为crewAI的模型后端
llama.cpp·crewai
YuanDaima20488 个月前
[CrewAI] 第5课|基于多智能体构建一个 AI 客服支持系统
人工智能·笔记·多智能体·智能体·crewai