1. 理解LangChain中LLM与提示词的协作机制
在构建基于大语言模型(LLM)的应用时,提示词(Prompt)设计与模型调用的配合方式直接决定了系统表现。LangChain作为LLM应用开发框架,提供了多种灵活的模式来实现这种协作。本笔记将深入剖析四种典型协作模式,并分享实际项目中的调优经验。
关键认知:提示词不是静态模板,而是与LLM形成动态对话的工作记忆区。理解这一点是掌握协作机制的前提。
1.1 基础协作模式解析
最基本的协作方式是通过LLMChain将提示词模板与LLM绑定:
python复制from langchain.prompts import PromptTemplate
from langchain.llms import OpenAI
prompt = PromptTemplate(
input_variables=["product"],
template="为{product}写5个创意广告语,要求:",
)
llm = OpenAI(temperature=0.7)
chain = LLMChain(llm=llm, prompt=prompt)
print(chain.run("智能手表"))
这种模式下有三个关键控制点:
- 模板变量:通过
input_variables定义插值点位 - 温度参数:控制LLM输出的随机性(0-1范围)
- 提示结构:隐式包含指令、上下文和输出指示
实测发现,当temperature=0.7时,既能保持创意性又不会过于天马行空,是商业文案生成的甜点值。
1.2 动态提示词进阶技巧
实际项目中往往需要更复杂的提示词组装逻辑。以下是三种进阶模式:
1.2.1 条件式提示组装
python复制from langchain.prompts import (
PromptTemplate,
SystemMessagePromptTemplate,
HumanMessagePromptTemplate
)
system_prompt = PromptTemplate(
template="你是一个专业的{domain}专家",
input_variables=["domain"]
)
human_prompt = PromptTemplate(
template="请用{style}风格回答:{question}",
input_variables=["style", "question"]
)
final_prompt = ChatPromptTemplate.from_messages([
SystemMessagePromptTemplate(prompt=system_prompt),
HumanMessagePromptTemplate(prompt=human_prompt)
])
这种分层结构允许:
- 系统角色定义与用户提问解耦
- 不同组件可独立复用
- 支持动态插入领域知识
1.2.2 少样本提示(Few-shot Prompting)
python复制examples = [
{"input": "高兴", "output": "艳阳高照,鸟儿欢唱"},
{"input": "悲伤", "output": "阴云密布,细雨绵绵"}
]
example_prompt = PromptTemplate(
input_variables=["input", "output"],
template="输入:{input}\n输出:{output}"
)
few_shot_prompt = FewShotPromptTemplate(
examples=examples,
example_prompt=example_prompt,
prefix="根据示例风格续写",
suffix="输入:{adjective}\n输出:",
input_variables=["adjective"]
)
关键配置参数:
examples:示范样本列表example_prompt:单个样本的格式化模板suffix:最后追加的提示引导语
经验:样本数量建议3-5个,过多会导致token浪费且可能干扰模型
1.2.3 提示词流水线
对于复杂场景,可以使用PipelinePrompt组合多个子提示:
python复制from langchain.prompts.pipeline import PipelinePromptTemplate
intro = PromptTemplate.from_template("你是一个{role}")
task = PromptTemplate.from_template("请完成:{instruction}")
format = PromptTemplate.from_template("用{style}格式回复")
full_prompt = PipelinePromptTemplate(
final_prompt=ChatPromptTemplate.from_messages([
("system", "{intro}"),
("human", "{task}\n{format}")
]),
pipeline_prompts=[
("intro", intro),
("task", task),
("format", format)
]
)
这种架构特别适合:
- 多阶段任务分解
- 团队协作开发(不同成员负责不同提示模块)
- A/B测试不同提示组合
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 性能优化实战技巧
2.1 上下文窗口管理
当提示词过长时,需要特别注意LLM的上下文窗口限制。以GPT-3.5为例:
python复制def calculate_token(prompt):
# 简单估算:英文1token≈4字符,中文1token≈2字符
return len(prompt) // (4 if is_english else 2)
context_window = 4096 # GPT-3.5的上下文token数
safety_margin = 512 # 为输出保留的空间
if calculate_token(prompt) > (context_window - safety_margin):
# 触发压缩策略
prompt = summarize_long_prompt(prompt)
常用压缩策略:
- 提取关键句而非完整段落
- 用标签替代详细描述(如"[用户历史]")
- 动态移除最早的历史消息
2.2 结构化输出控制
通过提示词约束输出格式,便于后续解析:
python复制template = """请按指定格式回复:
问题:{query}
返回JSON格式:
{{
"answer": "...",
"confidence": 0-5,
"sources": ["..."]
}}"""
prompt = PromptTemplate(
template=template,
input_variables=["query"],
output_parser=JSONOutputParser()
)
配合output_parser可实现:
- 自动验证格式有效性
- 直接转换为Python对象
- 与下游系统无缝对接
2.3 多模型协作策略
不同LLM擅长不同任务,可通过路由机制动态选择:
python复制from langchain.llms import OpenAI, Anthropic
from langchain.chains.router import LLMRouterChain
science_llm = Anthropic(temperature=0.3) # 适合严谨内容
creative_llm = OpenAI(temperature=0.9) # 适合创意生成
router_chain = LLMRouterChain.from_llms(
[science_llm, creative_llm],
prompt_selectors=[
{"contains": "实验数据"}, # 路由到science_llm
{"contains": "故事创作"} # 路由到creative_llm
]
)
路由规则可以基于:
- 关键词匹配
- 语义相似度
- 用户指定标签
3. 调试与优化方法论
3.1 提示词版本控制
建议采用如下目录结构管理提示词迭代:
code复制/prompts
/v1
system.md
user.md
/v2
system.md
user.md
current -> v2 # 符号链接
配合Git实现:
- 差异对比
- 版本回滚
- 多人协作
3.2 评估指标设计
建立量化评估体系:
python复制def evaluate_response(response, criteria):
score = 0
if criteria["relevance"]:
score += check_relevance(response)
if criteria["creativity"]:
score += check_creativity(response)
return score
# 使用示例
criteria = {"relevance": True, "creativity": False}
evaluate_response("示例回答", criteria)
常用评估维度:
- 相关性(0-5分)
- 创造性(0-5分)
- 安全性(通过/不通过)
- 格式合规性(布尔值)
3.3 常见问题排查
问题1:输出不符合预期
检查步骤:
- 打印最终生成的完整提示词
- 验证模板变量是否正确填充
- 检查temperature参数是否合适
- 测试最小可复现示例
问题2:响应速度慢
优化策略:
- 减少不必要的few-shot示例
- 使用
stop参数提前终止生成 - 启用流式响应显示部分结果
问题3:结果不一致
解决方案:
- 固定
seed参数 - 使用
top_p替代temperature - 添加更明确的输出约束
4. 高级应用模式
4.1 记忆增强提示
通过ConversationBufferMemory实现多轮对话:
python复制from langchain.memory import ConversationBufferMemory
memory = ConversationBufferMemory()
memory.save_context(
{"input": "推荐适合程序员的健身方式"},
{"output": "建议尝试..."}
)
# 后续提问会自动包含历史
chain.run("为什么推荐这个?", memory=memory)
记忆管理技巧:
- 设置
max_token_limit防止膨胀 - 定期总结历史而非完整保留
- 区分长期记忆和短期记忆
4.2 工具调用集成
结合Tools实现增强功能:
python复制from langchain.agents import load_tools
tools = load_tools(["serpapi", "wolfram-alpha"])
agent = initialize_agent(
tools,
llm,
agent="zero-shot-react-description",
verbose=True
)
agent.run("圆周率的前10位是多少?")
提示词会自动包含:
- 工具描述
- 调用格式
- 结果处理说明
4.3 混合编排模式
使用LangGraph实现复杂工作流:
python复制from langgraph.graph import Graph
workflow = Graph()
workflow.add_node("generate", generation_chain)
workflow.add_node("validate", validation_chain)
workflow.add_edge("generate", "validate")
workflow.add_conditional_edges(
"validate",
lambda x: "revise" if needs_revision(x) else "publish",
)
这种模式下:
- 每个节点有独立提示词
- 路由逻辑可自定义
- 支持循环修正
在实际项目中,我通常会先设计提示词的状态转换图,再对应实现各个节点的提示模板。例如内容审核流程可能包含:生成→基础校验→合规检查→风格调整→最终输出,每个环节都有针对性的提示设计。
