Java+Python智能化云盘【Day3】

提示词工程Prompt

简介:大模型必备 Prompt 提示词工程讲解

什么是Prompt Engineering提示词工程

  • 通过特定格式的文本输入引导 AI 模型生成期望输出的技术,明确地告诉模型你想要解决的问题或完成的任务
  • 也是大语言模型理解用户需求并生成相关、准确回答或内容的基础
  • 类比:给 Java 程序员的任务需求文档(越清晰明确,结果越符合预期)
  • 为什么需要学习?
    • 大模型就是你的员工,你可以有多个助手,OpenAI、DeepSeek、千问等
    • 作为老板的你,需要正确的下达任务,描述合理和交付目标等
传统编程:写代码→计算机执行
Prompt工程:写自然语言指令→大模型生成结果

Prompt 设计四要素

  • 角色设定(Role Prompting)

    • 作用:限定模型回答视角
    • 示例
      • [差] 写一首关于春天的诗
      • [优] 你是一位擅长写现代诗的诗人,请用比喻手法创作一首 8 行的春天主题短诗
  • 任务描述

    • STAR 原则:Situation 场景、Task 任务、Action 行动、Result 结果
    • 示例
      • (场景) 用户提交了一个技术问题
      • (任务) 需要给出准确且易懂的解答
      • (行动) 分步骤说明解决方案
      • (结果) 最后用一句话总结要点
  • 格式规范

    • 常用格式指令:分点列表、指定段落数、表格呈现、代码格式
  • 约束条件

    • 常见约束类型

      类型 示例
      长度 “答案控制在 200 字内”
      风格 “用初中生能理解的语言”
      内容 “不包含专业术语”
      逻辑 “先解释概念再举例说明”

LangChain 提示模板 PromptTemplate 介绍

ok啊现在开始简介代码部分的内容,前面就是感受下好的提示词所带来的答案准确且精辟。

Prompt Template介绍

英文翻译过来其实就是提示词的模板的意思

  • 是 LangChain 中用于构建结构化提示词的组件,负责将用户输入 / 动态数据转换为 LLM 可理解的格式
  • 它是一种单纯的字符模板,后续还有进阶的 ChatPromptTemplate

主要解决的问题就是:动态内容组装、避免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)

大模型 ChatModel 聊天模型和 Token 计算

为了后续的那个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)
# 输出: 《星际穿越》的主演是马修·麦康纳和安妮·海瑟薇...

聊天模型 ChatPromptTemplate 讲解

ok啊通过上述的描述,肯定会对这种聊天式的提示词模板有了更加深沉式的理解了

对比一下普通的PromptTemplate

  • 核心差异
    • 支持消息角色(system/user/assistant)
    • 天然适配聊天模型(如GPT-3.5/4)
    • 可维护对话上下文

Java+Python智能化云盘【Day3】_第1张图片

很重要的一点关于消息类型的体系

消息模板类 对应角色 典型用途
SystemMessagePromptTemplate 系统消息 设定 AI 行为规则
HumanMessagePromptTemplate 用户消息 接收用户输入
AIMessagePromptTemplate AI 回复消息 记录历史响应
ChatPromptTemplate 容器模板 组合多个消息模板

掌握两个常见类方法

  • ChatPromptTemplate.from_template()

    • 用于创建单条消息模板,通常结合其他方法构建更复杂的对话流程。
    • 适用于单一角色的消息定义(如仅系统指令或用户输入)。
    • 需与其他模板组合使用,例如通过 from_messages 整合多个单模板
  • ChatPromptTemplate.from_messages()

    • 用于构建多轮对话模板,支持定义不同角色(如系统、用户、AI)的消息,并允许动态插入变量。
    • 支持消息列表,每个消息可以是元组或 MessagePromptTemplate 对象。
    • 角色类型包括:system(系统指令)、human(用户输入)、ai(模型回复)
    • 可通过占位符(如 {variable})动态替换内容。
  • 汇总对比

    方法 适用场景 灵活性 代码复杂度
    from_messages 多角色、多轮对话(如聊天机器人) 较高(需定义列表)
    from_template 单角色消息模板(需组合使用) 简单

OK啊我知道这么多其实很难通过中国文字去理解对于小白来说,所以废话不多说上案例<( ̄︶ ̄)↗[GO!]

  • 使用from_messages构建多轮对话模板 [这种就是直接构建,很简单]
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_template与from_messages
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)

LangChain链和LLMChain链

