LangChain Prompt Templates 概念指南

LangChain 提示模板概念指南

在这里插入图片描述

概述

提示模板帮助将用户输入和参数转换为语言模型的指令。这可以用来指导模型的响应,帮助它理解上下文并生成相关且连贯的基于语言的输出。

提示模板接受一个字典作为输入,其中每个键代表提示模板中要填充的变量。

提示模板输出一个PromptValue。这个PromptValue可以传递给LLM或ChatModel,也可以转换为字符串或消息列表。存在PromptValue的原因是为了方便在字符串和消息之间切换。

提示模板的类型

LangChain中有几种不同类型的提示模板:

1. String PromptTemplates(字符串提示模板)

这些提示模板用于格式化单个字符串,通常用于较简单的输入。例如,构造和使用PromptTemplate的常见方式如下:

from langchain_core.prompts import PromptTemplate

# 创建提示模板
prompt_template = PromptTemplate.from_template("Tell me a joke about {topic}")

# 调用模板并传入参数
prompt_template.invoke({"topic": "cats"})
详细示例
from langchain_core.prompts import PromptTemplate

# 方式1:使用from_template方法
prompt = PromptTemplate.from_template(
    "你是一个{role},请回答关于{topic}的问题:{question}"
)

# 方式2:使用构造函数
prompt = PromptTemplate(
    input_variables=["role", "topic", "question"],
    template="你是一个{role},请回答关于{topic}的问题:{question}"
)

# 使用模板
result = prompt.invoke({
    "role": "专业的Python开发者",
    "topic": "机器学习",
    "question": "如何选择合适的算法?"
})

print(result.to_string())
# 输出: 你是一个专业的Python开发者,请回答关于机器学习的问题:如何选择合适的算法?
高级字符串模板功能
# 支持条件逻辑的模板
conditional_template = PromptTemplate.from_template(
    """
    {%- if user_type == "premium" -%}
    欢迎尊贵的用户!您可以享受以下高级功能:
    {%- else -%}
    欢迎普通用户!
    {%- endif -%}
    
    请问您需要什么帮助?关于:{topic}
    """
)

# 支持循环的模板
list_template = PromptTemplate.from_template(
    """
    以下是关于{topic}的要点:
    {%- for item in items %}
    - {{ item }}
    {%- endfor %}
    """
)

2. ChatPromptTemplates(聊天提示模板)

这些提示模板用于格式化消息列表。这些"模板"由模板列表本身组成。例如,构造和使用ChatPromptTemplate的常见方式如下:

from langchain_core.prompts import ChatPromptTemplate

# 创建聊天提示模板
prompt_template = ChatPromptTemplate([
    ("system", "You are a helpful assistant"),
    ("user", "Tell me a joke about {topic}")
])

# 调用模板
prompt_template.invoke({"topic": "cats"})

在上面的示例中,这个ChatPromptTemplate在调用时将构造两条消息。第一条是系统消息,没有要格式化的变量。第二条是HumanMessage,将由用户传入的topic变量进行格式化。

详细的聊天模板示例
from langchain_core.prompts import ChatPromptTemplate

# 复杂的聊天模板
chat_template = ChatPromptTemplate([
    ("system", "你是一个{role},专门帮助用户解决{domain}相关的问题。"),
    ("human", "我的问题是:{question}"),
    ("ai", "我理解您的问题。让我为您详细解答。"),
    ("human", "请提供更多细节关于{specific_aspect}")
])

# 使用模板
messages = chat_template.invoke({
    "role": "技术专家",
    "domain": "人工智能",
    "question": "什么是深度学习?",
    "specific_aspect": "神经网络架构"
})

# 输出将包含4条格式化的消息
for message in messages.to_messages():
    print(f"{message.type}: {message.content}")
不同消息类型的使用
from langchain_core.prompts import ChatPromptTemplate

# 支持多种消息类型
multi_role_template = ChatPromptTemplate([
    ("system", "你是一个{assistant_type}助手。"),
    ("human", "{user_input}"),
    ("ai", "我明白了。让我来帮助您。"),
    ("human", "具体来说,{specific_request}"),
    ("ai", "好的,我会{action}。")
])

# 实际使用
result = multi_role_template.invoke({
    "assistant_type": "编程",
    "user_input": "我需要学习Python",
    "specific_request": "我想了解面向对象编程",
    "action": "为您详细解释面向对象编程的概念"
})

3. MessagesPlaceholder(消息占位符)

这个提示模板负责在特定位置添加消息列表。在上面的ChatPromptTemplate中,我们看到了如何格式化两条消息,每条都是字符串。但是如果我们希望用户传入一个消息列表,我们将其插入到特定位置呢?这就是使用MessagesPlaceholder的方式。

