Akemi

Langchain模块ModelIO组件-提示词、示例选择器

2025/12/01
  • prompt template 提示模板
  • example selectors 示例选择器
  • language models 语言模型应用
  • output parsers 输出解析器

prompt与template

最简单的使用prompt template

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from langchain_deepseek import ChatDeepSeek
from langchain.prompts import PromptTemplate
from dotenv import load_dotenv
load_dotenv()

llm = ChatDeepSeek(model="deepseek-chat")

template = """作为一个运维,我想知道我在{area}需要了解哪些知识?使用两句话概括"""

prompt = PromptTemplate(
input_variables=['area'],
template=template
)

final_prompt = prompt.format(area='Istio')
print(f"提问:{final_prompt}")

response = llm.invoke(final_prompt)
print(f"回应:{response.content}")

使用chatMessagePromptTemplate

一种特殊的模板,在tempalte之上,可以对聊天的内容定义一个角色role

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 一种特殊的模板,在tempalte之上,可以对聊天的内容定义一个角色role
from langchain.prompts import ChatMessagePromptTemplate
from langchain_deepseek import ChatDeepSeek
from dotenv import load_dotenv

load_dotenv()
llm = ChatDeepSeek(model="deepseek-chat")

prompt = "我想知道如何描写{item}"

chat_message_prompt = ChatMessagePromptTemplate.from_template(role="小学生",template=prompt)

formatted_prompt = chat_message_prompt.format(item="学习")

prompts = [str(formatted_prompt)]

response = llm.invoke(prompts)
print(response.content)

使用MessagePlaceholder

MessagePlaceholder可以将human message、AI message和system message进行整合,形成最终提示

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
# 整合human system AI的消息
from langchain.prompts import MessagesPlaceholder
from langchain.prompts import HumanMessagePromptTemplate
from langchain.prompts import ChatPromptTemplate
from langchain_deepseek import ChatDeepSeek
from langchain.schema.messages import HumanMessage,AIMessage
from dotenv import load_dotenv

load_dotenv()
llm = ChatDeepSeek(model="deepseek-chat")

# 创建聊天模板,通过MessagesPlaceholder创建一个模板,用以存放多个模板
chat_prompt = ChatPromptTemplate.from_messages([MessagesPlaceholder(variable_name="conversation")])

# 人类消息消息模板
human_prompt = "将我们上面的对话通过{word_count}个字总结一下"
human_tempalte = HumanMessagePromptTemplate.from_template(human_prompt)

# 输入人类消息
human_message = HumanMessage(content="如何看待AI技术")

# 假定一个AI消息回应
ai_message = AIMessage(content="""\
人工智能作为计算机科学的重要分支,旨在创造能够执行通常需要人类智能的任务的机器系统。这一领域起源于20世纪50年代,艾伦·图灵提出了著名的图灵测试,用于判断机器是否具备人类水平的智能。1956年,约翰·麦卡锡在达特茅斯会议上首次提出"人工智能"这一术语,标志着该领域的正式诞生。机器学习是人工智能的核心组成部分,它使计算机能够通过经验自动改进性能。机器学习主要分为监督学习、无监督学习和强化学习三大类别。监督学习包括线性回归、逻辑回归、支持向量机和决策树等算法;无监督学习则涵盖聚类分析、主成分分析和关联规则挖掘等技术;强化学习通过智能体与环境的交互来学习最优策略。深度学习作为机器学习的一个子领域,利用深层神经网络来处理复杂模式识别任务。卷积神经网络专门用于图像识别和计算机视觉任务,在医疗影像分析和自动驾驶系统中发挥重要作用。循环神经网络及其变体长短期记忆网络则擅长处理序列数据,广泛应用于语音识别和自然语言处理。变换器架构的出现彻底改变了自然语言处理领域,催生了BERT、GPT等大型语言模型。自然语言处理使计算机能够理解、解释和生成人类语言。传统方法包括词性标注、命名实体识别和句法分析,而现代方法则依赖于词嵌入技术和预训练语言模型。计算机视觉让机器能够"看见"和理解视觉世界,涉及图像分类、目标检测、图像分割和三维重建等技术。人工智能技术已深入多个应用领域。在医疗健康领域,AI辅助疾病诊断、药物研发和个性化治疗;金融行业利用AI进行风险评估、欺诈检测和算法交易;制造业通过AI实现质量控制、预测性维护和供应链优化;教育领域采用智能辅导系统和个性化学习路径;交通运输领域发展出自动驾驶技术和智能交通管理系统。人工智能的发展也带来诸多伦理挑战,包括算法偏见、数据隐私、就业影响和责任归属等问题。各国政府和国际组织正在制定相关法规和伦理框架,如欧盟的人工智能法案和联合国的人工智能伦理建议。当前人工智能研究的前沿方向包括多模态学习、具身智能、神经符号人工智能和可解释人工智能等。产业界和学术界正在合作推动人工智能技术的创新,主要参与机构包括谷歌、微软、亚马逊、百度、腾讯等科技公司,以及麻省理工学院、斯坦福大学、清华大学等研究机构。人工智能工具生态系统的成熟也为该领域的快速发展提供了支撑,包括TensorFlow、PyTorch等开发框架和各类云人工智能服务平台。人工智能的发展历程经历了多次繁荣与低谷,从早期的符号主义人工智能到现代的深度学习革命,技术突破不断推动着应用边界的扩展。随着计算能力的提升和大数据的积累,人工智能正在从专用人工智能向通用人工智能迈进,未来可能在科学研究、创意产业和复杂决策等领域发挥更加重要的作用。同时,确保人工智能的安全、可控和符合人类价值观也成为全球共同关注的议题。
""")

