1. LangChain 提示模板

LangChain 提示模板是 LangChain 框架中用于创建和管理提示词(prompts)的工具。提示模板允许开发者定义具有占位符的文本模板,这些占位符可以在运行时被动态的值替换,从而使提示词更加灵活和可重用。

提示模板的主要优势在于:

  • 将提示词的结构与具体数据分离
  • 实现提示词的复用和标准化
  • 便于管理复杂的提示词逻辑

2. LangChain PromptTemplate 语法

LangChain 中 PromptTemplate 的基本语法如下:

from langchain.prompts import PromptTemplate

# 创建一个简单的提示模板
template = "你好 {name},我是一个 {role}。"

# 初始化 PromptTemplate 对象
prompt = PromptTemplate(
    input_variables=["name", "role"],  # 定义需要填充的变量
    template=template                  # 提供模板字符串
)

# 使用模板生成最终的提示词
formatted_prompt = prompt.format(name="张三", role="AI助手")
print(formatted_prompt)  # 输出: 你好 张三,我是一个 AI助手。

PromptTemplate 的主要参数:

  • template: 包含占位符的字符串模板
  • input_variables: 模板中用到的所有变量名列表
  • template_format: 模板格式,默认是 “f-string”
  • validate_template: 布尔值,是否验证所有的 input_variables 都在模板中使用

3. PromptTemplate 小案例

以下是一个创建智能客服回复的小案例:

from langchain.prompts import PromptTemplate
from langchain.llms import OpenAI

# 创建一个用于客服回复的提示模板
customer_service_template = """
你是一名专业的客服代表,需要回答客户关于{product}的问题。
客户问题: {question}

请用友好专业的语气回答,确保包含相关的{product}信息。
如果你不知道答案,请诚实地表明并提供可能的解决途径。

回复:
"""

# 初始化提示模板
customer_service_prompt = PromptTemplate(
    input_variables=["product", "question"],
    template=customer_service_template
)

# 使用OpenAI模型
llm = OpenAI(temperature=0.7)

# 客户问题示例
product = "智能手机X100"
question = "我的手机电池续航很差,有什么解决方法吗?"

# 格式化提示词
formatted_prompt = customer_service_prompt.format(
    product=product,
    question=question
)

# 生成回复
response = llm(formatted_prompt)
print(response)

这个案例演示了如何:

  1. 创建包含多个变量的复杂提示模板
  2. 将用户输入和产品信息动态注入到模板中
  3. 使用格式化后的提示来生成适合特定情境的回复

更复杂的场景中,您还可以使用 LangChain 的 FewShotPromptTemplate 来添加示例,或者使用 PipelinePrompt 来组合多个提示模板。

4. 项目中 PromptTemplate 的使用思路和技巧

模块化提示设计

  1. 分层结构设计

    • 将复杂提示拆分为基础模板和专用模板
    • 创建模板库,按功能/领域组织不同的提示模板
    base_template = PromptTemplate(
        template="系统: {system_message}\n\n用户: {user_input}",
        input_variables=["system_message", "user_input"]
    )
    
    specialized_templates = {
        "客服": "你是专业的{industry}客服,帮助解决{type}问题",
        "分析": "你是数据分析专家,分析{data_type}并提供{output_format}格式的见解"
    }
    
  2. 上下文管理

    • 使用 ConversationBufferMemory 维护对话历史
    • 动态调整提示长度以适应模型上下文窗口
    from langchain.memory import ConversationBufferMemory
    
    memory = ConversationBufferMemory(return_messages=True)
    prompt = ChatPromptTemplate.from_messages([
        ("system", template.format(domain="医疗")),
        MessagesPlaceholder(variable_name="history"),
        ("human", "{input}")
    ])
    

优化技巧

  1. 提示模板版本控制

    • 为不同版本的提示模板创建追踪机制
    • 实验不同版本并评估效果
    prompt_versions = {
        "v1": PromptTemplate(...),
        "v2": PromptTemplate(...),
        "v3": PromptTemplate(...)
    }
    
    # 使用配置或A/B测试框架选择版本
    current_version = "v2"
    prompt = prompt_versions[current_version]
    
  2. 动态提示组合

    • 使用条件逻辑动态组装提示的不同部分
    • 根据用户需求或场景选择适当的提示组件
    def build_prompt(user_query, user_context):
        components = ["base_instruction"]
        
        if "数据分析" in user_query:
            components.append("data_analysis_instruction")
        
        if user_context.get("expertise_level") == "beginner":
            components.append("simplified_explanation")
        
        return PromptTemplate.from_template(
            "\n\n".join([templates[comp] for comp in components])
        )
    
  3. 提示模板参数化

    • 提取关键参数为配置项,便于调整
    • 使用 YAML 或 JSON 存储提示配置
    # config.yaml
    prompts:
      customer_service:
        template: "你是{company}的客服代表..."
        parameters:
          politeness: high
          detail_level: comprehensive
          tone: friendly
    
    # 代码中加载配置
    with open("config.yaml") as f:
        config = yaml.safe_load(f)
        
    prompt = PromptTemplate(
        template=config["prompts"]["customer_service"]["template"],
        input_variables=["company", "query"]
    )
    

