# 使用 LangChain 构建结构化 Prompt 管理系统
## 背景介绍
这两年 Prompt 工程火得不行。随着大语言模型越来越便宜、越来越好用,怎么跟这些模型有效对话变成了每个开发者必须面对的问题。
我之前做个项目,需要同时维护几十个不同的 Prompt。每个都有自己的模板、变量和输出格式要求。手动管理这些 Prompt 简直是个灾难——改一处要搜半天,还容易出错。后来用 LangChain 写了套管理系统,轻松多了。
## 问题描述
在用 LLM 做开发时,大家基本都会遇到这几个破事:
**Prompt 散落各地**。代码里东一个西一个,想改的时候根本找不到在哪。
**变量替换太麻烦**。字符串拼来拼去,一不小心格式就挂了了。
**没有版本控制**。Prompt 效果变差了,想回退到之前版本?做梦。
**根本没法复用**。明明差不多的 Prompt,还得重新写一遍。
所以我们需要一个能集中管理模板、处理变量替换、支持版本控制的东西。
## 详细步骤
### 1. 环境准备
就两行命令:
“`bash
pip install langchain langchain-openai
“`
### 2. 创建 Prompt 模板
LangChain 的 PromptTemplate 挺好用的:
“`python
from langchain.prompts import PromptTemplate
# 基础模板
template = PromptTemplate(
input_variables=[“topic”, “audience”],
template=”””
你是一位专业的技术作家。
任务:为 {audience} 写一篇关于 {topic} 的技术文章。
要求:
1. 文章需要有清晰的标题
2. 内容要实用、有价值
3. 适当使用代码示例
4. 总结要点
“””,
)
# 用了它
formatted_prompt = template.format(
topic=”Python 异步编程”,
audience=”中级开发者”
)
“`
### 3. 组合多个 Prompt
有时候需要把几个 Prompt 串联起来用,比如先输出开头、再输出正文、最后总结。PipelinePrompt 就是干这个的:
“`python
from langchain.prompts.pipeline import PipelinePrompt
from langchain.prompts import PromptTemplate
# 各阶段模板
intro_template = PromptTemplate(
input_variables=[“topic”],
template=”介绍 {topic} 的背景和重要性:”
)
body_template = PromptTemplate(
input_variables=[“topic”],
template=”详细讲解 {topic} 的核心概念和实践:”
)
conclusion_template = PromptTemplate(
input_variables=[“topic”],
template=”总结 {topic} 的关键要点:”
)
# 最终组合
final_template = PromptTemplate(
input_variables=[“topic”],
template=”””{introduction}
{body}
{conclusion}”””
)
# 做成 Pipeline
pipeline_prompts = [
(“introduction”, intro_template),
(“body”, body_template),
(“conclusion”, conclusion_template),
]
full_pipeline = PipelinePrompt(
pipeline_prompts=pipeline_prompts,
final_prompt=final_template,
)
# 用了
result = full_pipeline.format(topic=”LangChain”)
“`
### 4. 自定义 Prompt 管理器
光有模板还不够,我们需要个管理器来统一处理版本、验证这些破事:
“`python
from langchain.prompts import PromptTemplate
from datetime import datetime
from typing import Dict, List, Optional
class PromptManager:
“””Prompt 管理器”””
def __init__(self):
self.templates: Dict[str, PromptTemplate] = {}
self.versions: Dict[str, List[dict]] = {}
def add_template(
self,
name: str,
template: str,
input_variables: List[str],
version: str = “1.0”
):
“””添加一个新模板”””
prompt_template = PromptTemplate(
template=template,
input_variables=input_variables
)
self.templates[name] = prompt_template
if name not in self.versions:
self.versions[name] = []
self.versions[name].append({
“version”: version,
“template”: template,
“input_variables”: input_variables,
“timestamp”: datetime.now().isoformat()
})
print(f”✓ 模板 {name} v{version} 已添加”)
def get_template(self, name: str, version: Optional[str] = None) -> PromptTemplate:
“””获取模板”””
if version:
for v in self.versions[name]:
if v[“version”] == version:
prompt_template = PromptTemplate(
template=v[“template”],
input_variables=v[“input_variables”]
)
return prompt_template
return self.templates[name]
def format_prompt(self, name: str, **kwargs) -> str:
“””格式化模板”””
template = self.get_template(name)
return template.format(**kwargs)
def list_templates(self) -> List[str]:
“””列出所有模板”””
return list(self.templates.keys())
def get_versions(self, name: str) -> List[dict]:
“””获取版本历史”””
return self.versions.get(name, [])
# 用了
manager = PromptManager()
manager.add_template(
name=”code_reviewer”,
template=”请审查以下 {language} 代码,指出潜在问题和改进建议:\n\n“`{language}\n{code}\n“`”,
input_variables=[“language”, “code”],
version=”1.0″
)
manager.add_template(
name=”code_reviewer”,
template=”你是一位 {language} 专家。请详细审查以下代码:\n\n“`{language}\n{code}\n“`\n\n请从以下维度进行分析:\n1. 代码规范\n2. 性能优化\n3. 安全性\n4. 可维护性”,
input_variables=[“language”, “code”],
version=”2.0″
)
formatted = manager.format_prompt(
“code_reviewer”,
language=”python”,
code=”def hello(): print(“Hello”)”
)
print(formatted)
“`
### 5. 集成 OpenAI 调用
把 Prompt 管理和实际调用结合起来:
“`python
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model=”gpt-4″, temperature=0.7)
manager = PromptManager()
manager.add_template(
name=”summarizer”,
template=”请用三句话总结以下文章:\n\n{article}”,
input_variables=[“article”]
)
article = “””
LangChain 是一个用于构建 LLM 应用的框架。
它提供了丰富的组件和工具,帮助开发者快速构建 AI 应用。
本文介绍了如何使用 LangChain 管理 Prompt。
“””
prompt = manager.format_prompt(“summarizer”, article=article)
response = llm.invoke(prompt)
print(response.content)
“`
### 6. 高级功能:动态模板选择
不同场景用不同模板:
“`python
class DynamicPromptSelector:
“””动态选择器”””
def __init__(self):
self.default_prompts: Dict[str, PromptTemplate] = {}
self.specialized_prompts: Dict[str, Dict[str, PromptTemplate]] = {}
def register_default(self, name: str, template: PromptTemplate):
self.default_prompts[name] = template
def register_specialized(
self,
category: str,
name: str,
template: PromptTemplate
):
if category not in self.specialized_prompts:
self.specialized_prompts[category] = {}
self.specialized_prompts[category][name] = template
def select(
self,
name: str,
category: Optional[str] = None,
**kwargs
) -> str:
if category and category in self.specialized_prompts:
if name in self.specialized_prompts[category]:
template = self.specialized_prompts[category][name]
return template.format(**kwargs)
if name in self.default_prompts:
template = self.default_prompts[name]
return template.format(**kwargs)
raise ValueError(f”模板 {name} 不存在”)
# 用了
selector = DynamicPromptSelector()
selector.register_default(
“explainer”,
PromptTemplate(
template=”解释 {concept} 的概念:”,
input_variables=[“concept”]
)
)
selector.register_specialized(
“medical”,
“explainer”,
PromptTemplate(
template=”从医学角度解释 {concept},包括病因、症状、诊断和治疗方法:”,
input_variables=[“concept”]
)
)
print(selector.select(“explainer”, concept=”糖尿病”))
print(selector.select(“explainer”, category=”medical”, concept=”糖尿病”))
“`
## 运行结果
跑上面的代码看看效果。
**版本管理输出**:
“`
✓ 模板 code_reviewer v1.0 已添加
✓ 模板 code_reviewer v2.0 已添加
“`
**格式化后的 Prompt**:
“`
你是一位 Python 专家。请详细审查以下代码:
“`python
def hello(): print(“Hello”)
“`
请从以下维度进行分析:
1. 代码规范
2. 性能优化
3. 安全性
4. 可维护性
“`
**查版本历史**:
“`python
versions = manager.get_versions(“code_reviewer”)
for v in versions:
print(f”版本: {v[“version”]}, 时间: {v[“timestamp”]}”)
“`
输出:
“`
版本: 1.0, 时间: 2024-01-15T10:30:00
版本: 2.0, 时间: 2024-01-16T14:20:00
“`
## 总结
用 LangChain 搭了这套 Prompt 管理系统,实实在在解决了几个痛点:
**代码复用**。模板化之后,同样的结构可以反复用,换个变量就生成新 Prompt,不用重复写。
**好维护**。所有 Prompt 放在一个地,改一处全局生效。再也不用满代码库搜字符串了。
**版本控制**。完整的版本记录,想回退到任意历史版本分分钟的事。
**方便协作**。统一接口、统一格式,团队里谁用都顺手。
这套东西虽然做得比较简单,但日常开发足够用了。实际项目中可以根据需要再扩展,比如加个模板验证、接个 A/B 测试什么的。
Prompt 工程这行当发展挺快的,工具和方法也在不断更新。关键就是保持简单、好维护,让 Prompt 跟代码一样能被版本控制、能协作。