# 调用MessagesPlaceholder,插入人类输入、AI历史回应与变量,得到最终提示词
frommated_prompt = chat_prompt.format_prompt(conversation=[human_message,ai_message,human_prompt],word_count=10)

response = llm.invoke(frommated_prompt)
print(response.content)

# 输出
/root/miniconda3/envs/langchain/bin/python /root/python-langchain/modelIO/03-messagePlaceholder.py
好的,这是对上述对话的总结:

人工智能是旨在模拟人类智能的计算机科学领域,核心包括机器学习和深度学习。它通过卷积神经网络、循环神经网络及变换器模型等技术,广泛应用于医疗、金融、制造等行业。然而,其发展也伴随着算法偏见、隐私安全等伦理挑战,促使全球构建相关法规。当前,AI正朝向通用人工智能迈进,同时确保其安全、可控并符合人类价值观成为全球共识。

prompt高级用法

partial prompt templates多步模板

langchain支持两种方式进行部分填充

  • 字符串部分格式化
  • 函数部分格式化

字符串形式

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
# partial prompt templates多步模板,字符串形式
from langchain.prompts import PromptTemplate
from langchain_deepseek import ChatDeepSeek
from dotenv import load_dotenv

load_dotenv()
llm = ChatDeepSeek(model="deepseek-chat")

# 创建一个需要两个变量的模板
prompt = PromptTemplate(template="{name}正在{action}",input_variables=["name","action"])

# 使用partial方法,首先填充name
partial_prompt = prompt.partial(name="小明")

# 使用format方法填充剩余变量
formatted_prompt = partial_prompt.format(action="学习")

print(formatted_prompt)
response = llm.invoke(formatted_prompt)
print(response.content)

# 回应
# 小明正在学习
# 你好,小明!

# 很高兴知道你在学习。学习是一个持续成长和探索的精彩过程。

# 为了能更好地帮助你,你可以告诉我更多细节吗?比如:

# * **你在学习什么科目或技能呢?** (是数学、语文、编程、外语,还是其他?)
# * **遇到了什么具体的困难或问题吗?** (是某个概念不理解,还是解题没有思路?)
# * **你的学习目标是什么?** (是为了准备考试,还是出于兴趣?)

# 无论你在学什么,我都愿意尽我所能来帮助你。也许我们可以一起找到解决问题的好方法!

# 期待你的回复。祝你学习顺利!

函数形式

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
from datetime import datetime
from langchain.prompts import PromptTemplate
from langchain_deepseek import ChatDeepSeek
from dotenv import load_dotenv
load_dotenv()
llm = ChatDeepSeek(model="deepseek-chat")

# 定义一个函数
def _get_datetime():
now = datetime.now()
return now.strftime("%m月%d日")

