前言
前几个月忙于准备软考(PS:今年的高项真是让我无语了,所以理所应当的挂了,心痛😣),所以一直没有更新文章。近几年一直在讨论AI,而AI中的MCP
和Agent
又是很火爆的概念,本文通过在日常开发的实践来阐述 MCP
和 Agent
来梳理自己的AI的知识体系。
什么是MCP?
概念
MCP,全称 Model Context Protocol,中文可以翻译为"模型上下文协议" ,是一种用于组织、规范、封装和传递大语言模型(LLM)所需上下文信息的协议或数据结构。
自己理解
最早接触到MCP
这个概念的时候是今年3月份,翻过一些文章,大概都将MCP比做为USB接口
,就台式电脑主机来说,鼠标、键盘、无线网卡都是通过USB接口来连接主机,如果这些硬件设施都有自己不同的接口,并且存在更新迭代(今天鼠标我啊升级了,要用USC接口),那么主机的零部件制造商要骂娘了。这里就可以引出MCP的作用中的一点,作为中间协议层,统一上下文。
MCP有什么作用?
- 不同模型对输入的要求不一样
- 有的要 Chat history、有的要 JSON prompt、有的支持函数调用、有的不支持
- 比如 OpenAI 支持 messages、function_call,Anthropic 支持 system, user, assistant 分段输入
- 开发者很难为每个模型分别维护输入结构
- 没有协议,开发者就需要为每个模型单独处理上下文拼接方式
- 多模型/多智能体交互时,缺少统一的上下文中间层
- 例如一个任务需要 GPT 生成草稿,Claude 校对,你怎么在多个模型之间传递上下文?
- 这时候 MCP 就是中间协议层。
运行MCP来深入理解
以运行高德MCP来加深概念,具体配置步骤在高德官方手册中已经罗列的比较详细了这里不做过多介绍。
需求描述
shell
##我五一计划去昆明游玩4天的旅行攻略。
#帮制作旅行攻略,考虑出行时间和路线,以及天气状况路线规划。
#制作网页地图自定义绘制旅游路线和位置。
##网页使用简约美观页面风格,景区图片以卡片展示。
#行程规划结果在高德地图app展示,并集成到h5页面中。
##同一天行程景区之间我想打车前往。
#生成文件名 kmTravel.html。
在 Cursor 中实际运行的效果
运行结果
MCP在这个运行过程中如何工作的?
接收并结构化用户输入
根据用户输入的需求,MCP会做以下事情
内容 | MCP 操作 |
---|---|
"计划五一去昆明旅游 4 天" | 提取目标城市、时间、天数 → slots: { city: "昆明", days: 4, date: "五一" } |
"制作网页地图、卡片式展示" | 明确输出格式要求 → output_format: "html_card_layout_with_map" |
"高德地图 app 展示路线" | 明确地图调用方式、工具偏好 → map_provider: "高德" |
"一天多景点打车" | 推断交通方式 → transport: "打车" |
"生成文件名 kmTravel.html" | 明确输出目标文件名 → file_output: "kmTravel.html" |
这些信息被 MCP 结构化封装为模型输入上下文 ,并转化成 prompt
,让 LLM 明确任务结构。
生成调用计划并调度 Agent
MCP 不直接执行任务,但它通过上下文组织,帮助 LLM 输出 可执行计划(Plan) ,并触发 Agent 动作:
json
{
"plan": [
"提取用户计划中的旅游日期和城市",
"搜索昆明热门景点,匹配天数分配",
"为每一天制定路线(支持打车移动)",
"调用地图服务获取坐标/地址",
"生成 html 页面,卡片样式展示图片和描述",
"命名为 kmTravel.html 并输出"
]
}
这时候,Agent 便根据计划调用工具(maps_text_search)
动态上下文管理
在 Cursor 的运行中可以看到一直在频繁调用maps_text_search这是:
- MCP 持续维护上下文状态
- 比如哪些景点已选、打车路线规划到第几天
- 并将这些状态每轮拼入新的 prompt 传递给 LLM,保持"多轮任务有记忆"
构建输出结果
最终 LLM 输出的 HTML 网页结构,也会由 MCP 提供辅助上下文信息
字段 | 含义 |
---|---|
title:五一昆明4天游玩攻略 | 作为html的标题 |
images: [url1, url2...] | 作为卡片图展示 |
day1: [景点1, 景点2] | 作为行程结构数据 |
MCP会将这些结构转化为 Prompt 中的填充信息、以及将模板变量供LLM生成网页代码。到这里算是MCP在这个示例中一个大致的运行框架,也引申出下列几个问题
Q&A
1. MCP构建的Prompt和我们自己配置的Prompt有什么区别?
传统 Prompt 和 MCP的对比
比较维度 | 传统 Prompt | MCP(模型上下文协议) |
---|---|---|
输入方式 | 人工写一句长 prompt | 自动组装结构化上下文 |
适配性 | 针对特定模型定制 | 一套结构,多模型通用(GPT、Claude、Gemini) |
可维护性 | 难以维护、易碎 | 清晰字段定义,可模块拼接 |
自动化 | 手动管理 | 支持自动提取意图、填槽、拼接上下文 |
多轮支持 | 很难构建 | 内置对话历史管理、压缩、重构能力 |
工具调用 | 需要 prompt hack | 支持 Function Calling 等机制原生封装 |
通用性 | prompt 写死 | 类似"协议层",可在多个 Agent 或系统中复用 |
举例说明
一份普通的Prompt
请帮我制作一份五一去昆明旅游4天的攻略,
包括出行路线、景点安排、地图定位、网页展示,
图片风格简洁美观,路线用高德地图展示,最好打车前往,
并生成 kmTravel.html 文件。
缺点:
- 语义混杂:多个需求混在一段文字中,不易解析
- 歧义大:模型不确定用户想重点解决什么(地图、网页、交通?)
- 无法多轮接力:每轮都要重述上下文,模型没有状态
- 不适合拆分执行:模型无法基于 Prompt 计划步骤调用工具
MCP 的结构化的Prompt
json
{
"task": "旅游攻略生成",
"slots": {
"location": "昆明",
"days": 4,
"date": "五一",
"transport": "打车",
"output_file": "kmTravel.html"
},
"preferences": {
"style": "简约卡片式网页",
"map_provider": "高德地图",
"features": ["路线规划", "景点地图", "图片展示"]
},
"history": [],
"tools": ["maps_text_search", "map_route_plan", "html_generator"]
}
MCP 会自动生成类似的prompt
ts
[
{ role: "system", content: "你是一个专业的旅游助手,帮用户生成可视化旅行攻略网页。" },
{ role: "user", content: "用户计划五一期间去昆明旅游,共4天。希望生成一份 HTML 网页攻略,要求如下:\n\n- 使用高德地图展示路线\n- 每天包含多个景点,打车前往\n- 页面为简约卡片风格\n- 输出文件名为 kmTravel.html\n\n请按天规划景点,调用地图工具获取位置,并最终生成网页。"}
]
而这种结构化更有利于Agent和LLM进行对话、也便于维护上下文状态、方便后续任务的复用。
2. 什么是Agent?
Agent 是一个能够自主感知环境、制定决策并执行动作的智能系统。
在大语言模型(LLM)时代的语境中:
AI Agent 是利用大模型(如 GPT-4、Claude)为"大脑",根据上下文、目标、工具,自主做决策并完成任务的模块化系统。
可以把Agent理解为一个"自动运行的AI助理",我们将人类助理与Agent进行比较
人类助理 | AI Agent |
---|---|
会接收你的任务 | 接收用户指令或系统任务 |
知道任务目标和背景 | 通过上下文(MCP)了解目标和约束 |
会用工具(浏览器、表格) | 会调用函数 / API / 插件 |
会根据反馈调整做法 | 具备多轮思考、决策、规划能力 |
会主动汇报或继续行动 | 能自动生成后续指令、递归执行 |
举例说明
在使用 Cursor中 你会把文件拖到对话框中然后进行询问,例如
我们分解这个流程
1. 用户提出请求
用户问 Cursor :"请帮我优化这个函数"
- 输入是自然语言
- 系统必须通过理解上下文(函数在哪?当前文件是什么?)来推理函数如何进行优化
2. 系统构建上下文
Agent 首先会自动从 IDE 获取当前上下文信息,构造给模型的前置信息:
信息维度 | 内容示例 |
---|---|
当前文件名 | Gold.vue |
光标位置 | 第 83 行 - 第 86行 |
当前函数名称 | randomList() |
用户指令 | "优化这个函数" |
环境 | 当前是 Vue 项目 |
3. LLM 分析意图 + 生成计划(可能多步)
json
{
"intent": "优化函数",
"plan": [
"分析 randomList 函数当前逻辑",
"识别用户希望优化的点",
"建议修改方案",
"执行代码修改"
]
}
如果用 OpenAI Function calling 结构,它还可能返回一个 function_call 给 Agent,例如:
json
{
"function_call": {
"name": "editCode",
"arguments": {
"file": "src/views/Gold.vue",
"range": [83, 90],
"new_code": "...修改后的函数体..."
}
}
}
4. Agent 接管执行(这是 Cursor 的核心)
Cursor 的 Agent 系统会接收到 LLM 的 function_call 或指令,然后做几件事:
操作 | 工具 | 说明 |
---|---|---|
查询代码 | readFile(file) 或 getCodeContext(location) | 获取目标函数 |
分析代码 | 可用辅助模型再次检查 | 交叉验证新逻辑是否符合 |
修改代码 | writeFile(file, newCode) | 实际执行写入 |
回显结果 | 展示 diff 或直接修改编辑器内容 | 用户可回滚 |
Cursor 背后的 agent 通常还会包括一些辅助功能:
- 文件跳转 / 依赖扫描
- Git 状态检查 / 是否保存
- 多文件引用追踪(symbol graph)
- 自动 commit
这就是一个 Cursor 使用Agent 执行的一个简单流程的示例了。
总结
本文其实比较浅显,MCP和Agent都是以很简单的例子进行介绍,着重是能明白这些东西都做了什么?这些东西有什么作用?梳理一下在AI洪流下的知识框架。