from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.messages import HumanMessage

# 创建包含消息占位符的模板
prompt_template = ChatPromptTemplate([
    ("system", "You are a helpful assistant"),
    MessagesPlaceholder("msgs")
])

# 调用时传入消息列表
prompt_template.invoke({"msgs": [HumanMessage(content="hi!")]})

这将产生两条消息的列表,第一条是系统消息,第二条是我们传入的HumanMessage。如果我们传入了5条消息,那么总共会产生6条消息(系统消息加上传入的5条)。这对于让消息列表插入到特定位置很有用。

MessagesPlaceholder的高级用法
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.messages import HumanMessage, AIMessage

# 复杂的消息占位符使用
complex_template = ChatPromptTemplate([
    ("system", "你是一个{role},当前时间是{current_time}。"),
    MessagesPlaceholder("chat_history"),
    ("human", "{user_input}"),
    MessagesPlaceholder("additional_context", optional=True)
])

# 准备聊天历史
chat_history = [
    HumanMessage(content="你好"),
    AIMessage(content="您好!我是您的助手。"),
    HumanMessage(content="我想了解机器学习")
]

# 准备额外上下文
additional_context = [
    HumanMessage(content="请注意我是初学者")
]

# 使用模板
result = complex_template.invoke({
    "role": "AI导师",
    "current_time": "2025年1月",
    "chat_history": chat_history,
    "user_input": "请解释什么是监督学习",
    "additional_context": additional_context
})
替代语法

不使用MessagesPlaceholder类的替代方式:

# 使用占位符语法
prompt_template = ChatPromptTemplate([
    ("system", "You are a helpful assistant"),
    ("placeholder", "{msgs}")  # <-- 这是改变的部分
])

# 这与使用MessagesPlaceholder("msgs")效果相同

实际应用场景

1. 客服机器人模板

from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder

# 客服场景的提示模板
customer_service_template = ChatPromptTemplate([
    ("system", """
    你是{company_name}的客服代表。请遵循以下准则:
    1. 保持友好和专业的态度
    2. 如果无法解决问题,请转接给人工客服
    3. 始终询问客户是否还有其他需要帮助的地方
    
    当前客户等级:{customer_level}
    """),
    MessagesPlaceholder("conversation_history"),
    ("human", "{customer_message}"),
])

# 使用示例
response = customer_service_template.invoke({
    "company_name": "科技公司",
    "customer_level": "VIP",
    "conversation_history": [],
    "customer_message": "我的订单还没有收到"
})

2. 代码助手模板

# 代码助手的提示模板
code_assistant_template = ChatPromptTemplate([
    ("system", """
    你是一个{programming_language}编程专家。请:
    1. 提供清晰、可运行的代码示例
    2. 解释代码的工作原理
    3. 指出潜在的问题和最佳实践
    4. 如果需要,提供测试用例
    """),
    ("human", "编程语言:{programming_language}"),
    ("human", "问题描述:{problem_description}"),
    ("human", "代码要求:{requirements}"),
    MessagesPlaceholder("code_context", optional=True)
])

# 使用示例
code_response = code_assistant_template.invoke({
    "programming_language": "Python",
    "problem_description": "实现一个二分查找算法",
    "requirements": "需要处理边界情况,包含详细注释",
    "code_context": []
})

3. 教育辅导模板

# 教育辅导的提示模板
tutoring_template = ChatPromptTemplate([
    ("system", """
    你是一个{subject}的专业导师,学生的水平是{student_level}。
    教学风格:{teaching_style}
    
    请:
    1. 根据学生水平调整解释的复杂度
    2. 使用具体例子帮助理解
    3. 鼓励学生思考和提问
    4. 提供练习建议
    """),
    MessagesPlaceholder("learning_history"),
    ("human", "学生问题:{student_question}"),
    ("human", "学习目标:{learning_objective}")
])

高级模板技术

1. 条件模板

from langchain_core.prompts import ChatPromptTemplate

# 基于条件的动态模板
def create_conditional_template(user_type, has_premium=False):
    base_messages = [
        ("system", f"你是为{user_type}用户服务的助手。")
    ]
    
    if has_premium:
        base_messages.append(
            ("system", "用户拥有高级权限,可以访问所有功能。")
        )
    
    base_messages.extend([
        ("human", "{user_query}"),
        ("ai", "我来帮助您解决这个问题。")
    ])
    
    return ChatPromptTemplate(base_messages)

# 使用条件模板
premium_template = create_conditional_template("企业", has_premium=True)
basic_template = create_conditional_template("个人", has_premium=False)

2. 模板组合

from langchain_core.prompts import ChatPromptTemplate

