很多人把 Prompt Engineering 理解为"咒语收集",这是低估了它。一个工程化的提示词是一份合约:你声明角色、任务、约束和验收标准,模型按合约履约。本文是我常用的结构模式,全部经过大量真实任务验证。
四件套:角色 × 任务 × 约束 × 示例
[角色] 你是一名资深后端工程师,熟悉 Go 和 PostgreSQL。
[任务] 审查下面的数据库迁移脚本,找出可能导致锁表或数据丢失的风险。
[约束] 只报告高置信度问题;每条给出依据和建议修复;不要重写整个脚本。
[示例] 输入: ALTER TABLE orders ADD COLUMN status text;
期望输出: {"risk": "full_table_rewrite", "reason": "...", "fix": "..."}
四个组件各有分工:角色激活相关语料分布,任务给出唯一目标,约束收窄输出空间,示例(few-shot)比任何形容词都精确——展示一个,胜过描述十个。
指令的位置:头尾优于中间
长上下文里,模型对开头和结尾的注意力显著高于中部(即所谓 lost in the middle 现象)。工程上的推论:
- 系统级不变量放 system 消息,不与用户内容混排
- 关键指令要么置顶,要么在输入数据之后重申一次
- 大段材料(日志、代码)放在中间,任务要求放在材料之后,而不是之前
思维链的取舍
“让我一步一步思考"不是免费的:推理 token 直接增加成本与延迟。我的判断标准:
| 场景 | 用不用 CoT |
|---|---|
| 模式识别、抽取、改写 | 不用,直答更快更稳 |
| 多步推理、数学、规划 | 用,且要求先列计划再执行 |
| 结构化输出 | 谨慎:推理过程可能泄漏进 JSON,要求"仅输出结果” |
负面指令基本无效
“不要出现幻觉"“不要编造 API”——这类禁令对生成分布的约束力远弱于正面设计。更有效的替代:
- 提供权威材料,声明"仅基于以下内容回答,找不到就说不知道”
- 用 schema 约束输出结构,让"编造"无处安放
- 对关键事实要求附出处引用
把提示词当代码管理
提示词放版本库而不是散落在代码字符串里;每次修改跑一遍黄金集(见本板块《评估驱动的提示开发》);变量插值显式化(模板引擎),避免隐式拼接。
一句总结:提示词不是许愿,是合约——写得像合约,模型才像履约方。