高级应用场景

  1. 多语言支持

    • 创建多语言提示模板库
    • 动态选择适合用户语言的模板
    language_templates = {
        "en": PromptTemplate(template="You are a helpful assistant...", input_variables=[...]),
        "zh": PromptTemplate(template="你是一个有帮助的助手...", input_variables=[...]),
        "es": PromptTemplate(template="Eres un asistente útil...", input_variables=[...])
    }
    
    def get_prompt(lang_code):
        return language_templates.get(lang_code, language_templates["en"])
    
  2. 领域适应

    • 为特定领域创建专用提示模板
    • 嵌入领域术语和专业知识
    legal_template = """
    作为法律顾问,请分析以下案例:
    案例描述: {case_description}
    
    考虑以下法律因素:
    - {jurisdiction}相关法规
    - 相似判例的先例
    - 可能的法律解释
    
    分析:
    """
    
    medical_template = """
    作为医疗顾问,请分析以下病例:
    患者情况: {patient_description}
    
    考虑以下医学因素:
    - 症状与可能的诊断
    - 推荐的检查方法
    - 潜在的治疗方案
    
    分析:
    """
    
  3. 提示链接

    • 使用 SequentialChain 将多个提示模板连接为工作流
    • 前一个模板的输出作为下一个模板的输入
    from langchain.chains import SequentialChain, LLMChain
    
    # 第一步:提取关键信息
    extraction_prompt = PromptTemplate(
        template="从以下文本中提取关键点:\n{text}\n\n关键点:",
        input_variables=["text"]
    )
    extraction_chain = LLMChain(llm=llm, prompt=extraction_prompt, output_key="key_points")
    
    # 第二步:生成分析
    analysis_prompt = PromptTemplate(
        template="基于以下关键点分析问题:\n{key_points}\n\n分析:",
        input_variables=["key_points"]
    )
    analysis_chain = LLMChain(llm=llm, prompt=analysis_prompt, output_key="analysis")
    
    # 第三步:生成建议
    recommendation_prompt = PromptTemplate(
        template="基于以下分析提供建议:\n{analysis}\n\n建议:",
        input_variables=["analysis"]
    )
    recommendation_chain = LLMChain(llm=llm, prompt=recommendation_prompt, output_key="recommendation")
    
    # 组合为工作流
    workflow = SequentialChain(
        chains=[extraction_chain, analysis_chain, recommendation_chain],
        input_variables=["text"],
        output_variables=["key_points", "analysis", "recommendation"]
    )
    

通过这些策略和技巧,您可以在项目中更有效地利用 PromptTemplate,创建更加灵活、可维护和强大的 AI 应用。

5. 项目中, PromptTemplate 注意事项

性能考量

  1. 提示长度管理

    • 长提示会消耗更多 token,增加成本和延迟
    • 监控提示长度,特别是在包含对话历史时
    • 实现自动截断机制,保留最重要的上下文信息
    def truncate_history(history, max_tokens=2000):
        current_tokens = 0
        truncated_history = []
        
        for message in reversed(history):
            message_tokens = len(message.split()) * 1.3  # 粗略估计
            if current_tokens + message_tokens <= max_tokens:
                truncated_history.insert(0, message)
                current_tokens += message_tokens
            else:
                break
                
        return truncated_history
    
  2. 缓存策略

    • 对常用的提示格式化结果进行缓存
    • 使用相同参数的重复请求可直接返回缓存结果
    from functools import lru_cache
    
    @lru_cache(maxsize=100)
    def get_formatted_prompt(template_name, **kwargs):
        template = prompt_library[template_name]
        return template.format(**kwargs)
    