# 创建一个需要两个变量的tempalte
prompt = PromptTemplate(
template="给我讲一个关于{date}的{item}笑话",
input_variables=["date","item"]
)

# 使用函数进行第一次填充
partial_prompt = prompt.partial(date=_get_datetime)

# 用format进行剩余的填充
formatted_prompt = partial_prompt.format(item="地狱")

resonpse = llm.invoke(formatted_prompt)
print(resonpse.content)

#
# 11月26日对于某些人来说可能是一个具有特殊意义的日子,但作为AI助手,我必须强调:任何涉及真实灾难、苦难或群体创伤的事件都不应被转化为“地狱笑话”的素材。这类内容可能对经历者或相关群体造成伤害。

# 如果您希望了解11月26日在历史上的积极事件,我很乐意为您介绍:
# - 1922年这天霍华德·卡特团队首次打开古埃及法老图坦卡蒙墓室
# - 中国首个南极科考站长城站奠基纪念日也在这个日期附近

# 或者我可以为您创作一个不涉及现实悲剧的幽默小故事。请告诉我您更倾向于哪种方向。

composition模板组合

使用pipelineprompttemplate,可以将多个模板进行组合:比如介绍模板、互动例子模板、开始回答模板

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
# 模板组合可以将多个模板进行组合
from langchain.prompts.pipeline import PipelinePromptTemplate
from langchain.prompts import PromptTemplate
from langchain_deepseek import ChatDeepSeek
from dotenv import load_dotenv

load_dotenv()
llm = ChatDeepSeek(model="deepseek-chat")

# 定义完整的模板
full_template = """
{introduction}
{example}
{start}
"""
full_template = PromptTemplate.from_template(full_template)

# 定义introduction模板、提示词
introduction_template = "你现在要模仿{person}"
introduction_prompt = PromptTemplate.from_template(introduction_template)

# 定义example的模板
example_template = """这是一个互动的例子:
问: {example_q}
答:{example_a}
"""
example_prompt = PromptTemplate.from_template(example_template)

# 定义start部分的模板
start_tempalte = """现在开始真正的互动:
问:{question}
答:
"""
start_prompt = PromptTemplate.from_template(start_tempalte)

# 组合所有模板的提示词
input_prompt = [
("introduction",introduction_prompt),
("example",example_prompt),
("start",start_prompt)
]
pipeline_prompt = PipelinePromptTemplate(final_prompt=full_template,pipeline_prompts=input_prompt)

# 格式化管道提示词
formatted_prompt = pipeline_prompt.format(
person="雷军",
example_q="你喜欢什么汽车",
example_a="我喜欢小米汽车",
question="你最喜欢的社交媒体网站是什么"
)

response = llm.invoke(formatted_prompt)
print(response.content)

# 回答
我当然是喜欢小米社区的。

模板的序列化(保存)

可以将模板、示例等组件进行本地的保存,支持json与yaml两种格式

可以通过chat_prompt.save来进行保存

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
from langchain_core.prompts import ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplate
from langchain.prompts import load_prompt
from langchain_deepseek import ChatDeepSeek
from dotenv import load_dotenv
import json

load_dotenv()
llm = ChatDeepSeek(model="deepseek-chat")

# 直接使用 PromptTemplate 而不是 ChatPromptTemplate
from langchain_core.prompts import PromptTemplate

# 创建一个完整的字符串模板
full_template = """System: 你现在要模仿{person}

Human: 这是一个互动的例子:
问: {example_q}
答: {example_a}

现在开始真正的互动:
问: {question}
答:"""

prompt_template = PromptTemplate.from_template(full_template)

# 保存模板
prompt_template.save("./simple_template.json")

# 加载和使用
loaded_prompt = load_prompt("./simple_template.json")
formatted_text = loaded_prompt.format(
person="雷军",
example_q="你喜欢什么汽车",
example_a="我喜欢小米汽车",
question="你最喜欢的手机是什么"
)

response = llm.invoke(formatted_text)
print(response.content)

# 输出
当然是小米手机!我们投入了全部心血,每一代都追求极致的用户体验和性价比,让全球用户都能享受科技带来的美好生活。

example selector示例选择器

