Featured image of post 提示词工程

提示词工程

大模型Prompt工程指南,从基础到进阶技巧

大模型prompt工程指南

提示工程(Prompt Engineering),也称为 In-Context Prompting,是指在不更新模型权重的情况下如何与大模型互以引导其行为以获得所需结果的方法。

在人工智能领域,Prompt指的是用户给大型语言模型发出的指令。

例如,“「讲个笑话」”、“「用Python编个贪吃蛇游戏」”、“「写封情书」”等。

虽然看似简单,但实际上,Prompt的设计对于模型的结果影响很大。

因此如何设计prompt,进而与模型更好的交互,是研究人员必备的必不可少的技能(提示工程)。

技巧

  • 详细的描述
  • 让ai扮演某个角色
  • 使用分隔符标注输入的不同部分(强调重点等)
  • 指定任务的步骤
  • 提供例子
  • 使用参考文本(降低模型的幻觉)

如:

根据下文中三重引号引起来的文章来回答问题。
如果在文章中找不到答案,请写“我找不到答案”,
不要自己造答案。

“”"<在此插入文档>""""<在此插入文档>"""" 问题: <在此插入问题>

提示词工程就是更好的向模型提问的技巧。大模型本身是一种很简单的结构,即:用户输入,模型输出。

  • 用更详细、更清晰、有逻辑、有参考的提问,获得期望中的回答效果
  • 不管是 RAG 还是 Agent 智能体亦或是其它围绕模型的各类复杂的开发工作,本质上都可以简单总结为在提示词上下功夫。

Zero-shot思想

Zero-shot学习是指在训练阶段不存在与阶段完全相同的类别,但是模型可以是同训练过的知识来推广到测试集中的新类别上。

这种能力称为”零样本“学习,因为模型在训练是从未见过的测试集中的新类别,在模型训练和提示词优化中均有体现。

在模型训练中:

  1. 已知马(四脚兽)、虎(有条纹)、熊猫(黑白色)的特征,但未训练过斑马的数据(不认识)
  2. 告知模型:斑马是四脚兽、有黑白色的条纹
  3. 模型可以在已知数据中进行推理,从而识别斑马。

在提示词优化中:

Zero-shot 思想用于基于已训练的能力,不提供任何示例,仅通过语言去描述任务的要求、目标和约束,让模型直接生成结果。

简单来说就是 “用语言定义任务,解放(信任)模型的预训练知识”

比如:请判断 "" 包围的用户评论中的情感倾向,输出 正面 或 负面。
“这款代餐鸡胸肉饱腹感很强,吃起来也不柴,很推荐!”

Few-shot思想

Few-shot 学习(Few-shot Learning)是指少样本学习,当模型在学习了一定类别的大量数据后,对于新的类别,只需要少量的样本就能快速学习,对应的有 one-shot learning,单样本学习,也算样本少到为一的情况下的一种 few-shot learning。

在模型训练中(相似度判断方法):

基于少量企鹅样本并结合相识度判断,推论未知图片内含 “企鹅”

在提示词优化中:

Few-shot 主要用于基于少量示例,让模型参考示例回答。

简单来说就是 “用示例定义任务,在模型的预训练知识的基础上,提升模型回答的对齐精度(比如参考示例的格式)”

比如:请抽取产品名称和核心卖点 2 个字段,格式为 Json,我提供 2 个示例。

  • 示例 1:MacBookPro 高效节能,性能强大,适合牛马工作使用
    • 输出: {“产品名称”: “MacBookPro”, “产品卖点”: “高效节能,性能强大”}
  • 示例 2:联想笔记本拥有 RTX4060 独立显卡,畅玩游戏,丝滑流畅
    • 输出: {“产品名称”: “联想笔记本”, “产品卖点”: “畅玩游戏,丝滑流畅”} 请处理:华为 MatepadPro,高清大屏,长效续航,你的好帮手。

实例案例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
from openai import OpenAI

# 1. 获取client对象,OpenAI类对象
client = OpenAI(
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
)

examples_data = {  # 示例数据
    '新闻报道': '今日,股市经历了一轮震荡,受到宏观经济数据和全球贸易紧张局势的影响。投资者密切关注美联储可能的政策调整,以适应市场的不确定性。',
    '财务报告': '本公司年度财务报告显示,去年公司实现了稳步增长的盈利,同时资产负债表呈现强劲的状况。经济环境的稳定和管理层的有效战略执行为公司的健康',
    '公司公告': '本公司高兴地宣布成功完成最新一轮并购交易,收购了一家在人工智能领域领先的公司。这一战略举措将有助于扩大我们的业务领域,提高市场竞争力',
    '分析师报告': '最新的行业分析报告指出,科技公司的创新将成为未来增长的主要推动力。云计算、人工智能和数字化转型被认为是引领行业发展的关键因素,投资'
}

