前端开发者的 AI 笔记(二):Agent、MCP 与上下文管理 🤖

39 阅读8分钟

本篇聚焦于 Agent(智能体)的工程化落地:它是什么、能做什么,MCP 协议又扮演什么角色,以及在 AI IDE 中如何通过 Rules / Commands / Skills 实现高效的上下文管理。

一、从 LLM 到 Agent:缺了什么,补了什么

从最早的 GPT-3.5、Claude、DeepSeek-R1,这些大语言模型(LLM)本身就具备思考与规划的能力。

但那个阶段,它们有几个明显的局限:

问题原因
几天前的对话它不记得无 Memory(记忆)机制
给它一个链接让它处理,只能给建议无 Tools(工具调用)能力
无法获取最新资讯受训练截止日期限制,无搜索能力
无法基于私密文档回答缺少 RAG 内部知识库

后来,Copilot、Cursor 等 AI IDE 出现,带来了 Agent 模式,支持读写文件、执行命令、调用远端 MCP,能力边界被大幅拓展。

什么是 Agent(智能体/代理人)?

Agent 就是将大语言模型与工具结合,创建能够推理任务、决策工具选择并迭代寻找解决方案的系统。 简言之:给大模型加上 Tools、Memory、RAG 等能力扩展,满足其中若干项即构成 Agent。


二、用代码直观理解 Agent

拿 LangChain.js 举例,创建一个 Agent 的核心结构非常清晰:

import { ChatOpenAI } from "@langchain/openai";
import { tool } from "@langchain/core/tools";
import { HumanMessage, SystemMessage, ToolMessage } from "@langchain/core/messages";
import { z } from "zod";
import fs from "node:fs/promises";

// 1. 初始化大语言模型
const model = new ChatOpenAI({
  model: "gpt-5",
  temperature: 0,
});

// 2. 定义工具:读取文件内容
const readFileTool = tool(
  async ({ filePath }) => {
    const content = await fs.readFile(filePath, "utf-8");
    return `文件内容:\n${content}`;
  },
  {
    name: "read_file",
    description: "读取文件内容,输入文件路径(相对或绝对路径均可)",
    schema: z.object({
      filePath: z.string().describe("要读取的文件路径"),
    }),
  }
);

// 3. 将工具绑定到模型,Agent 可自主决定是否调用
const modelWithTools = model.bindTools([readFileTool]);

// 4. 发起对话,模型自动决策是否调用工具
const messages = [
  new SystemMessage("你是一个代码助手,可以使用工具读取并解释文件内容。"),
  new HumanMessage("请读取 ./index.ts 并解释这段代码"),
];

let response = await modelWithTools.invoke(messages);
messages.push(response);

// 5. 循环处理工具调用,直到模型不再需要工具
while (response.tool_calls?.length > 0) {
  for (const toolCall of response.tool_calls) {
    const result = await readFileTool.invoke(toolCall.args);
    messages.push(
      new ToolMessage({ content: result, tool_call_id: toolCall.id })
    );
  }
  // 将工具结果传回模型,继续推理
  response = await modelWithTools.invoke(messages);
}

console.log(response.content); // 最终回复

关键理解model 是大脑,tools 是手脚。bindTools 并不是强制模型调用工具,而是告知模型"有这些能力可用",由模型自主决策是否调用。

工具调用的完整闭环是:模型返回 tool_calls → 宿主代码执行对应工具 → 将结果以 ToolMessage 写回消息历史 → 模型再次推理,直到不再需要工具为止。 这个循环,就是 Agent "自主迭代"能力的核心。


三、MCP:Agent 的工具调用标准

Function Calling → MCP 的演进

早期让大模型调用外部工具,靠的是 Function Calling:在请求体中定义一组函数描述,模型决定调用哪个,再由开发者手动实现调用逻辑。每家模型厂商的实现方式不同,接入成本高,工具也无法跨 IDE、跨 Agent 复用。

MCP(Model Context Protocol) 解决的就是这个问题:它是一套开放的标准协议,Agent 与外部工具之间的通信方式被统一规范。

本质上,MCP 就是一个能返回一组 tools 的服务。 Agent 连接 MCP Server,获取可用工具列表,按需调用——和 Function Calling 做的是同一件事,但标准化、可复用、跨平台。


MCP 的两种连接模式

MCP 支持两种通信方式,适用场景不同:

模式通信方式典型场景
Stdio(标准输入输出)本地进程间通信本地文件操作、命令执行、浏览器桥接
HTTP(远程服务)网络请求云端 API、跨机器调用,如 Context7

对应配置示例:

{
  "mcpServers": {
    // Stdio 模式:启动一个本地 Node.js 子进程
    "browsermcp": {
      "command": "npx",
      "args": ["@browsermcp/mcp@latest"]
    },
    // HTTP 模式:直连远端服务
    "context7": {
      "url": "https://mcp.context7.com/mcp",
      "headers": {
        "CONTEXT7_API_KEY": "xxxxxxx"
      }
    }
  }
}

Cursor 启动时发生了什么?

当 Cursor 启动时,会读取本地 MCP 配置文件,并立即将每个 Stdio 类型的 MCP 作为一个子进程启动。以 browsermcp 为例,实际上是在后台执行了:

npx @browsermcp/mcp@latest

