什么是Prompt Engineering提示词工程
传统编程:写代码→计算机执行
Prompt工程:写自然语言指令→大模型生成结果
角色设定(Role Prompting)
任务描述
格式规范
约束条件
常见约束类型
类型 | 示例 |
---|---|
长度 | “答案控制在 200 字内” |
风格 | “用初中生能理解的语言” |
内容 | “不包含专业术语” |
逻辑 | “先解释概念再举例说明” |
ok啊现在开始简介代码部分的内容,前面就是感受下好的提示词所带来的答案准确且精辟。
Prompt Template介绍
英文翻译过来其实就是提示词的模板的意思
主要解决的问题就是:动态内容组装、避免Prompt硬编码
整体的一个流程其实可以看下图的一个结构图
到这里其实也就是一个普通的一个和Ai一个问答的交互,他不具备多轮的一个记忆回复,但是他比起简单的去调用模型api问答,它起到了一个提示词模板结构化的一个功能,他会规范用户的问题从而更好的让ai做出回答
OK到了最喜欢的环节|上案例<( ̄︶ ̄)↗[GO!]|
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import PromptTemplate
llm = ChatOpenAI(
model_name = "qwen-plus",
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
api_key="", # 这里使用自己的阿里云百炼平台的api-key
temperature=0.7 # 这个参数是模型的多变性的控制
)
# 创建Prompt
prompt = PromptTemplate(
# 当不显式声明 input_variables 时 系统会自动推断变量
input_variables=["product"],
template="为{product}写三个吸引人的广告语,只需要返回纯文本"
)
# 调用LLM
message = prompt.invoke({'product': '小滴课堂'})
response = llm.invoke(message)
print(response)
print("------------")
# 创建输出解析器 (其实直接输出response.content也是可以的构建输出解析器其实就是为了规范好看,后面其实它除了前面的这个功能他还有其他的妙用)
output_parser = StrOutputParser()
answer = output_parser.invoke(response)
print(answer)
为了后续的那个ChatPromptTemplate的好理解,先了解一下目前市面上的ChatModel模型的机制
什么是ChatModel
是专为多轮对话场景设计的大语言模型(LLM),通过理解上下文和对话逻辑,生成连贯、符合人类交互习惯的回复。
不仅是简单的文本生成工具,更是能处理复杂对话流程的智能系统
说到底就是他的回复会参考上下文了,回答的更加准确,同时它的token消耗也是非常巨大的,而且他对于对话的安全性也更加高,他会自动屏蔽掉有害、偏见、敏感的政治内容。ok接下来就是重点了,它主要的核心的内容
ChatModel,通过角色话消息实现对话的控制,核心角色包括:
角色类型 | 标识符 | 功能定位 | 使用场景示例 |
---|---|---|---|
System | system | 定义 AI 的行为准则和角色设定 | 设定 AI 身份、回答规则、知识范围 (“system”, “你是一位医疗助手…”) |
User | user | 代表用户的输入信息 | 用户提问、指令、反馈 (“human”, “如何缓解头痛?”) |
Assistant | assistant | 存储 AI 的历史回复 | 维护对话上下文、保持回答连贯性 (“ai”, “建议服用布洛芬…”) |
参考OpenAi代码
# 多轮对话示例
messages = [
{"role": "system", "content": "你是一个电影推荐助手"},
{"role": "user", "content": "我喜欢科幻片,推荐三部经典"},
{"role": "assistant", "content": "1.《银翼杀手2049》... 2.《星际穿越》... 3.《黑客帝国》"},
{"role": "user", "content": "第二部的主演是谁?"} # 基于上下文追问
]
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=messages
)
print(response.choices[0].message.content)
# 输出: 《星际穿越》的主演是马修·麦康纳和安妮·海瑟薇...
ok啊通过上述的描述,肯定会对这种聊天式的提示词模板有了更加深沉式的理解了
对比一下普通的PromptTemplate
很重要的一点关于消息类型的体系
消息模板类 | 对应角色 | 典型用途 |
---|---|---|
SystemMessagePromptTemplate | 系统消息 | 设定 AI 行为规则 |
HumanMessagePromptTemplate | 用户消息 | 接收用户输入 |
AIMessagePromptTemplate | AI 回复消息 | 记录历史响应 |
ChatPromptTemplate | 容器模板 | 组合多个消息模板 |
掌握两个常见类方法
ChatPromptTemplate.from_template()
ChatPromptTemplate.from_messages()
汇总对比
方法 | 适用场景 | 灵活性 | 代码复杂度 |
---|---|---|---|
from_messages | 多角色、多轮对话(如聊天机器人) | 高 | 较高(需定义列表) |
from_template | 单角色消息模板(需组合使用) | 低 | 简单 |
OK啊我知道这么多其实很难通过中国文字去理解对于小白来说,所以废话不多说上案例<( ̄︶ ̄)↗[GO!]
from langchain_core.prompts import ChatPromptTemplate
# 定义消息列表,包含系统指令、用户输入和AI回复模板,通过元组列表定义角色和模板,动态插入name和user_input变量
chat_template = ChatPromptTemplate.from_messages([
("system", "你是一个助手AI,名字是{name}。"),
("human", "你好,最近怎么样?"),
("ai", "我很好,谢谢!"),
("human", "{user_input}")
])
# 格式化模板并传入变量
messages = chat_template.format_messages(
name="Bob",
user_input="你最喜欢的编程语言是什么?"
)
print(messages)
# 输出结果示例:
# SystemMessage(content='你是一个助手AI,名字是Bob。')
# HumanMessage(content='你好,最近怎么样?')
# AIMessage(content='我很好,谢谢!')
# HumanMessage(content='你最喜欢的编程语言是什么?')
from langchain_core.prompts import (
ChatPromptTemplate,
SystemMessagePromptTemplate,
HumanMessagePromptTemplate
)
# 创建单条消息模板,通过细分模板类(如SystemMessagePromptTemplate)定义单条消息,再通过from_messages组合
system_template = SystemMessagePromptTemplate.from_template(
"你是一个{role},请用{language}回答。"
)
user_template = HumanMessagePromptTemplate.from_template("{question}")
# 组合成多轮对话模板
chat_template = ChatPromptTemplate.from_messages([
system_template,
user_template
])
# 使用示例
messages = chat_template.format_messages(
role="翻译助手",
language="中文",
question="将‘I love Python’翻译成中文。"
)
print(messages)
# 输出结果示例:
# SystemMessage(content='你是一个翻译助手,请用中文回答。')
# HumanMessage(content='将‘I love Python’翻译成中文。')
上面两个的案例其实就是构建出了个结构化的模板,现在其实后面和PromptTemplate结合ChateModel差不多都是直接构建model,然后把Template直接喂给它,然后获取得到answer【简单记执行顺序:from_template -> from_messages -> format_messages】
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage,SystemMessage
from langchain_core.prompts import (
ChatPromptTemplate,
SystemMessagePromptTemplate,
HumanMessagePromptTemplate
)
from langchain_core.output_parsers import StrOutputParser
compliance_template = ChatPromptTemplate.from_messages([
("system", """你是{company}的助手,需遵守:
1.不透露内部系统名称
2.不提供医疗/金融建议
3.遇到{transfer_code}转人工"""),
("human", "[{user_level}]用户:{query}")
])
message = compliance_template.format(
company = "IBM",
transfer_code = "用户反馈问题无法解决或者支付问题转人工",
user_level = "普通用户",
query = "怎么完成支付"
)
# 构建模型
model = ChatOpenAI(
model_name="qwen-plus",
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
api_key="XXXx",
temperature=0.7
)
# 构建输出解析器
out_parser = StrOutputParser()
# 构建问答链
response = out_parser.invoke(model.invoke(message))
# 输出结果
print(response)
LLMChain 类详解(最基础的链,少用仍保留,推荐用 LCEL)
是最基础的 Chain,负责结合提示模板和 LLM 模型,生成并执行模型的调用流程
专门用于与大语言模型(如 ChatGPT)交互的标准化处理单元
核心功能
核心参数
参数 | 类比 Java 场景 | 示例值 |
---|---|---|
llm | 依赖注入的模型对象 | new OpenAI () |
prompt | 预定义的提示词模板 | PromptTemplate (“回答用户问题: {input}”) |
output_parser | 结果解析器(类似 Jackson 处理 JSON) | new CommaSeparatedListOutputParser () |
但是值得一提的就是这种方法其实已经很少会使用了现在都是使用LCEL的写法去写了
# 老版的写法
from IPython.core.debugger import prompt
from langchain_core.prompts import PromptTemplate
from langchain.chains import LLMChain
from langchain_openai import ChatOpenAI
#创建提示词模型
promptTemplate = PromptTemplate(
input_variables=["name"],
template="你是一个文案高手,为{name}设计卖点!" # 注意这里需要使用 {name} 变量
)
#创建模型
model = ChatOpenAI(
model_name = "qwen-plus",
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
api_key="XXXX",# 用自己的
temperature=0.7
)
#创建chain
chain = LLMChain(
llm=model,
prompt=promptTemplate
)
# 使用新的方式创建可执行序列(很简洁且易懂)
chain = prompt | model
result=chain.invoke("只能手机")
print(result)
OK啊学习了这个东西其实就不再需要像前面那样复杂的去调用model
其实简单的来讲就是在prompt后面加上一段内置的话语,如果说你在chain中最后管的时候加上了输出解析器,那么最后的输出数据就会是你想要的那种content,也就是俗称的结构化。
简介: 输出解析器 OutputParse 实战和原理讲解
为什么需要输出解析器 OutputParse?
解析器工作原理
parse()
:解析原始文本为结构化数据。parse_with_prompt()
:结合上下文提示词解析(处理多轮对话场景)。get_format_instructions()
:生成提示词模板,指导 LLM 输出格式。输出解析器基础结构三要素
from langchain.output_parsers import XxxParser
# 要素1: 创建解析器(类似Java的Gson实例)
parser = XxxParser()
# 要素2: 构建提示词模板(注意{format_instructions}占位符)
prompt = PromptTemplate(
template="请生成用户信息,按格式: {format_instructions}\n输入: {input}",
input_variables=["input"],
partial_variables={"format_instructions": parser.get_format_instructions()}
)
# 要素3: 组合成链(类似Java的责任链模式)
chain = prompt | model | parser
上案例<( ̄︶ ̄)↗[GO!]
from langchain_core.output_parsers import JsonOutputParser, CommaSeparatedListOutputParser
from langchain_core.prompts import ChatPromptTemplate
#parser = JsonOutputParser()
parser = CommaSeparatedListOutputParser()
# 获取格式指令
format_instructions = parser.get_format_instructions()
# 定义提示词
prompt = ChatPromptTemplate.from_template("""
分析以下商品评论,按指定格式返回结果:
评论内容: {review}
格式要求:
{format_instructions}
""")
# 注入格式指令
final_prompt = prompt.partial(format_instructions=format_instructions)
print(final_prompt.format_prompt(review="这个手机超级好用,超级流畅"))
from langchain_core.output_parsers import CommaSeparatedListOutputParser
from langchain.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
# 1. 实例化一个 CommaSeparatedListOutputParser对象,将逗号分隔文本转为列表
output_parser = CommaSeparatedListOutputParser()
format_instructions = output_parser.get_format_instructions()
# 2. 创建一个 prompt template,将 output_parser.get_format_instructions()追加到的prompt里面
prompt = PromptTemplate(
template="列举多个常见的 {subject}.{format_instructions}",
input_variables=["subject"],
partial_variables={"format_instructions": format_instructions}, # 变量被预先填充到模板
)
# 3. 创建模型
model = ChatOpenAI(
model_name = "qwen-plus",
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
api_key="XXX",
temperature=0.7
)
# 4. 构建链
chain = prompt | model | output_parser
print(chain.invoke({"subject": "水果"}))
注意事项 【非常的重要,重要,重要!说三遍】
OK后面我再说两种输出解释器的案例来供给大家理解
导包StrOutputParser
from langchain_core.output_parsers import StrOutputParser
StrOutputParser类
from langchain_core.output_parsers import StrOutputParser
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
# 定义链
prompt = ChatPromptTemplate.from_template("写一首关于{topic}的诗")
# 创建模型
model = ChatOpenAI(
model_name = "qwen-plus",
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
api_key="XXX",
temperature=0.7
)
# 创建解析器
parser = StrOutputParser()
chain = prompt | model | parser
# 调用
result = chain.invoke({"topic": "秋天"})
print(result) # 输出: 秋天的落叶轻轻飘落...
导包CommaSeparatedListOutputParser
from langchain_core.output_parsers import CommaSeparatedListOutputParser
CommaSeparatedListOutputParser类
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import CommaSeparatedListOutputParser
from langchain_openai import ChatOpenAI
parser = CommaSeparatedListOutputParser()
prompt = ChatPromptTemplate.from_template("列出3个与{topic}相关的关键词: ")
# 创建模型
model = ChatOpenAI(
model_name = "qwen-plus",
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
api_key="",
temperature=0.7
)
chain = prompt | model | parser
# 调用
result = chain.invoke({"topic": "Java"})
print(result) # 输出: ["机器学习", "深度学习", "神经网络"]
导包JsonOutputParser
from langchain_core.output_parsers import JsonOutputParser
JsonOutputParser类
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import JsonOutputParser
prompt = ChatPromptTemplate.from_template(
"返回JSON: {{'name': '姓名', 'age': 年龄}}, 输入: {input}"
)
# 创建模型
model = ChatOpenAI(
model_name = "qwen-plus",
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
api_key="",
temperature=0.7
)
chain = prompt | model | JsonOutputParser()
result = chain.invoke({"input": "张三今年30岁,准备结婚后学AI大模型课程"})
print(result)
# 输出: {"name": "张三", "age": 30}
但是如果说chain = prompt | model 后面没有JsonOutputParser()输出解释器的话,那最后如果说你是这样子输出
print(f"姓名:{result:['name']} ,年龄:{result:['age']} ")
# 这样子就会报错,因为得到的result还是一串BaseMessage类型的数据不是字典类型的
OK啊继续学习,LLM解析器。首先先讲下Pydantic模型
传统 Python 方式(样板代码)
class User:
def __init__(self, name: str, age: int):
if not isinstance(name, str):
raise TypeError("name必须是字符串")
if not isinstance(age, int):
raise TypeError("age必须是整数")
if age > 150:
raise ValueError("年龄必须在0-150之间")
self.name = name
self.age = age
在传统 Python 方式中,通过__init__
方法对传入的参数进行类型和值的检查,不符合要求就抛出相应异常。这种方式同样需要编写较多的条件判断代码,不够简洁。
pydantic 方式(声明式验证)
from pydantic import BaseModel, Field
class User(BaseModel):
name: str = Field(min_length=1, max_length=50) # 内置字符串长度验证
age: int = Field(ge=0, le=150) # 数值范围验证(类似Java的@Min/@Max)
Pydantic 采用声明式验证,继承BaseModel
后,通过Field
来定义字段的验证规则,仅需少量代码就能实现完整验证,相比前两种方式更加简洁、高效,代码可读性和维护性也更好。
说到底其实就是数据的一种校验库,内置功能强大!对了在你使用这个之前记得要先安装pydantic库
pip install pydantic==2.7.4 # 我用的是这个版本的你们看着来把 Python要3.10+
OK啊我也是在20号结束了期末周了,考完了,一身轻松了,开始继续学习AI应用开发了。然后在考试当中特别搞笑的事情,考离散数学,我就复习了2天多一点(从0开始的),然后我考试做完所有题目还剩下1h,我看我tm同班的人还在写,我真的想笑,这就很难评了(哈哈哈)!然后考完也是疯玩了半天。最后看了手机工作室的老师发了个实习的通知,很可惜大二的鼠鼠我问了老师,老师说下学期大三还有课,叫我最好再等等。但是其实我没和他说就是其实我打算在9月份的时候就开始找实习了,哎~可惜错过了个机会。好了今天的学习也是差不多到这了,但是晚上其实有空了的话可能会把这个Pydantic模型学完吧,学到这里其实感觉真的越来越好了,我自己其实也是python(0基础),但是听完了这个其实还好,感觉语言之间没有什么特别大的区别了。好了拜拜!下期见吧。对了说下计划把,就是后面基本上全是python这边的Ai开发了,如果说有想跟着我的这个记录学习的包子,还是要先学习一下python的前置内容的。然后有需要我的ai配置环境可以私聊我给你发,Java后端的话其实我目前没有去弄了,打算是后面去弄的,然后你们如果说想去独立锻炼自己去开发网盘的后端业务逻辑的写的话,可以看看Day2那篇文章中的最后分享的UML图,其实画的很详细了,看图写代码我觉得没有什么难度了,里面核心的一些业务代码逻辑其实理得都差不多了。
Day2学习文章链接:https://blog.csdn.net/QU0235535/article/details/148594988