智能体二次开发:langchain:核心组件详解_prompts

差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录 前一修订版
智能体二次开发:langchain:核心组件详解_prompts [2026/05/20 19:01] – 移除 - 外部编辑 (未知日期) 127.0.0.1智能体二次开发:langchain:核心组件详解_prompts [2026/05/20 19:01] (当前版本) – ↷ 页面langchain二次开发:核心组件详解_prompts被移动至智能体二次开发:langchain:核心组件详解_prompts 张叶安
行 1: 行 1:
 +====== 第三章:核心组件详解 - Prompts ======
 +
 +在 LangChain 框架中,Prompt(提示词)是与大语言模型(LLM)交互的核心桥梁。精心设计的提示词可以显著提升模型的输出质量和准确性。本章将深入探讨 LangChain 中的提示词工程、PromptTemplate 的使用、Few-shot Prompting 技术以及动态提示词的管理方法。
 +
 +===== 3.1 提示词工程基础 =====
 +
 +==== 3.1.1 什么是提示词工程 ====
 +
 +提示词工程(Prompt Engineering)是指通过设计和优化输入提示词,引导大语言模型生成高质量、符合预期的输出内容的技术。它是与大语言模型交互的艺术和科学。
 +
 +**提示词工程的重要性:**
 +
 +  * **输出质量**:好的提示词能让模型产生更准确、更有用的回答
 +  * **一致性**:通过结构化提示词,可以确保模型输出的格式一致
 +  * **可控性**:提示词工程让我们能更好地控制模型的行为和输出风格
 +  * **效率**:优化后的提示词可以减少不必要的迭代和修正
 +
 +==== 3.1.2 提示词的基本结构 ====
 +
 +一个完整的提示词通常包含以下几个部分:
 +
 +**1. 指令(Instruction)**
 +告诉模型需要执行什么任务。这是最核心的部分。
 +
 +<code python>
 +instruction = "请用简洁的语言总结以下文章的主要内容:"
 +</code>
 +
 +**2. 上下文(Context)**
 +提供完成任务所需的背景信息。
 +
 +<code python>
 +context = """
 +这篇文章发布于2024年,作者是人工智能领域的专家。
 +目标读者是技术初学者,因此需要使用通俗易懂的语言。
 +"""
 +</code>
 +
 +**3. 输入数据(Input Data)**
 +模型需要处理的具体内容。
 +
 +<code python>
 +input_data = """
 +人工智能(AI)正在改变我们的生活方式...
 +[文章内容]
 +"""
 +</code>
 +
 +**4. 输出指示(Output Indicator)**
 +明确说明期望的输出格式。
 +
 +<code python>
 +output_indicator = """
 +请输出:
 +1. 核心观点(50字以内)
 +2. 三个关键要点
 +3. 结论
 +"""
 +</code>
 +
 +**完整的提示词示例:**
 +
 +<code python>
 +full_prompt = f"""
 +{instruction}
 +
 +{context}
 +
 +文章:
 +{input_data}
 +
 +{output_indicator}
 +"""
 +</code>
 +
 +==== 3.1.3 提示词设计原则 ====
 +
 +**原则一:清晰明确**
 +
 +提示词应该清楚地表达你想要什么。模糊的要求会导致模糊的答案。
 +
 +<code python>
 +# ❌ 不好的示例
 +bad_prompt = "写点东西关于苹果"
 +
 +# ✅ 好的示例
 +good_prompt = """
 +请写一篇200字的产品描述,介绍 iPhone 15 的主要特点:
 +- 钛金属设计
 +- A17 Pro 芯片
 +- 专业级摄像系统
 +
 +语气要求:专业、吸引人、面向科技爱好者
 +"""
 +</code>
 +
 +**原则二:提供上下文**
 +
 +模型不知道你知道什么。提供足够的背景信息可以帮助模型更好地理解任务。
 +
 +<code python>
 +# ❌ 缺乏上下文
 +no_context = "分析这个数据"
 +
 +# ✅ 提供上下文
 +with_context = """
 +背景:你是一位数据分析专家,正在为一家电商公司工作。
 +
 +数据:2024年第一季度销售数据
 +- 总销售额:1000万元
 +- 订单数量:5000单
 +- 退货率:5%
 +
 +请分析这些数据,并给出改进建议。
 +"""
 +</code>
 +
 +**原则三:指定输出格式**
 +
 +如果你想要特定格式的输出,一定要在提示词中明确说明。
 +
 +<code python>
 +format_prompt = """
 +请根据以下客户反馈,生成一份报告。
 +
 +反馈内容:
 +"产品很好用,但是配送太慢了,希望改进物流服务。"
 +
 +输出格式(JSON):
 +{{
 +    "sentiment": "正面/负面/中性",
 +    "category": "产品/物流/服务/其他",
 +    "key_points": ["要点1", "要点2"],
 +    "urgency": "高/中/低"
 +}}
 +"""
 +</code>
 +
 +**原则四:使用分隔符**
 +
 +使用清晰的分隔符(如###、---、""")来区分提示词的不同部分。
 +
 +<code python>
 +structured_prompt = """
 +### 指令
 +总结以下文章的主要观点。
 +
 +### 文章
 +"""
 +{article_content}
 +"""
 +
 +### 要求
 +- 不超过100字
 +- 使用 bullet points
 +- 突出关键数据
 +"""
 +</code>
 +
 +**原则五:给出示例(Few-shot)**
 +
 +当任务比较复杂或格式要求严格时,提供示例是最好的方式。
 +
 +<code python>
 +few_shot_prompt = """
 +将以下描述转换为结构化数据。
 +
 +示例1:
 +输入:张三,25岁,软件工程师,北京
 +输出:{{"name": "张三", "age": 25, "job": "软件工程师", "city": "北京"}}
 +
 +示例2:
 +输入:李四,30岁,产品经理,上海
 +输出:{{"name": "李四", "age": 30, "job": "产品经理", "city": "上海"}}
 +
 +现在请处理:
 +输入:王五,28岁,数据分析师,深圳
 +输出:
 +"""
 +</code>
 +
 +==== 3.1.4 常见的提示词模式 ====
 +
 +**模式一:角色扮演(Role Prompting)**
 +
 +让模型扮演特定角色,以获得更专业的回答。
 +
 +<code python>
 +role_prompt = """
 +你是一位经验丰富的心理咨询师,拥有15年的临床经验。
 +
 +一位来访者说:"我最近工作压力很大,晚上睡不着,不知道该怎么办。"
 +
 +请给出专业的建议,注意:
 +1. 语气温和、同理心强
 +2. 提供具体可行的建议
 +3. 如果情况严重,建议寻求专业帮助
 +"""
 +</code>
 +
 +**模式二:思维链(Chain-of-Thought)**
 +
 +引导模型逐步思考,而不是直接给出答案。
 +
 +<code python>
 +cot_prompt = """
 +问题:一个农场有鸡和兔子,一共有35个头,94只脚。鸡和兔子各有多少只?
 +
 +请按以下步骤思考并回答:
 +1. 设鸡的数量为x,兔子的数量为y
 +2. 根据头的数量列出方程
 +3. 根据脚的数量列出方程
 +4. 解方程组
 +5. 验证答案
 +
 +详细展示你的思考过程。
 +"""
 +</code>
 +
 +**模式三:零样本思维链(Zero-shot CoT)**
 +
 +即使没有示例,也可以通过简单的指令引导模型逐步思考。
 +
 +<code python>
 +zero_shot_cot = """
 +问题:如果5台机器5分钟生产5个零件,那么100台机器生产100个零件需要多少分钟?
 +
 +让我们一步一步思考:
 +"""
 +</code>
 +
 +**模式四:自洽性检查(Self-Consistency)**
 +
 +让模型从多个角度思考问题,然后选择最一致的答案。
 +
 +<code python>
 +self_consistency_prompt = """
 +问题:解释为什么天空是蓝色的。
 +
 +请从以下三个角度分别解释,然后综合得出最准确的答案:
 +1. 物理学角度(光的散射)
 +2. 生物学角度(人眼感知)
 +3. 大气科学角度(大气成分)
 +
 +最后,整合以上观点,给出简洁准确的解释。
 +"""
 +</code>
 +
 +===== 3.2 PromptTemplate 详解 =====
 +
 +==== 3.2.1 PromptTemplate 概述 ====
 +
 +PromptTemplate 是 LangChain 中用于创建和管理提示词的核心组件。它允许你定义带有变量的模板,并在运行时动态填充这些变量。
 +
 +**为什么使用 PromptTemplate?**
 +
 +  * **可复用性**:定义一次模板,多次使用
 +  * **类型安全**:变量可以被验证和处理
 +  * **灵活性**:轻松切换不同的模型和配置
 +  * **维护性**:集中管理提示词,易于修改
 +
 +==== 3.2.2 基础使用 ====
 +
 +**安装和导入:**
 +
 +<code python>
 +# 安装依赖
 +# pip install langchain
 +
 +from langchain.prompts import PromptTemplate
 +</code>
 +
 +**创建基础模板:**
 +
 +<code python>
 +from langchain.prompts import PromptTemplate
 +
 +# 定义一个简单的模板
 +template = "请用{style}的风格,写一段关于{topic}的描述,大约{length}字。"
 +
 +# 创建 PromptTemplate 对象
 +prompt_template = PromptTemplate(
 +    input_variables=["style", "topic", "length"],
 +    template=template
 +)
 +
 +# 查看模板结构
 +print(prompt_template.input_variables)  # ['style', 'topic', 'length']
 +</code>
 +
 +**格式化模板:**
 +
 +<code python>
 +# 方式1:使用 format 方法
 +prompt = prompt_template.format(
 +    style="幽默",
 +    topic="人工智能",
 +    length=100
 +)
 +print(prompt)
 +# 输出:请用幽默的风格,写一段关于人工智能的描述,大约100字。
 +
 +# 方式2:使用 format_prompt 方法(返回 PromptValue 对象)
 +prompt_value = prompt_template.format_prompt(
 +    style="专业",
 +    topic="区块链",
 +    length=200
 +)
 +print(prompt_value.to_string())
 +</code>
 +
 +==== 3.2.3 高级模板功能 ====
 +
 +**部分变量(Partial Variables)**
 +
 +有时你希望预先填充部分变量,创建一个"半成品"模板。
 +
 +<code python>
 +from langchain.prompts import PromptTemplate
 +
 +# 定义完整模板
 +full_template = PromptTemplate(
 +    template="你是一位{role},请用{language}回答:{question}",
 +    input_variables=["role", "language", "question"]
 +)
 +
 +# 部分填充:预先设定角色
 +partial_template = full_template.partial(role="Python专家")
 +
 +# 使用时只需提供剩余变量
 +prompt1 = partial_template.format(
 +    language="中文",
 +    question="什么是装饰器?"
 +)
 +print(prompt1)
 +# 输出:你是一位Python专家,请用中文回答:什么是装饰器?
 +
 +# 可以再次部分填充
 +chinese_template = partial_template.partial(language="中文")
 +prompt2 = chinese_template.format(question="解释列表推导式")
 +print(prompt2)
 +</code>
 +
 +**使用函数作为部分变量:**
 +
 +<code python>
 +from datetime import datetime
 +
 +def get_current_date():
 +    return datetime.now().strftime("%Y年%m月%d日")
 +
 +template_with_date = PromptTemplate(
 +    template="今天是{date},请根据以下信息生成报告:{content}",
 +    input_variables=["content"],
 +    partial_variables={"date": get_current_date}
 +)
 +
 +prompt = template_with_date.format(content="销售数据...")
 +print(prompt)
 +# 输出:今天是2024年01月15日,请根据以下信息生成报告:销售数据...
 +</code>
 +
 +==== 3.2.4 模板验证 ====
 +
 +PromptTemplate 会自动验证输入变量,确保所有必需变量都已提供。
 +
 +<code python>
 +from langchain.prompts import PromptTemplate
 +
 +# 定义模板
 +template = PromptTemplate(
 +    template="你好{name},欢迎{action}!",
 +    input_variables=["name", "action"]
 +)
 +
 +# ✅ 正确:提供所有变量
 +try:
 +    prompt = template.format(name="张三", action="加入我们")
 +    print("成功:", prompt)
 +except Exception as e:
 +    print("错误:", e)
 +
 +# ❌ 错误:缺少变量
 +try:
 +    prompt = template.format(name="张三" # 缺少 action
 +except KeyError as e:
 +    print(f"缺少变量: {e}")
 +</code>
 +
 +==== 3.2.5 自定义输入解析器 ====
 +
 +有时输入变量需要特殊的处理,你可以自定义输入变量的解析方式。
 +
 +<code python>
 +from langchain.prompts import PromptTemplate
 +from langchain.prompts.base import StringPromptValue
 +
 +class MyPromptTemplate(PromptTemplate):
 +    def format(self, **kwargs) -> str:
 +        # 自定义格式化逻辑
 +        if "name" in kwargs:
 +            kwargs["name"] = kwargs["name"].upper()
 +        return super().format(**kwargs)
 +
 +template = MyPromptTemplate(
 +    template="尊敬的{name},{message}",
 +    input_variables=["name", "message"]
 +)
 +
 +prompt = template.format(name="alice", message="欢迎光临")
 +print(prompt)  # 尊敬的ALICE,欢迎光临
 +</code>
 +
 +===== 3.3 Few-shot Prompting =====
 +
 +==== 3.3.1 什么是 Few-shot Prompting ====
 +
 +Few-shot Prompting(少样本提示)是一种通过提供少量示例来指导模型完成任务的技术。它特别适用于:
 +
 +  * 需要特定输出格式的任务
 +  * 复杂的推理任务
 +  * 风格转换或语气调整
 +  * 特定的命名实体识别
 +
 +==== 3.3.2 基础示例 ====
 +
 +<code python>
 +from langchain.prompts import FewShotPromptTemplate, PromptTemplate
 +
 +# 定义示例
 +examples = [
 +    {
 +        "input": "今天天气真好,我想去公园散步。",
 +        "output": "积极"
 +    },
 +    {
 +        "input": "这部电影太糟糕了,完全浪费时间。",
 +        "output": "消极"
 +    },
 +    {
 +        "input": "会议定在下午三点。",
 +        "output": "中性"
 +    }
 +]
 +
 +# 定义示例的格式
 +example_template = """
 +文本:{input}
 +情感:{output}
 +"""
 +
 +example_prompt = PromptTemplate(
 +    template=example_template,
 +    input_variables=["input", "output"]
 +)
 +
 +# 创建 FewShotPromptTemplate
 +few_shot_prompt = FewShotPromptTemplate(
 +    examples=examples,
 +    example_prompt=example_prompt,
 +    prefix="请判断以下文本的情感倾向(积极/消极/中性):",
 +    suffix="\n文本:{input}\n情感:",
 +    input_variables=["input"],
 +    example_separator="\n---\n"
 +)
 +
 +# 生成提示词
 +prompt = few_shot_prompt.format(input="这家餐厅的饭菜真好吃!")
 +print(prompt)
 +</code>
 +
 +**输出示例:**
 +<code>
 +请判断以下文本的情感倾向(积极/消极/中性):
 +
 +文本:今天天气真好,我想去公园散步。
 +情感:积极
 +
 +---
 +
 +文本:这部电影太糟糕了,完全浪费时间。
 +情感:消极
 +
 +---
 +
 +文本:会议定在下午三点。
 +情感:中性
 +
 +---
 +
 +文本:这家餐厅的饭菜真好吃!
 +情感:
 +</code>
 +
 +==== 3.3.3 示例选择器(Example Selectors) ====
 +
 +当示例很多时,你可能只想选择最相关的几个示例。LangChain 提供了多种示例选择器。
 +
 +**长度限制选择器:**
 +
 +<code python>
 +from langchain.prompts import FewShotPromptTemplate
 +from langchain.prompts.example_selector import LengthBasedExampleSelector
 +
 +examples = [
 +    {"input": "happy", "output": "sad"},
 +    {"input": "tall", "output": "short"},
 +    {"input": "energetic", "output": "lethargic"},
 +    {"input": "sunny", "output": "gloomy"},
 +    {"input": "windy", "output": "calm"},
 +]
 +
 +example_prompt = PromptTemplate(
 +    template="输入: {input}\n输出: {output}",
 +    input_variables=["input", "output"]
 +)
 +
 +# 根据长度选择示例
 +example_selector = LengthBasedExampleSelector(
 +    examples=examples,
 +    example_prompt=example_prompt,
 +    max_length=100  # 最大长度限制
 +)
 +
 +dynamic_prompt = FewShotPromptTemplate(
 +    example_selector=example_selector,
 +    example_prompt=example_prompt,
 +    prefix="请找出以下单词的反义词:",
 +    suffix="输入: {input}\n输出:",
 +    input_variables=["input"]
 +)
 +
 +# 输入越长,选择的示例越少
 +short_prompt = dynamic_prompt.format(input="big")
 +print("短输入的提示词长度:", len(short_prompt))
 +
 +long_prompt = dynamic_prompt.format(input="这是一个非常长的输入,包含很多字符...")
 +print("长输入的提示词长度:", len(long_prompt))
 +</code>
 +
 +**语义相似度选择器:**
 +
 +<code python>
 +from langchain.prompts import FewShotPromptTemplate
 +from langchain.prompts.example_selector import SemanticSimilarityExampleSelector
 +from langchain.embeddings import OpenAIEmbeddings
 +from langchain.vectorstores import Chroma
 +
 +examples = [
 +    {"question": "谁活了最长?", "answer": "艾德加多·阿尔瓦伦加活了138年。"},
 +    {"question": "2023年谁是美国总统?", "answer": "乔·拜登是2023年的美国总统。"},
 +    {"question": "《呼啸山庄》的作者是谁?", "answer": "艾米莉·勃朗特是《呼啸山庄》的作者。"},
 +    {"question": "谁发明了相对论?", "answer": "阿尔伯特·爱因斯坦发明了相对论。"},
 +    {"question": "《哈利·波特》的作者是谁?", "answer": "J.K.罗琳是《哈利·波特》的作者。"},
 +]
 +
 +example_prompt = PromptTemplate(
 +    template="问题: {question}\n答案: {answer}",
 +    input_variables=["question", "answer"]
 +)
 +
 +# 使用语义相似度选择器
 +example_selector = SemanticSimilarityExampleSelector.from_examples(
 +    examples,
 +    OpenAIEmbeddings(),
 +    Chroma,
 +    k=2  # 选择最相似的2个示例
 +)
 +
 +similar_prompt = FewShotPromptTemplate(
 +    example_selector=example_selector,
 +    example_prompt=example_prompt,
 +    prefix="请根据示例回答以下问题:",
 +    suffix="问题: {input}\n答案:",
 +    input_variables=["input"]
 +)
 +
 +# 输入与示例相关的问题
 +prompt = similar_prompt.format(input="《指环王》是谁写的?")
 +print(prompt)
 +# 可能会选择《哈利·波特》和《呼啸山庄》相关的示例
 +</code>
 +
 +==== 3.3.4 Few-shot 最佳实践 ====
 +
 +**选择合适的示例数量:**
 +
 +<code python>
 +# 通常 3-5 个示例效果最好
 +# 太多示例可能导致:
 +# 1. Token 消耗增加
 +# 2. 上下文窗口限制
 +# 3. 模型注意力分散
 +
 +# 平衡策略
 +examples = [
 +    # 示例1:展示基本格式
 +    {...},
 +    # 示例2:展示边界情况
 +    {...},
 +    # 示例3:展示复杂场景
 +    {...},
 +]
 +</code>
 +
 +**示例的质量要求:**
 +
 +<code python>
 +# ✅ 好的示例特点:
 +# 1. 清晰明确
 +# 2. 覆盖不同场景
 +# 3. 格式一致
 +# 4. 输入输出相关
 +
 +good_examples = [
 +    {
 +        "instruction": "总结以下文章",
 +        "input": "[一篇500字的文章]",
 +        "output": "[简洁的50字总结]"
 +    },
 +    {
 +        "instruction": "提取关键信息",
 +        "input": "[同样的文章]",
 +        "output": "[关键数据列表]"
 +    }
 +]
 +
 +# ❌ 避免:
 +# 1. 示例之间矛盾
 +# 2. 格式不一致
 +# 3. 示例与任务不相关
 +</code>
 +
 +===== 3.4 Prompt 组合与管理 =====
 +
 +==== 3.4.1 组合多个 Prompt ====
 +
 +在实际应用中,你可能需要组合多个提示词模板来构建复杂的工作流。
 +
 +**使用 PipelinePromptTemplate:**
 +
 +<code python>
 +from langchain.prompts import PipelinePromptTemplate, PromptTemplate
 +
 +# 定义各个阶段的模板
 +introduction_template = """你是一个{role}。
 +你的任务是:{task}
 +"""
 +introduction_prompt = PromptTemplate(
 +    template=introduction_template,
 +    input_variables=["role", "task"]
 +)
 +
 +example_template = """以下是几个示例:
 +{examples}
 +"""
 +example_prompt = PromptTemplate(
 +    template=example_template,
 +    input_variables=["examples"]
 +)
 +
 +question_template = """现在请回答以下问题:
 +{question}
 +"""
 +question_prompt = PromptTemplate(
 +    template=question_template,
 +    input_variables=["question"]
 +)
 +
 +# 组合成完整的 pipeline
 +full_template = """{introduction}
 +
 +{example}
 +
 +{question}"""
 +full_prompt = PromptTemplate(
 +    template=full_template,
 +    input_variables=["introduction", "example", "question"]
 +)
 +
 +# 创建 pipeline
 +pipeline_prompt = PipelinePromptTemplate(
 +    final_prompt=full_prompt,
 +    pipeline_prompts=[
 +        ("introduction", introduction_prompt),
 +        ("example", example_prompt),
 +        ("question", question_prompt)
 +    ]
 +)
 +
 +# 使用 pipeline
 +result = pipeline_prompt.format(
 +    role="数据分析师",
 +    task="分析销售数据并给出建议",
 +    examples="示例1: ...\n示例2: ...",
 +    question="Q1季度的销售额下降了10%,可能是什么原因?"
 +)
 +print(result)
 +</code>
 +
 +==== 3.4.2 使用 ChatPromptTemplate ====
 +
 +对于聊天模型,LangChain 提供了专门的 ChatPromptTemplate,可以定义不同角色的消息。
 +
 +<code python>
 +from langchain.prompts import ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplate
 +
 +# 系统消息模板
 +system_template = """你是一个{role}助手。
 +你的专长领域是:{expertise}
 +回答时请遵循以下规则:
 +{rules}
 +"""
 +system_message_prompt = SystemMessagePromptTemplate.from_template(system_template)
 +
 +# 人类消息模板
 +human_template = "{user_input}"
 +human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)
 +
 +# 组合成聊天提示词
 +chat_prompt = ChatPromptTemplate.from_messages([
 +    system_message_prompt,
 +    human_message_prompt
 +])
 +
 +# 格式化
 +messages = chat_prompt.format_prompt(
 +    role="编程",
 +    expertise="Python 和数据分析",
 +    rules="1. 代码必须可运行\n2. 添加详细注释",
 +    user_input="写一个计算斐波那契数列的函数"
 +).to_messages()
 +
 +for message in messages:
 +    print(f"{message.type}: {message.content}")
 +</code>
 +
 +**输出:**
 +<code>
 +system: 你是一个编程助手。
 +你的专长领域是:Python 和数据分析
 +回答时请遵循以下规则:
 +1. 代码必须可运行
 +2. 添加详细注释
 +
 +human: 写一个计算斐波那契数列的函数
 +</code>
 +
 +==== 3.4.3 多轮对话模板 ====
 +
 +<code python>
 +from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
 +from langchain.schema import HumanMessage, AIMessage
 +
 +# 创建包含对话历史的模板
 +chat_prompt = ChatPromptTemplate.from_messages([
 +    ("system", "你是一个有帮助的助手。"),
 +    MessagesPlaceholder(variable_name="history"),  # 占位符,用于插入对话历史
 +    ("human", "{input}")
 +])
 +
 +# 模拟对话历史
 +history = [
 +    HumanMessage(content="你好"),
 +    AIMessage(content="你好!有什么我可以帮助你的吗?"),
 +    HumanMessage(content="我想了解 Python"),
 +    AIMessage(content="Python 是一门很棒的编程语言...")
 +]
 +
 +# 格式化
 +messages = chat_prompt.format_prompt(
 +    history=history,
 +    input="如何安装 Python?"
 +).to_messages()
 +
 +for msg in messages:
 +    print(f"{msg.type}: {msg.content}")
 +</code>
 +
 +==== 3.4.4 Prompt 管理最佳实践 ====
 +
 +**使用配置文件管理提示词:**
 +
 +<code python>
 +# prompts.yaml
 +# prompts_config.yaml
 +greeting:
 +  template: "你好{name},欢迎{action}!"
 +  input_variables: ["name", "action"]
 +
 +summarization:
 +  template: |
 +    请总结以下内容:
 +    {content}
 +    
 +    要求:
 +    - {style}
 +    - 大约{length}字
 +  input_variables: ["content", "style", "length"]
 +</code>
 +
 +<code python>
 +import yaml
 +from langchain.prompts import load_prompt
 +
 +# 加载 YAML 配置
 +with open("prompts_config.yaml", "r", encoding="utf-8") as f:
 +    config = yaml.safe_load(f)
 +
 +# 动态创建模板
 +templates = {}
 +for name, cfg in config.items():
 +    templates[name] = PromptTemplate(
 +        template=cfg["template"],
 +        input_variables=cfg["input_variables"]
 +    )
 +
 +# 使用
 +greeting_prompt = templates["greeting"]
 +print(greeting_prompt.format(name="张三", action="访问"))
 +</code>
 +
 +**版本控制提示词:**
 +
 +<code python>
 +from dataclasses import dataclass
 +from datetime import datetime
 +import json
 +
 +@dataclass
 +class PromptVersion:
 +    version: str
 +    template: str
 +    variables: list
 +    description: str
 +    created_at: str
 +    performance_score: float = 0.0
 +
 +class PromptRegistry:
 +    def __init__(self):
 +        self.prompts = {}
 +    
 +    def register(self, name: str, version: PromptVersion):
 +        if name not in self.prompts:
 +            self.prompts[name] = []
 +        self.prompts[name].append(version)
 +    
 +    def get_latest(self, name: str):
 +        if name in self.prompts and self.prompts[name]:
 +            return sorted(self.prompts[name], 
 +                         key=lambda x: x.version)[-1]
 +        return None
 +    
 +    def save(self, filepath: str):
 +        data = {}
 +        for name, versions in self.prompts.items():
 +            data[name] = [
 +                {
 +                    "version": v.version,
 +                    "template": v.template,
 +                    "variables": v.variables,
 +                    "description": v.description,
 +                    "created_at": v.created_at,
 +                    "performance_score": v.performance_score
 +                }
 +                for v in versions
 +            ]
 +        with open(filepath, "w", encoding="utf-8") as f:
 +            json.dump(data, f, ensure_ascii=False, indent=2)
 +
 +# 使用示例
 +registry = PromptRegistry()
 +
 +v1 = PromptVersion(
 +    version="1.0.0",
 +    template="总结:{content}",
 +    variables=["content"],
 +    description="基础总结模板",
 +    created_at=datetime.now().isoformat(),
 +    performance_score=0.85
 +)
 +
 +registry.register("summarization", v1)
 +registry.save("prompt_registry.json")
 +</code>
 +
 +===== 3.5 动态提示词 =====
 +
 +==== 3.5.1 条件提示词 ====
 +
 +根据输入动态调整提示词内容。
 +
 +<code python>
 +from langchain.prompts import PromptTemplate
 +from typing import Optional
 +
 +def create_conditional_prompt(
 +    content: str,
 +    audience: str = "general",
 +    include_examples: bool = True
 +) -> str:
 +    """根据受众和选项创建条件提示词"""
 +    
 +    # 基础模板
 +    base = "请对以下内容进行解释:\n\n{content}"
 +    
 +    # 根据受众调整
 +    audience_instructions = {
 +        "general": "使用通俗易懂的语言,避免专业术语。",
 +        "technical": "可以使用专业术语,提供技术细节。",
 +        "executive": "重点关注商业价值和高层次概念。",
 +        "beginner": "从最基础的概念开始,逐步深入。"
 +    }
 +    
 +    instruction = audience_instructions.get(audience, audience_instructions["general"])
 +    
 +    # 条件添加示例
 +    example_section = ""
 +    if include_examples:
 +        example_section = """
 +
 +请提供具体的例子帮助理解。
 +示例格式:
 +- 场景描述
 +- 具体应用
 +- 预期结果"""
 +    
 +    template = f"""{base}
 +
 +受众:{audience}
 +要求:{instruction}{example_section}
 +"""
 +    
 +    return template.format(content=content)
 +
 +# 使用示例
 +prompt_general = create_conditional_prompt(
 +    content="区块链是一种分布式账本技术...",
 +    audience="beginner",
 +    include_examples=True
 +)
 +print("初学者版本:")
 +print(prompt_general)
 +
 +prompt_technical = create_conditional_prompt(
 +    content="区块链是一种分布式账本技术...",
 +    audience="technical",
 +    include_examples=False
 +)
 +print("\n技术版本:")
 +print(prompt_technical)
 +</code>
 +
 +==== 3.5.2 模板继承与组合 ====
 +
 +<code python>
 +class PromptBuilder:
 +    """动态提示词构建器"""
 +    
 +    def __init__(self):
 +        self.sections = []
 +        self.variables = set()
 +    
 +    def add_instruction(self, text: str):
 +        """添加指令部分"""
 +        self.sections.append(("指令", text))
 +        return self
 +    
 +    def add_context(self, text: str, **vars):
 +        """添加上下文部分"""
 +        self.sections.append(("上下文", text))
 +        self.variables.update(vars.keys())
 +        return self
 +    
 +    def add_constraints(self, constraints: list):
 +        """添加约束条件"""
 +        constraint_text = "约束条件:\n" + "\n".join(f"- {c}" for c in constraints)
 +        self.sections.append(("约束", constraint_text))
 +        return self
 +    
 +    def add_output_format(self, format_spec: str):
 +        """添加输出格式说明"""
 +        self.sections.append(("输出格式", format_spec))
 +        return self
 +    
 +    def build(self) -> str:
 +        """构建最终提示词"""
 +        parts = []
 +        for section_type, content in self.sections:
 +            parts.append(f"### {section_type}\n{content}")
 +        return "\n\n".join(parts)
 +
 +# 使用示例
 +builder = PromptBuilder()
 +prompt = (builder
 +    .add_instruction("请分析以下用户反馈并提供改进建议。")
 +    .add_context(
 +        "用户反馈:{feedback}\n产品类型:{product_type}",
 +        feedback="",
 +        product_type=""
 +    )
 +    .add_constraints([
 +        "分析必须客观",
 +        "建议必须可行",
 +        "考虑用户情绪"
 +    ])
 +    .add_output_format("""
 +JSON格式:
 +{
 +    "sentiment": "正面/负面/中性",
 +    "issues": ["问题1", "问题2"],
 +    "suggestions": ["建议1", "建议2"]
 +}
 +""")
 +    .build())
 +
 +print(prompt)
 +</code>
 +
 +==== 3.5.3 动态 Few-shot 示例 ====
 +
 +根据查询动态选择最相关的示例。
 +
 +<code python>
 +from typing import List, Dict
 +import numpy as np
 +
 +class DynamicExampleSelector:
 +    """动态示例选择器"""
 +    
 +    def __init__(self, examples: List[Dict], embeddings_model=None):
 +        self.examples = examples
 +        self.embeddings = embeddings_model
 +        self.example_embeddings = None
 +        
 +        if embeddings_model:
 +            # 预计算示例的嵌入向量
 +            texts = [ex["input"] for ex in examples]
 +            self.example_embeddings = embeddings_model.embed_documents(texts)
 +    
 +    def select_by_similarity(self, query: str, k: int = 3) -> List[Dict]:
 +        """基于相似度选择示例"""
 +        if not self.embeddings or not self.example_embeddings:
 +            # 如果没有嵌入模型,随机选择
 +            import random
 +            return random.sample(self.examples, min(k, len(self.examples)))
 +        
 +        # 计算查询的嵌入向量
 +        query_embedding = self.embeddings.embed_query(query)
 +        
 +        # 计算相似度
 +        similarities = [
 +            np.dot(query_embedding, ex_emb) / 
 +            (np.linalg.norm(query_embedding) * np.linalg.norm(ex_emb))
 +            for ex_emb in self.example_embeddings
 +        ]
 +        
 +        # 选择最相似的 k 个
 +        top_k_indices = np.argsort(similarities)[-k:][::-1]
 +        return [self.examples[i] for i in top_k_indices]
 +    
 +    def select_by_category(self, category: str) -> List[Dict]:
 +        """基于类别选择示例"""
 +        return [ex for ex in self.examples if ex.get("category") == category]
 +    
 +    def create_few_shot_prompt(
 +        self, 
 +        query: str, 
 +        k: int = 3,
 +        template: str = "输入: {input}\n输出: {output}\n---"
 +    ) -> str:
 +        """创建 few-shot 提示词"""
 +        selected = self.select_by_similarity(query, k)
 +        
 +        example_texts = []
 +        for ex in selected:
 +            example_texts.append(template.format(**ex))
 +        
 +        return "\n".join(example_texts) + f"\n输入: {query}\n输出:"
 +
 +# 使用示例
 +examples = [
 +    {"input": "天气怎么样?", "output": "询问天气", "category": "weather"},
 +    {"input": "今天会下雨吗?", "output": "询问天气", "category": "weather"},
 +    {"input": "附近有什么餐厅?", "output": "询问餐厅", "category": "food"},
 +    {"input": "推荐一家好吃的火锅店", "output": "询问餐厅", "category": "food"},
 +    {"input": "怎么去机场?", "output": "询问路线", "category": "navigation"},
 +]
 +
 +selector = DynamicExampleSelector(examples)
 +prompt = selector.create_few_shot_prompt("明天需要带伞吗?", k=2)
 +print(prompt)
 +</code>
 +
 +==== 3.5.4 自适应提示词长度 ====
 +
 +根据上下文窗口自动调整提示词长度。
 +
 +<code python>
 +from langchain.prompts import PromptTemplate
 +
 +class AdaptivePromptTemplate:
 +    """自适应提示词模板"""
 +    
 +    def __init__(
 +        self, 
 +        base_template: str,
 +        max_tokens: int = 2000,
 +        tokenizer=None
 +    ):
 +        self.base_template = base_template
 +        self.max_tokens = max_tokens
 +        self.tokenizer = tokenizer
 +    
 +    def estimate_tokens(self, text: str) -> int:
 +        """估计 token 数量"""
 +        if self.tokenizer:
 +            return len(self.tokenizer.encode(text))
 +        # 简单估计:中文字符约1个token,英文单词约1.3个token
 +        return len(text) // 2
 +    
 +    def format_adaptive(
 +        self, 
 +        **kwargs
 +    ) -> str:
 +        """自适应格式化,确保不超过最大 token 数"""
 +        # 尝试完整格式化
 +        prompt = self.base_template.format(**kwargs)
 +        tokens = self.estimate_tokens(prompt)
 +        
 +        if tokens <= self.max_tokens:
 +            return prompt
 +        
 +        # 需要压缩内容
 +        compression_ratio = self.max_tokens / tokens * 0.9  # 留一些余量
 +        
 +        compressed_kwargs = {}
 +        for key, value in kwargs.items():
 +            if isinstance(value, str) and len(value) > 100:
 +                # 截断长文本
 +                keep_length = int(len(value) * compression_ratio)
 +                compressed_kwargs[key] = value[:keep_length] + "... [内容已截断]"
 +            else:
 +                compressed_kwargs[key] = value
 +        
 +        return self.base_template.format(**compressed_kwargs)
 +
 +# 使用示例
 +template = """请分析以下长篇文档:
 +
 +文档内容:
 +{document}
 +
 +分析要求:
 +{requirements}
 +
 +输出格式:
 +{format}
 +"""
 +
 +adaptive = AdaptivePromptTemplate(template, max_tokens=1000)
 +
 +long_document = "这是一篇非常长的文档..." * 500  # 模拟长文档
 +
 +result = adaptive.format_adaptive(
 +    document=long_document,
 +    requirements="提取关键信息",
 +    format="JSON格式"
 +)
 +
 +print(f"生成的提示词长度: {len(result)}")
 +</code>
 +
 +==== 3.5.5 实时提示词优化 ====
 +
 +根据模型反馈实时调整提示词。
 +
 +<code python>
 +class PromptOptimizer:
 +    """提示词优化器"""
 +    
 +    def __init__(self, llm):
 +        self.llm = llm
 +        self.history = []
 +    
 +    def optimize_prompt(
 +        self, 
 +        original_prompt: str,
 +        target_output: str = None,
 +        feedback: str = None
 +    ) -> str:
 +        """基于反馈优化提示词"""
 +        
 +        optimization_instruction = f"""
 +你是一位提示词工程专家。请优化以下提示词,使其产生更好的结果。
 +
 +原始提示词:
 +{original_prompt}
 +
 +"""
 +        if target_output:
 +            optimization_instruction += f"""
 +目标输出示例:
 +{target_output}
 +
 +"""
 +        
 +        if feedback:
 +            optimization_instruction += f"""
 +当前问题反馈:
 +{feedback}
 +
 +"""
 +        
 +        optimization_instruction += """
 +请提供优化后的提示词,并说明:
 +1. 改进了哪些方面
 +2. 为什么这些改进会产生更好的结果
 +3. 优化后的完整提示词
 +
 +优化后的提示词:
 +"""
 +        
 +        optimized = self.llm.predict(optimization_instruction)
 +        return optimized
 +    
 +    def iterative_improvement(
 +        self,
 +        base_prompt: str,
 +        test_cases: list,
 +        iterations: int = 3
 +    ) -> str:
 +        """通过多次迭代改进提示词"""
 +        current_prompt = base_prompt
 +        
 +        for i in range(iterations):
 +            print(f"\n=== 迭代 {i+1}/{iterations} ===")
 +            
 +            # 在当前提示词上测试
 +            results = []
 +            for test in test_cases:
 +                result = self.llm.predict(current_prompt.format(**test["input"]))
 +                results.append({
 +                    "input": test["input"],
 +                    "expected": test["expected"],
 +                    "actual": result
 +                })
 +            
 +            # 分析结果
 +            feedback = self._analyze_results(results)
 +            print(f"反馈: {feedback}")
 +            
 +            # 优化提示词
 +            if i < iterations - 1:  # 最后一次不需要优化
 +                current_prompt = self.optimize_prompt(
 +                    current_prompt,
 +                    feedback=feedback
 +                )
 +                print(f"优化后的提示词预览: {current_prompt[:200]}...")
 +        
 +        return current_prompt
 +    
 +    def _analyze_results(self, results: list) -> str:
 +        """分析测试结果并生成反馈"""
 +        correct = sum(1 for r in results if r["expected"] in r["actual"])
 +        total = len(results)
 +        
 +        feedback = f"准确率: {correct}/{total}\n"
 +        
 +        for i, result in enumerate(results):
 +            if result["expected"] not in result["actual"]:
 +                feedback += f"\n测试用例 {i+1} 失败:"
 +                feedback += f"\n  输入: {result['input']}"
 +                feedback += f"\n  期望: {result['expected']}"
 +                feedback += f"\n  实际: {result['actual'][:100]}..."
 +        
 +        return feedback
 +
 +# 使用示例(伪代码)
 +"""
 +from langchain.llms import OpenAI
 +
 +llm = OpenAI()
 +optimizer = PromptOptimizer(llm)
 +
 +test_cases = [
 +    {"input": {"text": "今天天气很好"}, "expected": "积极"},
 +    {"input": {"text": "这部电影太糟糕了"}, "expected": "消极"},
 +]
 +
 +final_prompt = optimizer.iterative_improvement(
 +    base_prompt="分析文本情感:{text}",
 +    test_cases=test_cases,
 +    iterations=3
 +)
 +"""
 +</code>
 +
 +===== 3.6 本章小结 =====
 +
 +本章深入探讨了 LangChain 中的提示词工程,涵盖了以下核心内容:
 +
 +**提示词工程基础:**
 +  * 提示词的基本结构:指令、上下文、输入数据、输出指示
 +  * 设计原则:清晰明确、提供上下文、指定输出格式、使用分隔符、给出示例
 +  * 常见模式:角色扮演、思维链、自洽性检查
 +
 +**PromptTemplate 详解:**
 +  * 基础使用方法
 +  * 部分变量(Partial Variables)技巧
 +  * 模板验证机制
 +  * 自定义输入解析器
 +
 +**Few-shot Prompting:**
 +  * 基础示例和实现
 +  * 示例选择器(长度限制、语义相似度)
 +  * 最佳实践和注意事项
 +
 +**Prompt 组合与管理:**
 +  * PipelinePromptTemplate 的使用
 +  * ChatPromptTemplate 处理多轮对话
 +  * 使用配置文件管理提示词
 +  * 提示词版本控制
 +
 +**动态提示词:**
 +  * 条件提示词
 +  * 模板继承与组合
 +  * 动态 Few-shot 示例选择
 +  * 自适应提示词长度
 +  * 实时提示词优化
 +
 +掌握这些提示词技术,将帮助你构建更高质量、更可控的 LLM 应用。在实际项目中,建议:
 +
 +  * 建立统一的提示词管理规范
 +  * 使用版本控制跟踪提示词变化
 +  * 收集用户反馈持续优化提示词
 +  * 根据具体场景选择合适的提示词策略
 +
 +在下一章中,我们将学习 LangChain 的 Chains 组件,了解如何将多个操作串联起来构建复杂的工作流。
 +
 +===== 练习 =====
 +
 +1. **基础练习**:创建一个 PromptTemplate,用于生成产品描述。模板应包含产品名称、特点列表、目标受众等变量。
 +
 +2. **进阶练习**:实现一个 Few-shot 情感分析提示词,包含5个示例,并使用长度限制选择器。
 +
 +3. **综合项目**:设计一个动态提示词系统,能够根据用户输入的复杂度自动选择不同数量和类型的示例。
 +
 +===== 参考资源 =====
 +
 +  * [[https://python.langchain.com/docs/modules/model_io/prompts|LangChain 官方文档 - Prompts]]
 +  * [[https://www.promptingguide.ai/zh|提示工程指南]]
 +  * [[https://github.com/f/awesome-chatgpt-prompts|Awesome ChatGPT Prompts]]
 +
  

该主题尚不存在

您访问的页面并不存在。如果允许,您可以使用创建该页面按钮来创建它。