examples_types = ['新闻报道', '财务报道', '公司公告', '分析师报告']

# 提问数据
questions = [
    "今日,央行发布公告宣布降低利率,以刺激经济增长。这一降息举措将影响贷款利率,并在未来几个季度内对金融市场产生影响。",
    "ABC公司今日发布公告称,已成功完成对XYZ公司股权的收购交易。本次交易是ABC公司在扩大业务范围、加强市场竞争力方面的重要举措。据悉,此次收购将进一步",
    "公司资产负债表显示,公司偿债能力强劲,现金流充足,为未来投资和扩张提供了坚实的财务基础。",
    "最新的分析报告指出,可再生能源行业预计将在未来几年经历持续增长,投资者应该关注这一领域的投资机会",
    "小明喜欢小新哟"
]

"""

[
    {"role": "system", "content": "你是金融专家,将文本分类为['新闻报道', '财务报道', '公司公告', '分析师报告'],不清楚的分类为'不清楚'"},
    {"role": "user", "content": "今日,央行发布公告宣布降............"},
    {"role": "assistant", "content": "新闻报道"},
    {"role": "user", "content": "ABC公司今日发布公告称,已成功完成对XYZ公司股.................."},
    {"role": "assistant", "content": "财务报告"},
    {"role": "user", "content": "公司资产负债表显示,公司偿债能力强劲,现金流充足.................."},
    {"role": "assistant", "content": "公司公告"},
    {"role": "user", "content": "最新的分析报告指出,可再生能源..............."},
    {"role": "assistant", "content": "分析师报告"},
    {"role": "user", "content": "要提问的问题"}
]

"""

messages = [
    {"role": "system", "content": "你是金融专家,将文本分类为['新闻报道', '财务报道', '公司公告', '分析师报告'],不清楚的分类为'不清楚类别'"}
]

for key, value in examples_data.items():
    messages.append({"role": "user", "content": value})
    messages.append({"role": "assistant", "content": key})


# 向模型提问
for q in questions:
    response = client.chat.completions.create(
        model="qwen3-max",
        messages=messages + [{"role": "user", "content": f"按照示例,回答这段文本的分类类别: {q}"}]
    )

    print(response.choices[0].message.content)

Json数据格式

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。

Json 是带有格式的字符串,主要用于数据交换,即程序和程序之间的信息互传,使用 Json 会更加方便,如下示例:

1
2
3
4
5
1 周杰伦11岁是个男孩

2 蔡依临12岁是个女孩

3 小明16岁是一个男孩子  

Text文本,非结构化,抓取信息不方便

1
2
3
4
5
1 周杰伦,11,男

2 蔡依临,12,女

3 小明,16,男

CSV(固定分隔符)文本,结构化,抽取信息方便,数据不含schema,有一定风险。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
{
    "name": "周杰伦",
    "age": 11,
    "gender": "男"
}
{
    "name": "蔡依临",
    "age": 12,
    "gender": "女"
}
{
    "name": "小明",
    "age": 16,
    "gender": "男"
}

Json格式文本,结构化,抽取信息方便,每条数据都包含Schema,但空间占用大。

Json有两种结构,Json对象和Json数组

Json对象

1
2
3
4
{
    "key":value,
    "key":value
}

Jaon数组

1
[{},{},{},...]

实例

1
2
3
4
5
6
7
{
[
    {"name": "周杰伦", "age": 11},
    {"name": "蔡依临", "age": 12},
    {"name": "小明", "age": 16}
]
}

Python 中使用 Json

Python 中使用 Json 主要完成:

  • 将 Python 字典、列表转换为 Json 字符串
  • 读取 Json 字符串,转换为 Python 字典或列表

主要使用 Python 内置的 json 库

  • json.dumps(字典或列表, ensure_ascii=False):将字典或列表转换为 Json 字符串
    • ensure_ascii参数确保中文能正常显示
    • 返回值:Json 字符串
  • json.loads(json字符串):将 Json 字符串转换为 Python 字典或列表
    • 返回值:Python 字典 或 Python 列表
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import json

d = {
    "name": "周杰伦",
    "age": 11,
    "gender": "男"
}

s = json.dumps(d, ensure_ascii=False)
print(s)

l = [
    {
        "name": "周杰伦",
        "age": 11,
        "gender": "男"
    },
    {
        "name": "蔡依临",
        "age": 12,
        "gender": "女"
    },
    {
        "name": "小明",
        "age": 16,
        "gender": "男"
    }
]
print(json.dumps(l, ensure_ascii=False))

json_str = '{"name": "周杰伦", "age": 11, "gender": "男"}'
json_array_str = '[{"name": "周杰伦", "age": 11, "gender": "男"}, {"name": "蔡依临", "age": 12, "gender": "女"}, {"name": "小明", "age": 16, "gender": "男"}]'

res_dict = json.loads(json_str)
print(res_dict, type(res_dict))

res_list = json.loads(json_array_str)
print(res_list, type(res_list))

提示词优化案例——金融信息文本抽取

prompt

在该任务的 prompt 设计中,我们主要考虑 2 点:

  • 需要向模型解释什么叫作「信息抽取任务」
  • 需要让模型按照我们指定的格式(json)输出 为了让模型知道什么叫做「信息抽取」,我们借用 FewShot 的方式,先给模型展示几个正确的例子:

User: ‘2023-01-10,股市震荡。股票古哥 - D [EOOE] 美股今日开盘价 100 美元,一度飙升至 105 美元,随后回落至 98 美元,最终以 102 美元收盘,成交量达到 520000。’。提取上述句子中 “金融” (’ 日期 ‘, ’ 股票名称 ‘, ’ 开盘价 ‘, ’ 收盘价 ‘, ’ 成交量 ‘) 类型的实体,并按照 JSON 格式输出,上述句子中没有的信息用 [’ 原文中未提及 ‘] 来表示,多个值之间用 ‘,’ 分隔。

Bot: {‘日期’: [‘2023-01-10’], ‘股票名称’: [‘古哥-D[EOOE]美股’], ‘开盘价’: [‘100美元’], ‘收盘价’: [‘102美元’], ‘成交量’: [‘520000’]} …

其中,User 代表我们输入给模型的句子,Bot 代表模型的回复内容。

注意:上述例子中 Bot 的部分也是由人工输入的,其目的是希望看到在看到类似 User 中的句子时,模型应当做出类似 Bot 的回答。

示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
from openai import OpenAI
import json

client = OpenAI(
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
    # base_url="http://localhost:11434/v1"
)

schema = ['日期', '股票名称', '开盘价', '收盘价', '成交量']

examples_data = [  # 示例数据
    {
        "content": "2023-01-10,股市震荡。股票强大科技A股今日开盘价100人民币,一度飙升至105人民币,随后回落至98人民币,最终以102人民币收盘,成交量达到520000。",
        "answers": {
            "日期": "2023-01-10",
            "股票名称": "强大科技A股",
            "开盘价": "100人民币",
            "收盘价": "102人民币",
            "成交量": "520000"
        }
    },
    {
        "content": "2024-05-16,股市利好。股票英伟达美股今日开盘价105美元,一度飙升至109美元,随后回落至100美元,最终以116美元收盘,成交量达到3560000。",
        "answers": {
            "日期": "2024-05-16",
            "股票名称": "英伟达美股",
            "开盘价": "105美元",
            "收盘价": "116美元",
            "成交量": "3560000"
        }
    }
]

questions = [  # 提问问题
    "2025-06-16,股市利好。股票传智教育A股今日开盘价66人民币,一度飙升至70人民币,随后回落至65人民币,最终以68人民币收盘,成交量达到123000。",
    "2025-06-06,股市利好。股票黑马程序员A股今日开盘价200人民币,一度飙升至211人民币,随后回落至201人民币,最终以206人民币收盘。"
]

"""
[
    {"role": "system",
     "content": f"你帮我完成信息抽取,我给你句子,你抽取{schema}信息,按JSON字符串输出,如果某些信息不存在,用'原文未提及'表示,请参考如下示例:"},

    {"role": "user",
     "content": "2023-01-10,股市震荡。股票强大科技A股今日开盘价100人民币,一度飙升至105人民币,随后回落至98人民币,最终以102人民币收盘,成交量达到520000。"},
    {"role": "assistant",
     "content": '{"日期":"2023-01-10","股票名称":"强大科技A股","开盘价":"100人民币","收盘价":"102人民币","成交量":"520000"}'},

    {"role": "user",
     "content": "2024-05-16,股市利好。股票英伟达美股今日开盘价105美元,一度飙升至109美元,随后回落至100美元,最终以116美元收盘,成交量达到3560000。"},
    {"role": "assistant",
     "content": '{"日期":"2024-05-16","股票名称":"英伟达美股","开盘价":"105美元","收盘价":"116美元","成交量":"3560000"}'},

    {"role": "user",
     "content": f"按照上述示例,现在抽取这个句子的信息:{要抽取的句子文本}"}
]
"""

messages = [
    {"role": "system", "content": f"你帮我完成信息抽取,我给你句子,你抽取{schema}信息,按JSON字符串输出,如果某些信息不存在,用'原文未提及'表示,请参考如下示例:"}
]

