96SEO 2026-04-20 23:30 1
在上一篇文章中,我们虽然Yi经成功搭建了一个Neng够跑通的MCP服务端,但老实说那仅仅是触及了皮毛。我们仅仅利用了Zui基础的ToolNeng力,就像买了一台顶配的电脑却只用来打字一样,实在有些大材小用。MCP真正的魅力,在于它精心设计的三大原语——ToolsResources以及Prompts。这三者并非孤立存在而是各自拥有独特的设计哲学,只有深刻理解它们并灵活组合,才Neng构建出真正强大的AI应用。

今天我们就来一场深度的技术探险,不再满足于“Neng用”,而是要追求“好用”和“极致”。我们将剖析每一个原语的高级特性,并通过一个完整的“企业内部知识库助手”案例,kankan这三者是如何像齿轮一样精密咬合,协同工作的。准备好了吗?让我们开始吧。
一、 核心架构:三大原语的哲学在深入代码之前,我们需要先在脑海中建立起一个宏观的框架。hen多开发者容易混淆这三个概念,导致设计出来的系统逻辑混乱。其实区分它们非常简单,你只需要问自己三个问题:
AI需要“知道”什么? —— 这是 Resources。它是数据,是上下文,是AI读取信息的源头。比如数据库的当前状态、系统日志、或者一份PDF文档。资源通常是只读的,或者至少是偏向于“提供信息”的。
AI需要“Zuo”什么? —— 这是 Tools。它是动作,是执行Neng力。比如发送邮件、修改数据库记录、调用API。工具往往带有副作用,会改变系统的状态。
AI该“怎么”Zuo? —— 这是 Prompts。它是工作流,是标准作业程序。它告诉AI在面对特定任务时应该遵循什么样的步骤,调用什么工具,引用什么资源。
为了geng直观地理解,我们Ke以把这三者kan作一个团队:
┌─────────────────────────────────────────┐
│ │
│ Resources Tools Prompts │
│ │
│ │
│ 提供数据 执行具体动作 制定策略 │
│ 只读为主 读写均可 结构化引导 │
│ │
└─────────────────────────────────────────┘
二、 Tools 深度解析:不仅仅是函数调用
工具是AI与外部世界交互的手臂。但Ru果你只是简单地把一个Python函数包装成Tool,那你可Neng忽略了MCP协议提供的强大控制Neng力。
1. 输入 Schema 的高级用法Tools 的 inputSchema 完整支持 JSON Schema 规范。这不仅仅是用来校验参数的,它是AI理解如何使用工具的“说明书”。写得好的Schema,Neng让AI少犯hen多低级错误。
我们来kan一个TypeScript的例子,这是一个用于分析Pull Request的工具:
{
name: "analyze_pr",
description: "深入分析 Pull Request 中的代码变geng细节",
inputSchema: {
type: "object",
properties: {
pr_number: {
type: "integer",
description: "需要分析的PR编号",
minimum: 1
},
analysis_type: {
type: "string",
enum: ,
description: "指定分析的维度",
default: "all"
},
severity_threshold: {
type: "string",
enum: ,
description: "过滤阈值,只报告高于此级别的严重问题",
default: "medium"
}
},
required: ,
additionalProperties: false
}
}
这里有个细节值得玩味:additionalProperties: false。这行代码告诉AI:“别自作聪明,除了我定义的参数,其他的dou别传。”这在防止AI产生幻觉参数时非常有效。
而在Python中,借助于FastMCP,我们Ke以用geng优雅的方式实现同样的逻辑。框架会自动从类型注解和文档字符串生成JSON Schema,省去了手写繁琐JSON的痛苦:
from mcp.server.fastmcp import FastMCP
mcp = FastMCP
@mcp.tool
def search_documents(
query: str,
categories: list | None = None,
date_range: dict | None = None,
max_results: int = 10,
sort_by: str = "relevance"
) -> list:
"""
在内部文档库中进行全文检索
参数说明:
query: 用户输入的搜索关键词
categories: 用于过滤的文档类别列表
date_range: 时间限制,格式为 {"start": "2023-01-01", "end": "2023-12-31"}
max_results: 返回结果的Zui大数量,建议在 5-20 之间
sort_by: 排序策略,支持 "relevance"或 "date"
"""
# 实际的搜索逻辑将在这里执行
...
2. 工具注解:给AI装上“红绿灯”
有些操作是无害的,比如读取配置;但有些操作是危险的,比如删除数据库。MCP允许我们通过“注解”来标记工具的行为,从而让主机决定是否需要用户确认。
比如下面这个删除记录的工具,我们明确告诉主机:这玩意儿有副作用,而且不可逆!
{
name: "delete_records",
description: "从数据库中彻底删除指定记录",
inputSchema: { ... },
// 关键在于这里的 annotations 字段
annotations: {
readOnlyHint: false, // 明确这不是只读操作
destructiveHint: true, // 警告:这是破坏性操作,不可撤销
idempotentHint: false, // 提示:这不是幂等的,重复执行会出问题
openWorldHint: false // 说明:仅影响本地系统状态
}
}
这些注解就像是给AI装上了红绿灯。当AIkan到 destructiveHint: true 时就会知道必须停下来请求用户的明确批准,而不Neng偷偷摸摸地执行。
| 注解字段 | 具体含义 | 主机的潜在反应 |
|---|---|---|
readOnlyHint: true |
纯粹的读取操作 | Ke以直接自动执行,无需打扰用户 |
destructiveHint: true |
破坏性、不可逆操作 | 强制弹出确认框,要求用户点头 |
idempotentHint: true |
幂等操作 | 网络波动时Ke以安全地自动重试 |
openWorldHint: true |
影响外部系统 | 执行前会格外谨慎,可Neng需要二次确认 |
在开发中,我们经常混淆两种错误:一种是工具本身挂了另一种是工具运行正常,但业务逻辑没通过。在MCP中,我们必须严格区分这两者。
协议级错误: 这种情况下直接抛出异常。MCP宿主会将其视为系统故障。
@mcp.tool
def read_file -> str:
if not os.path.exists:
# 文件不存在这是系统层面的异常,直接抛出
raise FileNotFoundError
return open.read
业务级错误: 这种情况下工具其实成功执行了应该返回一个带有 isError: true 标记的结果,而不是抛异常。这样AI就Neng理解:“哦,原来是用户输错了密码”,而不是“程序崩溃了”。
// TypeScript 示例:处理业务逻辑错误
server.setRequestHandler => {
const result = await performOperation;
if {
// 注意这里:我们返回了内容,但标记了 isError
return {
content: ,
isError: true // 告诉AI:这是业务失败,不是系统崩溃
};
}
return {
content:
};
});
三、 Resources 深度解析:数据的脉搏
Ru果说Tools是肌肉,那Resources就是血液。它为AI提供实时的、结构化的数据。
1. URI 的艺术Resources通过URI进行标识。一个好的URI设计,Neng让AI一眼就kan懂资源的含义。MCP支持各种自定义的URI协议,这让系统 性极强:
file:///var/log/app.log # 本地日志文件
postgres://prod-db/users/schema # 数据库结构
memory://session/current # 内存中的会话状态
config://app/production # 配置信息
custom://sensors/temperature # 自定义传感器数据
我们Ke以把资源分为两类:
静态资源: URI固定,内容可Neng变,但地址不变。
@mcp.resource
def get_settings -> str:
"""获取应用的运行时配置"""
return json.dumps({
"version": "2.4.0",
"environment": "production",
"features": {"new_ui": True, "dark_mode": False}
})
动态资源: URI本身包含参数,根据参数返回不同数据。
@mcp.resource
def get_user_profile -> str:
"""根据用户ID获取档案信息"""
user = db.query
if not user:
raise ValueError
return json.dumps
2. 资源订阅:实时推送
这是ResourcesZui酷的功Neng之一。AI不需要轮询,而是Ke以订阅一个资源。一旦资源发生变化,Server会主动通知AI:“嘿,数据变了快来kankan!”
比如我们要监控CPU使用率:
from mcp.server.fastmcp import FastMCP
from mcp.types import Resource
import psutil
import time
import json
mcp = FastMCP
# 注册一个支持订阅的资源
@mcp.resource
def get_cpu_metrics -> str:
"""获取当前CPU使用率"""
return json.dumps({
"usage_percent": psutil.cpu_percent,
"timestamp": time.time
})
在TypeScript端,我们需要处理订阅请求并设置定时推送:
// 处理订阅请求
server.setRequestHandler => {
const { uri } = request.params;
if ) {
// 开启一个定时器,每2秒推送一次geng新
setInterval => {
await server.notification({
method: "notifications/resources/updated",
params: { uri }
});
}, 2000);
}
return {};
});
3. Resource vs Tool:到底用哪个?
这是新手Zui容易纠结的地方。这里有一个简单的判断口诀:
Ru果你只是想“kan一眼数据” → 用 Resource
Ru果你需要“执行某个动作” → 用 Tool
Ru果数据“一直在变” → Resource + 订阅
Ru果操作“有副作用且不可逆” → 用 Tool
四、 Prompts 深度解析:指挥的艺术
Prompts是连接用户意图和AINeng力的桥梁。它不仅仅是文字,它是结构化的模板。
1. 静态 Prompt:标准作业程序对于固定的任务,我们Ke以预定义好Prompt模板。比如一个安全审计流程:
@mcp.prompt
def security_audit_prompt -> str:
"""触发标准化的安全审计工作流"""
return """请严格按照以下步骤执行完整的安全审计:
1. 调用 scan_dependencies 工具,检查所有依赖库是否存在Yi知漏洞。
2. 调用 check_config 工具,验证服务器配置是否符合安全基线。
3. 调用 find_secrets 工具,扫描代码库中是否硬编码了密钥。
4. 汇总所有发现,按照 CVSS 评分进行降序排列。
5. 为每一个高危问题提供具体的修复建议和优先级。"""
2. 动态 Prompt:千人千面
Prompts也Ke以接受参数,根据不同的输入生成不同的指令。比如代码迁移助手:
@mcp.prompt
def code_migration_prompt(
from_framework: str,
to_framework: str,
file_path: str | None = None
) -> list:
"""
生成代码迁移指导方案
参数:
from_framework: 源技术栈
to_framework: 目标技术栈
file_path: 指定要迁移的文件路径
"""
scope = f"文件 {file_path}" if file_path else "整个项目"
return
3. 嵌入 Resources 的 Prompt
PromptsZui强大的功Neng之一,是Ke以直接引用Resources。这意味着AI在开始工作前,就Yi经“加载”了必要的数据。比如生成周报时直接嵌入本周的指标数据:
server.setRequestHandler => {
if {
const weekNumber = request.params.arguments?.week || getCurrentWeek;
return {
description: "生成工作周报",
messages:
};
}
});
五、 综合实战:构建企业级知识库助手
讲了这么多理论,是时候把它们揉在一起了。我们将构建一个企业知识库助手,它需要具备搜索文档、添加文档以及基于知识库回答问题的Neng力。
这个案例将完美展示三大原语的协同:
from mcp.server.fastmcp import FastMCP
import chromadb # 引入向量数据库
import json
import time
import hashlib
from pathlib import Path
# 初始化
mcp = FastMCP
client = chromadb.PersistentClient
collection = client.get_or_create_collection
# ── Resources:知识库数据层 ──────────────────────
@mcp.resource
def get_kb_stats -> str:
"""返回知识库的统计概览"""
count = collection.count
return json.dumps({
"total_documents": count,
"last_updated": time.strftime
})
@mcp.resource
def get_document -> str:
"""根据ID获取文档的完整内容"""
result = collection.get
if not result:
raise ValueError
return result
# ── Tools:知识库操作层 ──────────────────────────
@mcp.tool
def search_knowledge_base(
query: str,
n_results: int = 5,
category: str | None = None
) -> list:
"""
执行语义搜索
参数:
query: 搜索问题
n_results: 返回结果数量
category: 按类别过滤
"""
where = {"category": category} if category else None
results = collection.query(
query_texts=,
n_results=min,
where=where
)
documents =
# 格式化搜索结果
for i, doc in enumerate:
metadata = results
documents.append({
"id": results,
"title": metadata.get,
"category": metadata.get,
"relevance_score": 1 - results, # 转换为相似度
"excerpt": doc + "..." if len> 200 else doc
})
return documents
@mcp.tool
def add_document(
title: str,
content: str,
category: str,
tags: list | None = None
) -> str:
"""
向知识库录入新文档
参数:
title: 文档标题
content: 文档正文
category: 所属分类
tags: 标签列表
"""
# 生成唯一ID
doc_id = hashlib.md5).hexdigest
collection.add(
ids=,
documents=,
metadatas=
)
return f"✅ 文档Yi成功入库!ID: {doc_id}"
# ── Prompts:智Neng问答工作流 ──────────────────────
@mcp.prompt
def answer_with_kb -> str:
"""
基于知识库回答问题的标准模板
参数:
question: 用户提出的问题
strict: 严格模式
"""
strictness_note = "必须严格依据知识库内容回答,若库中无相关信息,请明确告知。" if strict else "优先参考知识库,必要时可补充通用知识。"
return f"""用户问题:{question}
请按以下步骤进行回答:
1. 调用 search_knowledge_base 工具,从不同角度检索相关内容。
2. 若找到相关文档,利用 kb://document/{{id}} 资源获取完整上下文。
3. 综合所有信息,给出完整、准确的回答。
回答要求:
- {strictness_note}
- 必须注明信息来源。
- 若发现信息冲突,请指出差异并给出Zui可靠的判断。"""
if __name__ == "__main__":
mcp.run
六、 Neng力协商:握手阶段的原理
你可Neng好奇,AI怎么知道这个Server支持哪些工具和资源?这一切dou发生在MCP Server启动时的“握手阶段”。
Server启动后会向主机发送一份“Neng力清单”,声明自己支持什么:
// Server 声明的Neng力清单示例
{
"capabilities": {
"tools": {
"listChanged": true // 告诉主机:我的工具列表可Neng会动态变化
},
"resources": {
"subscribe": true, // 告诉主机:我支持资源订阅功Neng
"listChanged": true // 告诉主机:我的资源列表可Neng会动态变化
},
"prompts": {
"listChanged": true // 告诉主机:我的提示模板可Neng会动态变化
}
}
}
主机收到这份清单后就会根据这些Neng力来调整自己的行为。比如Ru果kan到 resources.subscribe: true,它就知道Ke以建立长连接来监听数据变化了。
通过今天的深入剖析,相信你Yi经对MCP的三大原语有了全新的认识。从简单的Tool调用,到复杂的Resource订阅,再到结构化的Prompt工作流,MCP为我们提供了一套构建AI原生应用的完整“积木”。
真正的实战,不仅仅是写出Neng运行的代码,geng是要理解何时该用Tool,何时该用Resource,以及如何用Prompt将它们串联起来。那个“企业知识库助手”的例子,仅仅是一个开始。在下一篇文章中,我们将探讨 MCP + RAG 实战,kankan如何将向量检索和MCP深度结合,构建出真正具备推理Neng力的智Neng系统。国内使用Claude Code 访问ccAiHub.com,我们下期见!
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback