【AI】二. Prompt提示词工程和案例最佳实践 小滴课堂讲师 2025年09月17日 ai大模型, aigc 预计阅读 25 分钟 #### 大模型必备Prompt提示词工程 ##### 什么是Prompt Engineering提示词工程 * 通过特定格式的文本输入引导AI模型生成期望输出的技术,明确地告诉模型你想要解决的问题或完成的任务 * 也是大语言模型理解用户需求并生成相关、准确回答或内容的基础 * **类比:给Java程序员的任务需求文档(越清晰明确,结果越符合预期)** * 为什么需要学习 * 大模型就是你的员工,你可以有多个助手,OpenAI、DeepSeek、千问等 * 作为老板的你,需要正确的下达任务,描述合理和交付目标等 ```markdown 传统编程:写代码→计算机执行 Prompt工程:写自然语言指令→大模型生成结果 ``` ##### Prompt设计四要素 * 角色设定(Role Prompting) * 作用:限定模型回答视角 ```python [差] 写一首关于春天的诗 [优] 你是一位擅长写现代诗的诗人,请用比喻手法创作一首8行的春天主题短诗 ``` * 任务描述 * STAR原则:Situation 场景、Task 任务、Action 行动、Result 结果 ```python (场景)用户提交了一个技术问题 (任务)需要给出准确且易懂的解答 (行动)分步骤说明解决方案 (结果)最后用一句话总结要点 ``` * 格式规范 * 常用格式指令:分点列表、指定段落数、表格呈现、代码格式 ```python 用JSON格式输出包含以下字段: { "summary": "不超过50字的摘要", "keywords": ["关键词1", "关键词2", "关键词3"] } ``` * 约束条件 * 常见约束类型: | 类型 | 示例 | | :--: | :--------------------: | | 长度 | "答案控制在200字内" | | 风格 | "用初中生能理解的语言" | | 内容 | "不包含专业术语" | | 逻辑 | "先解释概念再举例说明" | * 汇总 | 要素 | 说明 | 反面案例 | 优化案例 | | :----------: | :------------: | :----------: | :-------------------------: | | **角色设定** | 明确模型身份 | "帮我写代码" | "你是一个资深Java架构师..." | | **任务说明** | 具体执行要求 | "分析数据" | "使用Markdown表格对比..." | | **输出格式** | 结构化结果定义 | 自由文本 | JSON/XML/YAML格式 | | **约束条件** | 限制输出范围 | 无限制 | "不超过200字,不用专业术语" | ##### 模板结构设计(黄金公式) ```python # 标准三段式结构 prompt_template = """ [角色设定] 你是一个具有10年经验的{领域}专家,擅长{特定技能} [任务说明] 需要完成以下任务: 1. {步骤1} 2. {步骤2} 3. {步骤3} [输出要求] 请按照以下格式响应: {示例格式} """ ``` * 常见问题和排查原因 | 现象 | 可能原因 | 解决方案 | | :--------------: | :----------------: | :----------------------: | | 输出内容偏离主题 | 角色设定不明确 | 添加"忽略无关信息"约束 | | 生成结果过于笼统 | 缺少具体步骤要求 | 添加"分步骤详细说明"指令 | | 格式不符合要求 | 未提供明确格式示例 | 添加XML/JSON标记示例 | #### Prompt提示词工程多案例最佳实践 ##### 需求 * 利用在线大模型或者本地大模型 * 测试不同的提示词效果,分析优化前、后的Prompt工程 * **案例实战:通用回答助手、代码生成助手、技术问答、AI数据分析 等案例实战** ##### 案例实战一:通用回答 * 差Prompt: ``` 告诉我关于人工智能的信息 ``` * 问题分析:过于宽泛,缺乏焦点、没有指定回答的深度和范围、未明确期望的格式 * 输出结果:可能得到从历史发展到技术原理的冗长概述,缺乏针对性 * 好prompt ```python 你是一位科技专栏作家,请用通俗易懂的方式向高中生解释: 1. 什么是人工智能(用1个生活化比喻说明) 2. 列举3个当前主流应用场景 3. 字数控制在300字以内 要求使用「首先」、「其次」、「最后」的结构 ``` * 优化后 * 设定回答视角(科技专栏作家) * 明确目标受众(高中生) * 结构化输出要求 * 添加格式约束 ##### 案例实战二:代码生成 * 差Prompt: ```python 写个Python程序 ``` * 问题分析:没有具体功能描述、未指定输入输出格式、忽略异常处理需求 * 输出结果:可能生成简单的"Hello World"程序,与真实需求不符 * 好Prompt: ```python 编写一个Python函数,实现以下功能: - 输入:字符串形式的日期(格式:YYYY-MM-DD) - 输出:该日期对应的季度(1-4) - 要求: - 包含参数校验(不符合格式时抛出ValueError) - 使用datetime模块 - 编写对应的单元测试用例 示例: 输入 "2024-03-15" → 返回 1 ``` * 优化后 * 明确定义输入输出 * 指定实现方式 * 包含测试要求 * 提供示例验证 ##### 案例实战三:技术问答 * 差Prompt ```python 如何优化网站性能? ``` * 问题分析:问题范围过大、未说明技术栈、缺少评估标准 * 输出结果:可能得到泛泛而谈的通用建议 * 好Prompt ```python 针对使用SpringBoot+Vue3的技术栈,请给出5项可量化的性能优化方案: 要求: 1. 每项方案包含: - 实施步骤 - 预期性能提升指标(如LCP减少20%) - 复杂度评估(低/中/高) 2. 优先前端和后端优化方案 3. 引用Web Vitals评估标准 限制条件: - 不涉及服务器扩容等硬件方案 - 排除已广泛采用的方案(如代码压缩) ``` * 优化点 * 限定技术范围 * 结构化响应要求 * 设定评估标准 * 排除已知方案 ##### 案例实战四:数据分析 * 差Prompt ```python 分析这份销售数据 ``` * 问题分析:未说明数据特征、没有指定分析方法、缺少可视化要求 * 输出结果:可能得到无重点的描述性统计,缺乏洞察 * 好Prompt ```python 你是一位资深数据分析师,请完成以下任务: 数据集特征: - 时间范围:2027年1-12月 - 字段:日期/产品类别/销售额/利润率 要求: 1. 找出销售额top3的月份,分析增长原因 2. 识别利润率低于5%的产品类别 3. 生成包含趋势图的Markdown报告 输出格式: ## 分析报告 ### 关键发现 - 要点1(数据支撑) - 要点2(对比分析) ### 可视化 趋势图描述,生成base64编码的折线图 ``` * 优化点: * 明确分析者角色 * 描述数据集特征 * 指定分析方法论 * 规范输出格式 #### LangChain 提示模板PromptTemplate介绍 ##### 需求 * 掌握LangChain 提示模板PromptTemplate常见用法 * 掌握提示词里面的占位符使用和预置变量 ##### PromptTemplate介绍 * 是LangChain中用于构建结构化提示词的组件,负责将用户输入/动态数据转换为LLM可理解的格式 * 它是一种单纯的字符模板,后续还有进阶的ChatPromptTemplate * 主要解决:动态内容组装、避免Prompt硬编码  * PromptTemplate核心变量和方法 * template 定义具体的模板格式,其中 `{变量名}` 是占位符 * input_variables 定义模板中可以使用的变量。 * partial_variables:前置变量,可以提前定义部分变量的值,预填充进去 * format 使用 `format` 方法填充模板中的占位符,形成最终的文本 ##### 案例实战 * 创建PromptTemplate对象简单模版 ```python from langchain.prompts import PromptTemplate # 定义模板 template = """ 你是一位专业的{domain}顾问,请用{language}回答: 问题:{question} 回答: """ # 创建实例 prompt = PromptTemplate( input_variables=["domain", "language", "question"], template=template ) print(prompt) # 格式化输出 print(prompt.format( domain="网络安全", language="中文", question="如何防范钓鱼攻击?" )) ``` * 自动推断变量 ```python from langchain.prompts import PromptTemplate # 当不显式声明 input_variables 时 template = "请将以下文本翻译成{target_language}:{text}" prompt = PromptTemplate.from_template(template) print(prompt.input_variables) # 输出: ['target_language', 'text'] ``` * 默认值设置 ```python from langchain.prompts import PromptTemplate template = """分析用户情绪(默认分析类型:{analysis_type}): 用户输入:{user_input} 分析结果:""" prompt_template = PromptTemplate( input_variables=["user_input"], template=template, template_format="f-string", # 新增参数 partial_variables={"analysis_type": "情感极性分析"} # 固定值 ) print(prompt_template.format(user_input="这个产品太难用了")) #====打印内部的变量====== print(prompt_template.template) print(prompt_template.input_variables) print(prompt_template.template_format) print(prompt_template.input_types) print(prompt_template.partial_variables) ``` #### PromptTemplate结合LLM案例实战 ```python from langchain_openai import ChatOpenAI from langchain_core.prompts import PromptTemplate from langchain_core.output_parsers import StrOutputParser #创建prompt AIGC prompt_template = PromptTemplate( input_variables=["product"], template="为{product}写3个吸引人的广告语,需要面向年轻人", ) prompt = prompt_template.invoke({"product":"小滴课堂"}) #创建模型 model = ChatOpenAI( model_name = "qwen-plus", base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", api_key="sk-005c3c25f6d042848b29d75f2f020f08", temperature=0.7 ) #调用大模型 response = model.invoke(prompt) #print(response.content) #创建输出解析器 out_parser = StrOutputParser() answer = out_parser.invoke(response) print(answer) ``` #### 大模型ChatModel聊天模型和Token计算 ##### 什么是ChatModel * 是专为**多轮对话场景**设计的大语言模型(LLM),通过理解上下文和对话逻辑,生成连贯、符合人类交互习惯的回复。 * 不仅是简单的文本生成工具,更是能处理复杂对话流程的智能系统 * 核心特点 | 特性 | 说明 | 示例场景 | | :--------------: | :----------------------------------------------: | :----------------------------------------------------------: | | **上下文感知** | 追踪多轮对话历史,理解指代关系(如“它”、“这个”) | 用户:“什么是量子计算?” → AI 解释 → 用户:“它有什么应用?” → AI 能正确关联“它”指量子计算 | | **角色扮演能力** | 可设定特定角色(如客服、教师)并保持一致性 | 设定AI为“医疗助手”时,拒绝提供诊断建议,仅提供健康信息 | | **意图识别** | 解析用户深层需求(如咨询、投诉、闲聊) | 用户:“我的订单没收到!” → AI 识别为物流投诉,优先转接人工客服 | | **情感分析** | 识别用户情绪(积极/消极),调整回复语气 | 用户表达不满时,AI 回复:“非常抱歉给您带来不便,我们会立刻处理...” | | **安全过滤** | 避免生成有害、偏见或敏感内容 | 用户请求生成暴力内容时,AI 拒绝并提示:“我无法协助这个请求” | ChatModel vs. 传统 Text Model | **对比维度** | **ChatModel** | **传统 Text Model(如 text-davinci-003)** | | :------------: | :------------------------------------: | :----------------------------------------: | | **核心目标** | 多轮交互式对话 | 单次文本生成(文章、代码等) | | **输入格式** | 结构化消息序列(System/Human/AI 角色) | 纯文本提示 | | **上下文处理** | 自动管理对话历史 | 需手动拼接历史文本 | | **输出控制** | 内置安全审查和格式约束 | 依赖提示词工程控制 | | **典型应用** | 客服机器人、虚拟助手 | 内容创作、数据清洗 | 聊天模型(如 GPT-3.5-turbo、GPT-4)通过 **角色化消息** 实现对话控制,核心角色包括: | 角色类型 | 标识符 | 功能定位 | 使用场景示例 | | :-----------: | :---------: | :------------------------: | :----------------------------------------------------------: | | **System** | `system` | 定义AI的行为准则和角色设定 | 设定AI身份、回答规则、知识范围`("system", "你是一位医疗助手...")` | | **User** | `user` | 代表用户的输入信息 | 用户提问、指令、反馈`("human", "如何缓解头痛?")` | | **Assistant** | `assistant` | 存储AI的历史回复 | 维护对话上下文、保持回答连贯性`("ai", "建议服用布洛芬...")` | 参考案例OpenAI代码 ```python # 多轮对话示例 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) # 输出:《星际穿越》的主演是马修·麦康纳和安妮·海瑟薇... ``` ##### Chat聊天多轮对话中的Token如何计算 * 在多轮对话场景下,上下文通常涵盖以下几部分: * **用户的历史输入** :之前用户说过的话,这些内容会作为上下文的一部分,帮助模型理解当前对话的背景和意图。 * **模型的历史回复** :模型之前给出的回应,这样能让模型保持对话的连贯性和一致性。 * **系统提示** :用于设定聊天机器人的角色、目标等,引导对话的方向和风格。 * 随着上下文内容的增加,Token 数量也会相应增多。 * 多轮对话的上下文 Token 累积 * 假设每轮对话中,用户的输入和模型的输出分别对应一定数量的 Token * 我们以每轮对话输入 50 Token、输出 100 Token 为例来计算: * **第 1 轮** :用户的输入为 50 Token,模型的输出为 100 Token,此时上下文中的 Token 总数为 50 + 100 = 150 Token。 * **第 2 轮** :新的用户输入为 50 Token,模型新的输出为 100 Token,加上之前的历史上下文 150 Token,此时上下文中的 Token 总数为 50 + 100 + 150 = 300 Token。 * **第 3 轮** :再次新增用户输入 50 Token 和模型输出 100 Token,加上之前的历史上下文 300 Token,上下文中的 Token 总数变为 50 + 100 + 300 = 450 Token * 上下文窗口的限制 * 每个大语言模型都有一个 “上下文窗口大小”(Context Window)的限制, * 它决定了模型能够处理的上下文的最大 Token 数量。 * 常见的上下文窗口大小有: * 4k Tokens :例如 OpenAI GPT - 3.5,其上下文窗口大小为 4096 个 Token。 * 8k、32k Tokens :支持长上下文的模型,如 GPT-4 等,有更大的上下文窗口,分别为 8192 个和 32768 个 Token。 #### 聊天模型ChatPromptTemplate讲解 ##### ChatPromptTemplate 核心概念 * 核心差异 * 支持**消息角色**(system/user/assistant) * 天然适配聊天模型(如GPT-3.5/4) * 可维护对话上下文  * 消息类型体系 | 消息模板类 | 对应角色 | 典型用途 | | :-------------------------: | :--------: | :--------------: | | SystemMessagePromptTemplate | 系统消息 | 设定AI行为规则 | | HumanMessagePromptTemplate | 用户消息 | 接收用户输入 | | AIMessagePromptTemplate | AI回复消息 | 记录历史响应 | | ChatPromptTemplate | 容器模板 | 组合多个消息模板 | ##### 掌握两个常见类方法 * `ChatPromptTemplate.from_template()` * 用于创建单条消息模板,通常结合其他方法构建更复杂的对话流程。 * 适用于单一角色的消息定义(如仅系统指令或用户输入)。 * 需与其他模板组合使用,例如通过`from_messages`整合多个单模板 * `ChatPromptTemplate.from_messages()` * 用于构建多轮对话模板,支持定义不同角色(如系统、用户、AI)的消息,并允许动态插入变量。 * 支持消息列表,每个消息可以是元组或`MessagePromptTemplate`对象。 * 角色类型包括:`system(系统指令)、human(用户输入)、ai(模型回复)` * 可通过占位符(如`{variable}`)动态替换内容。 * 汇总对比 | 方法 | 适用场景 | 灵活性 | 代码复杂度 | | :-------------: | :------------------------------: | :----: | :----------------: | | `from_messages` | 多角色、多轮对话(如聊天机器人) | 高 | 较高(需定义列表) | | `from_template` | 单角色消息模板(需组合使用) | 低 | 简单 | ##### 案例实战 * 使用from_messages构建多轮对话模板 ```python 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` ```python 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'翻译成中文。' ``` #### LangChain聊天模型多案例实战 ##### 需求 * 聊天模型案例实战,需要结合LLM大模型进行调用 * 简单记执行顺序 ` from_template->from_messages->format_messages` * 最终传递给大模型是完整构建消息列表对象 ##### 领域专家案例实战 ```python from langchain_openai import ChatOpenAI from langchain_core.messages import SystemMessage, HumanMessage model = ChatOpenAI( model_name = "qwen-plus", base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", api_key="sk-005c3c25f6d042848b29d75f2f020f08", temperature=0.7 ) # 构建消息列表(类似Java的ListMessage>) messages = [ SystemMessage(content="你是一个Java专家,用中文回答"), HumanMessage(content="解释volatile关键字的作用") ] # 同步调用(类似Java的execute()) response = model.invoke(messages) print(response.content) """ volatile关键字主要用于: 1. 保证变量可见性... 2. 禁止指令重排序... """ ``` ##### 带参数的领域专家 ```python from langchain_openai import ChatOpenAI from langchain_core.prompts import ChatPromptTemplate from langchain.prompts import ( ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplate ) # 定义系统消息模板 system_template = SystemMessagePromptTemplate.from_template( "你是一位专业的{domain}专家,回答需满足:{style_guide}" ) # 定义用户消息模板 human_template = HumanMessagePromptTemplate.from_template( "请解释:{concept}" ) # 组合聊天提示 chat_prompt = ChatPromptTemplate.from_messages([ system_template, human_template ]) # 格式化输出 messages = chat_prompt.format_messages( domain="机器学习", style_guide="使用比喻和示例说明", concept="过拟合" ) model = ChatOpenAI( model_name = "qwen-plus", base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", api_key="sk-005c3c25f6d042848b29d75f2f020f08", temperature=0.7 ) response = model.invoke(messages) print(response) ``` ##### 合规客服系统 ```python from langchain_openai import ChatOpenAI from langchain_core.prompts import ChatPromptTemplate model = ChatOpenAI( model_name = "qwen-plus", base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", api_key="sk-005c3c25f6d042848b29d75f2f020f08", temperature=0.7 ) compliance_template = ChatPromptTemplate.from_messages([ ("system", """您是{company}客服助手,遵守: 1. 不透露内部系统名称 2. 不提供医疗/金融建议 3. 遇到{transfer_cond}转人工"""), ("human", "[{user_level}用户]:{query}") ]) messages = compliance_template.format_messages(company="小滴课堂老王医生", transfer_cond="病情咨询、支付问题", user_level="VIP", query="感冒应该吃什么药?") response = model.invoke(messages) print(response) ```
评论区