第2章:模型调用与提示词
本章将深入学习LangChain最核心的功能:如何调用各种AI模型,以及如何编写高效的提示词(Prompt)。掌握这些技能是构建LLM应用的基础。
2.1 支持的模型类型
LangChain支持多种大语言模型,让你可以根据需求灵活选择:
2.1.1 OpenAI模型
最常用、文档最完善的选项:
- GPT-4/GPT-4o:最强大的模型,适合复杂任务
- GPT-3.5-turbo:性价比高,响应速度快
- Text-Embedding:用于文本向量化的嵌入模型
# OpenAI模型使用示例
from langchain.llms import OpenAI
from langchain.chat_models import ChatOpenAI
# 文本补全模型(旧版接口)
llm = OpenAI(model_name="gpt-3.5-turbo-instruct")
# 对话模型(推荐使用)
chat_model = ChatOpenAI(model="gpt-3.5-turbo")
2.1.2 Anthropic Claude模型
以长文本处理和安全性著称:
# Anthropic Claude模型
from langchain.chat_models import ChatAnthropic
claude = ChatAnthropic(model="claude-3-sonnet-20240229")
2.1.3 本地模型(HuggingFace)
在本地运行开源模型,无需联网、数据隐私:
# HuggingFace本地模型
from langchain.llms import HuggingFacePipeline
from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
# 加载本地模型
model_id = "meta-llama/Llama-2-7b-chat-hf"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(model_id)
# 创建pipeline
pipe = pipeline(
"text-generation",
model=model,
tokenizer=tokenizer,
max_new_tokens=100
)
llm = HuggingFacePipeline(pipeline=pipe)
2.1.4 Azure OpenAI
企业级部署选择,符合合规要求:
# Azure OpenAI
from langchain.chat_models import AzureChatOpenAI
azure_llm = AzureChatOpenAI(
azure_deployment="your-deployment-name",
openai_api_version="2024-02-01",
azure_endpoint="https://your-resource.openai.azure.com/",
openai_api_key="your-azure-api-key"
)
2.1.5 其他模型
| 提供商 | 导入路径 | 特点 |
|---|---|---|
| Google Gemini | langchain.chat_models.ChatGoogleGenerativeAI |
Google最新模型 |
| Cohere | langchain.llms.Cohere |
专注于企业应用 |
| 百度文心 | langchain.llms.ErnieBot |
国产中文模型 |
| 阿里通义 | langchain.chat_models.ChatTongyi |
国产大模型 |
安装提示:使用不同模型前,需要先安装对应的Python包。例如:
pip install anthropic、pip install google-generativeai。
2.2 LLM vs Chat Model
LangChain提供了两种主要模型接口,理解它们的区别非常重要:
2.2.1 LLM(文本补全模型)
工作原理:接收一个文本字符串,预测后续文本。
- 输入:单个字符串
- 输出:单个字符串
- 类似"自动补全"功能
# LLM使用示例
from langchain.llms import OpenAI
# 创建LLM实例
llm = OpenAI(temperature=0.7)
# 输入一个字符串
prompt = "中国的首都是"
response = llm.predict(prompt)
print(response) # 输出: 北京
2.2.2 Chat Model(对话模型)
工作原理:接收一组消息(包含角色信息),生成回复消息。
- 输入:消息列表(System、Human、AI)
- 输出:AI消息对象
- 更适合构建对话应用
# Chat Model使用示例
from langchain.chat_models import ChatOpenAI
from langchain.schema import HumanMessage, SystemMessage
# 创建Chat Model实例
chat = ChatOpenAI(model="gpt-3.5-turbo", temperature=0.7)
# 构建消息列表
messages = [
SystemMessage(content="你是一个 helpful 的助手"), # 系统指令
HumanMessage(content="你好,请介绍一下自己") # 用户输入
]
# 调用模型
response = chat.predict_messages(messages)
print(response.content) # 输出AI的回复
2.2.3 代码对比
| 特性 | LLM | Chat Model |
|---|---|---|
| 输入类型 | 字符串 | 消息列表 |
| 支持系统指令 | ❌ 不支持 | ✅ 支持(SystemMessage) |
| 对话历史 | ❌ 手动拼接 | ✅ 消息列表自然支持 |
| 价格 | 部分模型较便宜 | GPT-3.5-turbo性价比高 |
| 推荐使用 | 简单文本任务 | ⭐ 对话应用(强烈推荐) |
最佳实践:新建项目建议直接使用 Chat Model(如 ChatOpenAI),它功能更强大、设计更合理,是LangChain推荐的主流用法。
2.3 Prompt Templates(提示词模板)
提示词模板是LangChain最强大的功能之一,让你可以创建可复用、可配置的提示词。
2.3.1 什么是提示词模板?
提示词模板 = 提示词 + 变量占位符
类比理解:
- 普通提示词:"用一句话介绍Python编程语言"
- 提示词模板:"用一句话介绍{language}编程语言" → 可替换为任意语言
2.3.2 PromptTemplate基础用法
用于LLM(文本补全模型)的模板:
# PromptTemplate基础用法
from langchain.prompts import PromptTemplate
# 方式1:使用from_template工厂方法(推荐)
template = PromptTemplate.from_template(
"请用{style}风格,介绍一下{topic}"
)
# 方式2:直接实例化
template = PromptTemplate(
input_variables=["style", "topic"],
template="请用{style}风格,介绍一下{topic}"
)
# 格式化模板(填入变量值)
formatted_prompt = template.format(
style="幽默",
topic="人工智能"
)
print(formatted_prompt)
# 输出: 请用幽默风格,介绍一下人工智能
2.3.3 ChatPromptTemplate对话模板
用于Chat Model的模板,支持多角色消息:
# ChatPromptTemplate使用示例
from langchain.prompts import ChatPromptTemplate
from langchain.schema import SystemMessage, HumanMessage
# 方式1:使用from_messages创建多角色模板
chat_template = ChatPromptTemplate.from_messages([
("system", "你是一个专业的{role}"),
("human", "{question}")
])
# 方式2:使用消息对象
chat_template = ChatPromptTemplate.from_messages([
SystemMessage(content="你是一个专业的{role}"),
HumanMessage(content="{question}")
])
# 格式化模板
messages = chat_template.format_messages(
role="厨师",
question="如何做红烧肉?"
)
# messages现在是:[SystemMessage, HumanMessage]
print(messages)
2.3.4 带变量的模板实战
更复杂的模板示例,包含多个变量和不同类型的消息:
# 复杂模板示例
from langchain.prompts import ChatPromptTemplate
from langchain.chat_models import ChatOpenAI
# 创建一个翻译助手的提示词模板
translation_template = ChatPromptTemplate.from_messages([
# 系统指令:定义AI的角色和行为
("system", """你是一个专业的翻译助手。
请将用户输入的{text_language}文本翻译成{target_language}。
要求:
1. 保持原文的语气和风格
2. 专业术语翻译准确
3. 只输出翻译结果,不要解释"""),
# few-shot示例:给AI举例子
("human", "Hello, how are you?"),
("ai", "你好,你好吗?"),
# 真正的用户输入
("human", "{input_text}")
])
# 使用模板
messages = translation_template.format_messages(
text_language="英文",
target_language="中文",
input_text="The quick brown fox jumps over the lazy dog."
)
# 调用模型
chat = ChatOpenAI()
response = chat.predict_messages(messages)
print(response.content)
提示词工程技巧:在模板中加入few-shot示例(给AI看几个例子),能显著提升输出质量。人类学习需要例子,AI也一样!
2.3.5 模板的高级特性
# 模板组合
from langchain.prompts import PromptTemplate, ChatPromptTemplate
# 创建基础模板
base_template = PromptTemplate.from_template("请用{tone}的语气")
instruction_template = PromptTemplate.from_template("解释{topic}")
# 组合模板
full_template = PromptTemplate.from_template(
"{base},{instruction}",
partial_variables={
"base": base_template,
"instruction": instruction_template
}
)
# 部分格式化(先填部分变量)
template = PromptTemplate.from_template("你好{name},{message}")
partial_template = template.partial(name="小明") # 先填入name
final = partial_template.format(message="欢迎光临!") # 再填入message
2.4 输出解析器 Output Parsers
大语言模型输出的是文本,但我们通常需要结构化数据(如JSON)。输出解析器可以自动完成这个转换。
2.4.1 PydanticOutputParser结构化输出
使用Pydantic定义数据模型,让AI按指定格式输出:
# PydanticOutputParser示例
from langchain.output_parsers import PydanticOutputParser
from langchain.prompts import PromptTemplate
from langchain.chat_models import ChatOpenAI
from pydantic import BaseModel, Field
from typing import List
# 第1步:定义输出数据结构
class MovieReview(BaseModel):
"""电影评论的结构化输出格式"""
movie_name: str = Field(description="电影名称")
rating: float = Field(description="评分(1-10分)")
summary: str = Field(description="一句话总结")
pros: List[str] = Field(description="优点列表")
cons: List[str] = Field(description="缺点列表")
# 第2步:创建解析器
parser = PydanticOutputParser(pydantic_object=MovieReview)
# 第3步:查看格式说明(会自动生成)
format_instructions = parser.get_format_instructions()
print(format_instructions)
# 输出包含JSON格式的说明和要求
# 第4步:创建带格式说明的提示词模板
prompt = PromptTemplate(
template="""请对以下电影进行评论:
{movie_title}
{format_instructions}
""",
input_variables=["movie_title"],
partial_variables={"format_instructions": format_instructions}
)
# 第5步:调用模型
chat = ChatOpenAI(temperature=0)
formatted_prompt = prompt.format(movie_title="肖申克的救赎")
response = chat.predict(formatted_prompt)
# 第6步:解析输出
movie_review = parser.parse(response)
print(f"电影: {movie_review.movie_name}")
print(f"评分: {movie_review.rating}")
print(f"优点: {movie_review.pros}")
2.4.2 JsonOutputParser
如果只需要JSON格式,可以使用更简单的JsonOutputParser:
# JsonOutputParser示例
from langchain.output_parsers import JsonOutputParser
from langchain.prompts import PromptTemplate
from langchain.chat_models import ChatOpenAI
# 创建JSON解析器
parser = JsonOutputParser()
# 获取格式说明
format_instructions = parser.get_format_instructions()
# 创建提示词
template = """请提取以下文本中的关键信息,并以JSON格式输出:
文本: {text}
{format_instructions}
"""
prompt = PromptTemplate(
template=template,
input_variables=["text"],
partial_variables={"format_instructions": format_instructions}
)
# 调用
chat = ChatOpenAI()
response = chat.predict(prompt.format(text="张三,25岁,软件工程师,毕业于清华大学"))
# 解析JSON
data = parser.parse(response)
print(data)
# 输出: {'name': '张三', 'age': 25, ...}
2.4.3 完整示例:让AI输出JSON格式
# 完整的结构化输出示例
from langchain.output_parsers import PydanticOutputParser
from langchain.prompts import ChatPromptTemplate
from langchain.chat_models import ChatOpenAI
from pydantic import BaseModel, Field
# 定义产品信息的数据结构
class ProductInfo(BaseModel):
product_name: str = Field(description="产品名称")
category: str = Field(description="产品类别")
price_range: str = Field(description="价格区间")
key_features: list = Field(description="主要特点列表")
target_audience: str = Field(description="目标用户群体")
# 创建解析器
parser = PydanticOutputParser(pydantic_object=ProductInfo)
# 创建提示词模板
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个产品分析专家。请分析用户输入的产品描述,提取关键信息。"),
("human", """请分析以下产品:
{product_description}
{format_instructions}
""")
])
# 填入变量
messages = prompt.format_messages(
product_description="iPhone 15 Pro Max,售价9999元起,搭载A17 Pro芯片,配备钛金属边框,支持USB-C接口,拥有4800万像素主摄,适合追求极致体验的高端用户。",
format_instructions=parser.get_format_instructions()
)
# 调用模型
chat = ChatOpenAI(temperature=0)
response = chat.predict_messages(messages)
# 解析结果
product = parser.parse(response.content)
print(product.json(indent=2, ensure_ascii=False))
注意事项:即使使用了输出解析器,AI有时仍可能输出不符合格式的内容(特别是弱一点的模型)。生产环境建议加上错误处理:
try/except 包裹 parser.parse()。
2.5 Runnable接口与管道操作符
LangChain Expression Language (LCEL) 提供了更简洁的链式调用方式。
2.5.1 pipe操作符 | 的使用
使用 | 符号将多个组件串联起来:
# Runnable接口与管道操作符
from langchain.prompts import ChatPromptTemplate
from langchain.chat_models import ChatOpenAI
from langchain.output_parsers import StrOutputParser
# 定义提示词模板
prompt = ChatPromptTemplate.from_template(
"请用中文解释{concept}的概念"
)
# 创建模型
model = ChatOpenAI(model="gpt-3.5-turbo")
# 创建输出解析器(将AIMessage转为字符串)
output_parser = StrOutputParser()
# 使用管道符连接组件 |
# 数据流向: prompt -> model -> output_parser
chain = prompt | model | output_parser
# 调用链
result = chain.invoke({"concept": "区块链"})
print(result)
# 等价于传统写法:
# messages = prompt.format_messages(concept="区块链")
# response = model.predict_messages(messages)
# result = output_parser.parse(response)
2.5.2 管道的工作流程
# 复杂管道示例
from langchain.prompts import ChatPromptTemplate
from langchain.chat_models import ChatOpenAI
from langchain.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field
# 定义输出结构
class AnalysisResult(BaseModel):
keywords: list = Field(description="关键词列表")
sentiment: str = Field(description="情感倾向")
summary: str = Field(description="内容摘要")
parser = PydanticOutputParser(pydantic_object=AnalysisResult)
# 创建提示词
prompt = ChatPromptTemplate.from_template("""
请分析以下文本:
{text}
{format_instructions}
""")
# 构建管道
# 第一步:将输入字典格式化为提示词
# 第二步:调用模型生成回复
# 第三步:解析为结构化数据
chain = (
{"text": lambda x: x["text"], "format_instructions": lambda x: parser.get_format_instructions()}
| prompt
| ChatOpenAI(temperature=0)
| parser
)
# 调用
result = chain.invoke({"text": "这家餐厅的食物太美味了!服务也很棒,下次一定再来!"})
print(result)
管道操作符的优势:
1. 代码更简洁、可读性更强
2. 自动支持流式输出(streaming)
3. 自动支持批处理(batch)
4. 内置重试和错误处理机制
1. 代码更简洁、可读性更强
2. 自动支持流式输出(streaming)
3. 自动支持批处理(batch)
4. 内置重试和错误处理机制
2.6 完整实战:构建"翻译助手"链
综合运用本章知识,构建一个完整的翻译助手应用。
2.6.1 需求分析
我们要实现的功能:
- 输入:中文文本
- 处理:翻译成英文
- 输出:JSON格式(包含原文、译文、单词数)
2.6.2 完整代码
# translator_app.py
# 完整实战:构建翻译助手链
from langchain.prompts import ChatPromptTemplate
from langchain.chat_models import ChatOpenAI
from langchain.output_parsers import PydanticOutputParser
from langchain.schema import StrOutputParser
from pydantic import BaseModel, Field
from typing import Literal
# ==================== 第1步:定义输出数据结构 ====================
class TranslationResult(BaseModel):
"""翻译结果的数据结构"""
original_text: str = Field(description="原文")
translated_text: str = Field(description="译文")
source_language: Literal["中文", "英文"] = Field(description="源语言")
target_language: Literal["中文", "英文"] = Field(description="目标语言")
word_count: int = Field(description="译文单词/字数")
confidence: Literal["高", "中", "低"] = Field(description="翻译置信度")
# ==================== 第2步:创建组件 ====================
# 创建输出解析器
parser = PydanticOutputParser(pydantic_object=TranslationResult)
# 创建提示词模板
translation_prompt = ChatPromptTemplate.from_messages([
("system", """你是一位专业的翻译助手,精通中英文互译。
请将用户的输入翻译成目标语言,并提供结构化输出。
翻译要求:
1. 准确传达原文意思
2. 保持原文的语气和风格
3. 专业术语翻译准确
4. 如果原文有歧义,选择最可能的解释
"""),
("human", """请翻译以下内容:
源语言: {source_language}
目标语言: {target_language}
原文: {text}
{format_instructions}
""")
])
# 创建模型
model = ChatOpenAI(
model="gpt-3.5-turbo",
temperature=0.3 # 翻译任务需要较低的温度以保证准确性
)
# ==================== 第3步:构建链 ====================
# 使用管道操作符构建链
# 输入: {"text": "...", "source_language": "...", "target_language": "..."}
# 输出: TranslationResult对象
translation_chain = (
{
"text": lambda x: x["text"],
"source_language": lambda x: x["source_language"],
"target_language": lambda x: x["target_language"],
"format_instructions": lambda x: parser.get_format_instructions()
}
| translation_prompt
| model
| parser
)
# ==================== 第4步:使用链 ====================
def translate(text: str, source: str = "中文", target: str = "英文") -> TranslationResult:
"""
翻译函数
参数:
text: 要翻译的文本
source: 源语言("中文"或"英文")
target: 目标语言("中文"或"英文")
返回:
TranslationResult对象,包含翻译结果和元信息
"""
try:
result = translation_chain.invoke({
"text": text,
"source_language": source,
"target_language": target
})
return result
except Exception as e:
print(f"翻译出错: {e}")
raise
# ==================== 第5步:测试运行 ====================
if __name__ == "__main__":
# 测试1: 中译英
print("=" * 50)
print("测试1: 中译英")
print("=" * 50)
result1 = translate(
text="人工智能正在改变我们的生活方式。",
source="中文",
target="英文"
)
print(f"原文: {result1.original_text}")
print(f"译文: {result1.translated_text}")
print(f"字数: {result1.word_count}")
print(f"置信度: {result1.confidence}")
# 测试2: 英译中
print("\n" + "=" * 50)
print("测试2: 英译中")
print("=" * 50)
result2 = translate(
text="The future belongs to those who believe in the beauty of their dreams.",
source="英文",
target="中文"
)
print(f"原文: {result2.original_text}")
print(f"译文: {result2.translated_text}")
print(f"字数: {result2.word_count}")
print(f"置信度: {result2.confidence}")
# 以JSON格式输出
print("\n" + "=" * 50)
print("JSON格式输出:")
print("=" * 50)
print(result2.json(indent=2, ensure_ascii=False))
2.6.3 运行结果示例
==================================================
测试1: 中译英
==================================================
原文: 人工智能正在改变我们的生活方式。
译文: Artificial intelligence is transforming the way we live.
字数: 9
置信度: 高
==================================================
测试2: 英译中
==================================================
原文: The future belongs to those who believe in the beauty of their dreams.
译文: 未来属于那些相信梦想之美的人。
字数: 16
置信度: 高
==================================================
JSON格式输出:
==================================================
{
"original_text": "The future belongs to those who believe in the beauty of their dreams.",
"translated_text": "未来属于那些相信梦想之美的人。",
"source_language": "英文",
"target_language": "中文",
"word_count": 16,
"confidence": "高"
}
代码亮点:
1. 使用Pydantic严格定义输入输出结构
2. 提示词模板包含清晰的翻译要求
3. 管道操作符让代码简洁易读
4. 添加了完整的错误处理
5. 支持中/英双向翻译
1. 使用Pydantic严格定义输入输出结构
2. 提示词模板包含清晰的翻译要求
3. 管道操作符让代码简洁易读
4. 添加了完整的错误处理
5. 支持中/英双向翻译
本章小结
恭喜完成第2章的学习!你已经掌握了LangChain最核心的技能:
- ✅ 了解各种模型类型和如何选择
- ✅ 掌握LLM和Chat Model的区别(强烈推荐使用Chat Model)
- ✅ 熟练使用PromptTemplate和ChatPromptTemplate
- ✅ 使用Output Parser获取结构化输出
- ✅ 使用Runnable接口和管道操作符简化代码
- ✅ 完成一个完整的翻译助手实战项目
关键概念回顾
| 概念 | 用途 | 关键类/方法 |
|---|---|---|
| Chat Model | 对话式AI交互 | ChatOpenAI, predict_messages() |
| 提示词模板 | 复用和参数化提示词 | ChatPromptTemplate.from_messages() |
| 输出解析器 | 结构化模型输出 | PydanticOutputParser |
| 管道操作符 | 链式组合组件 | | (如 prompt | model | parser) |
下章预告:第3章我们将学习Chains(链)的更多用法,以及如何使用Memory让AI记住对话历史,构建真正的对话机器人!