MCP Resources:让 AI Agent 拥有"知识库"

MCP 协议除了众所周知的 Tools(工具),还定义了 Resources(资源)------ 一种让 AI Agent 在对话开始前就"知道"上下文信息的机制。本文从概念到代码,深入解析 Resources 的设计思路和最佳实践。


问题:Agent 的"知识盲区"

每个 AI 编码 Agent 都会遇到同样的问题:模型很聪明,但对你的项目一无所知。

bash 复制代码
你: "帮我写个新功能"
Agent: "好的,我先看看项目结构..."
      → list_directory
      → read_file (package.json)
      → read_file (src/...)
      → read_file (src/...)
      (读了 5 个文件才理解项目)
      → 开始写代码

前几轮对话全花在"了解项目"上。更麻烦的是,有些知识文件里根本没有------比如团队的编码规范、API 鉴权规则、数据库命名约定。

你当然可以每次手动复制粘贴到任务描述里,但那就不是"自主 Agent"了。

MCP 的答案:Resources

MCP 协议定义了三种原语(Primitive):

原语 作用 方向
Tools 让 Agent 做事 Agent → Server
Resources 让 Agent 知道 Server → Agent
Prompts 让 Agent Server → Agent

Resources 的设计目标很明确:把知识从 prompt 中分离出来,交给专门的服务器管理

服务端:两种资源定义方式

静态资源 --- 固定 URI,内容不变

适合编码规范、API 约定、部署文档等内容固定的知识:

javascript 复制代码
server.registerResource(
  '编码规范',
  'guide://coding-standards',   // 固定 URI
  {
    description: '团队编码规范和最佳实践',
    mimeType: 'text/markdown',
  },
  async (uri) => ({
    contents: [{
      uri: uri.href,
      text: '# 编码规范 v1.0\n\n## 命名约定\n...',
    }],
  })
);

动态资源模板 --- 参数化 URI

适合项目文件、数据库 Schema 等按路径变化的资源:

javascript 复制代码
server.registerResource(
  '项目文件',
  new ResourceTemplate('project://{path}', {
    list: async () => ({           // 客户端发现有哪些资源
      resources: [
        { uri: 'project://package.json', name: 'package.json' },
        { uri: 'project://CLAUDE.md',    name: 'CLAUDE.md' },
      ],
    }),
  }),
  { description: '读取项目文件' },
  async (uri, variables) => ({     // 客户端读取具体内容
    contents: [{ uri: uri.href, text: readFile(variables.path) }],
  })
);

客户端:预读 vs 按需,一个关键决策

获取到资源列表后,怎么给模型用?两种策略:

arduino 复制代码
策略 A: 预读 (preRead: true)
┌──────────────────────────────────────┐
│ System Prompt                        │
│ ├── 基础指令              ~500 tokens│
│ ├── 编码规范全文         ~2000 tokens│
│ ├── API 文档全文         ~8000 tokens│
│ ├── 数据库 Schema        ~5000 tokens│
│ └── 部署配置全文         ~3000 tokens│
│ 总计: ~18500 tokens                  │
│                                      │
│ 问题: 即使任务只是"修一个 typo"       │
│ 这些资源也每轮都全额付费              │
└──────────────────────────────────────┘

策略 B: 按需读取 (preRead: false)
┌──────────────────────────────────────┐
│ System Prompt                        │
│ ├── 基础指令              ~500 tokens│
│ ├── 资源目录              ~150 tokens│
│ │   - 编码规范 (guide://...)         │
│ │   - API文档   (doc://...)          │
│ │   - ...                            │
│ └── 提示: 用 read_mcp_resource 读取  │
│ 总计: ~650 tokens                    │
│                                      │
│ 模型判断需要规范 → 调用工具读取       │
│ → 资源内容作为 ToolMessage 返回       │
│ → 仅本轮多 ~2000 tokens              │
└──────────────────────────────────────┘

核心洞察 :Resources 和 Tools 可以互相转化。把"读取资源"包装成工具 read_mcp_resource,模型自己判断何时需要什么知识。这比把所有知识一股脑塞进 system prompt 要聪明得多。

实现:从 URI 到上下文

整条链路分四步:

javascript 复制代码
// 1. 客户端列出所有服务器的资源
const resources = await client.listResources();
// → { serverA: [{ uri, name, description }], serverB: [...] }

// 2. 构建资源目录(只取元数据,不读内容)
const ctx = await buildResourcesContext(mcpManager, { preRead: false });
// → "## 可用 MCP 资源\n- 编码规范 (guide://...)\n..."

// 3. 注入 system prompt
const prompt = createSystemPrompt(cwd, {
  toolNames: [...],
  mcpResourcesContext: ctx,
});

// 4. 模型按需调用 read_mcp_resource 工具
// → read_mcp_resource({ serverName: "demo", uri: "guide://coding-standards" })
// → ToolMessage: "# 编码规范 v1.0\n..."

工程实践:三个关键原则

1. 上下文窗口是稀缺资源

System Prompt 中的每个 token 都会在每一轮对话中被计费。把内容放在 ToolMessage(历史消息)中,只在实际用到的那几轮占用窗口。

2. 错误不阻断

资源读取失败只是 warn,不阻止 Agent 启动。Agent 降级为无资源的模式也能工作:

javascript 复制代码
async getResources() {
  try {
    return await this.#client.listResources();
  } catch (e) {
    logger.warn(`获取 resources 失败: ${e.message}`);
    return {};  // 降级,不崩溃
  }
}

3. 资源 = 元数据 + 内容,分两步给模型

第一步只给元数据(名称、描述、URI),模型不需要内容就能判断是否相关。第二步只在实际需要时才加载内容。这是典型的懒加载模式。

总结

MCP Resources 解决的是一个朴素的问题:如何让 AI Agent 在开始工作前就了解你的世界

答案不是把整个世界塞进 prompt,而是给它一个目录和一把钥匙------让它自己决定打开哪些门。

相关推荐
浮生望1 小时前
MCP 协议:打破工具围墙,让 AI Agent 跨语言跨进程调用任意工具
agent·mcp
凛风前行2 小时前
多智能体架构的 5 种经典模式
架构·agent
leeyi2 小时前
调试 Agent 的 3 个姿势:日志、断点、可视化(第49篇-E35)
aigc·agent·devops
ch8562 小时前
智能体13-RAG
agent
小林ixn2 小时前
远程 MCP 实战:让 AI 无缝调用地图、浏览器与文件系统
人工智能·agent·mcp
chanalbert2 小时前
Agent 工程化指南(一):概念与认知架构 — 智能体到底是什么、怎么思考
llm·agent
小林ixn2 小时前
AI Agent的“万能工具箱”:MCP协议实战,让工具调用不再受语言和进程束缚
人工智能·agent·mcp
一个处女座的程序猿4 小时前
Agent之Memory:claude-mem的简介、安装和使用方法、案例应用之详细攻略
agent·memory·claude-mem
To_OC5 小时前
MCP 入门实战:写一个能读本地文件的极简服务
人工智能·agent·mcp