for example in examples_data:
    messages.append(
        {"role": "user", "content": example["content"]}
    )
    messages.append(
        {"role": "assistant", "content": json.dumps(example["answers"], ensure_ascii=False)}
    )

for q in questions:
    response = client.chat.completions.create(
        model="qwen3-max",
        messages=messages + [{"role": "user", "content": f"按照上述的示例,现在抽取这个句子的信息:{q}"}]
    )
    print(response.choices[0].message.content)

LLM信息文本匹配任务介绍

首先我们构造几个短文本对

1
2
3
1. ('股票市场今日大涨,投资者乐观。', '持续上涨的市场让投资者感到满意。'),
2. ('油价大幅下跌,能源公司面临挑战。', '未来智能城市的建设趋势愈发明显。'),
3. ('利率上升,影响房地产市场。', '高利率对房地产有一定冲击。'),

我们期望模型能够帮我们识别出成对的句子中,2 句话是否是有关联的

。我们期望模型输出的结果为:

       ['是', '不是', '是']

Prompt设计

在该任务的 prompt 设计中,我们主要考虑 2 点:

  • 需要向模型解释什么叫作「文本匹配任务」
  • 需要让模型按照我们指定的格式输出

为了让模型知道什么叫做「文本匹配任务」,我们借用 FewShot 的方式,先给模型展示几个正确的例子:

User:

  • 句子一:公司 ABC 发布了季度财报,显示盈利增长。
  • 句子二:财报披露,公司 ABC 利润上升
  • Bot: 是

User:

  • 句子一:黄金价格下跌,投资者抛售。
  • 句子二:外汇市场交易额创下新高
  • Bot: 不是 …

其中,User 代表我们输入给模型的句子,Bot 代表模型的回复内容。

注意:上述例子中 Bot 的部分也是由人工输入的,其目的是希望看到在看到类似 User 中的句子时,模型应当做出类似 Bot 的回答。

示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
from openai import OpenAI

client = OpenAI(
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
    # base_url="http://localhost:11434/v1"
)

examples_data = {
    "是": [
        ("公司ABC发布了季度财报,显示盈利增长。", "财报披露,公司ABC利润上升。"),
        ("公司ITCAST发布了年度财报,显示盈利大幅度增长。", "财报披露,公司ITCAST更赚钱了。")
    ],
    "不是": [
        ("黄金价格下跌,投资者抛售。", "外汇市场交易额创下新高。"),
        ("央行降息,刺激经济增长。", "新能源技术的创新。")
    ]
}

questions = [
    ("利率上升,影响房地产市场。", "高利率对房地产有一定的冲击。"),
    ("油价大幅度下跌,能源公司面临挑战。", "未来智能城市的建设趋势越加明显。"),
    ("股票市场今日大涨,投资者乐观。", "持续上涨的市场让投资者感到满意。")
]

"""
{
    "role": "system",
    "content": f"你帮我完成文本匹配,我给你2个句子,被[]包围,你判断它们是否匹配,回答是或不是,请参考如下示例:"
},
{
    "role": "user",
    "content": "句子1:[公司ABC发布了季度财报,显示盈利增长。]句子2:[财报披露,公司ABC利润上升。]"
},
{
    "role": "assistant",
    "content": "是"
},
{
    "role": "user",
    "content": "句子1:[公司ITCAST发布了年度财报,显示盈利大幅度增长。]句子2:[财报披露,公司ITCAST更赚钱了。]"
},
{
    "role": "assistant",
    "content": "是"
},
{
    "role": "user",
    "content": "句子1:[黄金价格下跌,投资者抛售。]句子2:[外汇市场交易额创下新高。]"
},
{
    "role": "assistant",
    "content": "不是"
},
{
    "role": "user",
    "content": "句子1:[央行降息,刺激经济增长。]句子2:[新能源技术的创新。]"
},
{
    "role": "assistant",
    "content": "不是"
},
{
    "role": "user",
    "content": f"按照上述示例,回答这2个句子的情况。句子1:[...],句子2:[...]"
}
"""

messages = [
    {"role": "system", "content": f"你帮我完成文本匹配,我给你2个句子,被[]包围,你判断它们是否匹配,回答是或不是,请参考如下示例:"},
]

for key, value in examples_data.items():
    for t in value:
        messages.append(
            {"role": "user", "content": f"句子1: [{t[0]}], 句子2: [{t[1]}]"}
        )
        messages.append(
            {"role": "assistant", "content": key}
        )

for q in questions:
    response = client.chat.completions.create(
        model="qwen3-max",
        messages=messages + [{"role": "user", "content": f"句子1: [{q[0]}], 句子2: [{q[1]}]"}]
    )
    print(response.choices[0].message.content)
不嘻嘻
使用 Hugo 构建
主题 Stack 由 Jimmy 设计