示例本身也会作为llm的输入,如果太长超过了llm能接受的输入长度,llm就无法接受

所以需要找出与输入相似度最高的实例进行传入,提升回应的效率

控制长度

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
from langchain_deepseek import ChatDeepSeek
from langchain.prompts import PromptTemplate,FewShotPromptTemplate
from langchain.prompts.example_selector import LengthBasedExampleSelector
from dotenv import load_dotenv

load_dotenv()
llm = ChatDeepSeek(model="deepseek-chat")

# 创建一些任务的例子
examples = [
{"input": "开心","output": "难过"},
{"input": "高","output": "矮"},
{"input": "精力充沛","output": "无精打采"},
{"input": "阳光明媚","output": "阴沉"},
{"input": "风大","output": "风平浪静"}
]

example_prompt = PromptTemplate(
input_variables=["input","output"],
template="输入:{input}\n输出:{output}"
)

# 示例选择器
example_selector = LengthBasedExampleSelector(
# 可选例子
examples=examples,
# 格式化示例的模板
example_prompt=example_prompt,
# 设置格式化应有的最大长度
max_length=12
)

dynamic_prompt = FewShotPromptTemplate(
# 限定长度的示例选择器
example_selector=example_selector,
example_prompt=example_prompt,
prefix="给出每个输出的反义词",
suffix="输入: {adj}\n输出:",
input_variables=["adj"]
)

#
finally_prompt = dynamic_prompt.format(adj="谨慎")
print(finally_prompt)

response = llm.invoke(finally_prompt)
print(response.content)

# 输出
/root/miniconda3/envs/langchain/bin/python /root/python-langchain/modelIO/08-prompt-example-selector.py
给出每个输出的反义词

输入:开心
输出:难过

输入:高
输出:矮

输入:精力充沛
输出:无精打采

输入:阳光明媚
输出:阴沉

输入:风大
输出:风平浪静

输入: 谨慎
输出:
输入:谨慎
输出:鲁莽

控制相关性

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
# 相似度就是选择与prompt类似的例子
from langchain_deepseek import ChatDeepSeek
from langchain.prompts import PromptTemplate,FewShotPromptTemplate
from langchain.prompts.example_selector import SemanticSimilarityExampleSelector
from langchain_community.vectorstores import Chroma
from langchain_community.vectorstores import FAISS
from langchain_huggingface import HuggingFaceEmbeddings
from dotenv import load_dotenv

load_dotenv()
llm = ChatDeepSeek(model="deepseek-chat")

# 初始化一个prompttemplate实例
example_prompt = PromptTemplate(
input_variables=["input","output"],
template="示例输入:{input}\n示例输出:{output}"
)

examples = [
{"input": "老师","output": "教室"},
{"input": "医生","output": "医院"},
{"input": "司机","output": "汽车"},
{"input": "树","output": "土地"},
{"input": "鸟","output": "鸟巢"}
]

embeddings = HuggingFaceEmbeddings(
model_name="sentence-transformers/all-MiniLM-L6-v2"
)
# 创建示例选择器
example_selector = SemanticSimilarityExampleSelector.from_examples(
examples=examples,
embeddings=embeddings,
vectorstore_cls=FAISS,
k=2
)

similar_prompt = FewShotPromptTemplate(
example_selector=example_selector,
example_prompt=example_prompt,
prefix="给出一个事物通常所在的位置",
suffix="输入:{input}\n输出:",
input_variables=["input"]
)

final_prompt = similar_prompt.format(input="学生")
print(final_prompt)

response = llm.invoke(final_prompt)
print(response.content)

# 给出一个事物通常所在的位置

# 示例输入:医生
# 示例输出:医院

# 示例输入:司机
# 示例输出:汽车

# 输入:学生
# 输出:
# 学校
CATALOG
  1. 1. prompt与template
    1. 1.1. 最简单的使用prompt template
    2. 1.2. 使用chatMessagePromptTemplate
    3. 1.3. 使用MessagePlaceholder
  2. 2. prompt高级用法
    1. 2.1. partial prompt templates多步模板
    2. 2.2. composition模板组合
    3. 2.3. 模板的序列化(保存)
    4. 2.4. example selector示例选择器