简介:什么是LangChain和LLMChain

  • Chain链
    • 是构建语言模型应用的核心组件,用于将多个模块(如模型调用、提示模板、记忆系统等)组合成可复用的工作流程。
    • 本质:将多个处理单元(模型 / 工具 / 逻辑)按特定顺序连接起来,形成完整的任务处理流程
    • 类比:Java 中的责任链模式或工作流引擎中的步骤串联。

LLMChain 类详解(最基础的链,少用仍保留,推荐用 LCEL)

  • 是最基础的 Chain,负责结合提示模板和 LLM 模型,生成并执行模型的调用流程

  • 专门用于与大语言模型(如 ChatGPT)交互的标准化处理单元

  • 核心功能

    • 提示模板:将用户输入动态填充到预设的模板中,生成模型的输入文本。
    • 模型调用:将模板生成的文本传递给 LLM,返回生成结果。
    • 输出解析(可选):对模型输出进行后处理(如 JSON 解析)
  • 核心参数

    参数 类比 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

解析器 OutputParse 实战和原理讲解

其实简单的来讲就是在prompt后面加上一段内置的话语,如果说你在chain中最后管的时候加上了输出解析器,那么最后的输出数据就会是你想要的那种content,也就是俗称的结构化。

简介: 输出解析器 OutputParse 实战和原理讲解

为什么需要输出解析器 OutputParse?

  • 大模型原始输出通常是非结构化文本。
  • 实际需要
    • 将大模型的自由文本转为结构化数据(类似 Java 的 JSON/XML 解析)。
    • 自动处理模型输出的格式错误。

解析器工作原理

  • 流程:输入文本 → LLM 生成 → 解析器 → 结构化数据
  • 工作原理
    • 在提示模板中预留一个占位符变量,由输出解析器负责填充。
    • 当 LLM 按照输出要求返回文本答案后,该答案会被传递给输出解析器,解析为预期的数据结构。
    • 通俗来说,就是在 prompt 结尾追加,告诉大模型应该返回怎样的格式。
  • 解析器核心接口
    • parse():解析原始文本为结构化数据。
    • parse_with_prompt():结合上下文提示词解析(处理多轮对话场景)。
    • get_format_instructions():生成提示词模板,指导 LLM 输出格式。
  • 文档地址:https://python.langchain.com/docs/concepts/output_parsers/

输出解析器基础结构三要素

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": "水果"}))

注意事项 【非常的重要,重要,重要!说三遍】

  • 虽然有解析器,但是存在大模型返回内容不符合格式要求,则一样会报错。
  • 本质解析器还是 Prompt 提示词内容,如果有报错则可以让大模型重试。

OK后面我再说两种输出解释器的案例来供给大家理解

LangChain 字符串和列表输出解析器

导包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)  # 输出: ["机器学习", "深度学习", "神经网络"]

Json 输出解析器

导包JsonOutputParser

from langchain_core.output_parsers import JsonOutputParser

JsonOutputParser类

  • 功能:将模型输出解析为 JSON 对象。
  • 适用场景:需要模型返回结构化数据(如 API 响应),多数要结合 Pydantic 进行使用。
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类型的数据不是字典类型的

Pydantic 模型和 LLM 高级解析器实战

OK啊继续学习,LLM解析器。首先先讲下Pydantic模型

什么是Pydantic模型

  • Pydantic 是一个在 Python 中用于数据验证和解析的第三方库,是 Python 使用最广泛的数据验证库。
  • 以声明式的方式定义数据模型,结合 Python 类型提示的强大功能来执行数据验证和序列化。
  • 提供了从各种数据格式(例如 JSON、字典)到模型实例的转换功能。
  • 官方文档:https://pydantic.com.cn/
为什么要用 Pydantic
  • 处理来自系统外部的数据,如 API、用户输入或其他来源时,必须牢记开发中的原则:“永远不要相信用户的输入” 。
  • AI 智能体需要处理结构化数据(API 请求 / 响应,配置文件等)。
  • 必须对这些数据进行严格的检查和验证,确保它们被适当地格式化和标准化。
  • 解决的问题
    • 数据验证:自动验证输入数据的类型和格式。
    • 类型提示:结合 Python 类型提示系统。
    • 序列化:轻松转换数据为字典 / JSON 。
    • 配置管理:支持复杂配置项的验证。

传统 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

你可能感兴趣的:(Java+Python,Ai智能云盘项目开发专栏,java,python,开发语言)