为什么你的Prompt总是效果差?聊聊Prompt工程的底层逻辑
网上有一堆Prompt教程,列了一堆模板和技巧。加了”作为专家”、用了”逐步思考”、加了”请确保准确性”——结果输出还是不理想。
我花了不少时间研究这个问题,最后发现:大多数人的问题不是技巧不够,而是对Prompt的理解就不对。
Prompt不是命令,是信息
先搞清楚一件事:大模型不是”执行命令”的程序。它是根据你给的文本,预测”接下来应该说什么”的统计模型。
你写 请帮我写一个排序函数,它不是在”执行”这个命令。它是在想:在大量代码相关的文本里,“请帮我写一个排序函数”之后通常跟着什么内容?
理解这一点很重要。因为这意味着:Prompt的效果不取决于你写得有多权威,而取决于你给的信息有多精准。
我的”三层信息”框架
我把一个有效的Prompt拆解成三层信息:
第一层:上下文(Context)
“我现在在做___,我的技术栈是___,我遇到的问题是什么___。”
这一层回答”为什么需要”。
大部分人在这一层犯的错误是:给得太多或给得太少。
给太多的例子:“我是一个后端开发者,用Node.js和PostgreSQL,我们团队有6个人,敏捷开发,项目已经做了半年,最近在做用户权限模块……”
这些信息里,有些有用,有些没用。模型拿到后,注意力会被分散到不重要的细节上。
给太少的例子:“帮我写代码。”
好吧,什么代码?
经验法则:上下文应该只包含模型”不知道但需要知道”的信息。 比如”这个项目用的是Express + TypeScript,不要引入新依赖”——这就够了。
第二层:任务(Task)
“请___,输出格式是___。”
这一层回答”做什么”。
这里常见的错误是用模糊动词:“优化一下这段代码”、“改进这个方案”。
“优化”是什么意思?性能?可读性?安全性?模型不知道。它只能猜,而猜的结果通常不是你想要的。
更好的写法是给出明确的判断标准:
- “把这段代码的圈复杂度降到5以下”
- “给这段代码加上TypeScript类型定义”
- “用正则提取这段文本中的所有邮箱地址”
第三层:约束(Constraint)
“不要___,注意___。”
这一层回答”边界在哪里”。
这是我见过最容易被忽视的一层。大部分人的Prompt只有”做什么”,没有”不做什么”。
但模型的默认行为往往是”过度发挥”——它会把你的需求理解得很宽泛,然后给出一个大而全但用不上的方案。
约束层的经典句式:
- “只需要修改X函数,不要动其他部分”
- “输出纯JSON,不要解释”
- “不要用第三方库,只用标准库”
- “保留现有的错误处理逻辑”
一个实际的改写过程
这是我最近一次调Prompt的真实记录。
第一版(失败):
帮我分析一下这个API的性能问题,给出优化建议。输出了一堆泛泛的建议:“加缓存”、“优化数据库查询”、“使用CDN”——全对但全没用。
第二版(好一点):
我有一个Node.js的API,处理用户列表查询。响应时间大约2秒,目标是降到200ms以内。当前使用PostgreSQL,查询语句是SELECT * FROM users WHERE status = 'active',数据量约5万条。请分析性能瓶颈并给出优化建议。这次好了,提到了具体的数字、技术栈、查询语句。但输出仍然有些建议不切实际(比如”加Redis缓存”——我们的架构里不适合引入缓存层)。
第三版(可用):
Node.js + PostgreSQL API,用户列表查询耗时2秒,目标200ms。数据量5万条,查询:SELECT * FROM users WHERE status = 'active'。索引只有主键。
要求:1. 只考虑数据库层面的优化(SQL、索引),不考虑应用层缓存2. 不能改变表结构3. 输出具体的SQL语句和EXPLAIN分析思路这一版拿到了我可以直接执行的方案:加了status索引,改了SELECT *为具体字段,响应时间降到了150ms。
一个不太正确的结论
很多人追求”完美的Prompt模板”。但我觉得,没有完美的模板,只有迭代的过程。
最好的Prompt不是你一次写出来的,是你跟模型对话三次后磨出来的。
第一版先跑,看输出差在哪。第二版补上下文和约束。第三版微调措辞。
听起来很笨,但这就是最有效的做法。
你觉得呢?你写Prompt时最大的困惑是什么?