# 可组合的模板组件
def create_base_system_prompt(role, domain):
    return f"你是一个{role},专门处理{domain}相关的问题。"

def create_context_prompt(context_type):
    contexts = {
        "technical": "请提供技术细节和代码示例。",
        "business": "请从商业角度分析问题。",
        "educational": "请用简单易懂的方式解释。"
    }
    return contexts.get(context_type, "请提供详细的回答。")

# 组合模板
def create_specialized_template(role, domain, context_type):
    return ChatPromptTemplate([
        ("system", create_base_system_prompt(role, domain)),
        ("system", create_context_prompt(context_type)),
        ("human", "{user_question}"),
        MessagesPlaceholder("additional_info", optional=True)
    ])

# 创建特定用途的模板
tech_template = create_specialized_template(
    "软件架构师", "系统设计", "technical"
)

3. 模板验证和错误处理

from langchain_core.prompts import ChatPromptTemplate
from typing import Dict, Any

class ValidatedChatTemplate:
    def __init__(self, template: ChatPromptTemplate, required_vars: list):
        self.template = template
        self.required_vars = set(required_vars)
    
    def invoke(self, variables: Dict[str, Any]):
        # 验证必需变量
        missing_vars = self.required_vars - set(variables.keys())
        if missing_vars:
            raise ValueError(f"缺少必需的变量: {missing_vars}")
        
        # 验证变量类型
        for var, value in variables.items():
            if var.endswith("_list") and not isinstance(value, list):
                raise TypeError(f"变量 {var} 应该是列表类型")
        
        return self.template.invoke(variables)

# 使用验证模板
validated_template = ValidatedChatTemplate(
    ChatPromptTemplate([
        ("system", "你是{role}"),
        ("human", "{question}")
    ]),
    required_vars=["role", "question"]
)

性能优化和最佳实践

1. 模板缓存

from functools import lru_cache
from langchain_core.prompts import ChatPromptTemplate

class TemplateCache:
    def __init__(self):
        self._cache = {}
    
    @lru_cache(maxsize=100)
    def get_template(self, template_key: str):
        """缓存常用模板以提高性能"""
        templates = {
            "qa": ChatPromptTemplate([
                ("system", "你是一个问答助手"),
                ("human", "{question}")
            ]),
            "summarize": ChatPromptTemplate([
                ("system", "请总结以下内容"),
                ("human", "{content}")
            ]),
            "translate": ChatPromptTemplate([
                ("system", "请将以下内容翻译成{target_language}"),
                ("human", "{text}")
            ])
        }
        return templates.get(template_key)

# 使用缓存
template_cache = TemplateCache()
qa_template = template_cache.get_template("qa")

2. 异步模板处理

import asyncio
from langchain_core.prompts import ChatPromptTemplate

class AsyncTemplateProcessor:
    def __init__(self):
        self.templates = {}
    
    async def process_template_async(self, template_name: str, variables: dict):
        """异步处理模板以提高并发性能"""
        template = self.templates.get(template_name)
        if not template:
            raise ValueError(f"模板 {template_name} 不存在")
        
        # 模拟异步处理
        await asyncio.sleep(0.01)  # 模拟I/O操作
        return template.invoke(variables)
    
    async def batch_process(self, requests: list):
        """批量处理多个模板请求"""
        tasks = [
            self.process_template_async(req["template"], req["variables"])
            for req in requests
        ]
        return await asyncio.gather(*tasks)

3. 模板版本管理

from datetime import datetime
from typing import Dict, List

class TemplateVersionManager:
    def __init__(self):
        self.templates: Dict[str, List[dict]] = {}
    
    def add_template_version(self, name: str, template: ChatPromptTemplate, 
                           version: str, description: str = ""):
        """添加模板版本"""
        if name not in self.templates:
            self.templates[name] = []
        
        self.templates[name].append({
            "version": version,
            "template": template,
            "description": description,
            "created_at": datetime.now(),
            "active": True
        })
    
    def get_template(self, name: str, version: str = "latest"):
        """获取指定版本的模板"""
        if name not in self.templates:
            raise ValueError(f"模板 {name} 不存在")
        
        versions = self.templates[name]
        if version == "latest":
            # 返回最新的活跃版本
            active_versions = [v for v in versions if v["active"]]
            if not active_versions:
                raise ValueError(f"模板 {name} 没有活跃版本")
            return max(active_versions, key=lambda x: x["created_at"])["template"]
        else:
            # 返回指定版本
            for v in versions:
                if v["version"] == version:
                    return v["template"]
            raise ValueError(f"模板 {name} 版本 {version} 不存在")
    
    def deactivate_version(self, name: str, version: str):
        """停用指定版本"""
        for v in self.templates.get(name, []):
            if v["version"] == version:
                v["active"] = False
                break