安全与数据保护

  1. 输入验证与清理

    • 验证用户输入,防止注入攻击
    • 清理可能包含敏感信息的数据
    def sanitize_input(text):
        # 移除可能的敏感信息模式(如信用卡号、社保号等)
        patterns = [
            r'\b\d{16}\b',  # 信用卡号
            r'\b\d{3}-\d{2}-\d{4}\b',  # 社保号
            # 更多模式...
        ]
        
        for pattern in patterns:
            text = re.sub(pattern, "[REDACTED]", text)
            
        return text
    
    # 使用安全的输入
    safe_input = sanitize_input(user_input)
    formatted_prompt = template.format(query=safe_input)
    
  2. 敏感信息处理

    • 避免在提示中包含完整的个人身份信息
    • 实现数据脱敏处理
    def anonymize_data(data):
        # 替换实际名称为通用标识符
        anonymized = data.copy()
        if "name" in anonymized:
            anonymized["name"] = f"用户_{hash(data['name']) % 1000}"
        if "email" in anonymized:
            anonymized["email"] = "user@example.com"
        return anonymized
    
    # 使用匿名化数据
    safe_data = anonymize_data(user_data)
    prompt = template.format(**safe_data)
    

维护与调试

  1. 提示模板记录与监控

    • 记录提示使用情况及其结果
    • 创建提示有效性的指标仪表板
    def log_prompt_usage(template_id, parameters, result_quality):
        logging.info(f"Template: {template_id}, Parameters: {parameters}, Quality: {result_quality}")
        
        # 更新监控指标
        metrics = get_prompt_metrics(template_id)
        metrics["usage_count"] += 1
        metrics["avg_quality"] = (metrics["avg_quality"] * (metrics["usage_count"] - 1) + result_quality) / metrics["usage_count"]
        update_prompt_metrics(template_id, metrics)
    
  2. 提示调试工具

    • 实现提示预览功能,便于开发和测试
    • 使用对比测试评估不同提示的效果
    def preview_prompt(template_id, parameters):
        """生成预览并返回估计的token消耗"""
        template = get_template(template_id)
        formatted = template.format(**parameters)
        
        tokens = estimate_tokens(formatted)
        return {
            "formatted_prompt": formatted,
            "estimated_tokens": tokens,
            "estimated_cost": tokens * 0.002 / 1000  # 假设的成本计算
        }
    

扩展性考虑

  1. 跨模型兼容性

    • 为不同LLM模型创建适配的提示模板
    • 考虑模型间的能力差异
    model_specific_templates = {
        "gpt-4": PromptTemplate(
            template="详细分析以下问题: {question}",
            input_variables=["question"]
        ),
        "gpt-3.5-turbo": PromptTemplate(
            template="请简洁回答: {question}",
            input_variables=["question"]
        ),
        "llama2-70b": PromptTemplate(
            template="<s>[INST] {question} [/INST]",
            input_variables=["question"]
        )
    }
    
    def get_template_for_model(model_name):
        return model_specific_templates.get(model_name, default_template)
    
  2. 多模态支持

    • 扩展提示模板以支持图像、音频等多模态输入
    • 适应不同类型的多模态模型
    def create_multimodal_prompt(text_template, image_url=None, audio_url=None):
        parts = [{"type": "text", "content": text_template}]
        
        if image_url:
            parts.append({"type": "image", "url": image_url})
            
        if audio_url:
            parts.append({"type": "audio", "url": audio_url})
            
        return parts
    

业务逻辑集成

  1. 业务规则嵌入

    • 在提示模板中嵌入关键业务规则和约束
    • 确保AI响应符合组织政策
    compliance_template = """
    你是{company}的AI助手。在回答问题时,请遵循以下规则:
    
    1. 不提供{excluded_topics}相关的建议
    2. 确保所有建议符合{regulations}法规
    3. 如果不确定,提供免责声明并建议咨询专业人士
    
    问题: {question}
    """
    
    compliance_prompt = PromptTemplate(
        template=compliance_template,
        input_variables=["company", "excluded_topics", "regulations", "question"]
    )
    
  2. 错误恢复机制

    • 实现提示失败的回退策略
    • 设计渐进式提示方案,从简单到复杂
    def get_response_with_fallback(query):
        # 尝试详细提示
        try:
            detailed_prompt = detailed_template.format(query=query)
            response = llm(detailed_prompt, max_retries=2, timeout=10)
            if response_quality_check(response) > 0.7:
                return response
        except (TimeoutError, APIError) as e:
            logging.warning(f"Detailed prompt failed: {e}")
        
        # 尝试简化提示
        try:
            simple_prompt = simple_template.format(query=query)
            return llm(simple_prompt, max_retries=3, timeout=15)
        except Exception as e:
            logging.error(f"All prompts failed: {e}")
            return "抱歉,我现在无法处理您的请求。请稍后再试。"
    

通过关注这些注意事项,您可以构建更加稳健、安全和高效的 PromptTemplate 实现,更好地应对实际项目中的各种挑战和需求。

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