AI · #llm#prompt-engineering#chatgpt#productivity

用了一年 ChatGPT,真正有用的 prompt 写法就这几种

2024.04.01 3 min 1.2k
// 目录 · contents

用 ChatGPT 大概有一年了,从最开始随手输入问题,到现在有一套比较固定的写法。这篇文章不是 prompt engineering 的系统教程,只记录我实际反复在用的那几种,跳过那些我试过一次觉得鸡肋的。

把”你”换成”一个有经验的人”

最简单但效果明显的技巧。

1
2
3
4
5
6
7
# 效果一般
解释一下 Java 里的 volatile

# 效果明显好一些
你是一个写 Java 十年的工程师,正在给新入职的同事解释 volatile 关键字。
要解释清楚:它解决什么问题、内存可见性是什么意思、和 synchronized 的区别。
用类比帮助理解,最后给一个容易踩的坑。

为什么有用?第一版的问题是太泛了,模型不知道”你是谁”,回答就会面面俱到但没有重点。加了角色和场景之后,回答的角度和深度就定下来了。

这不是什么玄学,就是在告诉模型:这个问题的语境是什么,期待什么层次的读者。

让模型先思考再给答案

复杂问题直接问答案,质量不稳定。加一句”逐步分析”或者拆成几个步骤,效果好不少:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
帮我看这段 SQL 有没有性能问题。

先分析:
1. 涉及哪些操作(JOIN、WHERE、ORDER BY 等)
2. 每个操作的潜在性能影响
3. 哪些字段需要加索引

最后给出优化建议,包括具体的索引创建语句。

SQL:
SELECT u.name, COUNT(o.id) as order_count
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
WHERE o.status = 'paid' AND o.created_at > '2024-01-01'
GROUP BY u.id
ORDER BY order_count DESC
LIMIT 20;

这个方法对”分析类”的问题特别有用:代码审查、方案评审、异常排查。让模型把分析过程显化出来,比直接给结论更可靠,也更容易发现哪里推理有问题。

用例子说明你要什么格式

有时候与其用文字描述期望的输出,不如直接给一两个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
我要把 code review 意见转成 JIRA 任务,格式参考下面的例子。

例子 1:
输入:这个方法没有处理 null,可能 NPE
输出:
标题:修复 parseUser() 的 NPE 风险
类型:Bug / P2
描述:当 userId 为 null 时未做防御,建议加 Objects.requireNonNull 或提前返回

例子 2:
输入:这个 SQL 全表扫描了 500 万行
输出:
标题:优化订单查询 SQL 性能
类型:技术债 / P1
描述:EXPLAIN 显示全表扫描,建议在 (user_id, status, created_at) 创建复合索引

现在处理:登录接口没有限制重试次数,存在暴力破解风险

少样本比写一大段格式说明更直接,模型理解起来更准确。

要求结构化输出

在代码里调用 API 时,让模型输出 JSON,方便后续处理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
prompt = """
分析以下代码,以 JSON 格式输出,只输出 JSON,不要其他文字。

格式:
{
"issues": [
{
"type": "bug|performance|security",
"severity": "high|medium|low",
"line": 行号,
"description": "问题描述",
"suggestion": "修改建议"
}
]
}

代码:
{code}
"""

“只输出 JSON,不要其他文字”这句话很关键。模型有时候会在 JSON 前面加”好的,这是分析结果:“之类的,加上这句能大幅减少这种情况。

让模型说清楚它不确定的地方

这条我觉得很重要但经常被忽视。

模型会用很自信的语气给出错误答案,特别是涉及具体的 API、库版本、配置参数的时候。在 prompt 里加上:

1
2
如果你对某个细节不确定,请明确说出来,不要编造。
如果我的问题超出你能可靠回答的范围,直接说不确定。

加了这句之后,模型确实会更经常说”这里我不太确定,建议查官方文档”,而不是给一个听起来合理但可能错的答案。

不能完全依赖这个,但有一定效果。


一个我用来调试 prompt 的方法:如果回答不满意,不要反复追问,而是换一种问法,或者直接问模型”这个回答有什么问题,怎么改会更好?“。有时候让模型评估自己的回答,能得到很有用的角度。

还有一点:不要用模型查实时信息。库版本、API 文档、最新的框架特性,模型训练数据有截止日期,很容易给出过时的信息。用模型理解原理,用官方文档确认细节。

作者 · authorzt
发布 · date2024-04-01
篇幅 · length1.2k 字 · 3 min
许可 · licenseCC BY-SA 4.0
$ echo "comments" · 评论