错误处理和调试

1. 模板调试工具

from langchain_core.prompts import ChatPromptTemplate
import json

class TemplateDebugger:
    @staticmethod
    def debug_template(template: ChatPromptTemplate, variables: dict):
        """调试模板,显示详细信息"""
        print("=== 模板调试信息 ===")
        print(f"输入变量: {json.dumps(variables, ensure_ascii=False, indent=2)}")
        
        try:
            result = template.invoke(variables)
            print(f"生成的消息数量: {len(result.to_messages())}")
            
            for i, message in enumerate(result.to_messages()):
                print(f"\n消息 {i+1}:")
                print(f"  类型: {message.type}")
                print(f"  内容: {message.content}")
                
            return result
        except Exception as e:
            print(f"错误: {e}")
            print(f"错误类型: {type(e).__name__}")
            raise

# 使用调试器
debugger = TemplateDebugger()
template = ChatPromptTemplate([
    ("system", "你是{role}"),
    ("human", "{question}")
])

result = debugger.debug_template(template, {
    "role": "助手",
    "question": "什么是人工智能?"
})

2. 常见错误处理

from langchain_core.prompts import ChatPromptTemplate, PromptTemplate
from langchain_core.exceptions import LangChainException

def safe_template_invoke(template, variables):
    """安全地调用模板,处理常见错误"""
    try:
        return template.invoke(variables)
    except KeyError as e:
        missing_var = str(e).strip("'\"")
        raise ValueError(f"模板需要变量 '{missing_var}',但未提供")
    except TypeError as e:
        raise ValueError(f"变量类型错误: {e}")
    except LangChainException as e:
        raise ValueError(f"LangChain错误: {e}")
    except Exception as e:
        raise ValueError(f"未知错误: {e}")

# 使用安全调用
try:
    template = PromptTemplate.from_template("Hello {name}, you are {age} years old")
    result = safe_template_invoke(template, {"name": "Alice"})  # 缺少age变量
except ValueError as e:
    print(f"处理错误: {e}")

与其他LangChain组件的集成

1. 与LLM集成

from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI

# 创建模板和模型的组合
def create_qa_chain():
    template = ChatPromptTemplate([
        ("system", "你是一个专业的{domain}专家。请基于你的知识回答问题。"),
        ("human", "{question}")
    ])
    
    # 注意:这里使用模拟,实际使用时需要配置真实的模型
    # model = ChatOpenAI(temperature=0.7)
    
    # 创建链
    # chain = template | model
    
    return template

# 使用链
qa_template = create_qa_chain()
prompt = qa_template.invoke({
    "domain": "人工智能",
    "question": "什么是深度学习?"
})

2. 与输出解析器集成

from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import JsonOutputParser
from pydantic import BaseModel, Field

# 定义输出结构
class AnalysisResult(BaseModel):
    summary: str = Field(description="分析摘要")
    key_points: list = Field(description="关键要点")
    confidence: float = Field(description="置信度 (0-1)")

# 创建解析器
parser = JsonOutputParser(pydantic_object=AnalysisResult)

# 创建包含格式指令的模板
analysis_template = ChatPromptTemplate([
    ("system", """
    你是一个数据分析专家。请分析以下内容并按照指定格式返回结果。
    
    {format_instructions}
    """),
    ("human", "请分析:{content}")
])

# 使用模板
formatted_prompt = analysis_template.invoke({
    "content": "人工智能在医疗领域的应用越来越广泛...",
    "format_instructions": parser.get_format_instructions()
})

总结

提示模板是LangChain中的核心组件,它们提供了一种结构化的方式来构建和管理与语言模型的交互。

关键要点

  1. 模板类型

    • 字符串模板:适用于简单的文本格式化
    • 聊天模板:适用于多轮对话和复杂交互
    • 消息占位符:允许动态插入消息列表
  2. 最佳实践

    • 使用清晰、具体的变量名
    • 为模板添加适当的验证
    • 考虑性能优化和缓存
    • 实现错误处理和调试功能
  3. 高级功能

    • 条件逻辑和动态模板
    • 模板组合和重用
    • 版本管理和A/B测试
    • 与其他LangChain组件的集成

实施建议

  • 从简单开始:先使用基本的字符串模板,然后逐步采用更复杂的聊天模板
  • 模块化设计:创建可重用的模板组件
  • 测试和验证:确保模板在各种输入下都能正常工作
  • 性能监控:跟踪模板的性能和效果

提示模板是构建高质量AI应用的基础,通过合理使用这些工具,您可以创建更加智能和用户友好的应用程序。


参考链接LangChain Prompt Templates 官方文档

文档版本:基于 LangChain v0.3

最后更新:2025年1月

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值