不只是“提示词”
很多人对 Prompt 的理解,还停留在“怎么跟 ChatGPT 说话”这个层面。坦白说,这个理解有点浅了。

Prompt 的本质,其实是人类与大型语言模型之间的一份“通信协议”。
打个比方,HTTP 定义了浏览器和服务器如何沟通,SQL 定义了应用和数据库如何交互,那 Prompt 定义的就是你和那个拥有千亿参数的“概率模型”之间的对话规则。你写 Prompt,本质上是在编写一份“声明式程序规范”——你声明了模型要扮演的角色、要完成的任务、行为边界以及输出的格式。剩下的,模型会在它那庞大的参数空间里自行寻找最优路径。这跟你写一条 SQL 查询,让数据库引擎自己去选择最佳执行计划,本质上是同一个道理。
一份真正的“声明式规范”在实际应用中长什么样呢?核心就在于,你不需要告诉模型“怎么一步步推理”,只需要清晰地定义好输入、输出和约束条件:
# 角色
你是一个 React 性能优化专家,擅长用 React DevTools Profiler 定位渲染瓶颈。
# 任务
分析以下组件的渲染性能问题。
# 约束
- 每个问题必须指出具体行号并给出修复代码
- 如果没有发现明显问题,说"未发现性能问题",不要强行找茬
- 用中文回复
# 上下文
- React 版本:18.2
- 该组件在用户快速滚动时会明显卡顿,列表项约 200 条
# 代码
{code}
看,这段 Prompt 里没有一行是“推理指令”——它只是划定了边界。模型自己就在参数空间里完成了从“性能问题”到“具体行号+修复代码”的精准映射。
Prompt 之所以值得被当作一项“工程”来对待,理由主要有三点:
- 模型能力是常量,而 Prompt 是唯一变量。 同样一个 GPT-4,好的 Prompt 和差的 Prompt,产出的质量差距可以高达一个数量级。
- Prompt 的能力具有“向上穿透”效应。 你调 API 需要写 System Prompt,做 RAG 要设计检索增强的 Prompt,搞 Agent 要为其下的每个子 Agent 定义角色 Prompt,就连模型微调(Fine-tuning)也要构造训练用的 Prompt。可以说,Prompt 工程是所有 AI 应用技术的地基。
- 它的入门门槛极低。 不需要昂贵的 GPU,不需要海量的训练数据,你只需要一个 API Key 和一颗愿意反复尝试的大脑。
所以,一段优秀的 Prompt 本质上就是一份清晰的声明式规范:明确定义角色(这决定了模型的注意力分配机制)、任务描述、约束条件、上下文注入和输出格式。你无需告诉模型“怎么推理”,只需定义好输入、输出和边界。理解了这一点,你也就看透了为什么 Prompt 能贯穿整个 AI 工具链——后面出现的 Skills、MCP、Agent、Agentic AI,本质上都是对这份“声明式规范”进行结构化、工程化和系统化的产物。
但 Prompt 有一个致命的缺陷:它是一次性的。
不妨仔细想想:Prompt 究竟算什么?本质上,它只是为单个任务提供的一份临时输入。你这次用完了,任务结束,这些信息也就随之消散了。它更像是一份临时交接文档,而不是一个能持续发挥作用的能力。这就像你每天都在重新培训一个新员工,而不是培养一个已经熟悉业务流程的老手。
这个缺陷在实际工程中暴露得特别快。一开始,团队可能只是在 Prompt 里加几条规则——“用 pnpm,不要 npm install”“legacy 目录别动”“API 请求统一走 request.ts”。项目简单时还好说,稍微复杂一点,Prompt 就开始失控,越来越长,最后变成了一本巨型 README。很多团队被逼得开始拼 Prompt、分 Prompt、搞嵌套 Prompt、甚至动态生成 Prompt,整个系统变得越来越诡异,越来越难以维护。
追根溯源,根本原因在于:Prompt 本身就不适合用来存储“长期经验”。 所有规则都被迫同时挤在一个巨大的上下文窗口中,但在真实的工程场景里,经验应当是“按场景激活”的。这就好比要求一个工程师,脑子里要永远装着公司所有项目的全部规范——这不现实,也没必要。这个矛盾,在编程场景中最早被放大,也由此催生了“Vibe Coding”的第一次系统化尝试。
Vibe Coding:Prompt 工程的第一现场
为什么 Prompt 的“一次性问题”偏偏在编程场景中最早暴露出来?因为代码生成对于风格一致性和规范约束的要求,远比普通对话要高得多。你今天告诉 AI “用 pnpm”,明天它就可能又给你来个 npm install;你强调过 legacy 目录不要动,下一轮它可能又改了里面的文件。普通聊聊天,这种“健忘”大家还能忍,但代码不行——一次不一致,就意味着一个 bug 甚至一次线上事故。
2024 年,Andrej Karpathy 提出了“Vibe Coding”的概念:你沉浸在编码的“氛围”里,用自然语言描述你的意图,AI 负责生成代码,你来审查、调整、再描述,直到满意为止。
这等于把“写代码”这件事,彻底变成了“描述需求”——从“你必须知道怎么做”,变成了“你只需要知道要做什么”。
这一层的 Prompt 工程,核心在于四个要点:
身份设定。 这不是在“催眠”AI,而是一种注意力分配机制。当你说出“你是 React 性能优化专家”,模型内部的概率分布就会自然而然地向 React 相关的知识空间倾斜。
# 差(无身份,模型漫无目标)
"优化这个组件"
# 好(身份锚定了知识空间)
"你是一个 React 性能优化专家。请分析以下组件的渲染性能。重点关注:不必要的重渲染、大列表虚拟滚动缺失、render 中的昂贵计算。"
上下文注入。 这是最容易被跳过、但也是最致命的一步。像 Cursor 这类工具能看到当前的打开文件,但它看不到你的 package.json、tsconfig.json,更看不到你们团队内部统一的代码规范。花 30 秒多输入这些上下文信息,能为你省下 30 分钟的调试时间。
## 项目上下文
- 框架:Next.js 14 (App Router)
- UI 库:shadcn/ui(不要用 Ant Design)
- 样式:Tailwind CSS
- 路径别名:@/ → src/
- 网络请求:用 @/lib/api 的 fetcher 封装,不要直接用 fetch
- 类型:严格模式,禁止 any
思维链(Chain of Thought)。 别让模型直接给答案,而是让它先展示推理过程。大模型是逐 token 生成的,推理的那些 token 会自回归地影响后续生成的答案 token——这相当于模型给自己提供了一个中间计算空间,思考路径更清晰,结果也更可靠。
# 差(直接要结果,模型容易跳步、遗漏边界情况)
"把 Class Component 改成 Function Component"
# 好(拆解步骤,每步输出后再进行下一步)
"把这个 Class Component 重构成 Function Component + Hooks。按以下步骤,每步输出后再进行下一步:
1. 分析生命周期方法,映射到 Hooks(componentDidMount → useEffect 等)
2. 识别 state 和 side effects
3. 识别 this 绑定,转换为 useCallback
4. 给出完整重构代码
如果发现 componentDidCatch,说明用了 Error Boundary,请特别指出。"
Few-shot 示例。 给 AI 提供 1-3 个示例,让它理解你期望的输出模式。一个精心编写的 Few-shot 示例,其效果胜过你用十句话强调“按我们的风格写”。
## 输出格式示例
输入:用户点击提交按钮后页面无响应
期望输出:
### 问题定位
- **文件**:src/components/SubmitButton.tsx 第 23 行
- **原因**:handleSubmit 中未处理 loading 状态,导致重复提交
### 修复方案
const [loading, setLoading] = useState(false);
const handleSubmit = async () => {
if (loading) return;
setLoading(true);
// ...
};
请按照以上格式分析我提交的 Bug。
但这一层也有它的致命局限:每次都从零开始。 你写了 50 次“项目用 shadcn/ui,不要用 any,下载用 downloadFile”,心态终于要崩了。但真正的痛苦还不只是“重复打字”——而是你昨天花了整整一个下午教 AI 搞定了一个线上 Redis 问题的排查流程,今天它完全不记得了,又要从查数据库开始。Vibe Coding 的根本问题,不在于 Prompt 不够长,而在于 Prompt 天生就不适合存储跨会话的长期经验。
每一次对话都是独立的一次性上下文,就像每天早上都换一个新员工,没有交接、没有记忆、更没有成长。
这就是它最致命的缺点。
那么,有没有可能把这些经验保存下来,按场景封装成一个个模块,下次需要时自动加载?
Skills:Prompt 的结构化封装
Vibe Coding 暴露了一个深层次的矛盾:用 Prompt 来存储“长期经验”这件事,本身就不合理。
为什么 Vibe Coding 时代的团队会在 Prompt 里越写越多、越拼越长?因为 Prompt 最大的特点是“所有规则永远同时存在”——你的前端规范、后端规范、部署规范、安全规范,全部挤在一个巨大的 System Prompt 里。不管当前任务是什么,所有规则都会被加载。但真实的工程不是这样的。当你要修改一个按钮的样式时,你根本不需要知道数据库 migration 的规范;当你在排查线上 CPU 飙升的问题时,也完全用不着按钮样式的设计规范。
经验,应该按场景激活,而不是全量常驻。
这,就是 Skills 要解决的根本问题。Skills 就是把一套经过反复验证的 Prompt、工具和工作流,打包成一个可复用的模块,根据不同的任务场景动态加载。它的定义方式通常是一个 Markdown 文件,里面声明了角色、任务、约束、触发条件和可用的工具。
如果说 React 组件封装了 HTML、CSS 和 Ja vaScript,那 Skills 封装的就是 Prompt 的最佳实践。
更关键的一点是:好的 Prompt 是需要调试的。 一个“代码审查 Prompt”,可能要反复迭代 20 次,才能稳定地产出高质量的结果。这不再是随手打出的几行字——这是经过测试验证的、有明确输入输出约定的、可以被 AI 自动选择和加载的“知识资产”。从 Vibe Coding 到 Skills,Prompt 完成了一次质变:从“输入框里的临时文字”,变成了“代码库里的正式模块”。
一个完整的 Skill 定义文件大概长这样:
# SKILL.md
---
name: frontend-code-review
description: |
前端代码审查专家。触发词:审查代码、code review、帮我看看这段代码。
---
## 角色
你是资深前端代码审查专家,精通 React、TypeScript 和现代前端工程化。
## 审查维度(按优先级)
1. *安全漏洞*(XSS、注入、敏感信息泄露)
2. *逻辑错误*(边界条件、空值处理、竞态条件)
3. *性能问题*(不必要重渲染、内存泄漏、大列表未虚拟化)
4. *可维护性*(硬编码、魔法数字、过长的函数)
5. *最佳实践偏离*
## 输出格式
### *严重问题*
- **位置**:第 X 行
- **问题**:...
- **修复**:`
```tsx
// 修复代码
``` `
### *改进建议*
...
### *总体评分*:X/10
## 约束
- 使用中文回复
- 每个问题必须给出具体行号和可运行的修复代码
- 代码块统一使用 tsx 语法高亮
- 如果代码无明显问题,说"未发现明显问题,整体质量良好",不要强行找问题。
但这一层也有它的局限:AI 的能力仍然局限于生成文本。Skills 让 AI 更可靠了,它能帮你审查代码,但它读不了 Figma 设计稿、操作不了浏览器去做端到端测试、也查不了你的数据库。
那么,如何让 AI 能读取设计稿?如何让它能操作浏览器?
这就要说到 MCP(Model Context Protocol) 了。
MCP:Prompt 变成工具协议
Skills 解决了一个关键问题——经验可以按场景加载、跨会话复用了。
但它没有解决另一个问题:AI 怎么操作外部世界? 一个装配了 frontend-debug Skill 的 AI,能精准地告诉你代码哪里有问题,但它打不开浏览器去帮你验证、查不了 GitHub 上有没有类似的 Issue、也运行不了 CI 来看看你改动之后测试过了没有。
Skills 让 AI 有了“经验”,但它缺了一双“手脚”。
MCP(Model Context Protocol),由 Anthropic 在 2024 年底开源,是一个定义了 AI 如何标准化地发现和调用外部工具的协议。
在 MCP 出现之前,每个 AI 应用想要接入工具都得单独适配一遍——给 ChatGPT 写一套 GitHub 集成,给 Claude 再写一套,给 Cursor 还得再写一套。
MCP 做的事情,就是定义了一个“标准插座”——任何符合标准的工具 Server,任何 MCP Client 插上就能用。
这里必须厘清 MCP 和 Skills 的关系——它们解决的根本不是同一层的问题。
- MCP 是“工具接入层”(Capability),让 AI 能够连接数据库、浏览器、GitHub、文件系统。
- Skills 是“经验组织层”(Experience),让 AI 知道在面对不同任务时应该怎么做,有哪些教训需要记住。
MCP 解决的是“AI 能不能做事”,Skills 解决的是“AI 能不能越做越熟练”。
两者不但不矛盾,而且 Skills 其实是 MCP 之后必然会出现的补位——因为当 AI 能做的事情越来越多、接的工具越来越复杂,如果没有一套经验系统来兜底,它只会犯更多、更严重的错误。这也是为什么 Skills 在 MCP 出现之后反而更流行了:工具能力不等于工程经验,后者需要一套持久化、可复用的知识体系。
这里有一个关键洞察:MCP Server 里每个工具的描述,本质上就是一段 Prompt。工具描述告诉 AI “这个工具存在,它有这个能力”;参数描述告诉 AI “city 这个参数应该填城市名称”;System Prompt 告诉 AI “涉及实时数据,优先用工具”。从用户说“北京今天热不热”,到 AI 调用 get_weather("北京") 并返回结果,整个推理链条的每一个环节,其实都是由 Prompt 驱动的。
一个 MCP Server 中工具的定义,本质上就是在写 Prompt:
// MCP Server 定义工具 —— 工具描述就是 Prompt
server.tool(
"get_weather",
"获取指定城市的实时天气信息,包括温度、湿度、风速、天气状况。" +
"适用场景:用户询问某地天气时的首选工具。" +
"局限:仅支持中国大陆城市。",
{
city: z.string().describe("城市名称,如 '北京'、'上海'、'深圳'"),
},
async ({ city }) => {
const data = await fetchWeatherAPI(city);
return {
content: [{ type: "text", text: JSON.stringify(data) }],
};
}
);
AI 读到上面的定义后,会自主完成三段推理:
- 工具发现—— “用户问天气,我有个 get_weather 工具”。
- 参数填写—— “city 参数填‘北京’”。
- 结果呈现—— “拿到 JSON 后,把它翻译成自然语言回复用户”。
这三个环节里,没有一行是硬编码的 if-else 逻辑,全部是由 Prompt 驱动的。
而对应的 System Prompt,则决定了工具使用的整体策略:
# MCP 层 System Prompt
## 工具使用原则
1. 涉及实时数据(天气、股价、新闻)→ 必须调用工具,禁止凭训练记忆回答
2. 涉及内部文档查询 → 优先调用 search_internal_docs
3. 工具调用失败 → 重试一次,仍失败则如实告知用户,不要编造结果
4. 同一任务优先合并工具调用(减少往返次数)
5. 工具返回数据过大时,只提取关键信息展示给用户
在这一层,Prompt 扮演了三个角色:工具发现(工具描述 Prompt 决定了 AI 能否在正确时机识别出这个工具)、参数填写(参数描述 Prompt 决定了 AI 能否正确填写参数——city: z.string() 远不如 city: z.string().describe("城市名称,如'北京'") 来得清晰)、以及错误恢复(当工具调用失败时,System Prompt 里的降级策略决定了 AI 是重试、换工具还是告知用户)。
这一层的局限也很明显:MCP 解决的是单步工具调用,它处理不了像“分析 GitHub 仓库 → 筛选技术点 → 每个点搜索论文 → 生成趋势报告”这样的多步复杂任务。
Agent:Prompt 成为决策系统
走到这一步,AI 已经具备了“经验”(Skills)和“手脚”(MCP 工具),但它还缺一项能力:自主决策能力。
Skills 是被动的——触发条件匹配上了,它才加载经验;MCP 是响应式的——你告诉 AI 调用哪个工具,它才去调用。但真实世界里的任务,不是这样线性推进的。
想一想,一个“帮我研究这个技术方向并出报告”的任务,背后需要什么?它需要的是:先拆解目标 → 决定搜索哪些关键词 → 调用 GitHub/论文 API → 读到一半发现有个概念不懂 → 再去搜索补充资料 → 整理成报告 → 检查是否有遗漏 → 修正。这绝对不是“调用一个工具 + 加载一个 Skill”能解决的——这需要一个持续的、自主的决策循环。
Agent 不是让 AI 回答一次就结束,而是让它进入一个持续运行的循环:Think(理解任务、拆解子目标、选择最优行动)→ Act(调用工具、执行操作)→ Observe(检查结果、对比预期、判断是否完成)。如果未完成,则回到 Think 阶段,基于新的信息调整策略。
Agent 的本质,是把“单次推理”升级为“多步决策循环”。一个真实的例子:如果你的任务是指令“找出 GitHub Star 增长最快的前端项目并写一份分析报告”,一个 Agent 可能会自主完成 12 步——调用 GitHub API 获取数据 → 用 Python 进行数据处理和排序 → 逐一搜索项目的背景资料 → 生成报告 → 最终写入文件。每一步的输出,都是下一步的输入;每一步都可能因为结果不符合预期而触发策略调整。
在 Agent 这个阶段,Prompt 不再是“一段指令”,而是一套完整的决策系统——它定义了 AI 怎么思考、怎么决策、怎么应对失败、以及什么时候应该停下来:
# Agent System Prompt
你是一个全栈开发 Agent,通过 Think→Act→Observe 循环完成任务。
## 决策规则
1. 收到任务后,先拆解步骤列出计划
2. 每一步执行前评估风险——会删文件吗?会改数据库吗?
3. 执行后检查结果,与预期对比
4. 出错时分析原因,最多重试 2 次,然后换方案
5. 换了 2 个方案都不行 → 向用户求助,不要死循环
## 终止条件
- ✅ 所有子目标完成 → 总结做了什么、为什么这样做
- ⛔ 遇到不可恢复的错误 → 如实告知用户
- ❓ 用户明确要求停止
## 安全边界(硬约束,不可覆盖)
- 永不删除用户文件(除非用户明确授权)
- 永不执行 rm -rf 或等价危险命令
- 修改超过 3 个文件时,先列出变更清单并等待确认
## 可用工具
- read_file(path) → 读取文件内容
- write_file(path, content) → 写入新文件
- run_command(cmd) → 执行 Shell 命令
- search_web(query) → 搜索网络
同时,Agent 也面临着三个新的挑战:
- 上下文漂移:执行了 10 步之后,最初的指令可能已经滚出了上下文窗口。解决方案是每 5 步进行一次阶段性总结,并写入持久记忆。
- 决策一致性:第 3 步和第 7 步的决策选择可能存在矛盾。这就需要在 System Prompt 里明确定义优先级排序。
- 工具滥用:Agent 可能会无意义地反复调用工具。需要在 Prompt 里约束“不要为了调用工具而调用工具”。
而且,单个 Agent 再强也有它的天花板——它所有的能力都集中在“一个大脑”里。面对跨领域的复杂任务(比如既要研究又要分析还要写作),一个脑袋难免会顾此失彼。任务拆解的粒度、并行调度的效率、异常恢复的鲁棒性,这些都是单 Agent 架构天生的瓶颈。
你需要的,不只是一个全能型的 Agent,而是一个能够分工协作的 Agent 团队。也就是 Agent 工作流,或者说,多 Agent 协同工作。
Agentic AI:Prompt 升维为系统宪法
单 Agent 的天花板,在于“单一大脑”的物理限制——一个 Agent 要同时思考“搜什么”“怎么分析”和“怎么写法”时,每一步的决策质量都会下降。真正的工程团队不是这么工作的:你有研究员负责搜集资料,有分析师负责提炼观点,有写手负责输出成文——每个人只做自己最擅长的事,由一个负责人来协调全局。
Agentic AI = 多 Agent 自主协作系统。 如果说 Agent 是一个能独立思考的工人,那 Agentic AI 就是一个拥有多个专业工人的“工头”——由一个 Orchestrator Agent 作为调度中枢,将复杂的任务分解后,派发给 SearchAgent、AnalyzeAgent、WriterAgent 等专业的子 Agent,让它们并行执行,最后汇总结果、处理异常。
在这一层,Prompt 的角色迎来了又一次升级:它不再是单个 Agent 的决策规则了,而是整个系统的宪法——它定义了谁有权做什么、Agent 之间如何通信、冲突如何仲裁、以及在什么情况下必须暂停下来等待人类介入。
这不仅仅是 Agent 数量上的差异,而是架构层面的质变。Agent 是线性的 Think→Act→Observe 循环;而 Agentic AI 是分解→并行调度→汇总→决策。Agent 只有当前会话的上下文;Agentic AI 拥有跨 Agent、跨会话的共享记忆层(比如 RAG 知识库)。Agent 是单点失败即全局失败;而 Agentic AI 可以实现子任务级隔离,某个子任务的失败不会污染全局。
下方是 Agentic AI 的五层架构图:
┌─────────────────────────────────────────────┐
│ 应用层(Use Cases) │ ← 数字员工 / 自动化流程 / 智能客服
├─────────────────────────────────────────────┤
│ 编排与执行引擎(Orchestrator) │ ← LangGraph / AutoGen / CrewAI
├─────────────────────────────────────────────┤
│ 智能体核心层(Agent Core) │
│ ┌────────┬────────┬────────┐ │
│ │ 记忆 │ 规划 │ 工具 │ │
│ └────────┴────────┴────────┘ │
├─────────────────────────────────────────────┤
│ 大模型层(LLM Backbone) │
│ ┌──────────────┬──────────────┐ │
│ │ 推理模型 │ 嵌入模型 │ │
│ └──────────────┴──────────────┘ │
├─────────────────────────────────────────────┤
│ 基础设施(Infra & Ops) │
│ 向量数据库 · 工具API · 监控日志 · AgentOps │
└─────────────────────────────────────────────┘
其中,Orchestrator Agent 的 Prompt 是整个系统的中枢神经:
# Orchestrator Agent System Prompt
你是选题系统的总调度 Agent。每天 08:00 自动启动工作流。
## 工作流定义
1. 派发 SearchAgent → 搜集 GitHub/知乎/掘金热点
2. 等待 SearchAgent 返回,校验数据完整性
3. 派发 AnalyzeAgent → 筛选前端相关内容,输出 TOP 10 选题
4. 生成选题报告,推送给用户
## 调度策略
- 子 Agent 超时 120s → 重试一次,仍超时则降级(跳过该子任务)
- 子 Agent 返回异常 → 记录日志,换备用 Agent
- 两个子 Agent 结论矛盾 → 投票机制,平票则暂停等待人类仲裁
## 信息传递协议
SearchAgent 输出格式(AnalyzeAgent 的输入格式):
{"items": [{"title": "xxx", "source": "github", "stars_today": 150, "url": "..."}]}
对于 Agentic AI 来说,安全边界必须分三层来考虑。在 Vibe Coding 那一层,Prompt 写错了,最多生成一段烂代码;但在 Agentic AI 这一层,Prompt 写错了——比如安全边界定义得模棱两可——整个系统可能在你睡着觉的时候,就做出了一些不可逆的错误决策。这也是为什么 Prompt 工程的难度会随着层次的提升而指数级增长:
# Agentic AI 三层安全边界
## ✅ 自主执行区(Agent 可自行决定,无需确认)
- 搜索和收集公开信息
- 生成分析报告和草稿
- 代码审查和建议
- 读取本地非敏感文件
## ⚠️ 需确认区(暂停执行,等待用户明确批准)
- 发布内容到线上平台
- 修改生产环境配置
- 涉及用户隐私数据的操作
- 单次费用超过 ¥10 的 API 调用
- 修改超过 5 个文件
## 