模型调用与提示词工程
2026/5/14大约 9 分钟
模型调用与提示词工程
模型调用详解
Chat Model vs LLM
LangChain 中有两种模型类型,现在主流使用 Chat Model:
from langchain_openai import ChatOpenAI
# Chat Model — 推荐方式
chat_model = ChatOpenAI(model="gpt-4o-mini")
# 传入字符串(会自动转为 HumanMessage)
response = chat_model.invoke("你好")
# 传入消息列表(更灵活)
from langchain_core.messages import SystemMessage, HumanMessage
response = chat_model.invoke([
SystemMessage(content="你是一个友好的助手"),
HumanMessage(content="你好"),
])
模型参数调优
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="gpt-4o-mini",
# temperature: 控制随机性
# 0.0 — 确定性输出(代码生成、事实问答)
# 0.7 — 平衡(日常对话)
# 1.5 — 创意性(创意写作、头脑风暴)
temperature=0.7,
# max_tokens: 限制最大输出长度
max_tokens=1024,
# top_p: 核采样,与 temperature 二选一调节
# 0.1 — 只从概率最高的 10% token 中选
# 0.9 — 从概率最高的 90% token 中选
top_p=0.9,
# frequency_penalty: 频率惩罚(-2.0 ~ 2.0)
# 正值减少重复用词
frequency_penalty=0.0,
# presence_penalty: 存在惩罚(-2.0 ~ 2.0)
# 正值鼓励讨论新话题
presence_penalty=0.0,
# timeout: 请求超时(秒)
request_timeout=30,
# max_retries: 失败重试次数
max_retries=2,
)
不同场景的推荐参数配置:
| 场景 | temperature | top_p | max_tokens | 说明 |
|---|---|---|---|---|
| 代码生成 | 0.0 | 0.1 | 2048 | 需要精确、确定性输出 |
| 事实问答 | 0.1 | 0.3 | 512 | 低随机性,确保准确 |
| 日常对话 | 0.7 | 0.9 | 1024 | 平衡自然度和准确性 |
| 创意写作 | 1.2 | 0.95 | 2048 | 高随机性,鼓励创新 |
| 数据提取 | 0.0 | 0.1 | 512 | 严格按格式输出 |
结构化输出(bind_tools)
让模型返回结构化数据是实际应用中的高频需求:
from langchain_openai import ChatOpenAI
from pydantic import BaseModel, Field
# 方法一:使用 Pydantic 模型定义输出格式
class MovieReview(BaseModel):
"""电影评价"""
movie_name: str = Field(description="电影名称")
rating: int = Field(description="评分,1-10分")
summary: str = Field(description="一句话评价")
recommended: bool = Field(description="是否推荐观看")
llm = ChatOpenAI(model="gpt-4o-mini")
# 绑定输出格式
structured_llm = llm.with_structured_output(MovieReview)
result = structured_llm.invoke("请评价一下电影《肖申克的救赎》")
print(type(result)) # <class 'MovieReview'>
print(result.movie_name) # 肖申克的救赎
print(result.rating) # 10
print(result.summary) # 一部关于希望和自由的经典之作
print(result.recommended) # True
# 方法二:使用 with_structured_output + JSON Schema
from typing import Optional
from enum import Enum
class Sentiment(str, Enum):
POSITIVE = "正面"
NEGATIVE = "负面"
NEUTRAL = "中性"
class SentimentAnalysis(BaseModel):
"""情感分析结果"""
text: str = Field(description="分析的文本")
sentiment: Sentiment = Field(description="情感倾向")
confidence: float = Field(description="置信度,0-1之间")
keywords: list[str] = Field(description="关键词列表")
analyzer = llm.with_structured_output(SentimentAnalysis)
result = analyzer.invoke("这家餐厅的菜品味道很好,但是服务态度需要改进")
print(result.sentiment) # 中性
print(result.confidence) # 0.85
print(result.keywords) # ['菜品味道好', '服务态度']
提示词工程基础
为什么提示词很重要
同样的模型,不同的提示词可能产生天差地别的效果:
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o-mini")
# 差的提示词
bad = llm.invoke("说点关于Python的")
print(bad.content)
# 输出:可能是一段随机的 Python 历史介绍
# 好的提示词
good = llm.invoke(
"你是一个 Python 技术讲师。"
"请用3个要点解释 Python 的核心优势,"
"每个要点不超过30字,适合编程新手理解。"
)
print(good.content)
# 输出:结构清晰、准确的三个要点
提示词设计六要素
一个完整的提示词模板示例:
from langchain_core.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_messages([
# 1. 角色设定
("system", """你是一个资深的 {role},拥有10年以上的实战经验。
你的风格是:简洁、准确、注重实操。"""),
# 2. 任务 + 上下文
("human", """请帮我完成以下任务:
## 任务
{task}
## 背景
{context}
## 要求
- 输出格式:{output_format}
- 语言风格:专业但易懂
- 长度限制:{length_limit}
## 参考示例
{example}"""),
])
ChatPromptTemplate 详解
基本用法
ChatPromptTemplate 是 LangChain 管理提示词的核心工具:
from langchain_core.prompts import ChatPromptTemplate
# 方式一:从模板字符串创建
prompt = ChatPromptTemplate.from_template("给我讲一个关于{topic}的故事")
formatted = prompt.invoke({"topic": "太空探险"})
print(formatted)
# 显示: messages=[HumanMessage(content='给我讲一个关于太空探险的故事')]
# 方式二:从消息元组创建(推荐)
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个{role},擅长{skill}。"),
("human", "{question}"),
])
formatted = prompt.invoke({
"role": "Python 高级工程师",
"skill": "代码优化和重构",
"question": "如何减少 Django 项目的数据库查询次数?",
})
for msg in formatted.messages:
print(f"[{msg.type}] {msg.content}")
消息占位符
MessagesPlaceholder 用于动态插入一组消息(比如对话历史):
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个有帮助的AI助手。"),
MessagesPlaceholder(variable_name="chat_history"), # 动态消息列表
("human", "{input}"),
])
# 使用时传入历史对话
from langchain_core.messages import HumanMessage, AIMessage
result = prompt.invoke({
"chat_history": [
HumanMessage(content="你好,我叫小明"),
AIMessage(content="你好小明!很高兴认识你,有什么可以帮你的吗?"),
],
"input": "我叫什么名字?",
})
for msg in result.messages:
print(f"[{msg.type}] {msg.content}")
# 输出:
# [system] 你是一个有帮助的AI助手。
# [human] 你好,我叫小明
# [ai] 你好小明!很高兴认识你,有什么可以帮你的吗?
# [human] 我叫什么名字?
Few-Shot 提示(少样本学习)
通过提供示例来引导模型输出格式:
from langchain_core.prompts import ChatPromptTemplate, FewShotChatMessagePromptTemplate
# 定义示例
examples = [
{
"input": "这个产品真的太棒了,强烈推荐!",
"output": "{'sentiment': '正面', 'score': 0.95, 'keywords': ['产品棒', '推荐']}",
},
{
"input": "质量一般般,不值这个价格",
"output": "{'sentiment': '负面', 'score': 0.7, 'keywords': ['质量一般', '不值']}",
},
{
"input": "还行吧,没什么特别的",
"output': "{'sentiment': '中性', 'score': 0.5, 'keywords': ['没什么特别']}",
},
]
# 创建 Few-Shot 提示模板
example_prompt = ChatPromptTemplate.from_messages([
("human", "{input}"),
("ai", "{output}"),
])
few_shot_prompt = FewShotChatMessagePromptTemplate(
example_prompt=example_prompt,
examples=examples,
)
# 组合最终提示词
final_prompt = ChatPromptTemplate.from_messages([
("system", "你是一个情感分析专家,请分析文本的情感倾向。返回 JSON 格式。"),
few_shot_prompt,
("human", "{input}"),
])
# 使用
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o-mini")
chain = final_prompt | llm
response = chain.invoke({"input": "包装精美,但是味道不太行"})
print(response.content)
# 输出:{"sentiment": "负面", "score": 0.6, "keywords": ["包装精美", "味道不行"]}
提示词高级技巧
思维链(Chain of Thought)
引导模型分步推理,显著提升复杂问题的准确率:
from langchain_core.prompts import ChatPromptTemplate
cot_prompt = ChatPromptTemplate.from_messages([
("system", "你是一个数学老师,请一步步推理解答问题。"),
("human", """请解答以下问题,要求展示完整的推理过程:
问题:{question}
请按以下格式回答:
1. 理解问题:用自己的话复述问题
2. 已知条件:列出所有已知信息
3. 推理步骤:逐步推导
4. 最终答案:给出结论"""),
])
角色扮演提示
role_prompt = ChatPromptTemplate.from_messages([
("system", """你现在是 {character}。
## 你的背景
{background}
## 你的性格特点
{personality}
## 回答要求
- 保持角色一致性
- 使用符合角色的语气和用词
- 回答长度不超过200字"""),
("human", "{question}"),
])
# 使用示例:扮演代码审查专家
chain = role_prompt | ChatOpenAI(model="gpt-4o-mini")
result = chain.invoke({
"character": "资深代码审查专家",
"background": "15年开发经验,曾在 Google 和字节跳动担任技术主管,以严谨著称",
"personality": "直率、注重代码质量和可维护性,会指出每一个潜在问题",
"question": "请审查这段代码:def add(a, b): return a + b",
})
print(result.content)
组合提示词管道
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser
llm = ChatOpenAI(model="gpt-4o-mini")
# 步骤1:生成主题大纲
outline_prompt = ChatPromptTemplate.from_template(
"为以下主题生成3个核心要点:{topic}。只输出要点,每行一个。"
)
# 步骤2:展开每个要点
expand_prompt = ChatPromptTemplate.from_template(
"请将以下要点展开为一段100字左右的说明:{point}"
)
# 组合管道
outline_chain = outline_prompt | llm | StrOutputParser()
# 先生成大纲
outline = outline_chain.invoke({"topic": "Python 异步编程"})
print("=== 大纲 ===")
print(outline)
# 再逐个展开
points = [p.strip() for p in outline.strip().split("\n") if p.strip()]
for i, point in enumerate(points, 1):
expand_chain = expand_prompt | llm | StrOutputParser()
detail = expand_chain.invoke({"point": point})
print(f"\n=== 要点 {i}:{point} ===")
print(detail)
提示词模板管理
从文件加载提示词
大型项目中,提示词应该独立管理,不要和业务代码混在一起:
# prompts/qa_prompt.py
from langchain_core.prompts import ChatPromptTemplate
QA_SYSTEM_PROMPT = """你是一个专业的问答助手。请基于提供的上下文回答用户的问题。
## 规则
1. 只根据上下文内容回答,不要编造信息
2. 如果上下文中没有相关信息,明确告诉用户
3. 回答要简洁明了
## 上下文
{context}
"""
qa_prompt = ChatPromptTemplate.from_messages([
("system", QA_SYSTEM_PROMPT),
("human", "{question}"),
])
# 使用时导入
from prompts.qa_prompt import qa_prompt
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser
qa_chain = qa_prompt | ChatOpenAI(model="gpt-4o-mini") | StrOutputParser()
answer = qa_chain.invoke({
"context": "LangChain 是一个用于构建 LLM 应用的框架,由 Harrison Chase 创建。",
"question": "谁创建了 LangChain?",
})
print(answer)
# 输出:LangChain 由 Harrison Chase 创建。
提示词版本管理建议
# prompts/__init__.py
"""
提示词版本管理策略:
1. 重大变更时创建新版本文件(v1, v2)
2. 保留旧版本用于 A/B 测试
3. 在文件中记录变更原因和效果
"""
# V1 版本
SUMMARY_PROMPT_V1 = ChatPromptTemplate.from_template(
"请总结以下内容:{text}"
)
# V2 版本 — 增加了格式要求和长度限制
SUMMARY_PROMPT_V2 = ChatPromptTemplate.from_template(
"请总结以下内容,要求:\n"
"1. 不超过200字\n"
"2. 突出核心观点\n"
"3. 使用列表格式\n\n"
"内容:{text}"
)
# 当前使用版本
SUMMARY_PROMPT = SUMMARY_PROMPT_V2
本章小结
核心要点
- Chat Model 优先:使用
ChatOpenAI而非OpenAI(文本补全) - 结构化输出:使用
with_structured_output让模型返回 Pydantic 对象 - 提示词模板:使用
ChatPromptTemplate管理提示词,不要拼接字符串 - Few-Shot 学习:通过示例引导模型输出格式和行为
- 思维链:复杂问题引导模型分步推理,提升准确率