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 statusnpm installdocker-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)已经可以:

  1. 解析 Prompt 中的流程定义
  2. 执行 Prompt 中指定的命令
  3. 调用 Prompt 中声明的工具
  4. 判断 条件分支,决定下一步

这就是为什么我说: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 里发生了什么:

  1. 调用外部工具get_jira_issueupdate_jira_issue
  2. 执行终端命令git logmarkdownlint
  3. 创建文件docs/design/<JIRA-KEY>.md
  4. 条件分支:等待用户确认后才继续
  5. 错误处理:检测到错误时自动修复

这不是聊天,这是一个完整的程序。


三、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 做了什么?

  1. 执行了 7 条终端命令
  2. 读写了 2 个文件
  3. 调用了 4 个 MCP Tools(GitLab、Slack、Jira)
  4. 实现了 条件分支(测试失败则停止)
  5. 实现了 循环(遍历 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,它的功能是:

  1. 从 Jira 获取今天完成的任务
  2. 从 Git 获取今天的提交记录
  3. 生成日报并保存到文件
  4. 可选:发送到 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: 保存文件

  1. 创建目录:docs/daily-reports/(如果不存在)
  2. 写入文件: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、处理错误,你就已经在用自然语言编程了。


扩展阅读


本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。