把 prompt 当代码,而不是当咒语
我见过两种对待 prompt 的态度。一种是”咒语派”:把 prompt 当玄学,认为写好 prompt 靠灵感,改一个词效果天差地别,所以反复试、凭感觉调。另一种是”代码派”:把 prompt 当工程产物,版本管理、diff、回归测试、code review 一套全上。
咒语派在 demo 阶段更快,代码派在生产阶段更稳。这篇文章讲我为什么从咒语派转向了代码派,以及怎么转。
prompt 作为代码的四个维度
1. 版本管理
prompt 必须进 git,和代码一起版本管理。这不是可选项。我见过一个项目,prompt 存在飞书文档里,三个人各改各的,最后没人知道线上跑的是哪个版本。出了 bug,翻遍了文档也找不到当前 prompt 是从哪版改过来的。
版本管理的好处不只是”能回退”,更重要的是可追溯。当线上效果下降时,你能 diff 出”上周三改了 prompt 的这段”,定位问题根源。没有版本管理,你连”改了什么”都不知道。
2. diff 与 review
prompt 的改动要和代码改动一样走 review。原因很简单:prompt 的副作用很难预测。你觉得加一句”请更详细地回答”是无害的,但它可能让输出变长 3 倍、token 成本翻倍、还引入了幻觉。
review 时重点看三件事:
- 为什么改:这个改动解决什么问题?有没有对应的 bad case?
- 改了什么:diff 出来,确认只改了该改的地方。
- 影响范围:跑了一遍回归集吗?其他场景没掉吗?
第三点最容易被忽略。很多人改完 prompt 只测自己关心的场景,不看其他场景有没有被影响。这和改代码不跑测试是一样的——不负责任。
3. 回归测试
每次改 prompt 必须跑回归集。这条我在《评测体系》那篇里详细讲过,这里只强调一个 prompt 特有的问题:prompt 的改动是非线性的。
改代码时,你大概能预测”改了这个函数会影响哪些调用方”。但改 prompt 时,一个词的变化可能影响完全不相关的场景。因为 LLM 对 prompt 的理解是整体的,局部改动会产生全局副作用。
所以 prompt 的回归测试比代码更关键。代码改了可以只跑相关测试,prompt 改了必须跑全量回归。
**实践建议:**把 prompt 拆成”模块化片段”(系统指令、角色定义、任务描述、输出格式),分别管理。改一个模块只影响它负责的部分,比改一整段 prompt 更可控。这和代码的函数拆分是一个道理。
4. 灰度与回滚
prompt 上线要灰度,不能全量切。我的一般做法是:新 prompt 先放 10% 流量,观察 24 小时,关键指标没掉再放到 50%,再观察 24 小时,最后全量。
灰度的前提是你有可观测的指标。如果连”当前准确率是多少”都不知道,灰度就失去了意义——你看不出新旧版本的差异。
回滚要比上线快。prompt 出问题时,你要能在一分钟内切回上一版。这意味着 prompt 不能硬编码在代码里(改代码要重新部署),要从配置中心或数据库加载,热切换。
一个 prompt 仓库长什么样
我的 prompt 仓库结构通常是这样:
每个 prompt 文件头部有 metadata:版本号、依赖的模型、上次评测分数、负责人。改 prompt 时必须同步更新 metadata 和测试结果。
反模式
反模式一:prompt 写在代码字符串里。改 prompt 要改代码、重新部署。正确做法是 prompt 和代码分离,从外部加载。
反模式二:一个 prompt 解决所有问题。一个 2000 字的 prompt 里塞了意图识别、信息抽取、答案生成、安全检查。改任何一处都会影响全局。正确做法是按任务拆分,每个 prompt 只做一件事。
反模式三:没有 few-shot 版本管理。few-shot 例子是 prompt 的一部分,但它经常被单独存在一个文件里,改了不登记。结果 prompt 没变但效果变了,排查半天才发现是例子换了。
结语
把 prompt 当代码,核心不是”写得多好”,而是”管得多好”。写出一个惊艳的 prompt 是灵感,稳定地管理 50 个 prompt 的版本、测试、上线、回滚,是工程。
AI 项目的工程化,最后一公里往往不在模型、不在数据,在 prompt 管理。这一公里走完了,你的系统才算真正可控。