Prompt-as-Code:当 Prompt 不只是"话",而是可执行的"程序"
Posted on Tue 20 January 2026 in AI
| Abstract | Prompt 不只是"话",而是可执行的"程序" |
|---|---|
| Authors | Walter Fan |
| Category | AI 工程 |
| Status | v1.1 |
| Updated | 2026-01-20 |
| License | CC-BY-NC-ND 4.0 |
"Any sufficiently advanced prompt is indistinguishable from code." —— 改编自 Arthur C. Clarke
开篇:Prompt 已经不是你以为的那个"Prompt"了
很多人对 Prompt 的认知还停留在"和 AI 聊天"的阶段:
你:"帮我写一段 Python 代码"
AI:"好的,这是代码……"
你:"谢谢"
结束。
但如果我告诉你,现代的 Prompt 可以:
- ✅ 执行终端命令(
git status、npm install、docker-compose up) - ✅ 调用外部 API(Jira、GitLab、Slack、数据库)
- ✅ 读写文件系统(创建文件、修改代码、生成配置)
- ✅ 定义完整的工作流(条件分支、循环、多步骤协作)
- ✅ 触发 CI/CD 流程(提交代码、创建 PR、部署服务)
你会怎么想?
这不是"聊天",这是在写程序。
只不过,这个"程序"是用自然语言写的。
这就是今天要聊的主题:Prompt-as-Code。
它不仅仅是"把 Prompt 存到文件里"这么简单,更重要的是:
Prompt 可以像代码一样被执行,定义工作流,调用工具,产生副作用。
读完这篇文章,你会收获: 1. 理解 Prompt-as-Code 的两层含义:管理 + 执行 2. 掌握如何在 Prompt 中定义 Workflow 3. 了解 MCP(Model Context Protocol)如何让 Prompt 调用外部工具 4. 看一个真实案例:OpenSpec 是如何用 Prompt 编排复杂流程的
一、Prompt-as-Code 的两层含义
1.1 第一层:像管理代码一样管理 Prompt
这是最基础的理解:
| 传统 Prompt | Prompt-as-Code |
|---|---|
| 存在聊天记录里 | 存在 Git 仓库里 |
| 每次从头写 | 一次定义,多次调用 |
| 只有自己知道 | 团队可共享、可 review |
| 无法追溯修改 | 有 commit history |
如果你只做到这一步,你已经比 80% 的人强了。
但这还不够。
1.2 第二层:Prompt 本身就是可执行的程序
这才是 Prompt-as-Code 的精髓:
传统代码: if (condition) { doSomething(); }
Prompt 代码:如果用户要求创建新功能,先运行 `openspec list` 检查冲突
两者的本质是一样的——都是定义"在什么条件下,执行什么操作"。
区别只是: - 传统代码用编程语言(Python/JavaScript) - Prompt 代码用自然语言(中文/英文)
而现代 AI 助手(如 Cursor)已经可以:
- 解析 Prompt 中的流程定义
- 执行 Prompt 中指定的命令
- 调用 Prompt 中声明的工具
- 判断 条件分支,决定下一步
这就是为什么我说:Prompt 已经是可执行的程序了。
二、在 Prompt 中定义 Workflow
2.1 什么是 Prompt Workflow?
传统的 Prompt 是"一问一答":
用户:帮我写一个函数
AI:好的,这是函数……
Workflow Prompt 是"多步骤协作":
用户:帮我创建一个新功能
AI:
1. 首先,我需要检查现有功能 → 运行 `openspec list`
2. 发现没有冲突 → 创建 proposal.md
3. 等待用户确认 → 用户说"继续"
4. 创建 tasks.md → 创建 specs/
5. 运行验证 → `openspec validate --strict`
6. 完成!
这就是 Workflow——一个有步骤、有条件、有反馈的完整流程。
2.2 Workflow 的核心要素
在 Prompt 中定义 Workflow,需要包含以下要素:
| 要素 | 说明 | 示例 |
|---|---|---|
| 触发条件 | 什么时候启动这个流程 | "当用户要求创建新功能时" |
| 前置检查 | 开始前需要确认什么 | "先运行 openspec list 检查冲突" |
| 步骤序列 | 按什么顺序执行 | "1. 创建目录 2. 生成模板 3. 验证格式" |
| 条件分支 | 遇到不同情况怎么处理 | "如果已存在同名功能,询问用户是否覆盖" |
| 工具调用 | 需要调用什么外部工具 | "运行 git status,读取 Jira 票据" |
| 终止条件 | 什么时候算完成 | "当 openspec validate 返回成功时" |
2.3 真实示例:一个完整的 Workflow Prompt
以下是一个真实的 Cursor Command,它定义了一个完整的"创建技术设计文档"工作流:
---
name: /design-doc
description: 从 Jira 需求生成技术设计文档
---
# 技术设计文档生成器
## 触发条件
当用户输入 `/design-doc <JIRA-KEY>` 时触发。
## Workflow
### Step 1: 获取需求上下文
1. 调用 MCP Tool `get_jira_issue` 获取 Jira 票据详情
2. 读取 `openspec/project.md` 了解项目技术栈
3. 运行 `git log --oneline -10` 了解最近的代码变更
### Step 2: 分析并确认范围
1. 总结 Jira 票据的核心需求
2. 列出受影响的模块和文件
3. **询问用户确认**:展示分析结果,等待用户说"继续"或修改
### Step 3: 生成设计文档
如果用户确认,则:
1. 创建 `docs/design/<JIRA-KEY>.md`
2. 按照以下模板生成内容:
- ## 背景与目标
- ## 技术方案
- ## API 设计
- ## 数据模型
- ## 风险与缓解措施
### Step 4: 关联与验证
1. 调用 MCP Tool `update_jira_issue` 将文档链接写入 Jira
2. 运行 `markdownlint` 检查文档格式
3. 如果有错误,自动修复
### Step 5: 完成
输出:"✅ 设计文档已生成:docs/design/<JIRA-KEY>.md"
注意这个 Prompt 里发生了什么:
- 调用外部工具:
get_jira_issue、update_jira_issue - 执行终端命令:
git log、markdownlint - 创建文件:
docs/design/<JIRA-KEY>.md - 条件分支:等待用户确认后才继续
- 错误处理:检测到错误时自动修复
这不是聊天,这是一个完整的程序。
三、MCP:让 Prompt 拥有"手脚"
3.1 什么是 MCP?
MCP(Model Context Protocol)是 Anthropic 提出的一个协议,它让 AI 可以调用外部工具。
如果说 Prompt 是 AI 的"大脑",那么 MCP Tools 就是 AI 的"手脚":
┌─────────────────────────────────────────────────────────────┐
│ AI 大脑 │
│ (理解、推理、决策) │
├─────────────────────────────────────────────────────────────┤
│ MCP Protocol │
├──────────┬──────────┬──────────┬──────────┬────────────────┤
│ 文件系统 │ 终端 │ Jira │ GitLab │ 浏览器 │
│ 读写文件 │ 执行命令 │ 读写票据 │ 读写 MR │ 自动化测试 │
└──────────┴──────────┴──────────┴──────────┴────────────────┘
3.2 常用的 MCP Tools
| Tool 类别 | 具体功能 | 在 Prompt 中怎么用 |
|---|---|---|
| 文件系统 | 读写文件、创建目录 | "读取 src/config.ts 的内容" |
| 终端 | 执行 Shell 命令 | "运行 npm run test" |
| Jira | 获取/更新票据 | "获取 JIRA-12345 的详情" |
| GitLab | 创建 MR、获取 Diff | "提交代码并创建 Merge Request" |
| 浏览器 | 自动化测试、截图 | "打开 localhost:3000,检查页面是否正常" |
| 数据库 | 查询/更新数据 | "查询用户表中的活跃用户数" |
| Slack/飞书 | 发送消息 | "在 #dev 频道发送部署通知" |
3.3 在 Prompt 中调用 MCP Tools
以下是一个调用多个 MCP Tools 的 Prompt 示例:
# 自动化发布流程
## 触发条件
当用户说"发布 v1.2.3"时触发。
## Workflow
### Step 1: 预检查
1. 运行终端命令:`git status`
- 如果有未提交的更改,**停止**并提示用户先提交
2. 运行终端命令:`npm run test`
- 如果测试失败,**停止**并展示失败原因
### Step 2: 准备发布
1. 读取文件:`package.json`
2. 更新版本号为 `1.2.3`
3. 写入文件:`package.json`
4. 读取文件:`CHANGELOG.md`
5. 在顶部插入本次更新内容
6. 写入文件:`CHANGELOG.md`
### Step 3: 提交与推送
1. 运行终端命令:`git add .`
2. 运行终端命令:`git commit -m "chore: release v1.2.3"`
3. 运行终端命令:`git tag v1.2.3`
4. 运行终端命令:`git push && git push --tags`
### Step 4: 创建 GitLab Release
1. 调用 MCP Tool `submit_merge_request`:
- 标题:"Release v1.2.3"
- 描述:从 CHANGELOG.md 提取
2. 调用 MCP Tool `get_merge_request_info` 获取 MR 链接
### Step 5: 通知团队
1. 调用 MCP Tool(假设有 Slack Tool):
- 发送到 #releases 频道
- 内容:"🚀 v1.2.3 已发布!MR: <链接>"
### Step 6: 更新 Jira
1. 调用 MCP Tool `search_jira_issues`:查找 fixVersion=1.2.3 的票据
2. 对每个票据,调用 `update_jira_issue`:状态改为"已发布"
## 完成
输出:"✅ v1.2.3 发布完成!"
这个 Prompt 做了什么?
- 执行了 7 条终端命令
- 读写了 2 个文件
- 调用了 4 个 MCP Tools(GitLab、Slack、Jira)
- 实现了 条件分支(测试失败则停止)
- 实现了 循环(遍历 Jira 票据)
这已经是一个完整的 CI/CD 流程了——只不过是用自然语言写的。
四、Cursor 的三层架构:Rules、Commands、MCP
Cursor 提供了一套优雅的 Prompt-as-Code 架构:
┌────────────────────────────────────────────────────────────┐
│ MCP Tools (外部工具) │
│ Jira / GitLab / 文件系统 / 终端 / 浏览器 / API │
├────────────────────────────────────────────────────────────┤
│ Commands (指令) │
│ /blog-write, /design-doc, /release 等 │
│ 定义 Workflow:步骤 + 条件 + 工具调用 │
├────────────────────────────────────────────────────────────┤
│ Rules (规则) │
│ 始终生效的约束:代码风格、人设、安全限制 │
└────────────────────────────────────────────────────────────┘
4.1 Rules:定义"始终生效"的约束
Rules 是 AI 的"宪法",存放在 .cursor/rules/ 目录下。
示例:
---
alwaysApply: true
---
# AI 行为约束
## 安全限制
- 永远不要执行 `rm -rf /` 或类似危险命令
- 在执行任何删除操作前,必须先询问用户确认
- 不要在 Prompt 中暴露敏感信息(API Key、密码)
## 代码风格
- 使用 TypeScript 严格模式
- 所有函数必须有类型注解
- 错误处理使用 try/catch,不要静默失败
## 工具使用偏好
- 优先使用 MCP Tools 而不是手动操作
- 如果 MCP Tool 失败,回退到终端命令
4.2 Commands:定义"可复用的 Workflow"
Commands 是"带参数的 Prompt 函数",存放在 .cursor/commands/ 目录下。
关键点:Command 里可以定义完整的 Workflow,包括步骤、条件、工具调用。
示例(code-review.md):
---
name: /code-review
description: 自动化代码审查流程
---
# Code Review 助手
## 触发
当用户输入 `/code-review` 或 `/code-review <file>` 时触发。
## Workflow
### Step 1: 确定审查范围
- 如果用户指定了文件 → 审查该文件
- 如果没有指定 → 运行 `git diff --name-only HEAD~1` 获取最近修改的文件
### Step 2: 读取代码
对于每个文件,使用文件系统 Tool 读取内容。
### Step 3: 审查维度
按以下维度审查每个文件:
1. **正确性**:逻辑是否正确?边界情况是否处理?
2. **可读性**:命名是否清晰?结构是否合理?
3. **性能**:是否有 N+1 查询?是否有不必要的循环?
4. **安全性**:是否有 SQL 注入、XSS 等风险?
### Step 4: 输出报告
使用 Markdown 表格输出审查结果:
| 文件 | 问题 | 严重程度 | 建议 |
|------|------|----------|------|
| ... | ... | 🔴/🟡/🟢 | ... |
### Step 5: 可选:自动修复
如果用户说"帮我修",则:
1. 读取有问题的文件
2. 应用修复
3. 写入文件
4. 运行 `npm run lint --fix` 格式化
4.3 三者的协作关系
| 层级 | 职责 | 生命周期 | 类比 |
|---|---|---|---|
| Rules | 定义约束和偏好 | 始终生效 | .eslintrc / tsconfig.json |
| Commands | 定义 Workflow | 按需调用 | Shell 脚本 / Makefile |
| MCP Tools | 执行具体操作 | 被调用时执行 | 系统 API / SDK |
执行流程:
用户输入 /design-doc JIRA-12345
↓
Cursor 加载 Commands 定义
↓
AI 解析 Workflow 步骤
↓
Step 1: 调用 MCP Tool (get_jira_issue)
↓
Step 2: 读取文件 (project.md)
↓
Step 3: 执行终端命令 (git log)
↓
Step 4: 生成内容 + 写入文件
↓
完成
五、深入案例:OpenSpec 的 Workflow 编排
OpenSpec 是一个"规格驱动开发"工具,它的 AGENTS.md 是 Prompt-as-Code 的经典案例。
5.1 OpenSpec 的三阶段 Workflow
## Three-Stage Workflow
### Stage 1: Creating Changes
**触发条件**:用户要求添加新功能、做破坏性变更、修改架构
**Workflow**:
1. 运行 `openspec list` 和 `openspec list --specs` 了解当前状态
2. 选择唯一的 `change-id`(kebab-case,动词开头)
3. 创建目录:`openspec/changes/<id>/`
4. 生成文件:`proposal.md`, `tasks.md`, `design.md`(可选)
5. 起草 spec 增量:`## ADDED|MODIFIED|REMOVED Requirements`
6. 运行 `openspec validate <id> --strict` 验证
7. **停止**:等待人工批准后再继续
### Stage 2: Implementing Changes
**触发条件**:proposal 已被批准
**Workflow**:
1. 读取 `proposal.md` 了解要做什么
2. 读取 `design.md`(如果有)了解技术决策
3. 读取 `tasks.md` 获取实施清单
4. **按顺序**实施每个任务
5. 每完成一个任务,更新 `tasks.md` 状态
6. 全部完成后,标记为 `- [x]`
### Stage 3: Archiving Changes
**触发条件**:实施完成,已部署
**Workflow**:
1. 运行 `openspec archive <change-id> --yes`
2. 如果是纯工具变更,加 `--skip-specs`
3. 运行 `openspec validate --strict` 确认归档成功
5.2 决策树:什么情况下走什么流程
OpenSpec 的 Prompt 中甚至包含了决策树:
### Decision Tree
New request?
├─ Bug fix restoring spec behavior? → Fix directly (不需要 proposal)
├─ Typo/format/comment? → Fix directly
├─ New feature/capability? → Create proposal
├─ Breaking change? → Create proposal
├─ Architecture change? → Create proposal
└─ Unclear? → Create proposal (safer)
这就是在 Prompt 中定义"条件分支"——AI 会根据用户的请求类型,自动选择正确的流程。
5.3 工具调用示例
OpenSpec 的 Prompt 中明确指定了要调用哪些工具:
### CLI Commands
# Essential commands
openspec list # 列出活跃变更
openspec list --specs # 列出规格
openspec show [item] # 查看详情
openspec validate [item] # 验证格式
openspec archive <change-id> # 归档变更
# Debugging
openspec show [change] --json --deltas-only
openspec validate [change] --strict
当 AI 执行 OpenSpec Workflow 时,它会真的运行这些命令,而不只是"假装"在运行。
六、动手实践:写一个带 Workflow 的 Command
6.1 需求:自动化日报生成器
我们来写一个 /daily-report Command,它的功能是:
- 从 Jira 获取今天完成的任务
- 从 Git 获取今天的提交记录
- 生成日报并保存到文件
- 可选:发送到 Slack
6.2 完整的 Command 定义
创建 .cursor/commands/daily-report.md:
---
name: /daily-report
description: 自动生成工作日报
---
# 日报生成器
## 触发条件
用户输入 `/daily-report` 或 `/daily-report --send`
## Workflow
### Step 1: 收集 Jira 数据
1. 获取当前用户信息:调用 MCP Tool `get_current_user`
2. 搜索今天完成的任务:
- 调用 MCP Tool `search_jira_issues`
- JQL: `assignee = currentUser() AND status changed to "Done" after startOfDay()`
3. 如果没有找到任务 → 输出"今天没有完成的 Jira 任务",但继续流程
### Step 2: 收集 Git 数据
1. 运行终端命令:`git log --author="$(git config user.email)" --since="00:00" --oneline`
2. 解析输出,提取 commit 列表
### Step 3: 生成日报
按以下格式生成 Markdown:
```markdown
# 工作日报 - YYYY-MM-DD
## 今日完成
### Jira 任务
- [JIRA-123] 任务标题
- [JIRA-456] 任务标题
### 代码提交
- abc1234: commit message 1
- def5678: commit message 2
## 明日计划
(留空,等待用户补充)
## 遇到的问题
(留空,等待用户补充)
Step 4: 保存文件
- 创建目录:
docs/daily-reports/(如果不存在) - 写入文件:
docs/daily-reports/YYYY-MM-DD.md
Step 5: 可选发送
如果用户加了 --send 参数:
1. 读取刚才生成的日报
2. 调用 Slack MCP Tool(如果有)发送到指定频道
3. 如果没有 Slack Tool → 输出"日报已保存,但无法发送(未配置 Slack)"
Step 6: 完成
输出:"✅ 日报已生成:docs/daily-reports/YYYY-MM-DD.md"
### 6.3 这个 Command 用到了什么?
| 能力 | 具体实现 |
|------|----------|
| **MCP Tool 调用** | `get_current_user`, `search_jira_issues`, Slack |
| **终端命令执行** | `git log --author=...` |
| **文件读写** | 创建目录、写入 Markdown 文件 |
| **条件分支** | `--send` 参数判断、无任务时的处理 |
| **模板生成** | 按固定格式生成日报内容 |
---
## 七、常见误区与最佳实践
### 误区 1:Workflow 步骤太细
❌ 错误:
```markdown
1. 打开终端
2. 输入 git
3. 输入空格
4. 输入 status
5. 按回车
✅ 正确:
1. 运行 `git status` 检查工作区状态
原则:Workflow 步骤应该是语义级别的,不是操作级别的。
误区 2:没有错误处理
❌ 错误:
1. 运行 `npm run build`
2. 运行 `npm run deploy`
✅ 正确:
1. 运行 `npm run build`
- 如果失败 → **停止**,输出错误信息
2. 运行 `npm run deploy`
- 如果失败 → **回滚**,运行 `git reset --hard HEAD~1`
误区 3:过度依赖 MCP Tools
并不是所有操作都需要 MCP Tool。简单的文本处理、格式转换,AI 自己就能做。
MCP Tool 适合:需要副作用的操作(写文件、调 API、执行命令)
AI 自己做:纯计算、推理、文本生成
最佳实践清单
| 实践 | 说明 |
|---|---|
| 步骤语义化 | 每一步做一件"有意义的事",不是一个"动作" |
| 显式错误处理 | 每个可能失败的步骤都要说明"失败了怎么办" |
| 人工确认点 | 危险操作前加"等待用户确认" |
| 幂等性 | 同一个 Workflow 跑两遍,结果应该一样 |
| 可观测性 | 每一步都输出状态,让用户知道"到哪了" |
总结
| 核心概念 | 说明 |
|---|---|
| Prompt-as-Code | Prompt = 可管理 + 可执行 的程序 |
| Workflow | 在 Prompt 中定义多步骤、有条件、可循环的流程 |
| MCP Tools | 让 Prompt 可以调用外部工具(Jira、GitLab、终端、文件系统) |
| Rules | 始终生效的约束(安全、风格、偏好) |
| Commands | 可复用的 Workflow 模板 |
Checklist:升级你的 Prompt 为"可执行程序"
- [ ] 把常用流程写成 Command,定义清晰的 Workflow 步骤
- [ ] 在 Workflow 中显式调用 MCP Tools(而不是"假装"在调用)
- [ ] 为每个可能失败的步骤添加错误处理
- [ ] 在危险操作前加入"等待用户确认"
- [ ] 测试 Workflow 的幂等性(跑两遍结果一样)
- [ ] 把 Rules、Commands 加入 Git 版本控制
这一篇你真正要记住的只有一句话
Prompt 不只是"和 AI 聊天",而是用自然语言写的"可执行程序"。
当你开始在 Prompt 里定义 Workflow、调用 Tools、处理错误,你就已经在用自然语言编程了。
扩展阅读
- Cursor Documentation: Rules — Cursor 官方 Rules 文档
- Model Context Protocol (MCP) — Anthropic 的 MCP 协议官方文档
- OpenSpec GitHub — 规格驱动开发工具
- Agent Skills Specification — AI Agent 技能定义规范
本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。