这个 Node.js 进程持续运行,通过 stdin/stdout 与 Cursor 保持通信。Cursor(作为 MCP Client)发送工具调用请求,MCP Server 处理后将结果写回 stdout,再返回给大模型。

整条链路如下:

┌──────────┐  stdio  ┌─────────────────┐  HTTP  ┌───────────────┐  Chrome API  ┌─────────────┐
│          │ ◄─────  │                 │ ◄────  │               │ ◄──────────► │             │
│  Cursor  │         │  Bridge Server  │        │  Chrome Ext   │              │  Chrome Tab │
│ (Agent)  │ ─────►  │   (Node.js)     │ ────►  │  (插件进程)    │ ──────────►  │  (用户页面)  │
└──────────┘         └─────────────────┘        └───────────────┘              └─────────────┘

上图以 chrome-mcp-stdio 这类"浏览器桥接型" MCP 为例。 它的特殊之处在于:不创建新浏览器实例,而是复用当前正在使用的浏览器及其登录状态,通过 Chrome Extension 作为中间桥接层传递消息。


四、上下文污染:Agent 工程化的真实挑战

由于 AI Agent 的 Context Window(上下文窗口)是有限的,如果把所有规范文档、组件库文档、提效脚本都以纯文本塞给大模型,会引发:

  • 信噪比下降:模型难以区分关键信息与冗余信息。
  • 推理效率下降:Token 消耗剧增,响应变慢。
  • AI 幻觉风险:过载的上下文可能导致模型"乱答"。

因此,现代 AI IDE(如 Cursor、反重力等)引入了模块化的上下文管理机制:Rules(规则)、Commands(命令)、Skills(技能)


五、三种上下文管理机制详解

Rules(规则)

  • 技术本质:相当于强注入的系统级 Prompt,每次会话都会被底层工具强制加载。
  • 性能开销:Always paid(持续 Token 消耗),无论当前任务是否相关。
  • 适用场合:代码库的绝对红线,例如编码规范、项目技术栈介绍。
  • 常见反模式:把长篇开发教程塞进 Rules,导致每次会话都背负巨大 Token 开销。

Commands(命令)

  • 技术本质:用户显式触发的确定性脚本,调用时将对应 Prompt 注入上下文。
  • 触发主体:开发者主动调用(如 /refactor/code-review)。
  • 性能开销:Paid when used(调用时才消耗 Token)。
  • 适用场合:重复性工作流的封装。
  • 常见反模式:把所有个人偏好设置都做成 Commands,导致命令列表膨胀难以维护。

Skills(技能)

  • 技术本质:标准化的数字资产文件夹结构,通常包含带 YAML 元数据的 SKILL.md 和配套的 scripts/references/,将特定领域的"标准作业程序(SOP)"模块化。
  • 触发机制:由 AI Agent 自行进行意图匹配并按需触发。
  • 运行机制:渐进式加载(Progressive Disclosure)——前端熟悉的懒加载理念:
    • L1 层:初始化时只读取描述元数据(用于路由判断)
    • L2 层:匹配到当前任务时,加载 Skill 正文说明
    • L3 层:执行过程中按需调用脚本或参考文档
  • 性能开销:Paid when needed(仅在 Agent 判定匹配时消耗 Token)。
  • 适用场合:特定领域的深度任务剧本。
  • 常见反模式:构建完全全局化的技能,相当于把 Skill 当成了 Rule 来用。

六、核心架构对比矩阵 📊

工程维度Rules(规则)Commands(命令)Skills(技能)
执行性质强制的全局拦截器(Interceptor)确定性的用户脚本(Script)启发式的动态模块(Dynamic Import)
触发主体宿主工具(The Tool)开发者(You)AI 代理(The Agent)
最佳实践核心配置与红线要求重复工作流封装领域任务级处理手册
上下文成本始终全量加载(Always paid)调用时加载(Paid when used)渐进式按需加载(Paid when needed)
常见反模式塞入长篇开发教程将所有偏好设置做成命令构建完全全局化的技能

七、架构协同与最佳实践

三者是松耦合但紧密协同的关系。以下是两个落地模式:

模式 A:Rules 作为"路由派发器"

为了保持 Rules 的轻量,将其定位为指向 Skills 的路由,而不是堆砌大量内容。

实践示例:

当调试生产环境错误时,加载 `incident-triage` skill;
当修改 UI 组件时,加载 `ui-change` skill。

优势:极大减少 System Prompt 体积,将"硬编码"变成"动态路由分发"。


模式 B:Commands 作为"API 聚合层"

将复杂逻辑沉淀在 Skills 中,把 Commands 作为触发一个或多个 Skills 的快捷入口

实践示例:

/refactor 命令背后的指令:
"加载 `tanstack` 和 `panda-css` skills,
并将此 Next.js 组件重构。
遇到文档问题时调用 Context7 MCP 服务器。"

优势:Commands 负责提升开发者体验(DX),Skills 负责维持代码质量和策略的可审查性


写在最后

从 LLM → Agent → MCP → 上下文管理工程化,这条线串联起来,就是 AI 从"聊天工具"到"工程化生产力"演进的路径。

作为前端工程师,理解这些机制的边界与协同,不仅能帮你用好现有的 AI IDE,也许未来会搭建出自己的 Agent 系统。

AI 还在快速演进,后面会继续更正或补充,欢迎关注~