我写了半年 prompt,最后发现最好的技巧就三个

写了半年 prompt 后发现,最有价值的是三个技巧:给格式约束、让模型先推理再回答、提供边界反面示例。

开始用 LLM 写代码之前,我以为 prompt 就是个"说清楚话"的事。你把需求写明白,模型就能给出你要的东西。后来发现完全不是这么回事。

我踩过一个很典型的坑。有段时间在做代码审查功能,想用模型自动分析 PR 的代码质量。一开始我写的 prompt 是这样的:

请审查以下代码,找出潜在问题。

结果模型给我回了三段非常空洞的话——"建议增强错误处理"、"代码风格良好"、"注意性能优化"。每句话都对,但没有一句有实质价值。它没有指出具体的行号,没有分析逻辑缺陷,没有区分严重等级。

我一开始觉得是模型不行。换了大模型,好了一点,但本质没变——输出的还是泛泛而谈。后来我意识到问题不在模型,在我。

第一个技巧:给格式,不给指令

人跟人沟通的时候,说"给我一份报告"和给一个表格模板让对方填,效率完全不一样。LLM 也是。

我改成这样:

分析以下代码,按这个格式输出:

严重问题(可能导致崩溃或数据丢失)

  • [行号] 问题描述 | 影响范围 | 修复建议

潜在问题(边界情况或异常路径)

  • [行号] 问题描述 | 影响范围 | 修复建议

风格建议(不影响功能但可改进)

  • [行号] 问题描述

不是"请找出问题",而是"请填这三张表"。结果完全不一样了。模型开始输出具体的行号、具体的缺陷类型、具体的修复建议。不是它突然变聪明了,而是输出格式限制迫使它在生成内容时做了更细粒度的推理

这个后来我查了资料才知道有个名字——"结构化提示"。原理很简单:当你告诉模型输出一个 JSON 或 Markdown 表格时,它内部生成每个字段的过程其实是在做一次独立的推理。一段自由文本的输出只需要一个连贯的思维流,而一个带格式的输出需要在多个槽位之间做信息分配——这迫使模型在多个维度上分别思考。

第二个技巧:让模型在回答之前先"说一遍"

做技术问答的时候,我发现一个现象:如果 prompt 里明确要求模型把推理过程写出来,最终答案的准确率会明显提升。

一开始我不理解为什么。后来想明白了:让人直接给结论和让人先把推理过程写出来再给结论,出错率是不一样的。 你让一个人心算 37 × 24,他可能直接说大概八九百。但如果要求他先把竖式写出来再报结果,他很难算错。

LLM 也一样。我试过一个对比实验:

第一组 prompt:

这段代码的时间复杂度是多少?
python for i in range(n): for j in range(i): print(i * j)

第二组 prompt:

分析这段代码的时间复杂度。先逐行分析每层循环的执行次数,然后求和,最后给出整体复杂度。
python for i in range(n): for j in range(i): print(i * j)

第一组模型经常直接答 O(n²) —— 对是对了,但一旦代码复杂一点,它直接给结论就容易错。第二组先要求把分析过程写出来,准确率高得多。就算最后答案错了,你也能从推理过程中看出它是在哪一步出问题的。

这个技巧现在各种模型都有内置支持了。OpenAI 的 o1 系列和 Anthropic 的 Claude 都有 reasoning 模式,本质上就是把这个过程内置到了模型推理阶段。但即使模型支持,我建议你还是在 prompt 里主动要求它这么做——不依赖模型自己"记住"要思考,而是你明确要求它思考。

第三个技巧:给反面例子

我花最长时间的摸索其实不是"怎么写 prompt",而是"怎么给模型建立正确的拒绝边界"。

做内容审核的场景,我需要模型判断一段用户评论是否包含攻击性语言。一开始的 prompt 是:

判断以下评论是否具有攻击性。是则回复 YES,否则回复 NO。

结果模型在边界案例上表现很差。比如用户评论"你们的客服水平也太高了",表面上正面,实际上是讽刺——模型判断成 NO。又比如"你这个方案写得真是垃圾"——模型判断成 YES,这没问题,但需要同时给出修改建议时它就不统一了。

后来我加了反面例子:

判断以下评论是否具有攻击性。是则回复 YES,否则回复 NO。

以下是示例:
评论:"你们的客服水平也太高了"
正确判断:YES(讽刺)

评论:"谢谢你的帮助"
正确判断:NO

评论:"你这个逻辑完全说不通"
正确判断:YES(否定对方能力)

评论:"我不同意你的观点,因为..."
正确判断:NO(有理由的反对不是攻击)

加了 Few-shot 反面示例之后,准确率从大概 70% 提到了 90% 以上。关键不在于例子多,而在于覆盖了最容易混淆的边界情况。你给的例子越贴近真实场景中容易出错的点,效果越好。

最后

回头看这半年的摸索,最有价值的发现不是某个特定的 prompt 模板或者技巧,而是一个更底层的认知:写 prompt 不是在跟一个"人"说话,而是在设计一个信息处理管线的入口。

格式约束、推理链要求、边界示例——这些技巧本质上是同一个东西:把信息以模型最容易处理的方式组织好送进去。你给输入管线的结构越清晰,输出就越可靠。

现在写 prompt,我只问自己三个问题:它知道输出格式吗?它有没有机会先思考再回答?我有没有告诉它哪些情况算错?这三个问题答完了,我一般就不太需要改 prompt 了。

评论

此博客中的热门博文